/* * Called by vmwareSetState() to ensure that the color register is properly set * for execution of rendering functions. */ static inline void vmware_validate_COLOR( VMWareDeviceData *vdev, CardState *state ) { switch (vdev->dst_format) { case DSPF_ARGB: vdev->color_pixel = PIXEL_ARGB( state->color.a, state->color.r, state->color.g, state->color.b ); break; case DSPF_RGB32: vdev->color_pixel = PIXEL_RGB32( state->color.r, state->color.g, state->color.b ); break; case DSPF_RGB16: vdev->color_pixel = PIXEL_RGB16( state->color.r, state->color.g, state->color.b ); break; default: D_BUG( "unexpected format %s", dfb_pixelformat_name(vdev->dst_format) ); } /* Set the flag. */ VMWARE_VALIDATE( COLOR ); }
/* * Called by pvr2dSetState() to ensure that the color is properly set * for execution of blitting functions. gdev->prog_index must be valid. */ static inline void pvr2d_validate_COLOR_BLIT(PVR2DDriverData *gdrv, PVR2DDeviceData *gdev, CardState *state) { D_DEBUG_AT(PVR2D__2D, "%s()\n", __FUNCTION__); gdrv->bltinfo.Colour = PIXEL_ARGB( state->color.a, state->color.r, state->color.g, state->color.b ); // Set the flag. PVR2D_VALIDATE(COLOR_BLIT); }
/* * Render a blended rectangle using the current hardware state. * * As the hardware does not directly support this, we blit a single * pixel with blending. */ static bool pxa3xxFillRectangleBlend( void *drv, void *dev, DFBRectangle *rect ) { PXA3XXDriverData *pdrv = drv; PXA3XXDeviceData *pdev = dev; u32 *prep = start_buffer( pdrv, 22 ); const u32 format = pixel_formats[DFB_PIXELFORMAT_INDEX( DSPF_ARGB )]; D_DEBUG_AT( PXA3XX_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( rect ) ); DUMP_INFO(); /* Set fake destination. */ prep[0] = 0x020000A2; prep[1] = pdev->fake_phys; prep[2] = (format << 19) | 4; /* Fill rectangle. */ prep[3] = 0x40000014 | (format << 8); prep[4] = 0; prep[5] = 0; prep[6] = PXA3XX_WH( rect->w, 1 ); prep[7] = PIXEL_ARGB( pdev->color.a, pdev->color.r, pdev->color.g, pdev->color.b ); /* Restore destination. */ prep[8] = 0x020000A2; prep[9] = pdev->dst_phys; prep[10] = (pixel_formats[pdev->dst_index] << 19) | (pdev->dst_pitch << 5) | pdev->dst_bpp; /* Set fake buffer as source. */ prep[11] = 0x02000002; prep[12] = pdev->fake_phys; prep[13] = (format << 19) | 4; /* Blit with blending. */ prep[14] = 0x47000107; prep[15] = rect->x; prep[16] = rect->y; prep[17] = 0; prep[18] = 0; prep[19] = rect->x; prep[20] = rect->y; prep[21] = PXA3XX_WH( rect->w, rect->h ); submit_buffer( pdrv, 22 ); /* Clear the flag. */ PXA3XX_INVALIDATE( SOURCE ); return true; }
static inline void tdfx_validate_color1( TDFXDriverData *tdrv, TDFXDeviceData *tdev, CardState *state ) { if (tdev->v_color1) return; tdfx_waitfifo( tdrv, tdev, 1 ); tdrv->voodoo3D->color1 = PIXEL_ARGB( state->color.a, state->color.r, state->color.g, state->color.b ); tdev->v_color1 = 1; }
static inline void savage4_validate_color( Savage4DeviceData *sdev, CardState *state ) { if (sdev->v_color) return; switch (state->destination->config.format) { case DSPF_A8: sdev->Fill_Color = state->color.a; break; case DSPF_ARGB1555: sdev->Fill_Color = PIXEL_ARGB1555(state->color.a, state->color.r, state->color.g, state->color.b); break; case DSPF_RGB16: sdev->Fill_Color = PIXEL_RGB16(state->color.r, state->color.g, state->color.b); break; case DSPF_RGB32: sdev->Fill_Color = PIXEL_RGB32(state->color.r, state->color.g, state->color.b); break; case DSPF_ARGB: sdev->Fill_Color = PIXEL_ARGB(state->color.a, state->color.r, state->color.g, state->color.b); break; case DSPF_RGB332: sdev->Fill_Color = PIXEL_RGB332(state->color.r, state->color.g, state->color.b); break; default: D_BUG( "unexpected destination format" ); break; } sdev->v_color = 1; }
static inline void savage3D_validate_color( Savage3DDriverData *sdrv, Savage3DDeviceData *sdev, CardState *state ) { if (sdev->v_color) return; savage3D_waitfifo( sdrv, sdev, 2 ); BCI_SEND( BCI_CMD_NOP | BCI_CMD_SEND_COLOR ); switch (state->destination->config.format) { case DSPF_A8: BCI_SEND( state->color.a ); break; case DSPF_ARGB1555: BCI_SEND( PIXEL_ARGB1555(state->color.a, state->color.r, state->color.g, state->color.b) ); break; case DSPF_RGB16: BCI_SEND( PIXEL_RGB16(state->color.r, state->color.g, state->color.b) ); break; case DSPF_RGB32: BCI_SEND( PIXEL_RGB32(state->color.r, state->color.g, state->color.b) ); break; case DSPF_ARGB: BCI_SEND( PIXEL_ARGB(state->color.a, state->color.r, state->color.g, state->color.b) ); break; default: D_ONCE( "unsupported destination format" ); break; } sdev->v_color = 1; }
static inline void tdfx_validate_colorFore( TDFXDriverData *tdrv, TDFXDeviceData *tdev, CardState *state ) { if (tdev->v_colorFore) return; tdfx_waitfifo( tdrv, tdev, 1 ); switch (state->destination->config.format) { case DSPF_A8: tdrv->voodoo2D->colorFore = state->color.a; break; case DSPF_ARGB1555: tdrv->voodoo2D->colorFore = PIXEL_ARGB1555( state->color.a, state->color.r, state->color.g, state->color.b ); break; case DSPF_RGB16: tdrv->voodoo2D->colorFore = PIXEL_RGB16( state->color.r, state->color.g, state->color.b ); break; case DSPF_RGB24: case DSPF_RGB32: tdrv->voodoo2D->colorFore = PIXEL_RGB32( state->color.r, state->color.g, state->color.b ); break; case DSPF_ARGB: tdrv->voodoo2D->colorFore = PIXEL_ARGB( state->color.a, state->color.r, state->color.g, state->color.b ); break; default: D_BUG( "unexpected pixelformat!" ); break; } tdev->v_colorFore = 1; }
void sis_validate_color(SiSDriverData *drv, SiSDeviceData *dev, CardState *state) { u32 color; if (dev->v_color) return; switch (state->destination->config.format) { case DSPF_LUT8: color = state->color_index; break; case DSPF_ARGB1555: color = PIXEL_ARGB1555(state->color.a, state->color.r, state->color.g, state->color.b); break; case DSPF_RGB16: color = PIXEL_RGB16(state->color.r, state->color.g, state->color.b); break; case DSPF_RGB32: color = PIXEL_RGB32(state->color.r, state->color.g, state->color.b); break; case DSPF_ARGB: color = PIXEL_ARGB(state->color.a, state->color.r, state->color.g, state->color.b); break; default: D_BUG("unexpected pixelformat"); return; } sis_wl(drv->mmio_base, SIS315_2D_PAT_FG_COLOR, color); dev->v_color = 1; }
static bool stretch_hvx( CardState *state, DFBRectangle *srect, DFBRectangle *drect ) { GenefxState *gfxs; const StretchFunctionTable *table; StretchHVx stretch; bool down = false; void *dst; void *src; StretchCtx ctx; int idx = STRETCH_NONE; u32 colors[256]; D_ASSERT( state != NULL ); DFB_RECTANGLE_ASSERT( srect ); DFB_RECTANGLE_ASSERT( drect ); gfxs = state->gfxs; if (srect->w > drect->w && srect->h > drect->h) down = true; if (down) { if (!(state->render_options & DSRO_SMOOTH_DOWNSCALE)) return false; } else { if (!(state->render_options & DSRO_SMOOTH_UPSCALE)) return false; } switch (gfxs->dst_format) { case DSPF_NV12: case DSPF_NV21: return stretch_hvx_planar( state, srect, drect, down ); default: break; } if (state->blittingflags & ~(DSBLIT_COLORKEY_PROTECT | DSBLIT_SRC_COLORKEY | DSBLIT_SRC_PREMULTIPLY)) return false; if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY && !DFB_PIXELFORMAT_IS_INDEXED( gfxs->src_format )) return false; if (DFB_PIXELFORMAT_INDEX(gfxs->dst_format) >= D_ARRAY_SIZE(stretch_tables)) return false; if (DFB_PIXELFORMAT_INDEX(gfxs->src_format) >= D_ARRAY_SIZE((stretch_tables[0])->f)) return false; table = stretch_tables[DFB_PIXELFORMAT_INDEX(gfxs->dst_format)]; if (!table) return false; if (state->blittingflags & DSBLIT_SRC_COLORKEY) idx |= STRETCH_SRCKEY; if (state->blittingflags & DSBLIT_COLORKEY_PROTECT) idx |= STRETCH_PROTECT; if (down) stretch = table->f[DFB_PIXELFORMAT_INDEX(gfxs->src_format)].down[idx]; else stretch = table->f[DFB_PIXELFORMAT_INDEX(gfxs->src_format)].up[idx]; if (!stretch) return false; ctx.clip = state->clip; if (!dfb_region_rectangle_intersect( &ctx.clip, drect )) return false; dfb_region_translate( &ctx.clip, - drect->x, - drect->y ); if (DFB_PIXELFORMAT_IS_INDEXED( gfxs->src_format )) { int i; const DFBColor *entries; u16 *colors16 = (void*) colors; D_ASSERT( gfxs->Blut != NULL ); entries = gfxs->Blut->entries; switch (gfxs->dst_format) { case DSPF_ARGB: if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { for (i=0; i<gfxs->Blut->num_entries; i++) { int alpha = entries[i].a + 1; switch (alpha) { case 0: colors[i] = 0; break; case 255: colors[i] = PIXEL_ARGB( entries[i].a, entries[i].r, entries[i].g, entries[i].b ); break; default: colors[i] = PIXEL_ARGB( entries[i].a, (alpha * entries[i].r) >> 8, (alpha * entries[i].g) >> 8, (alpha * entries[i].b) >> 8 ); } } } else { for (i=0; i<gfxs->Blut->num_entries; i++) colors[i] = PIXEL_ARGB( entries[i].a, entries[i].r, entries[i].g, entries[i].b ); } break; case DSPF_RGB32: for (i=0; i<gfxs->Blut->num_entries; i++) colors[i] = PIXEL_RGB32( entries[i].r, entries[i].g, entries[i].b ); break; case DSPF_RGB16: for (i=0; i<gfxs->Blut->num_entries; i++) colors16[i] = PIXEL_RGB16( entries[i].r, entries[i].g, entries[i].b ); break; case DSPF_ARGB4444: if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { for (i=0; i<gfxs->Blut->num_entries; i++) { int alpha = entries[i].a + 1; switch (alpha) { case 0: colors16[i] = 0; break; case 255: colors16[i] = PIXEL_ARGB4444( entries[i].a, entries[i].r, entries[i].g, entries[i].b ); break; default: colors16[i] = PIXEL_ARGB4444( entries[i].a, (alpha * entries[i].r) >> 8, (alpha * entries[i].g) >> 8, (alpha * entries[i].b) >> 8 ); } } } else { for (i=0; i<gfxs->Blut->num_entries; i++)
/* * Blit a glyph with alpha blending and colorizing using the current hardware state. */ static bool pxa3xxBlitGlyph( void *drv, void *dev, DFBRectangle *rect, int x, int y ) { PXA3XXDriverData *pdrv = drv; PXA3XXDeviceData *pdev = dev; u32 *prep = start_buffer( pdrv, 40 ); const u32 format = pixel_formats[DFB_PIXELFORMAT_INDEX( DSPF_ARGB )]; D_DEBUG_AT( PXA3XX_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( rect ) ); DUMP_INFO(); if (rect->w * (rect->h + 1) * 4 > pdev->fake_size) return false; /* Set fake destination. */ prep[0] = 0x020000A2; prep[1] = pdev->fake_phys; prep[2] = (format << 19) | ((rect->w << 2) << 5) | 4; /* Fill first row of fake buffer. */ prep[3] = 0x40000014 | (format << 8); prep[4] = 0; prep[5] = 0; prep[6] = PXA3XX_WH( rect->w, 1 ); prep[7] = PIXEL_ARGB( pdev->color.a, pdev->color.r, pdev->color.g, pdev->color.b ); /* Set first row of fake buffer as source1. */ prep[8] = 0x02000012; prep[9] = pdev->fake_phys; prep[10] = (format << 19) | 4; /* Blit with blending. */ prep[11] = 0x47000118; prep[12] = 0; prep[13] = 1; prep[14] = rect->x; prep[15] = rect->y; prep[16] = 0; prep[17] = 0; prep[18] = PXA3XX_WH( rect->w, rect->h ); prep[19] = 0; /* Restore destination. */ prep[20] = 0x020000A2; prep[21] = pdev->dst_phys; prep[22] = (pixel_formats[pdev->dst_index] << 19) | (pdev->dst_pitch << 5) | pdev->dst_bpp; /* Restore source1 to destination. */ prep[23] = 0x02000012; prep[24] = prep[21]; prep[25] = prep[22]; /* Set fake buffer as source0. */ prep[26] = 0x02000002; prep[27] = pdev->fake_phys; prep[28] = (format << 19) | ((rect->w << 2) << 5) | 4; /* Blit with blending. */ prep[29] = 0x47000107; prep[30] = x; prep[31] = y; prep[32] = 0; prep[33] = 1; prep[34] = x; prep[35] = y; prep[36] = PXA3XX_WH( rect->w, rect->h ); /* Restore source0. */ prep[37] = 0x02000002; prep[38] = pdev->src_phys; prep[39] = (pixel_formats[pdev->src_index] << 19) | (pdev->src_pitch << 5) | pdev->src_bpp; submit_buffer( pdrv, 40 ); return true; }
/* * Make sure that the hardware is programmed for execution of 'accel' according to the 'state'. */ void davinciSetState( void *drv, void *dev, GraphicsDeviceFuncs *funcs, CardState *state, DFBAccelerationMask accel ) { DavinciDeviceData *ddev = dev; StateModificationFlags modified = state->mod_hw; D_DEBUG_AT( Davinci_2D, "%s( state %p, accel 0x%08x ) <- dest %p, modified 0x%08x\n", __FUNCTION__, state, accel, state->destination, modified ); /* * 1) Invalidate hardware states * * Each modification to the hw independent state invalidates one or more hardware states. */ /* Simply invalidate all? */ if (modified == SMF_ALL) { D_DEBUG_AT( Davinci_2D, " <- ALL\n" ); DAVINCI_INVALIDATE( ALL ); } else if (modified) { /* Invalidate destination settings. */ if (modified & SMF_DESTINATION) { D_DEBUG_AT( Davinci_2D, " <- DESTINATION | FILLCOLOR\n" ); DAVINCI_INVALIDATE( DESTINATION | FILLCOLOR ); } else if (modified & SMF_COLOR) { D_DEBUG_AT( Davinci_2D, " <- FILLCOLOR\n" ); DAVINCI_INVALIDATE( FILLCOLOR ); } /* Invalidate source settings. */ if (modified & SMF_SOURCE) { D_DEBUG_AT( Davinci_2D, " <- SOURCE\n" ); DAVINCI_INVALIDATE( SOURCE ); } /* Invalidate source color(ize) settings. */ if (modified & (SMF_BLITTING_FLAGS | SMF_COLOR)) { D_DEBUG_AT( Davinci_2D, " <- SOURCE_MULT\n" ); DAVINCI_INVALIDATE( SOURCE_MULT ); } /* Invalidate blend function for blitting. */ if (modified & (SMF_BLITTING_FLAGS | SMF_SRC_BLEND | SMF_DST_BLEND)) { D_DEBUG_AT( Davinci_2D, " <- BLIT_BLEND_SUB\n" ); DAVINCI_INVALIDATE( BLIT_BLEND_SUB ); } /* Invalidate blend function for drawing. */ if (modified & (SMF_DRAWING_FLAGS | SMF_SRC_BLEND | SMF_DST_BLEND)) { D_DEBUG_AT( Davinci_2D, " <- DRAW_BLEND_SUB\n" ); DAVINCI_INVALIDATE( DRAW_BLEND_SUB ); } } /* * Just keep these values, no computations needed here. * Values used by state validation or rendering functions. */ ddev->blitting_flags = state->blittingflags; ddev->clip = state->clip; ddev->color = state->color; ddev->colorkey = state->src_colorkey; ddev->color_argb = PIXEL_ARGB( state->color.a, state->color.r, state->color.g, state->color.b ); /* * 2) Validate hardware states * * Each function has its own set of states that need to be validated. */ /* Always requiring valid destination... */ DAVINCI_CHECK_VALIDATE( DESTINATION ); /* Depending on the function... */ switch (accel) { case DFXL_FILLRECTANGLE: D_DEBUG_AT( Davinci_2D, " -> FILLRECTANGLE\n" ); /* Validate blend sub function index for drawing... */ if (state->drawingflags & (DSDRAW_BLEND | DSDRAW_SRC_PREMULTIPLY)) DAVINCI_CHECK_VALIDATE( DRAW_BLEND_SUB ); else /* ...or just validate fill color. */ DAVINCI_CHECK_VALIDATE( FILLCOLOR ); /* Choose function. */ switch (DFB_BYTES_PER_PIXEL( state->destination->config.format )) { case 2: funcs->FillRectangle = davinciFillRectangle16; break; case 4: if (state->drawingflags & (DSDRAW_BLEND | DSDRAW_SRC_PREMULTIPLY)) funcs->FillRectangle = davinciFillRectangleBlend32; else funcs->FillRectangle = davinciFillRectangle32; break; default: D_BUG( "unexpected destination bpp %d", DFB_BYTES_PER_PIXEL( state->destination->config.format ) ); break; } /* * 3) Tell which functions can be called without further validation, i.e. SetState() * * When the hw independent state is changed, this collection is reset. */ state->set |= DAVINCI_SUPPORTED_DRAWINGFUNCTIONS; break; case DFXL_BLIT: D_DEBUG_AT( Davinci_2D, " -> BLIT\n" ); /* ...require valid source. */ DAVINCI_CHECK_VALIDATE( SOURCE ); /* Validate blend sub function index for blitting. */ if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) { DAVINCI_CHECK_VALIDATE( BLIT_BLEND_SUB ); /* Validate ARGB source modulator. */ DAVINCI_CHECK_VALIDATE( SOURCE_MULT ); } /* Choose function. */ switch (DFB_BYTES_PER_PIXEL( state->destination->config.format )) { case 2: if (state->blittingflags & DSBLIT_SRC_COLORKEY) funcs->Blit = davinciBlitKeyed16; else if (state->source->config.format == DSPF_ARGB || state->source->config.format == DSPF_RGB32) funcs->Blit = davinciBlit32to16; else funcs->Blit = davinciBlit16; break; case 4: if (state->blittingflags & DSBLIT_SRC_COLORKEY) funcs->Blit = davinciBlitKeyed32; else if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) funcs->Blit = davinciBlitBlend32; else funcs->Blit = davinciBlit32; break; default: D_BUG( "unexpected destination bpp %d", DFB_BYTES_PER_PIXEL( state->destination->config.format ) ); break; } /* * 3) Tell which functions can be called without further validation, i.e. SetState() * * When the hw independent state is changed, this collection is reset. */ state->set |= DFXL_BLIT; break; case DFXL_STRETCHBLIT: D_DEBUG_AT( Davinci_2D, " -> STRETCHBLIT\n" ); /* ...require valid source. */ DAVINCI_CHECK_VALIDATE( SOURCE ); /* Choose function. */ #if 0 // only 32bit, statically set in driver_init_driver() switch (state->destination->config.format) { case DSPF_ARGB: case DSPF_RGB32: funcs->StretchBlit = davinciStretchBlit32; break; default: D_BUG( "unexpected destination format %s", dfb_pixelformat_name( state->destination->config.format ) ); break; } #endif /* * 3) Tell which functions can be called without further validation, i.e. SetState() * * When the hw independent state is changed, this collection is reset. */ state->set |= DFXL_STRETCHBLIT; break; default: D_BUG( "unexpected drawing/blitting function" ); break; } /* * 4) Clear modification flags * * All flags have been evaluated in 1) and remembered for further validation. * If the hw independent state is not modified, this function won't get called * for subsequent rendering functions, unless they aren't defined by 3). */ state->mod_hw = 0; }
unsigned int dfb_colorhash_lookup( DFBColorHashCore *core, CorePalette *palette, u8 r, u8 g, u8 b, u8 a ) { unsigned int pixel = PIXEL_ARGB(a, r, g, b); unsigned int index = (pixel ^ (unsigned long) palette) % HASH_SIZE; DFBColorHashCoreShared *shared; // D_ASSUME( core != NULL ); if (core) { D_MAGIC_ASSERT( core, DFBColorHashCore ); D_MAGIC_ASSERT( core->shared, DFBColorHashCoreShared ); } else core = core_colorhash; shared = core->shared; D_ASSERT( shared->hash != NULL ); fusion_skirmish_prevail( &shared->hash_lock ); /* try a lookup in the hash table */ if (shared->hash[index].palette == palette && shared->hash[index].pixel == pixel) { /* set the return value */ index = shared->hash[index].index; } else { /* look for the closest match */ DFBColor *entries = palette->entries; int min_diff = 0; unsigned int i, min_index = 0; for (i = 0; i < palette->num_entries; i++) { int diff; int r_diff = (int) entries[i].r - (int) r; int g_diff = (int) entries[i].g - (int) g; int b_diff = (int) entries[i].b - (int) b; int a_diff = (int) entries[i].a - (int) a; if (a) diff = (r_diff * r_diff + g_diff * g_diff + b_diff * b_diff + ((a_diff * a_diff) >> 6)); else diff = (r_diff + g_diff + b_diff + (a_diff * a_diff)); if (i == 0 || diff < min_diff) { min_diff = diff; min_index = i; } if (!diff) break; } /* store the matching entry in the hash table */ shared->hash[index].pixel = pixel; shared->hash[index].index = min_index; shared->hash[index].palette = palette; /* set the return value */ index = min_index; }