DFBResult dfb_surface_flip( CoreSurface *surface, bool swap ) { unsigned int back, front; D_MAGIC_ASSERT( surface, CoreSurface ); FUSION_SKIRMISH_ASSERT( &surface->lock ); if (surface->num_buffers == 0) return DFB_SUSPENDED; back = (surface->flips + CSBR_BACK) % surface->num_buffers; front = (surface->flips + CSBR_FRONT) % surface->num_buffers; D_ASSERT( surface->buffer_indices[back] < surface->num_buffers ); D_ASSERT( surface->buffer_indices[front] < surface->num_buffers ); if (surface->buffers[surface->buffer_indices[back]]->policy != surface->buffers[surface->buffer_indices[front]]->policy || (surface->config.caps & DSCAPS_ROTATED)) return DFB_UNSUPPORTED; if (swap) { int tmp = surface->buffer_indices[back]; surface->buffer_indices[back] = surface->buffer_indices[front]; surface->buffer_indices[front] = tmp; } else surface->flips++; dfb_surface_notify( surface, CSNF_FLIP ); return DFB_OK; }
DFBResult dfb_surface_set_palette( CoreSurface *surface, CorePalette *palette ) { D_MAGIC_ASSERT( surface, CoreSurface ); D_MAGIC_ASSERT_IF( palette, CorePalette ); if (fusion_skirmish_prevail( &surface->lock )) return DFB_FUSION; if (surface->palette != palette) { if (surface->palette) { dfb_palette_detach_global( surface->palette, &surface->palette_reaction ); dfb_palette_unlink( &surface->palette ); } if (palette) { dfb_palette_link( &surface->palette, palette ); dfb_palette_attach_global( palette, DFB_SURFACE_PALETTE_LISTENER, surface, &surface->palette_reaction ); } dfb_surface_notify( surface, CSNF_PALETTE_CHANGE ); } fusion_skirmish_dismiss( &surface->lock ); return DFB_OK; }
DFBResult dfb_surface_flip( CoreSurface *surface, bool swap ) { D_MAGIC_ASSERT( surface, CoreSurface ); FUSION_SKIRMISH_ASSERT( &surface->lock ); D_ASSERT( surface->buffer_indices[CSBR_BACK] < surface->num_buffers ); D_ASSERT( surface->buffer_indices[CSBR_FRONT] < surface->num_buffers ); if (surface->buffers[surface->buffer_indices[CSBR_BACK]]->policy != surface->buffers[surface->buffer_indices[CSBR_FRONT]]->policy) return DFB_UNSUPPORTED; if (swap) { int tmp = surface->buffer_indices[CSBR_BACK]; surface->buffer_indices[CSBR_BACK] = surface->buffer_indices[CSBR_FRONT]; surface->buffer_indices[CSBR_FRONT] = tmp; } else surface->flips++; dfb_surface_notify( surface, CSNF_FLIP ); return DFB_OK; }
static void surface_destructor( FusionObject *object, bool zombie, void *ctx ) { int i; CoreSurface *surface = (CoreSurface*) object; D_MAGIC_ASSERT( surface, CoreSurface ); D_DEBUG_AT( Core_Surface, "destroying %p (%dx%d%s)\n", surface, surface->config.size.w, surface->config.size.h, zombie ? " ZOMBIE" : ""); Core_Resource_RemoveSurface( surface ); CoreSurface_Deinit_Dispatch( &surface->call ); dfb_surface_lock( surface ); surface->state |= CSSF_DESTROYED; /* announce surface destruction */ dfb_surface_notify( surface, CSNF_DESTROY ); /* unlink palette */ if (surface->palette) { dfb_palette_detach_global( surface->palette, &surface->palette_reaction ); dfb_palette_unlink( &surface->palette ); } /* destroy buffers */ for (i=0; i<MAX_SURFACE_BUFFERS; i++) { if (surface->buffers[i]) dfb_surface_buffer_decouple( surface->buffers[i] ); } dfb_system_surface_data_destroy( surface, surface->data ); /* release the system driver specific surface data */ if (surface->data) { SHFREE( surface->shmpool, surface->data ); surface->data = NULL; } direct_serial_deinit( &surface->serial ); dfb_surface_unlock( surface ); fusion_skirmish_destroy( &surface->lock ); D_MAGIC_CLEAR( surface ); fusion_object_destroy( object ); }
DFBResult dfb_surface_set_field( CoreSurface *surface, int field ) { D_MAGIC_ASSERT( surface, CoreSurface ); if (fusion_skirmish_prevail( &surface->lock )) return DFB_FUSION; surface->field = field; dfb_surface_notify( surface, CSNF_FIELD ); fusion_skirmish_dismiss( &surface->lock ); return DFB_OK; }
ReactionResult _dfb_surface_palette_listener( const void *msg_data, void *ctx ) { const CorePaletteNotification *notification = msg_data; CoreSurface *surface = ctx; if (notification->flags & CPNF_DESTROY) return RS_REMOVE; if (notification->flags & CPNF_ENTRIES) { if (fusion_skirmish_prevail( &surface->lock )) return RS_OK; dfb_surface_notify( surface, CSNF_PALETTE_UPDATE ); fusion_skirmish_dismiss( &surface->lock ); } return RS_OK; }
static void surface_destructor( FusionObject *object, bool zombie, void *ctx ) { int i; CoreSurface *surface = (CoreSurface*) object; D_MAGIC_ASSERT( surface, CoreSurface ); D_DEBUG_AT( Core_Surface, "destroying %p (%dx%d%s)\n", surface, surface->config.size.w, surface->config.size.h, zombie ? " ZOMBIE" : ""); dfb_surface_lock( surface ); surface->state |= CSSF_DESTROYED; /* announce surface destruction */ dfb_surface_notify( surface, CSNF_DESTROY ); /* unlink palette */ if (surface->palette) { dfb_palette_detach_global( surface->palette, &surface->palette_reaction ); dfb_palette_unlink( &surface->palette ); } /* destroy buffers */ for (i=0; i<MAX_SURFACE_BUFFERS; i++) { if (surface->buffers[i]) dfb_surface_buffer_destroy( surface->buffers[i] ); } direct_serial_deinit( &surface->serial ); dfb_surface_unlock( surface ); fusion_skirmish_destroy( &surface->lock ); D_MAGIC_CLEAR( surface ); fusion_object_destroy( object ); }
DFBResult dfb_surface_set_alpha_ramp( CoreSurface *surface, u8 a0, u8 a1, u8 a2, u8 a3 ) { D_MAGIC_ASSERT( surface, CoreSurface ); if (fusion_skirmish_prevail( &surface->lock )) return DFB_FUSION; surface->alpha_ramp[0] = a0; surface->alpha_ramp[1] = a1; surface->alpha_ramp[2] = a2; surface->alpha_ramp[3] = a3; dfb_surface_notify( surface, CSNF_ALPHA_RAMP ); fusion_skirmish_dismiss( &surface->lock ); return DFB_OK; }
DFBResult dfb_surface_reconfig( CoreSurface *surface, const CoreSurfaceConfig *config ) { int i, buffers; DFBResult ret; CoreSurfaceConfig new_config; D_DEBUG_AT( Core_Surface, "%s( %p, %dx%d %s -> %dx%d %s )\n", __FUNCTION__, surface, surface->config.size.w, surface->config.size.h, dfb_pixelformat_name( surface->config.format ), (config->flags & CSCONF_SIZE) ? config->size.w : surface->config.size.w, (config->flags & CSCONF_SIZE) ? config->size.h : surface->config.size.h, (config->flags & CSCONF_FORMAT) ? dfb_pixelformat_name( config->format ) : dfb_pixelformat_name( surface->config.format ) ); D_MAGIC_ASSERT( surface, CoreSurface ); D_ASSERT( config != NULL ); if (config->flags & CSCONF_PREALLOCATED) return DFB_UNSUPPORTED; if (fusion_skirmish_prevail( &surface->lock )) return DFB_FUSION; if (surface->type & CSTF_PREALLOCATED) { fusion_skirmish_dismiss( &surface->lock ); return DFB_UNSUPPORTED; } if ( (config->flags == CSCONF_SIZE || ((config->flags == (CSCONF_SIZE | CSCONF_FORMAT)) && (config->format == surface->config.format))) && config->size.w <= surface->config.min_size.w && config->size.h <= surface->config.min_size.h) { surface->config.size = config->size; fusion_skirmish_dismiss( &surface->lock ); return DFB_OK; } new_config = surface->config; if (config->flags & CSCONF_SIZE) new_config.size = config->size; if (config->flags & CSCONF_FORMAT) new_config.format = config->format; if (config->flags & CSCONF_CAPS) { if (config->caps & DSCAPS_ROTATED) D_UNIMPLEMENTED(); new_config.caps = config->caps & ~DSCAPS_ROTATED; } if (new_config.caps & DSCAPS_SYSTEMONLY) surface->type = (surface->type & ~CSTF_EXTERNAL) | CSTF_INTERNAL; else if (new_config.caps & DSCAPS_VIDEOONLY) surface->type = (surface->type & ~CSTF_INTERNAL) | CSTF_EXTERNAL; else surface->type = surface->type & ~(CSTF_INTERNAL | CSTF_EXTERNAL); if (new_config.caps & DSCAPS_TRIPLE) buffers = 3; else if (new_config.caps & DSCAPS_DOUBLE) buffers = 2; else { buffers = 1; new_config.caps &= ~DSCAPS_ROTATED; } ret = Core_Resource_CheckSurfaceUpdate( surface, &new_config ); if (ret) return ret; /* Destroy the Surface Buffers. */ for (i=0; i<surface->num_buffers; i++) { dfb_surface_buffer_decouple( surface->buffers[i] ); surface->buffers[i] = NULL; } surface->num_buffers = 0; Core_Resource_UpdateSurface( surface, &new_config ); surface->config = new_config; /* Recreate the Surface Buffers. */ for (i=0; i<buffers; i++) { CoreSurfaceBuffer *buffer; ret = dfb_surface_buffer_create( core_dfb, surface, CSBF_NONE, &buffer ); if (ret) { D_DERROR( ret, "Core/Surface: Error creating surface buffer!\n" ); goto error; } dfb_surface_buffer_globalize( buffer ); surface->buffers[surface->num_buffers++] = buffer; switch (i) { case 0: surface->buffer_indices[CSBR_FRONT] = i; case 1: surface->buffer_indices[CSBR_BACK] = i; case 2: surface->buffer_indices[CSBR_IDLE] = i; } } dfb_surface_notify( surface, CSNF_SIZEFORMAT ); fusion_skirmish_dismiss( &surface->lock ); return DFB_OK; error: D_UNIMPLEMENTED(); fusion_skirmish_dismiss( &surface->lock ); return ret; }