bool davinciStretchBlit32( void *drv, void *dev, DFBRectangle *srect, DFBRectangle *drect ) { DavinciDriverData *ddrv = drv; DavinciDeviceData *ddev = dev; DFBRegion clip = DFB_REGION_INIT_FROM_RECTANGLE( drect ); D_DEBUG_AT( Davinci_2D, "%s( %4d,%4d-%4dx%4d <- %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS(drect), DFB_RECTANGLE_VALS(srect) ); if (!dfb_region_region_intersect( &clip, &ddev->clip )) return true; dfb_region_translate( &clip, -drect->x, -drect->y ); davinci_c64x_stretch_32__L( &ddrv->tasks, ddev->dst_phys + ddev->dst_pitch * drect->y + ddev->dst_bpp * drect->x, ddev->dst_pitch, ddev->src_phys + ddev->src_pitch * srect->y + ddev->src_bpp * srect->x, ddev->src_pitch, drect->w, drect->h, srect->w, srect->h, &clip ); return true; }
static DFBResult Test_DstGeometry( IDirectFBDisplayLayer *layer, void *arg ) { int i; IDirectFBWindow *window; DFBWindowGeometry geometry; DFBDimension size; D_ASSERT( m_toplevel_id != 0 ); /* * Get the top level window */ _T( layer->GetWindow( layer, arg ? (unsigned long) arg : m_toplevel_id, &window ) ); window->GetSize( window, &size.w, &size.h ); /* * Change destination geometry */ { DFBRectangle rects[] = { { 0, 0, size.w / 2, size.h / 2 }, { size.w / 2, 0, size.w / 2, size.h / 2 }, { size.w / 2, size.h / 2, size.w / 2, size.h / 2 }, { 0, size.h / 2, size.w / 2, size.h / 2 } }; for (i=0; i<D_ARRAY_SIZE(rects); i++) { SHOW_TEST( "SetDstGeometry( %4d,%4d-%4dx%4d - [%02d] )...", DFB_RECTANGLE_VALS(&rects[i]), i ); geometry.mode = DWGM_RECTANGLE; geometry.rectangle = rects[i]; _T( window->SetDstGeometry( window, &geometry ) ); SHOW_RESULT( "...SetDstGeometry( %4d,%4d-%4dx%4d - [%02d] ) done.", DFB_RECTANGLE_VALS(&rects[i]), i ); } } SHOW_TEST( "SetDstGeometry( DEFAULT )..." ); geometry.mode = DWGM_DEFAULT; _T( window->SetDstGeometry( window, &geometry ) ); SHOW_RESULT( "...SetDstGeometry( DEFAULT ) done." ); window->Release( window ); return DFB_OK; }
/* * Blit a scaled rectangle using the current hardware state. */ bool gles2StretchBlit(void *drv, void *dev, DFBRectangle *srect, DFBRectangle *drect) { GLES2DriverData *gdrv = drv; float x1 = drect->x; float y1 = drect->y; float x2 = drect->w + x1; float y2 = drect->h + y1; float tx1 = srect->x; float ty1 = srect->y; float tx2 = srect->w + tx1; float ty2 = srect->h + ty1; GLfloat pos[] = { x1, y1, x2, y1, x2, y2, x1, y2 }; GLfloat tex[8]; D_DEBUG_AT(GLES2__2D, "%s(%4d,%4d-%4dx%4d <- %4d,%4d-%4dx%4d)\n", __FUNCTION__, DFB_RECTANGLE_VALS(drect), DFB_RECTANGLE_VALS(srect)); if (gdrv->blittingflags & DSBLIT_ROTATE180) { tex[0] = tx2; tex[1] = ty2; tex[2] = tx1; tex[3] = ty2; tex[4] = tx1; tex[5] = ty1; tex[6] = tx2; tex[7] = ty1; } else { tex[0] = tx1; tex[1] = ty1; tex[2] = tx2; tex[3] = ty1; tex[4] = tx2; tex[5] = ty2; tex[6] = tx1; tex[7] = ty2; } glVertexAttribPointer(GLES2VA_POSITIONS, 2, GL_FLOAT, GL_FALSE, 0, pos); glVertexAttribPointer(GLES2VA_TEXCOORDS, 2, GL_FLOAT, GL_FALSE, 0, tex); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); // XXX hood - how are these magic numbers determined? gdrv->calls += 1 + drect->w * drect->h / (23 * 42); return true; }
static void * ScreenUpdateLoop( DirectThread *thread, void *arg ) { pthread_mutex_lock( &dfb_sdl->update.lock ); D_DEBUG_AT( SDL_Updates, "Entering %s()...\n", __FUNCTION__ ); while (!dfb_sdl->update.quit) { if (dfb_sdl->update.pending) { DFBRectangle update = DFB_RECTANGLE_INIT_FROM_REGION( &dfb_sdl->update.region ); dfb_sdl->update.pending = false; D_DEBUG_AT( SDL_Updates, "Got update %d,%d - %dx%d...\n", DFB_RECTANGLE_VALS( &update ) ); pthread_mutex_unlock( &dfb_sdl->update.lock ); update_screen( update.x, update.y, update.w, update.h ); pthread_mutex_lock( &dfb_sdl->update.lock ); } else pthread_cond_wait( &dfb_sdl->update.cond, &dfb_sdl->update.lock ); } D_DEBUG_AT( SDL_Updates, "Returning from %s()...\n", __FUNCTION__ ); pthread_mutex_unlock( &dfb_sdl->update.lock ); return NULL; }
/* * Render a filled rectangle using the current hardware state. */ bool gles2FillRectangle(void *drv, void *dev, DFBRectangle *rect) { GLES2DriverData *gdrv = drv; float x1 = rect->x; float y1 = rect->y; float x2 = rect->w + x1; float y2 = rect->h + y1; GLfloat pos[] = { x1, y1, x2, y1, x2, y2, x1, y2 }; D_DEBUG_AT(GLES2__2D, "%s(%4d,%4d-%4dx%4d)\n", __FUNCTION__, DFB_RECTANGLE_VALS(rect)); glVertexAttribPointer(GLES2VA_POSITIONS, 2, GL_FLOAT, GL_FALSE, 0, pos); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); // XXX hood - how are these magic numbers determined? gdrv->calls += 1 + rect->w * rect->h / (23 * 42); return true; }
/* * Blend a rectangle using the alpha value from the color using the current hardware state. */ static bool pxa3xxBlitBlendColorAlpha( void *drv, void *dev, DFBRectangle *rect, int x, int y ) { PXA3XXDriverData *pdrv = drv; PXA3XXDeviceData *pdev = dev; u32 *prep = start_buffer( pdrv, 9 ); D_DEBUG_AT( PXA3XX_BLT, "%s( %d, %d - %dx%d -> %d, %d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( rect ), x, y ); DUMP_INFO(); prep[0] = 0x47000138; prep[1] = x; prep[2] = y; prep[3] = rect->x; prep[4] = rect->y; prep[5] = x; prep[6] = y; prep[7] = PXA3XX_WH( rect->w, rect->h ); prep[8] = (pdev->color.a << 24) | (pdev->color.a << 16); submit_buffer( pdrv, 9 ); return true; }
static bool davinciFillRectangle32( void *drv, void *dev, DFBRectangle *rect ) { DavinciDriverData *ddrv = drv; DavinciDeviceData *ddev = dev; D_DEBUG_AT( Davinci_2D, "%s( %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS(rect) ); if (ddev->dst_format == DSPF_ARGB && ddev->color.a == 0xff) davinci_c64x_blit_blend_32__L( &ddrv->tasks, C64X_BLEND_ONE_INVSRC, ddev->dst_phys + ddev->dst_pitch * rect->y + ddev->dst_bpp * rect->x, ddev->dst_pitch, 0, 0, rect->w, rect->h, ddev->color_argb, 0xff ); else davinci_c64x_fill_32__L( &ddrv->tasks, ddev->dst_phys + ddev->dst_pitch * rect->y + ddev->dst_bpp * rect->x, ddev->dst_pitch, rect->w, rect->h, ddev->fillcolor ); return true; }
/* * Render a filled rectangle using the current hardware state. */ bool pvr2dFillRectangle(void *drv, void *dev, DFBRectangle *rect) { PVR2DDriverData *gdrv = drv; D_DEBUG_AT(PVR2D__2D, "%s(%4d,%4d-%4dx%4d)\n", __FUNCTION__, DFB_RECTANGLE_VALS(rect)); PVR2DERROR ePVR2DStatus; gdrv->bltinfo.DstX = rect->x; gdrv->bltinfo.DstY = rect->y; gdrv->bltinfo.DSizeX = rect->w; gdrv->bltinfo.DSizeY = rect->h; gdrv->bltinfo.SrcX = rect->x; gdrv->bltinfo.SrcY = rect->y; gdrv->bltinfo.SizeX = rect->w; gdrv->bltinfo.SizeY = rect->h; gdrv->bltinfo.CopyCode = 0xF0; ePVR2DStatus = PVR2DBlt( gdrv->hPVR2DContext, &gdrv->bltinfo ); if (ePVR2DStatus) { D_ERROR( "DirectFB/PVR2D: PVR2DBlt() failed! (status %d)\n", ePVR2DStatus ); return false; } return true; }
static DFBResult unrealize_region( CoreLayerRegion *region ) { DFBResult ret; int index; CoreLayer *layer; CoreLayerShared *shared; const DisplayLayerFuncs *funcs; D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) ); layer = dfb_layer_at( region->context->layer_id ); D_ASSERT( layer != NULL ); D_ASSERT( layer->shared != NULL ); D_ASSERT( layer->funcs != NULL ); shared = layer->shared; funcs = layer->funcs; D_ASSERT( fusion_vector_contains( &shared->added_regions, region ) ); index = fusion_vector_index_of( &shared->added_regions, region ); D_DEBUG_AT( Core_Layers, "Removing region (%d, %d - %dx%d) from '%s'.\n", DFB_RECTANGLE_VALS( ®ion->config.dest ), shared->description.name ); /* Remove the region from hardware and driver. */ if (funcs->RemoveRegion) { ret = funcs->RemoveRegion( layer, layer->driver_data, layer->layer_data, region->region_data ); if (ret) { D_DERROR( ret, "Core/Layers: Could not remove region!\n" ); return ret; } } /* Remove the region from the 'added' list. */ fusion_vector_remove( &shared->added_regions, index ); /* Deallocate the driver's region data. */ if (region->region_data) { SHFREE( shared->shmpool, region->region_data ); region->region_data = NULL; } /* Update the region's state. */ D_FLAGS_CLEAR( region->state, CLRSF_REALIZED ); D_FLAGS_SET( region->state, CLRSF_FROZEN ); if (region->surface && region->surface_lock.buffer) { dfb_surface_unlock_buffer( region->surface, ®ion->surface_lock ); dfb_surface_destroy_buffers( region->surface ); } return DFB_OK; }
DFBResult IWindow_Real::SetBounds( const DFBRectangle *bounds ) { D_DEBUG_AT( Core_Window, "IWindow_Real::%s( %p )\n", __FUNCTION__, obj ); D_MAGIC_ASSERT( obj, CoreWindow ); return dfb_window_set_bounds( obj, DFB_RECTANGLE_VALS( bounds ) ); }
/* * Render a rectangle outline using the current hardware state. */ bool pvr2dDrawRectangle(void *drv, void *dev, DFBRectangle *rect) { // PVR2DDriverData *gdrv = drv; D_DEBUG_AT(PVR2D__2D, "%s(%4d,%4d-%4dx%4d)\n", __FUNCTION__, DFB_RECTANGLE_VALS(rect)); return true; }
void sawman_dispatch_blit( SaWMan *sawman, SaWManWindow *sawwin, bool right_eye, const DFBRectangle *src, const DFBRectangle *dst, const DFBRegion *clip ) { SaWManListenerCallData data; if (clip) { D_DEBUG_AT( SaWMan_Draw, "%s( %p, %d,%d-%dx%d %d,%d-%dx%d %d,%d-%dx%d )\n", __FUNCTION__, sawwin, DFB_RECTANGLE_VALS( src ), DFB_RECTANGLE_VALS( dst ), DFB_RECTANGLE_VALS_FROM_REGION( clip ) ); } else { D_DEBUG_AT( SaWMan_Draw, "%s( %p, %d,%d-%dx%d %d,%d-%dx%d NO CLIP )\n", __FUNCTION__, sawwin, DFB_RECTANGLE_VALS( src ), DFB_RECTANGLE_VALS( dst ) ); } data.call = SWMLC_WINDOW_BLIT; data.stereo_eye = right_eye ? DSSE_RIGHT : DSSE_LEFT; data.window_id = sawwin->window->id; data.resource_id = sawwin->window->resource_id; data.src = *src; data.dst = *dst; if (clip) { if (dfb_clip_blit_precheck( clip, dst->w, dst->h, dst->x, dst->y )) { dfb_clip_stretchblit( clip, &data.src, &data.dst ); fusion_reactor_dispatch( sawman->reactor, &data, true, NULL ); } else D_DEBUG_AT( SaWMan_Draw, " -> CLIPPED!\n" ); } else fusion_reactor_dispatch( sawman->reactor, &data, true, NULL ); }
/* * 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; }
/* * Render a filled rectangle using the current hardware state. */ bool vmwareFillRectangle( void *drv, void *dev, DFBRectangle *rect ) { VMWareDeviceData *vdev = (VMWareDeviceData*) dev; void *addr = vdev->dst_addr + rect->y * vdev->dst_pitch + DFB_BYTES_PER_LINE(vdev->dst_format, rect->x); D_DEBUG_AT( VMWare_2D, "%s( %d,%d-%dx%d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( rect ) ); switch (vdev->dst_bpp) { case 4: while (rect->h--) { int w = rect->w; u32 *dst = addr; while (w--) *dst++ = vdev->color_pixel; addr += vdev->dst_pitch; } break; case 2: while (rect->h--) { int w = rect->w; u16 *dst = addr; while (w--) *dst++ = vdev->color_pixel; addr += vdev->dst_pitch; } break; case 1: while (rect->h--) { int w = rect->w; u8 *dst = addr; while (w--) *dst++ = vdev->color_pixel; addr += vdev->dst_pitch; } break; } return true; }
/* * Render a filled rectangle using the current hardware state. */ static bool pxa3xxFillRectangle( void *drv, void *dev, DFBRectangle *rect ) { PXA3XXDriverData *pdrv = drv; u32 *prep = start_buffer( pdrv, 4 ); D_DEBUG_AT( PXA3XX_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( rect ) ); DUMP_INFO(); prep[0] = 0x40000003; prep[1] = rect->x; prep[2] = rect->y; prep[3] = PXA3XX_WH( rect->w, rect->h ); submit_buffer( pdrv, 4 ); return true; }
static bool davinciFillRectangleBlend32( void *drv, void *dev, DFBRectangle *rect ) { DavinciDriverData *ddrv = drv; DavinciDeviceData *ddev = dev; D_DEBUG_AT( Davinci_2D, "%s( %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS(rect) ); davinci_c64x_blit_blend_32__L( &ddrv->tasks, ddev->draw_blend_sub_function, ddev->dst_phys + ddev->dst_pitch * rect->y + ddev->dst_bpp * rect->x, ddev->dst_pitch, 0, 0, rect->w, rect->h, ddev->color_argb, 0xff ); return true; }
/* * Render a filled rectangle using the current hardware state. */ bool vmwareBlit( void *drv, void *dev, DFBRectangle *srect, int dx, int dy ) { VMWareDeviceData *vdev = (VMWareDeviceData*) dev; void *dst = vdev->dst_addr + dy * vdev->dst_pitch + DFB_BYTES_PER_LINE(vdev->dst_format, dx); void *src = vdev->src_addr + srect->y * vdev->src_pitch + DFB_BYTES_PER_LINE(vdev->src_format, srect->x); D_DEBUG_AT( VMWare_2D, "%s( %d,%d-%dx%d -> %d, %d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( srect ), dx, dy ); while (srect->h--) { direct_memcpy( dst, src, srect->w * vdev->dst_bpp ); dst += vdev->dst_pitch; src += vdev->src_pitch; } return true; }
/* * Render a filled rectangle using the current hardware state. */ static bool davinciFillRectangle16( void *drv, void *dev, DFBRectangle *rect ) { DavinciDriverData *ddrv = drv; DavinciDeviceData *ddev = dev; D_DEBUG_AT( Davinci_2D, "%s( %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS(rect) ); /* FIXME: Optimize in DSP. */ if ((rect->x | rect->w) & 1) davinci_c64x_fill_16__L( &ddrv->tasks, ddev->dst_phys + ddev->dst_pitch * rect->y + ddev->dst_bpp * rect->x, ddev->dst_pitch, rect->w, rect->h, ddev->fillcolor ); else davinci_c64x_fill_32__L( &ddrv->tasks, ddev->dst_phys + ddev->dst_pitch * rect->y + ddev->dst_bpp * rect->x, ddev->dst_pitch, rect->w/2, rect->h, ddev->fillcolor ); return true; }
/* * Render a rectangle outline using the current hardware state. */ bool gles2DrawRectangle(void *drv, void *dev, DFBRectangle *rect) { GLES2DriverData *gdrv = drv; float x1 = rect->x + 1; float y1 = rect->y + 1; float x2 = rect->x + rect->w; float y2 = rect->y + rect->h; GLfloat pos[] = { x1, y1, x2, y1, x2, y2, x1, y2 }; D_DEBUG_AT(GLES2__2D, "%s(%4d,%4d-%4dx%4d)\n", __FUNCTION__, DFB_RECTANGLE_VALS(rect)); glVertexAttribPointer(GLES2VA_POSITIONS, 2, GL_FLOAT, GL_FALSE, 0, pos); glDrawArrays(GL_LINE_LOOP, 0, 4); gdrv->calls++; return true; }
static void draw_window( SaWManTier *tier, SaWManWindow *sawwin, SaWManWindow *sawwin2, CardState *state, DFBRegion *region, bool alpha_channel, bool right_eye ) { SaWMan *sawman; CoreWindow *window; DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; DFBRectangle dst; DFBRectangle src; DFBRegion clip; DFBRegion old_clip; int offset; D_MAGIC_ASSERT( sawwin, SaWManWindow ); D_MAGIC_ASSERT( state, CardState ); DFB_REGION_ASSERT( region ); sawman = sawwin->sawman; window = sawwin->window; dst = sawwin->dst; src = sawwin->src; D_MAGIC_ASSERT( sawman, SaWMan ); D_ASSERT( window != NULL ); D_ASSERT( window->surface != NULL ); D_DEBUG_AT( SaWMan_Draw, "%s( %p, %d,%d-%dx%d )\n", __FUNCTION__, sawwin, DFB_RECTANGLE_VALS_FROM_REGION( region ) ); if (window->config.options & DWOP_STEREO_SIDE_BY_SIDE_HALF) { src.x /= 2; src.w /= 2; if (right_eye) src.x += window->surface->config.size.w / 2; } /* Modify dst for stereo offset. */ offset = window->config.z; offset *= right_eye ? -1 : 1; dfb_rectangle_translate( &dst, offset, 0 ); /* Setup clipping region. */ clip = *region; if (!dfb_region_rectangle_intersect( &clip, &dst )) return; sawman_dispatch_blit( sawman, sawwin, right_eye, &sawwin->src, &dst, &clip ); if (sawwin2) sawman_dispatch_blit( sawman, sawwin2, right_eye, &sawwin2->src, &dst, &clip ); /* Backup clipping region. */ old_clip = state->clip; /* Use per pixel alpha blending. */ if (alpha_channel && (window->config.options & DWOP_ALPHACHANNEL)) flags |= DSBLIT_BLEND_ALPHACHANNEL; /* Use global alpha blending. */ if (window->config.opacity != 0xFF) { flags |= DSBLIT_BLEND_COLORALPHA; if (window->surface->config.caps & DSCAPS_PREMULTIPLIED) { /* Need to premultiply source with Ac? */ flags |= DSBLIT_SRC_PREMULTCOLOR; dfb_state_set_src_blend( state, DSBF_ONE ); } else dfb_state_set_src_blend( state, DSBF_SRCALPHA ); /* Set opacity as blending factor. */ if (state->color.a != window->config.opacity) { state->color.a = window->config.opacity; state->modified |= SMF_COLOR; } } /* if we specified some kind of color, we will colorise. no DWCAPS_COLOR here. */ if (window->config.color.a != 0) { DFBColor c; flags |= DSBLIT_COLORIZE; c = window->config.color; c.a = state->color.a; if (! DFB_COLOR_EQUAL( c, state->color )) { state->color = c; state->modified |= SMF_COLOR; } } /* Use source color keying. */ if (window->config.options & DWOP_COLORKEYING) { flags |= DSBLIT_SRC_COLORKEY; D_DEBUG_AT( SaWMan_Draw, " -> key 0x%08x\n", window->config.color_key ); /* Set window color key. */ dfb_state_set_src_colorkey( state, window->config.color_key ); } /* Use automatic deinterlacing. */ if (window->surface->config.caps & DSCAPS_INTERLACED) flags |= DSBLIT_DEINTERLACE; /* Different compositing methods depending on destination format. */ if (flags & DSBLIT_BLEND_ALPHACHANNEL) { if (DFB_PIXELFORMAT_HAS_ALPHA( state->destination->config.format )) { /* * Always use compliant Porter/Duff SRC_OVER, * if the destination has an alpha channel. * * Cd = destination color (non-premultiplied) * Ad = destination alpha * * Cs = source color (non-premultiplied) * As = source alpha * * Ac = color alpha * * cd = Cd * Ad (premultiply destination) * cs = Cs * As (premultiply source) * * The full equation to calculate resulting color and alpha (premultiplied): * * cx = cd * (1-As*Ac) + cs * Ac * ax = Ad * (1-As*Ac) + As * Ac */ dfb_state_set_src_blend( state, DSBF_ONE ); /* Need to premultiply source with As*Ac or only with Ac? */ if (! (window->surface->config.caps & DSCAPS_PREMULTIPLIED)) flags |= DSBLIT_SRC_PREMULTIPLY; else if (flags & DSBLIT_BLEND_COLORALPHA) flags |= DSBLIT_SRC_PREMULTCOLOR; /* Need to premultiply/demultiply destination? */ // if (! (state->destination->caps & DSCAPS_PREMULTIPLIED)) // flags |= DSBLIT_DST_PREMULTIPLY | DSBLIT_DEMULTIPLY; } else { /* * We can avoid DSBLIT_SRC_PREMULTIPLY for destinations without an alpha channel * by using another blending function, which is more likely that it's accelerated * than premultiplication at this point in time. * * This way the resulting alpha (ax) doesn't comply with SRC_OVER, * but as the destination doesn't have an alpha channel it's no problem. * * As the destination's alpha value is always 1.0 there's no need for * premultiplication. The resulting alpha value will also be 1.0 without * exceptions, therefore no need for demultiplication. * * cx = Cd * (1-As*Ac) + Cs*As * Ac (still same effect as above) * ax = Ad * (1-As*Ac) + As*As * Ac (wrong, but discarded anyways) */ if (window->surface->config.caps & DSCAPS_PREMULTIPLIED) { /* Need to premultiply source with Ac? */ if (flags & DSBLIT_BLEND_COLORALPHA) flags |= DSBLIT_SRC_PREMULTCOLOR; dfb_state_set_src_blend( state, DSBF_ONE ); } else dfb_state_set_src_blend( state, DSBF_SRCALPHA ); } } /* Use color (key) protection if layer is keyed. */ if (tier->context->config.options & DLOP_SRC_COLORKEY) { flags |= DSBLIT_COLORKEY_PROTECT; dfb_state_set_colorkey( state, &tier->key ); } /* Set blitting flags. */ dfb_state_set_blitting_flags( state, flags ); /* Set render options. */ if (sawman->scaling_mode == SWMSM_SMOOTH) dfb_state_set_render_options( state, DSRO_SMOOTH_DOWNSCALE | DSRO_SMOOTH_UPSCALE ); else dfb_state_set_render_options( state, DSRO_NONE ); /* Set blitting source. */ state->source = window->surface; state->from_eye = (right_eye && (sawwin->caps & DWCAPS_STEREO)) ? DSSE_RIGHT : DSSE_LEFT; state->modified |= SMF_SOURCE | SMF_FROM; D_DEBUG_AT( SaWMan_Draw, " [][] %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION( &clip ) ); /* Change clipping region. */ dfb_state_set_clip( state, &clip ); D_DEBUG_AT( SaWMan_Draw, " => %4d,%4d-%4dx%4d <- %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS( &dst ), DFB_RECTANGLE_VALS( &src ) ); #ifndef OLD_COREWINDOWS_STRUCTURE if (sawwin2) { CoreWindow *window2; DFBRectangle *src2; DFBPoint p1,p2,p; D_MAGIC_ASSERT( sawwin2, SaWManWindow ); window2 = sawwin2->window; D_ASSERT( window2 != NULL ); D_ASSERT( window2->surface != NULL ); src2 = &sawwin2->src; state->source2 = window2->surface; state->modified = SMF_SOURCE2; p1.x = src2->x + (sawwin->dst.x - sawwin2->dst.x); p1.y = src2->y + (sawwin->dst.y - sawwin2->dst.y); p2.x = sawwin->dst.x; p2.y = sawwin->dst.y; p.x = p1.x; p.y = p1.y; p1.x = src.x; p1.y = src.y; src.x = p.x; src.y = p.y; CoreGraphicsStateClient_Blit2( state->client, &src, &p2, &p1, 1 ); } else #endif { /* Scale window to the screen clipped by the region being updated. */ CoreGraphicsStateClient_StretchBlit( state->client, &src, &dst, 1 ); } /* Restore clipping region. */ dfb_state_set_clip( state, &old_clip ); }
void dfb_clip_blit_flipped_rotated( const DFBRegion *clip, DFBRectangle *srect, DFBRectangle *drect, DFBSurfaceBlittingFlags flags ) { DFBRegion dest = DFB_REGION_INIT_FROM_RECTANGLE( drect ); DFBRegion clipped = dest; D_ASSERT( !(flags & (DSBLIT_ROTATE270 | DSBLIT_ROTATE180)) ); if (flags & DSBLIT_ROTATE90) { D_ASSERT( srect->w == drect->h ); D_ASSERT( srect->h == drect->w ); } else { D_ASSERT( srect->w == drect->w ); D_ASSERT( srect->h == drect->h ); } dfb_region_region_intersect( &clipped, clip ); dfb_rectangle_from_region( drect, &clipped ); switch (flags & (DSBLIT_FLIP_HORIZONTAL | DSBLIT_FLIP_VERTICAL | DSBLIT_ROTATE90)) { case DSBLIT_NOFX: srect->x += clipped.x1 - dest.x1; srect->y += clipped.y1 - dest.y1; break; case DSBLIT_FLIP_HORIZONTAL: srect->x += dest.x2 - clipped.x2; srect->y += clipped.y1 - dest.y1; break; case DSBLIT_FLIP_VERTICAL: srect->x += clipped.x1 - dest.x1; srect->y += dest.y2 - clipped.y2; break; case DSBLIT_ROTATE90: srect->x += dest.y2 - clipped.y2; srect->y += clipped.x1 - dest.x1; break; case (DSBLIT_FLIP_HORIZONTAL | DSBLIT_FLIP_VERTICAL): // ROTATE180 srect->x += dest.x2 - clipped.x2; srect->y += dest.y2 - clipped.y2; break; case (DSBLIT_ROTATE90 | DSBLIT_FLIP_VERTICAL | DSBLIT_FLIP_HORIZONTAL): // ROTATE270 srect->x += clipped.y1 - dest.y1; srect->y += dest.x2 - clipped.x2; break; case (DSBLIT_ROTATE90 | DSBLIT_FLIP_HORIZONTAL): srect->x += clipped.y1 - dest.y1; srect->y += clipped.x1 - dest.x1; break; case (DSBLIT_ROTATE90 | DSBLIT_FLIP_VERTICAL): srect->x += dest.y2 - clipped.y2; srect->y += dest.x2 - clipped.x2; break; } if (flags & DSBLIT_ROTATE90) { srect->w = drect->h; srect->h = drect->w; } else { srect->w = drect->w; srect->h = drect->h; } D_DEBUG_AT( Core_Clipping, " => %4d,%4d-%4dx%4d -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS(srect), DFB_RECTANGLE_VALS(drect) ); }
DFBResult dfb_surface_write_buffer( CoreSurface *surface, CoreSurfaceBufferRole role, const void *source, int pitch, const DFBRectangle *prect ) { DFBResult ret; int bytes; DFBRectangle rect; DFBSurfacePixelFormat format; CoreSurfaceAllocation *allocation; D_MAGIC_ASSERT( surface, CoreSurface ); D_ASSERT( pitch > 0 || source == NULL ); DFB_RECTANGLE_ASSERT_IF( prect ); D_DEBUG_AT( Core_Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, surface, source, pitch ); /* Determine area. */ rect.x = 0; rect.y = 0; rect.w = surface->config.size.w; rect.h = surface->config.size.h; if (prect) { if (!dfb_rectangle_intersect( &rect, prect )) { D_DEBUG_AT( Core_Surface, " -> no intersection!\n" ); return DFB_INVAREA; } if (!DFB_RECTANGLE_EQUAL( rect, *prect )) { D_DEBUG_AT( Core_Surface, " -> got clipped to %d,%d-%dx%d!\n", DFB_RECTANGLE_VALS(&rect) ); return DFB_INVAREA; } } /* Calculate bytes per read line. */ format = surface->config.format; bytes = DFB_BYTES_PER_LINE( format, rect.w ); D_DEBUG_AT( Core_Surface, " -> %d,%d - %dx%d (%s)\n", DFB_RECTANGLE_VALS(&rect), dfb_pixelformat_name( format ) ); ret = CoreSurface_PreLockBuffer2( surface, role, CSAID_CPU, CSAF_WRITE, false, &allocation ); if (ret) return ret; D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation ); D_DEBUG_AT( Core_Surface, " -> PreLockBuffer returned allocation %p (%s)\n", allocation, allocation->pool->desc.name ); /* Try writing to allocation directly... */ ret = source ? dfb_surface_pool_write( allocation->pool, allocation, source, pitch, &rect ) : DFB_UNSUPPORTED; if (ret) { /* ...otherwise use fallback method via locking if possible. */ if (allocation->access[CSAID_CPU] & CSAF_WRITE) { int y; int bytes; DFBSurfacePixelFormat format; CoreSurfaceBufferLock lock; /* Calculate bytes per written line. */ format = surface->config.format; bytes = DFB_BYTES_PER_LINE( format, rect.w ); /* Lock the allocation. */ dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_WRITE ); ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock ); if (ret) { D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n", allocation->pool->desc.name ); dfb_surface_buffer_lock_deinit( &lock ); dfb_surface_allocation_unref( allocation ); return ret; } /* Move to start of write. */ lock.addr += DFB_BYTES_PER_LINE( format, rect.x ) + rect.y * lock.pitch; /* Copy the data. */ for (y=0; y<rect.h; y++) { if (source) { direct_memcpy( lock.addr, source, bytes ); source += pitch; } else memset( lock.addr, 0, bytes ); lock.addr += lock.pitch; } /* Unlock the allocation. */ ret = dfb_surface_pool_unlock( allocation->pool, allocation, &lock ); if (ret) D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", allocation->pool->desc.name ); dfb_surface_buffer_lock_deinit( &lock ); } } dfb_surface_allocation_unref( allocation ); return DFB_OK; }
static DFBResult drmkmsPlaneSetRegion( CoreLayer *layer, void *driver_data, void *layer_data, void *region_data, CoreLayerRegionConfig *config, CoreLayerRegionConfigFlags updated, CoreSurface *surface, CorePalette *palette, CoreSurfaceBufferLock *left_lock, CoreSurfaceBufferLock *right_lock ) { int ret; bool unmute = false; DRMKMSData *drmkms = driver_data; DRMKMSLayerData *data = layer_data; D_DEBUG_AT( DRMKMS_Layer, "%s()\n", __FUNCTION__ ); if ((updated & CLRCF_OPACITY) && data->muted && config->opacity) unmute = true; if ((updated & (CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_BUFFERMODE | CLRCF_DEST | CLRCF_SOURCE)) || unmute) { ret = drmModeSetPlane(drmkms->fd, data->plane->plane_id, drmkms->encoder[0]->crtc_id, (u32)(long)left_lock->handle, /* plane_flags */ 0, config->dest.x, config->dest.y, config->dest.w, config->dest.h, config->source.x << 16, config->source.y <<16, config->source.w << 16, config->source.h << 16); if (ret) { D_INFO( "DirectFB/DRMKMS: drmModeSetPlane(plane_id=%d, fb_id=%d , dest=%d,%d-%dx%d, src=%d,%d-%dx%d) failed! (%d)\n", data->plane->plane_id, (u32)(long)left_lock->handle, DFB_RECTANGLE_VALS(&config->dest), DFB_RECTANGLE_VALS(&config->source), ret ); return DFB_FAILURE; } data->config = config; data->muted = false; } if ((updated & (CLRCF_SRCKEY | CLRCF_OPTIONS)) && data->colorkey_propid) { uint32_t drm_colorkey = config->src_key.r << 16 | config->src_key.g << 8 | config->src_key.b; if (config->options & DLOP_SRC_COLORKEY) drm_colorkey |= 0x01000000; ret = drmModeObjectSetProperty( drmkms->fd, data->plane->plane_id, DRM_MODE_OBJECT_PLANE, data->colorkey_propid, drm_colorkey ); if (ret) { D_ERROR( "DirectFB/DRMKMS: drmModeObjectSetProperty() failed setting colorkey\n"); return DFB_FAILURE; } } if (updated & CLRCF_OPACITY) { if (config->opacity == 0) { ret = drmModeSetPlane(drmkms->fd, data->plane->plane_id, drmkms->encoder[0]->crtc_id, 0, /* plane_flags */ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0); if (ret) { D_ERROR( "DirectFB/DRMKMS: drmModeSetPlane() failed disabling plane\n"); return DFB_FAILURE; } data->muted = true; } else if (data->alpha_propid) { ret = drmModeObjectSetProperty( drmkms->fd, data->plane->plane_id, DRM_MODE_OBJECT_PLANE, data->alpha_propid, config->opacity ); if (ret) { D_ERROR( "DirectFB/DRMKMS: drmModeObjectSetProperty() failed setting alpha\n"); return DFB_FAILURE; } } } return DFB_OK; }
/* * 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; }
DFBResult dfb_surface_read_buffer( CoreSurface *surface, CoreSurfaceBufferRole role, void *destination, int pitch, const DFBRectangle *prect ) { DFBResult ret; int y; int bytes; DFBRectangle rect; DFBSurfacePixelFormat format; CoreSurfaceAllocation *allocation; D_MAGIC_ASSERT( surface, CoreSurface ); D_ASSERT( destination != NULL ); D_ASSERT( pitch > 0 ); DFB_RECTANGLE_ASSERT_IF( prect ); D_DEBUG_AT( Core_Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, surface, destination, pitch ); /* Determine area. */ rect.x = 0; rect.y = 0; rect.w = surface->config.size.w; rect.h = surface->config.size.h; if (prect && (!dfb_rectangle_intersect( &rect, prect ) || !DFB_RECTANGLE_EQUAL( rect, *prect ))) return DFB_INVAREA; /* Calculate bytes per read line. */ format = surface->config.format; bytes = DFB_BYTES_PER_LINE( format, rect.w ); D_DEBUG_AT( Core_Surface, " -> %d,%d - %dx%d (%s)\n", DFB_RECTANGLE_VALS(&rect), dfb_pixelformat_name( format ) ); ret = CoreSurface_PreLockBuffer2( surface, role, CSAID_CPU, CSAF_READ, false, &allocation ); if (ret == DFB_NOALLOCATION) { for (y=0; y<rect.h; y++) { memset( destination, 0, bytes ); destination += pitch; } return DFB_OK; } if (ret) return ret; D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation ); D_DEBUG_AT( Core_Surface, " -> PreLockBuffer returned allocation %p (%s)\n", allocation, allocation->pool->desc.name ); /* Try reading from allocation directly... */ ret = dfb_surface_pool_read( allocation->pool, allocation, destination, pitch, &rect ); if (ret) { /* ...otherwise use fallback method via locking if possible. */ if (allocation->access[CSAID_CPU] & CSAF_READ) { CoreSurfaceBufferLock lock; /* Lock the allocation. */ dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_READ ); ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock ); if (ret) { D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n", allocation->pool->desc.name ); dfb_surface_buffer_lock_deinit( &lock ); dfb_surface_allocation_unref( allocation ); return ret; } /* Move to start of read. */ lock.addr += DFB_BYTES_PER_LINE( format, rect.x ) + rect.y * lock.pitch; /* Copy the data. */ for (y=0; y<rect.h; y++) { direct_memcpy( destination, lock.addr, bytes ); destination += pitch; lock.addr += lock.pitch; } /* Unlock the allocation. */ ret = dfb_surface_pool_unlock( allocation->pool, allocation, &lock ); if (ret) D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", allocation->pool->desc.name ); dfb_surface_buffer_lock_deinit( &lock ); } } dfb_surface_allocation_unref( allocation ); return DFB_OK; }
static DFBResult update_screen( DFBX11 *x11, const DFBRectangle *clip, CoreSurfaceBufferLock *lock, XWindow *xw ) { void *dst; void *src; unsigned int offset = 0; XImage *ximage; CoreSurface *surface; CoreSurfaceAllocation *allocation; DFBX11Shared *shared; DFBRectangle rect; bool direct = false; D_ASSERT( x11 != NULL ); DFB_RECTANGLE_ASSERT( clip ); D_DEBUG_AT( X11_Update, "%s( %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( clip ) ); CORE_SURFACE_BUFFER_LOCK_ASSERT( lock ); shared = x11->shared; D_ASSERT( shared != NULL ); XLockDisplay( x11->display ); if (!xw) { XUnlockDisplay( x11->display ); return DFB_OK; } allocation = lock->allocation; CORE_SURFACE_ALLOCATION_ASSERT( allocation ); surface = allocation->surface; D_ASSERT( surface != NULL ); rect.x = rect.y = 0; rect.w = xw->width; rect.h = xw->height; if (!dfb_rectangle_intersect( &rect, clip )) { XUnlockDisplay( x11->display ); return DFB_OK; } D_DEBUG_AT( X11_Update, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS( &rect ) ); #ifdef USE_GLX /* Check for GLX allocation... */ if (allocation->pool == shared->glx_pool && lock->handle) { LocalPixmap *pixmap = lock->handle; D_MAGIC_ASSERT( pixmap, LocalPixmap ); /* ...and just call SwapBuffers... */ //D_DEBUG_AT( X11_Update, " -> Calling glXSwapBuffers( 0x%lx )...\n", alloc->drawable ); //glXSwapBuffers( x11->display, alloc->drawable ); D_DEBUG_AT( X11_Update, " -> Copying from GLXPixmap...\n" ); glXWaitGL(); XCopyArea( x11->display, pixmap->pixmap, xw->window, xw->gc, rect.x, rect.y, rect.w, rect.h, rect.x, rect.y ); glXWaitX(); XUnlockDisplay( x11->display ); return DFB_OK; } #endif /* Check for our special native allocation... */ if (allocation->pool == shared->x11image_pool && lock->handle) { x11Image *image = lock->handle; D_MAGIC_ASSERT( image, x11Image ); /* ...and directly XShmPutImage from that. */ ximage = image->ximage; direct = true; } else { /* ...or copy or convert into XShmImage or XImage allocated with the XWindow. */ ximage = xw->ximage; offset = xw->ximage_offset; xw->ximage_offset = (offset ? 0 : ximage->height / 2); /* make sure the 16-bit input formats are properly 2-pixel-clipped */ switch (surface->config.format) { case DSPF_I420: case DSPF_YV12: case DSPF_NV12: case DSPF_NV21: if (rect.y & 1) { rect.y--; rect.h++; } /* fall through */ case DSPF_YUY2: case DSPF_UYVY: case DSPF_NV16: if (rect.x & 1) { rect.x--; rect.w++; } default: /* no action */ break; } dst = xw->virtualscreen + rect.x * xw->bpp + (rect.y + offset) * ximage->bytes_per_line; src = lock->addr + DFB_BYTES_PER_LINE( surface->config.format, rect.x ) + rect.y * lock->pitch; switch (xw->depth) { case 32: dfb_convert_to_argb( surface->config.format, src, lock->pitch, surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h ); break; case 24: dfb_convert_to_rgb32( surface->config.format, src, lock->pitch, surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h ); break; case 16: if (surface->config.format == DSPF_LUT8) { int width = rect.w; int height = rect.h; const u8 *src8 = src; u16 *dst16 = dst; CorePalette *palette = surface->palette; int x; while (height--) { for (x=0; x<width; x++) { DFBColor color = palette->entries[src8[x]]; dst16[x] = PIXEL_RGB16( color.r, color.g, color.b ); } src8 += lock->pitch; dst16 += ximage->bytes_per_line / 2; } } else { dfb_convert_to_rgb16( surface->config.format, src, lock->pitch, surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h ); } break; case 15: dfb_convert_to_rgb555( surface->config.format, src, lock->pitch, surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h ); break; default: D_ONCE( "unsupported depth %d", xw->depth ); } } D_ASSERT( ximage != NULL ); /* Wait for previous data to be processed... */ XSync( x11->display, False ); /* ...and immediately queue or send the next! */ if (x11->use_shm) { /* Just queue the command, it's XShm :) */ XShmPutImage( xw->display, xw->window, xw->gc, ximage, rect.x, rect.y + offset, rect.x, rect.y, rect.w, rect.h, False ); /* Make sure the queue has really happened! */ XFlush( x11->display ); } else /* Initiate transfer of buffer... */ XPutImage( xw->display, xw->window, xw->gc, ximage, rect.x, rect.y + offset, rect.x, rect.y, rect.w, rect.h ); /* Wait for display if single buffered and not converted... */ if (direct && !(surface->config.caps & DSCAPS_FLIPPING)) XSync( x11->display, False ); XUnlockDisplay( x11->display ); return DFB_OK; }
/* * Blit a rectangle using the current hardware state. */ static bool pxa3xxBlit( void *drv, void *dev, DFBRectangle *rect, int x, int y ) { PXA3XXDriverData *pdrv = drv; PXA3XXDeviceData *pdev = dev; u32 rotation = 0; u32 *prep = start_buffer( pdrv, 6 ); D_DEBUG_AT( PXA3XX_BLT, "%s( %d, %d - %dx%d -> %d, %d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( rect ), x, y ); DUMP_INFO(); if (pdev->bflags & DSBLIT_ROTATE90) rotation = 3; else if (pdev->bflags & DSBLIT_ROTATE180) rotation = 2; else if (pdev->bflags & DSBLIT_ROTATE270) rotation = 1; prep[0] = 0x4A000005 | (rotation << 4); // FIXME: use 32byte alignment hint prep[1] = x; prep[2] = y; prep[3] = rect->x; prep[4] = rect->y; prep[5] = PXA3XX_WH( rect->w, rect->h ); submit_buffer( pdrv, 6 ); /* RASTER prep[0] = 0x4BCC0007; prep[1] = x; prep[2] = y; prep[3] = rect->x; prep[4] = rect->y; prep[5] = rect->x; prep[6] = rect->y; prep[7] = PXA3XX_WH( rect->w, rect->h ); submit_buffer( pdrv, 8 ); */ /* PATTERN prep[0] = 0x4C000006; prep[1] = x; prep[2] = y; prep[3] = rect->x; prep[4] = rect->y; prep[5] = PXA3XX_WH( rect->w, rect->h ); prep[6] = PXA3XX_WH( rect->w, rect->h ); submit_buffer( pdrv, 7 ); */ /* BIAS prep[0] = 0x49000016; prep[1] = x; prep[2] = y; prep[3] = rect->x; prep[4] = rect->y; prep[5] = PXA3XX_WH( rect->w, rect->h ); prep[6] = 0; submit_buffer( pdrv, 7 ); */ return true; }
static DFBResult x11Read( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceAllocation *allocation, void *alloc_data, void *destination, int pitch, const DFBRectangle *rect ) { XImage *image; XImage *sub; x11PoolLocalData *local = pool_local; x11AllocationData *alloc = alloc_data; DFBX11 *x11 = local->x11; D_DEBUG_AT( X11_Surfaces, "%s( %p )\n", __FUNCTION__, allocation ); D_DEBUG_AT( X11_Surfaces, " -> allocation: %s\n", ToString_CoreSurfaceAllocation( allocation ) ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation ); D_ASSERT( destination != NULL ); D_ASSERT( pitch >= 0 ); DFB_RECTANGLE_ASSERT( rect ); D_DEBUG_AT( X11_Surfaces, " => %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) ); XLockDisplay( x11->display ); #if 1 image = XCreateImage( x11->display, alloc->visual, alloc->depth, ZPixmap, 0, destination, rect->w, rect->h, 32, pitch ); if (!image) { D_ERROR( "X11/Surfaces: XCreateImage( %dx%d, depth %d ) failed!\n", rect->w, rect->h, alloc->depth ); XUnlockDisplay( x11->display ); return DFB_FAILURE; } sub = XGetSubImage( x11->display, alloc->xid, rect->x, rect->y, rect->w, rect->h, ~0, ZPixmap, image, 0, 0 ); #else image = XGetImage( x11->display, alloc->window ? alloc->window : alloc->xid, rect->x, rect->y, rect->w, rect->h, ~0, ZPixmap ); #endif if (image) { // dfb_surface_buffer_dump_type_locked2( allocation->buffer, ".", "x11Read", false, image->data, image->bytes_per_line ); /* FIXME: Why the X-hell is XDestroyImage() freeing *MY* data? */ image->data = NULL; XDestroyImage( image ); } XUnlockDisplay( x11->display ); #if 1 if (!sub) { D_ERROR( "X11/Surfaces: XGetSubImage( %d,%d-%dx%d ) failed!\n", DFB_RECTANGLE_VALS(rect) ); return DFB_FAILURE; } #endif return DFB_OK; }
static DFBResult x11Write( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceAllocation *allocation, void *alloc_data, const void *source, int pitch, const DFBRectangle *rect ) { XImage *image; x11PoolLocalData *local = pool_local; x11AllocationData *alloc = alloc_data; DFBX11 *x11 = local->x11; D_DEBUG_AT( X11_Surfaces, "%s( %p )\n", __FUNCTION__, allocation ); D_DEBUG_AT( X11_Surfaces, " -> allocation: %s\n", ToString_CoreSurfaceAllocation( allocation ) ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation ); D_ASSERT( source != NULL ); D_ASSERT( pitch >= 0 ); DFB_RECTANGLE_ASSERT( rect ); D_DEBUG_AT( X11_Surfaces, " <= %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) ); XLockDisplay( x11->display ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " <= %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) ); image = XCreateImage( x11->display, alloc->visual, alloc->depth, ZPixmap, 0, (void*) source, rect->w, rect->h, 32, pitch ); if (!image) { D_ERROR( "X11/Surfaces: XCreateImage( %dx%d, depth %d ) failed!\n", rect->w, rect->h, alloc->depth ); XUnlockDisplay( x11->display ); return DFB_FAILURE; } x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " <= %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) ); // dfb_surface_buffer_dump_type_locked2( allocation->buffer, ".", "x11Write", false, image->data, image->bytes_per_line ); XPutImage( x11->display, alloc->xid, alloc->gc, image, 0, 0, rect->x, rect->y, rect->w, rect->h ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " <= %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) ); /* FIXME: Why the X-hell is XDestroyImage() freeing *MY* data? */ image->data = NULL; XDestroyImage( image ); x11->Sync( x11 ); D_DEBUG_AT( X11_Surfaces, " <= %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) ); XUnlockDisplay( x11->display ); return DFB_OK; }
static DFBResult realize_region( CoreLayerRegion *region ) { DFBResult ret; CoreLayer *layer; CoreLayerShared *shared; DisplayLayerFuncs *funcs; D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_CONFIGURED ) ); D_ASSERT( ! D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) ); layer = dfb_layer_at( region->context->layer_id ); D_ASSERT( layer != NULL ); D_ASSERT( layer->shared != NULL ); D_ASSERT( layer->funcs != NULL ); shared = layer->shared; funcs = layer->funcs; D_ASSERT( ! fusion_vector_contains( &shared->added_regions, region ) ); /* Allocate the driver's region data. */ if (funcs->RegionDataSize) { int size = funcs->RegionDataSize(); if (size > 0) { region->region_data = SHCALLOC( 1, size ); if (!region->region_data) return D_OOSHM(); } } D_DEBUG_AT( Core_Layers, "Adding region (%d, %d - %dx%d) to '%s'.\n", DFB_RECTANGLE_VALS( ®ion->config.dest ), shared->description.name ); /* Add the region to the driver. */ if (funcs->AddRegion) { ret = funcs->AddRegion( layer, layer->driver_data, layer->layer_data, region->region_data, ®ion->config ); if (ret) { D_DERROR( ret, "Core/Layers: Could not add region!\n" ); if (region->region_data) { SHFREE( region->region_data ); region->region_data = NULL; } return ret; } } /* Add the region to the 'added' list. */ fusion_vector_add( &shared->added_regions, region ); /* Update the region's state. */ D_FLAGS_SET( region->state, CLRSF_REALIZED ); /* Initially setup hardware. */ ret = set_region( region, ®ion->config, CLRCF_ALL, region->surface ); if (ret) { unrealize_region( region ); return ret; } return DFB_OK; }