Ejemplo n.º 1
0
DFBResult
dfb_font_get_glyph_data( CoreFont        *font,
                         unichar          glyph,
                         CoreGlyphData  **ret_data )
{
     DFBResult      ret;
     CoreGlyphData *data;

     D_MAGIC_ASSERT( font, CoreFont );

     D_ASSERT( ret_data != NULL );

     if ((data = direct_tree_lookup (font->glyph_infos, (void *)glyph)) != NULL) {
          *ret_data = data;
          return DFB_OK;
     }

     data = (CoreGlyphData *) D_CALLOC(1, sizeof (CoreGlyphData));
     if (!data)
          return DFB_NOSYSTEMMEMORY;

     if (font->GetGlyphInfo &&
         font->GetGlyphInfo (font, glyph, data) == DFB_OK &&
         data->width > 0 && data->height > 0)
     {
          if (font->next_x + data->width > font->row_width) {
               CoreSurface *surface;

               if (font->row_width == 0) {
                    int width = 8192 / font->height;

                    if (width > 2048)
                         width = 2048;

                    if (width < font->maxadvance)
                         width = font->maxadvance;

                    font->row_width = (width + 7) & ~7;
               }

               ret = dfb_surface_create( font->core,
                                         font->row_width,
                                         MAX( font->height + 1, 8 ),
                                         font->pixel_format,
                                         CSP_VIDEOLOW, DSCAPS_NONE, NULL,
                                         &surface );
               if (ret) {
                    D_ERROR( "DirectFB/core/fonts: "
                              "Could not create glyph surface! (%s)\n",
                              DirectFBErrorString( ret ) );

                    D_FREE( data );
                    return ret;
               }

               font->next_x = 0;
               font->rows++;

               font->surfaces = D_REALLOC( font->surfaces, sizeof(void *) * font->rows );

               font->surfaces[font->rows - 1] = surface;
          }

          if (font->RenderGlyph(font, glyph, data,
                                font->surfaces[font->rows - 1]) == DFB_OK)
          {
               int align = DFB_PIXELFORMAT_ALIGNMENT(font->pixel_format);

               data->surface = font->surfaces[font->rows - 1];
               data->start   = font->next_x;
               font->next_x += (data->width + align) & ~align;

               dfb_gfxcard_flush_texture_cache();
          }
          else {
               data->start = data->width = data->height = 0;
          }
     }
     else {
          data->start = data->width = data->height = 0;
     }

     direct_tree_insert (font->glyph_infos, (void *) glyph, data);

     *ret_data = data;

     return DFB_OK;
}
Ejemplo n.º 2
0
static void
manage_interlocks( CoreSurfaceAllocation  *allocation,
                   CoreSurfaceAccessorID   accessor,
                   CoreSurfaceAccessFlags  access )
{
     int locks;

     locks = dfb_surface_allocation_locks( allocation );

#if 1
     /*
      * Manage access interlocks.
      *
      * SOON FIXME: Clearing flags only when not locked yet. Otherwise nested GPU/CPU locks are a problem.
      */
     /* Software read/write access... */
     if (accessor == CSAID_CPU) {
          /* If hardware has written or is writing... */
          if (allocation->accessed[CSAID_GPU] & CSAF_WRITE) {
               /* ...wait for the operation to finish. */
               dfb_gfxcard_sync(); /* TODO: wait for serial instead */

               /* Software read access after hardware write requires flush of the (bus) read cache. */
               dfb_gfxcard_flush_read_cache();

               if (!locks) {
                    /* ...clear hardware write access. */
                    allocation->accessed[CSAID_GPU] = (CoreSurfaceAccessFlags)(allocation->accessed[CSAID_GPU] & ~CSAF_WRITE);

                    /* ...clear hardware read access (to avoid syncing twice). */
                    allocation->accessed[CSAID_GPU] = (CoreSurfaceAccessFlags)(allocation->accessed[CSAID_GPU] & ~CSAF_READ);
               }
          }

          /* Software write access... */
          if (access & CSAF_WRITE) {
               /* ...if hardware has (to) read... */
               if (allocation->accessed[CSAID_GPU] & CSAF_READ) {
                    /* ...wait for the operation to finish. */
                    dfb_gfxcard_sync(); /* TODO: wait for serial instead */

                    /* ...clear hardware read access. */
                    if (!locks)
                         allocation->accessed[CSAID_GPU] = (CoreSurfaceAccessFlags)(allocation->accessed[CSAID_GPU] & ~CSAF_READ);
               }
          }
     }

     /* Hardware read access... */
     if (accessor == CSAID_GPU && access & CSAF_READ) {
          /* ...if software has written before... */
          if (allocation->accessed[CSAID_CPU] & CSAF_WRITE) {
               /* ...flush texture cache. */
               dfb_gfxcard_flush_texture_cache();

               /* ...clear software write access. */
               if (!locks)
                    allocation->accessed[CSAID_CPU] = (CoreSurfaceAccessFlags)(allocation->accessed[CSAID_CPU] & ~CSAF_WRITE);
          }
     }

     if (! D_FLAGS_ARE_SET( allocation->accessed[accessor], access )) {
          /* FIXME: surface_enter */
     }
#endif

     /* Collect... */
     allocation->accessed[accessor] = (CoreSurfaceAccessFlags)(allocation->accessed[accessor] | access);
}