/******************************Module*Header*******************************\ * Module Name: PAINT.c * Author: Noel VanHook * Date: Mar. 21, 1995 * Purpose: Handle calls to DrvPaint * * Copyright (c) 1995 Cirrus Logic, Inc. * \**************************************************************************/ /* This module handles calls to DrvPaint() by converting them into calls to DrvBitBlt(). The only conversion needed to to change the MIX into a ROP4. */ #include "precomp.h" #define PAINT_DBG_LEVEL 1 //========================================================================== // // In an attempt to trace the problems with the FIFO, we supply a few // macros that will allow us to easily try different FIFO stratagies. // // // This macro is executed at the start of every BLT, before any registers // are written. // #define STARTBLT() \ do { \ }while (0) // // This macro is executed at the top of inner BLT loops. // If there were clipping, for example, STARTBLT() would be executed // once at the start of the BLT, and STARTBLTLOOP() would be executed // before each rectangle in the clip list. // #define STARTBLTLOOP() \ do { \ REQUIRE(0); \ }while (0) //========================================================================== // // Table to convert ROP2 codes to ROP3 codes. // BYTE Rop2ToRop3[]= { 0xFF, // R2_WHITE /* 1 */ 0x00, // R2_BLACK /* 0 */ 0x05, // R2_NOTMERGEPEN /* DPon */ 0x0A, // R2_MASKNOTPEN /* DPna */ 0x0F, // R2_NOTCOPYPEN /* PN */ 0x50, // R2_MASKPENNOT /* PDna */ 0x55, // R2_NOT /* Dn */ 0x5A, // R2_XORPEN /* DPx */ 0x5F, // R2_NOTMASKPEN /* DPan */ 0xA0, // R2_MASKPEN /* DPa */ 0xA5, // R2_NOTXORPEN /* DPxn */ 0xAA, // R2_NOP /* D */ 0xAF, // R2_MERGENOTPEN /* DPno */ 0xF0, // R2_COPYPEN /* P */ 0xF5, // R2_MERGEPENNOT /* PDno */ 0xFA, // R2_MERGEPEN /* DPo */ 0xFF // R2_WHITE /* 1 */ }; // // If data logging is enabled, Prototype the logging files. // #if LOG_CALLS void LogPaint( int acc, SURFOBJ* psoDest, MIX mix, CLIPOBJ* pco, BRUSHOBJ* pbo); // // If data logging is not enabled, compile out the calls. // #else #define LogPaint(acc, psoDest, mix, pco, pbo) #endif /**************************************************************************\ * DrvPaint * * * * Paint the clipping region with the specified brush * * Accomplished by converting into a call to DrvBitBlt() * * * \**************************************************************************/ BOOL DrvPaint ( SURFOBJ *pso, CLIPOBJ *pco, BRUSHOBJ *pbo, POINTL *pptlBrush, MIX mix ) { ULONG fg_rop, bg_rop, rop4; DWORD color; PPDEV ppdev; #if NULL_PAINT { if (pointer_switch) return TRUE; } #endif ppdev = (PPDEV) pso->dhpdev; ASSERTMSG (ppdev,"No PDEV in DrvPaint."); SYNC_W_3D(ppdev); // // The destination rectangle is defined by the clipping region, // so we should never get a null clipping region. // ASSERTMSG (pco, "DrvPaint without a clip object!\n"); DISPDBG((PAINT_DBG_LEVEL,"Drvpaint: Entry.\n")); // Are we painting to a device bitmap? if (pso->iType == STYPE_DEVBITMAP) { // Yes. PDSURF pdsurf = (PDSURF)pso->dhsurf; // Is the device bitmap currently in host memory? if ( pdsurf->pso ) { // Yes. Move it into off screen memory. if ( !bCreateScreenFromDib(ppdev, pdsurf) ) { // We couldn't move it to off-screen memory. LogPaint(1, pso, mix, pco, pbo); return EngPaint(pdsurf->pso, pco, pbo, pptlBrush, mix); } } // The device bitmap now resides in off-screen memory. // This is the offset to it. ppdev->ptlOffset.x = pdsurf->ptl.x; ppdev->ptlOffset.y = pdsurf->ptl.y; } else { // No, we are not painting to a device bitmap. ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0; } // // DrvPaint is most often called with // mix 0D (PAT COPY) and mix 06 (DEST INVERT). // It behooves us, therefore, to handle these as // special cases... provided they aren't clipped. // if ((pco->iDComplexity != DC_COMPLEX)) { // =================== PATCOPY ================================== if (mix == 0x0D0D) { ASSERTMSG(pbo, "DrvPaint PATCOPY without a brush.\n"); if (pbo->iSolidColor != 0xFFFFFFFF) // Solid color { color = pbo->iSolidColor; switch (ppdev->ulBitCount) { case 8: // For 8 bpp duplicate byte 0 into byte 1. color |= (color << 8); case 16: // For 8,16 bpp, duplicate the low word into the high word. color |= (color << 16); break; } REQUIRE(9); LL_BGCOLOR(color, 0); LL_DRAWBLTDEF(0x100700F0, 0); LL_OP0(pco->rclBounds.left + ppdev->ptlOffset.x, pco->rclBounds.top + ppdev->ptlOffset.y); LL_BLTEXT ((pco->rclBounds.right - pco->rclBounds.left), (pco->rclBounds.bottom - pco->rclBounds.top)); LogPaint(0, pso, mix, pco, pbo); return TRUE; } // End PATCOPY with solid color. else // PATCOPY with a brush. { DWORD bltdef = 0x1000; if (SetBrush(ppdev, &bltdef, pbo, pptlBrush)) { REQUIRE(7); LL_DRAWBLTDEF((bltdef << 16) | 0x00F0, 0); LL_OP0 (pco->rclBounds.left + ppdev->ptlOffset.x, pco->rclBounds.top + ppdev->ptlOffset.y); LL_BLTEXT ((pco->rclBounds.right - pco->rclBounds.left) , (pco->rclBounds.bottom - pco->rclBounds.top) ); LogPaint(0, pso, mix, pco, pbo); return TRUE; } } // End PATCOPY with a brush } // End PATCOPY // ======================= DEST INVERT ============================ else if (mix == 0x0606) { REQUIRE(7); LL_DRAWBLTDEF(0x11000055, 0); LL_OP0(pco->rclBounds.left + ppdev->ptlOffset.x, pco->rclBounds.top + ppdev->ptlOffset.y); LL_BLTEXT ((pco->rclBounds.right - pco->rclBounds.left), (pco->rclBounds.bottom - pco->rclBounds.top) ); LogPaint(0, pso, mix, pco, pbo); return TRUE; } // End DEST INVERT } // End special cases // First, convert the fg and bg mix into a fg and bg rop fg_rop = Rop2ToRop3[ (mix & 0x0F) ]; // convert fg mix to fg rop. bg_rop = Rop2ToRop3[ ((mix>>8) & 0x0F) ]; // convert bg mix to bg rop rop4 = (bg_rop<<8) | fg_rop; // build rop4. // // Now convert Paint to BitBLT // LogPaint(2, pso, mix, pco, pbo); DISPDBG((PAINT_DBG_LEVEL,"Drvpaint: Convert to DrvBitBlt().\n")); return DrvBitBlt(pso, // Target (SURFOBJ *) NULL, // Source (SURFOBJ *) NULL, // Mask pco, // Clip object (XLATEOBJ *) NULL, // Xlate object &(pco->rclBounds), // Dest rectangle. (PPOINTL) NULL, // Src point. (PPOINTL) NULL, // Mask point. pbo, // Brush pptlBrush, // Brush alignment rop4); // ROP4 } #if LOG_CALLS // ============================================================================ // // Everything from here down is for data logging and is not used in the // production driver. // // ============================================================================ // **************************************************************************** // // LogPaint() // This routine is called only from DrvPaint() // Dump information to a file about what is going on in DrvPaint land. // // **************************************************************************** void LogPaint( int acc, SURFOBJ* psoDest, MIX mix, CLIPOBJ* pco, BRUSHOBJ* pbo) { PPDEV dppdev,sppdev,ppdev; char buf[256]; int i; BYTE fg_rop, bg_rop; ULONG iDComplexity; ppdev = (PPDEV) (psoDest ? psoDest->dhpdev : 0); #if ENABLE_LOG_SWITCH if (pointer_switch == 0) return; #endif i = sprintf(buf,"DrvPaint: "); WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); switch(acc) { case 0: // Accelerated i = sprintf(buf, "ACCL "); break; case 1: // Punted i = sprintf(buf,"PUNT host "); break; case 2: // Punted i = sprintf(buf, "PUNT BitBlt "); break; default: i = sprintf(buf, "PUNT unknown "); break; } WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); // // Check the DEST // if (psoDest) { if (psoDest->iType == STYPE_DEVBITMAP) { i = sprintf(buf, "Id=%p ", psoDest->dhsurf); WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); if ( ((PDSURF)psoDest->dhsurf)->pso ) i = sprintf(buf,"DST=DH "); else i = sprintf(buf,"DST=DF "); } else if (psoDest->hsurf == ppdev->hsurfEng) i = sprintf(buf,"DST=S "); else i = sprintf(buf,"DST=H "); } else i = sprintf(buf,"DST=N "); WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); // // Check the MIX // i = sprintf(buf,"MIX = 0x%04X ", mix); WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); // // Check the type of clipping. // iDComplexity = (pco ? pco->iDComplexity : DC_TRIVIAL); i = sprintf(buf,"CLIP=%s ", (iDComplexity==DC_TRIVIAL ? "T": (iDComplexity == DC_RECT ? "R" : "C" ))); WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); // // Type of pattern. // if (pbo == NULL) { i = sprintf(buf,"BRUSH=N "); WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } else if (pbo->iSolidColor == 0xFFFFFFFF ) { i = sprintf(buf,"BRUSH=P "); WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } else { i = sprintf(buf,"BRUSH=0x%08X ",(pbo->iSolidColor)); WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } i = sprintf(buf,"\r\n"); WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } #endif