Exemplo n.º 1
0
/*
 * Refresh the texture memory. This must be done after a device is
 * lost or after it is reset.
 */
void _al_d3d_refresh_texture_memory(void)
{
   unsigned int i;

   for (i = 0; i < created_bitmaps._size; i++) {
      ALLEGRO_BITMAP_D3D **bptr = (ALLEGRO_BITMAP_D3D **)_al_vector_ref(&created_bitmaps, i);
      ALLEGRO_BITMAP_D3D *bmp = *bptr;
      ALLEGRO_BITMAP *al_bmp = (ALLEGRO_BITMAP *)bmp;
      ALLEGRO_DISPLAY_D3D *bmps_display = (ALLEGRO_DISPLAY_D3D *)al_bmp->display;

      if ((al_bmp->flags & ALLEGRO_MEMORY_BITMAP) || (al_bmp->parent)) {
         continue;
      }

      d3d_create_textures(bmps_display, bmp->texture_w, bmp->texture_h,
         al_bmp->flags,
	 &bmp->video_texture, /*&bmp->system_texture*/0, al_bmp->format);
      d3d_sync_bitmap_texture(al_bmp,
	 0, 0, al_bmp->w, al_bmp->h);
      if (_al_d3d_render_to_texture_supported()) {
	 bmps_display->device->UpdateTexture(
	    (IDirect3DBaseTexture9 *)bmp->system_texture,
	    (IDirect3DBaseTexture9 *)bmp->video_texture);
      }
   }
}
Exemplo n.º 2
0
static void d3d_unlock_region(ALLEGRO_BITMAP *bitmap)
{
   ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;

   d3d_bmp->modified = true;

   if (bitmap->locked_region.format != 0 && bitmap->locked_region.format != bitmap->format) {
      if (!(bitmap->lock_flags & ALLEGRO_LOCK_READONLY)) {
         _al_convert_bitmap_data(
            bitmap->locked_region.data, bitmap->locked_region.format, bitmap->locked_region.pitch,
            d3d_bmp->locked_rect.pBits, bitmap->format, d3d_bmp->locked_rect.Pitch,
            0, 0, 0, 0, bitmap->lock_w, bitmap->lock_h);
      }
      al_free(bitmap->locked_region.data);
   }

   if (d3d_bmp->is_backbuffer) {
      ALLEGRO_DISPLAY_D3D *d3d_disp = (ALLEGRO_DISPLAY_D3D *)bitmap->display;
      d3d_disp->render_target->UnlockRect();
   }
   else {
      LPDIRECT3DTEXTURE9 texture;
      if (_al_d3d_render_to_texture_supported())
         texture = d3d_bmp->system_texture;
      else
         texture = d3d_bmp->video_texture;
      texture->UnlockRect(0);
      if (bitmap->lock_flags & ALLEGRO_LOCK_READONLY)
         return;
      d3d_do_upload(d3d_bmp, bitmap->lock_x, bitmap->lock_y,
         bitmap->lock_w, bitmap->lock_h, false);
   }
}
Exemplo n.º 3
0
/*
 * Must be called before the D3D device is reset (e.g., when
 * resizing a window). All non-synced display bitmaps must be
 * synced to memory.
 */
void _al_d3d_prepare_bitmaps_for_reset(ALLEGRO_DISPLAY_D3D *disp)
{
   unsigned int i;

   if (disp->device_lost)
      return;

   if (!_al_d3d_render_to_texture_supported())
      return;

   al_lock_mutex(_al_d3d_lost_device_mutex);

   for (i = 0; i < created_bitmaps._size; i++) {
      ALLEGRO_BITMAP_D3D **bptr = (ALLEGRO_BITMAP_D3D **)_al_vector_ref(&created_bitmaps, i);
      ALLEGRO_BITMAP_D3D *bmp = *bptr;
      ALLEGRO_BITMAP *al_bmp = (ALLEGRO_BITMAP *)bmp;
      if (bmp->display == disp) {
         //d3d_sync_bitmap_memory(al_bmp);
         if (!al_bmp->preserve_texture) {
            bmp->modified = false;
         }
         else if (!bmp->is_backbuffer && bmp->modified && !(al_bmp->flags & ALLEGRO_MEMORY_BITMAP)) {
            _al_d3d_sync_bitmap(al_bmp);
            bmp->modified = false;
         }
      }
   }

   al_unlock_mutex(_al_d3d_lost_device_mutex);
}
Exemplo n.º 4
0
/* Copy bitmap->memory to texture memory */
static void d3d_sync_bitmap_texture(ALLEGRO_BITMAP *bitmap,
   int x, int y, int width, int height)
{
   D3DLOCKED_RECT locked_rect;
   RECT rect;
   ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;
   LPDIRECT3DTEXTURE9 texture;

   rect.left = x;
   rect.top = y;
   rect.right = x + width;
   rect.bottom = y + height;

   if (_al_d3d_render_to_texture_supported())
      texture = d3d_bmp->system_texture;
   else
      texture = d3d_bmp->video_texture;

   if (texture->LockRect(0, &locked_rect, &rect, 0) == D3D_OK) {
	   _al_convert_bitmap_data(bitmap->memory, bitmap->format, bitmap->w*al_get_pixel_size(bitmap->format),
		  locked_rect.pBits, bitmap->format, locked_rect.Pitch,
		  x, y, 0, 0, width, height);
	   /* Copy an extra row and column so the texture ends nicely */
	   if (rect.bottom > bitmap->h) {
		  _al_convert_bitmap_data(
			 bitmap->memory,
			 bitmap->format, bitmap->w*al_get_pixel_size(bitmap->format),
			 locked_rect.pBits,
			 bitmap->format, locked_rect.Pitch,
			 0, bitmap->h-1,
			 0, height,
			 width, 1);
	   }
	   if (rect.right > bitmap->w) {
		  _al_convert_bitmap_data(
			 bitmap->memory,
			 bitmap->format, bitmap->w*al_get_pixel_size(bitmap->format),
			 locked_rect.pBits,
			 bitmap->format, locked_rect.Pitch,
			 bitmap->w-1, 0,
			 width, 0,
			 1, height);
	   }
	   if (rect.bottom > bitmap->h && rect.right > bitmap->w) {
		  _al_convert_bitmap_data(
			 bitmap->memory,
			 bitmap->format, bitmap->w*al_get_pixel_size(bitmap->format),
			 locked_rect.pBits,
			 bitmap->format, locked_rect.Pitch,
			 bitmap->w-1, bitmap->h-1,
			 width, height,
			 1, 1);
	   }
	   texture->UnlockRect(0);
   }
   else {
      ALLEGRO_ERROR("d3d_sync_bitmap_texture: Couldn't lock texture to upload.\n");
   }
}
Exemplo n.º 5
0
/* Copies video texture to system texture and bitmap->memory */
static void _al_d3d_sync_bitmap(ALLEGRO_BITMAP *dest)
{
   ALLEGRO_BITMAP_D3D *d3d_dest;
   LPDIRECT3DSURFACE9 system_texture_surface;
   LPDIRECT3DSURFACE9 video_texture_surface;
   UINT i;

   if (!_al_d3d_render_to_texture_supported())
      return;

   if (dest->locked) {
      return;
   }

   d3d_dest = (ALLEGRO_BITMAP_D3D *)dest;

   if (d3d_dest->system_texture == NULL || d3d_dest->video_texture == NULL) {
      return;
   }

   if (dest->parent) {
      dest = dest->parent;
   }

   if (d3d_dest->system_texture->GetSurfaceLevel(
         0, &system_texture_surface) != D3D_OK) {
      ALLEGRO_ERROR("_al_d3d_sync_bitmap: GetSurfaceLevel failed while updating video texture.\n");
      return;
   }

   if (d3d_dest->video_texture->GetSurfaceLevel(
         0, &video_texture_surface) != D3D_OK) {
      ALLEGRO_ERROR("_al_d3d_sync_bitmap: GetSurfaceLevel failed while updating video texture.\n");
      return;
   }

   if (d3d_dest->display->device->GetRenderTargetData(
         video_texture_surface,
         system_texture_surface) != D3D_OK) {
      ALLEGRO_ERROR("_al_d3d_sync_bitmap: GetRenderTargetData failed.\n");
      return;
   }

   if ((i = system_texture_surface->Release()) != 0) {
      ALLEGRO_DEBUG("_al_d3d_sync_bitmap (system) ref count == %d\n", i);
   }

   if ((i = video_texture_surface->Release()) != 0) {
      // This can be non-zero
      ALLEGRO_DEBUG("_al_d3d_sync_bitmap (video) ref count == %d\n", i);
   }

   d3d_sync_bitmap_memory(dest);
}
Exemplo n.º 6
0
static void d3d_do_upload(ALLEGRO_BITMAP_D3D *d3d_bmp, int x, int y, int width,
   int height, bool sync_from_memory)
{
   ALLEGRO_BITMAP *bmp = (ALLEGRO_BITMAP *)d3d_bmp;

   if (sync_from_memory) {
      d3d_sync_bitmap_texture(bmp, x, y, width, height);
   }

   if (_al_d3d_render_to_texture_supported()) {
      if (d3d_bmp->display->device->UpdateTexture(
            (IDirect3DBaseTexture9 *)d3d_bmp->system_texture,
            (IDirect3DBaseTexture9 *)d3d_bmp->video_texture) != D3D_OK) {
         ALLEGRO_ERROR("d3d_do_upload: Couldn't update texture.\n");
         return;
      }
   }
}
Exemplo n.º 7
0
/* Copy texture memory to bitmap->memory */
static void d3d_sync_bitmap_memory(ALLEGRO_BITMAP *bitmap)
{
   D3DLOCKED_RECT locked_rect;
   ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;
   LPDIRECT3DTEXTURE9 texture;

   if (_al_d3d_render_to_texture_supported())
      texture = d3d_bmp->system_texture;
   else
      texture = d3d_bmp->video_texture;

   if (texture->LockRect(0, &locked_rect, NULL, 0) == D3D_OK) {
      _al_convert_bitmap_data(locked_rect.pBits, bitmap->format, locked_rect.Pitch,
         bitmap->memory, bitmap->format, al_get_pixel_size(bitmap->format)*bitmap->w,
         0, 0, 0, 0, bitmap->w, bitmap->h);
      texture->UnlockRect(0);
   }
   else {
      ALLEGRO_ERROR("d3d_sync_bitmap_memory: Couldn't lock texture.\n");
   }
}
Exemplo n.º 8
0
static ALLEGRO_LOCKED_REGION *d3d_lock_region(ALLEGRO_BITMAP *bitmap,
   int x, int y, int w, int h, int format,
   int flags)
{
   ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;

   if (d3d_bmp->display->device_lost)
      return NULL;

   RECT rect;
   DWORD Flags = flags & ALLEGRO_LOCK_READONLY ? D3DLOCK_READONLY : 0;
   int f = _al_get_real_pixel_format(al_get_current_display(), format);
   if (f < 0) {
      return NULL;
   }

   rect.left = x;
   rect.right = x + w;
   rect.top = y;
   rect.bottom = y + h;

   if (d3d_bmp->is_backbuffer) {
      ALLEGRO_DISPLAY_D3D *d3d_disp = (ALLEGRO_DISPLAY_D3D *)bitmap->display;
      if (d3d_disp->render_target->LockRect(&d3d_bmp->locked_rect, &rect, Flags) != D3D_OK) {
         ALLEGRO_ERROR("LockRect failed in d3d_lock_region.\n");
         return NULL;
      }
   }
   else {
      LPDIRECT3DTEXTURE9 texture;
      if (_al_d3d_render_to_texture_supported()) {
         /* 
	  * Sync bitmap->memory with texture
          */
	 bitmap->locked = false;
         _al_d3d_sync_bitmap(bitmap);
	 bitmap->locked = true;
         texture = d3d_bmp->system_texture;
      }
      else {
         texture = d3d_bmp->video_texture;
      }
      if (texture->LockRect(0, &d3d_bmp->locked_rect, &rect, Flags) != D3D_OK) {
         ALLEGRO_ERROR("LockRect failed in d3d_lock_region.\n");
         return NULL;
      }
   }

   if (format == ALLEGRO_PIXEL_FORMAT_ANY || bitmap->format == format || f == bitmap->format) {
      bitmap->locked_region.data = d3d_bmp->locked_rect.pBits;
      bitmap->locked_region.format = bitmap->format;
      bitmap->locked_region.pitch = d3d_bmp->locked_rect.Pitch;
      bitmap->locked_region.pixel_size = al_get_pixel_size(bitmap->format);
   }
   else {
      bitmap->locked_region.pitch = al_get_pixel_size(f) * w;
      bitmap->locked_region.data = al_malloc(bitmap->locked_region.pitch*h);
      bitmap->locked_region.format = f;
      bitmap->locked_region.pixel_size = al_get_pixel_size(bitmap->format);
      if (!(bitmap->lock_flags & ALLEGRO_LOCK_WRITEONLY)) {
         _al_convert_bitmap_data(
            d3d_bmp->locked_rect.pBits, bitmap->format, d3d_bmp->locked_rect.Pitch,
            bitmap->locked_region.data, f, bitmap->locked_region.pitch,
            0, 0, 0, 0, w, h);
      }
   }

   return &bitmap->locked_region;
}
Exemplo n.º 9
0
static void d3d_draw_bitmap_region(
   ALLEGRO_BITMAP *src,
   ALLEGRO_COLOR tint,
   float sx, float sy, float sw, float sh, int flags)
{
   ALLEGRO_BITMAP *dest = al_get_target_bitmap();
   ALLEGRO_BITMAP_D3D *d3d_dest = (ALLEGRO_BITMAP_D3D *)dest;
   ALLEGRO_BITMAP_D3D *d3d_src = (ALLEGRO_BITMAP_D3D *)src;

   if (!_al_d3d_render_to_texture_supported()) {
      _al_draw_bitmap_region_memory(src, tint,
         (int)sx, (int)sy, (int)sw, (int)sh, 0, 0,
         (int)flags);
      return;
   }
   
   if (d3d_dest->display->device_lost)
      return;

   _al_d3d_set_bitmap_clip(dest);

   /* For sub-bitmaps */
   if (src->parent) {
      sx += src->xofs;
      sy += src->yofs;
      src = src->parent;
      d3d_src = (ALLEGRO_BITMAP_D3D *)src;
   }
   if (dest->parent) {
      dest = dest->parent;
      d3d_dest = (ALLEGRO_BITMAP_D3D *)dest;
   }

   if (d3d_src->is_backbuffer) {
      IDirect3DSurface9 *surface;
      D3DSURFACE_DESC desc;
      if (d3d_src->display->render_target->GetDesc(&desc) != D3D_OK) {
         ALLEGRO_ERROR("d3d_draw_bitmap_region: GetDesc failed.\n");
         return;
      }
      if (desc.MultiSampleType == D3DMULTISAMPLE_NONE) {
         surface = d3d_src->display->render_target;
      }
      else {
         RECT r;
         if (d3d_src->display->device->CreateRenderTarget(
		desc.Width,
		desc.Height,
		desc.Format,
		D3DMULTISAMPLE_NONE,
		0,
		TRUE,
		&surface,
		NULL
	) != D3D_OK) {
            ALLEGRO_ERROR(
	    	"d3d_draw_bitmap_region: CreateRenderTarget failed.\n");
            return;
         }
	 r.top = 0;
	 r.left = 0;
	 r.right = desc.Width;
	 r.bottom = desc.Height;
	 if (d3d_src->display->device->StretchRect(
	 	d3d_src->display->render_target,
		&r,
		surface,
		&r,
		D3DTEXF_NONE
	 ) != D3D_OK) {
	    ALLEGRO_ERROR("d3d_draw_bitmap_region: StretchRect failed.\n");
	    surface->Release();
	    return;
	 }
      }
      ALLEGRO_BITMAP *tmp_bmp = d3d_create_bitmap_from_surface(
         surface,
         src->flags);
      if (tmp_bmp) {
         d3d_draw_bitmap_region((ALLEGRO_BITMAP *)tmp_bmp, tint,
            sx, sy, sw, sh, flags);
         al_destroy_bitmap(tmp_bmp);
	 if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) {
	    surface->Release();
	 }
      }
      return;
   }

   _al_d3d_set_blender(d3d_dest->display);

   d3d_draw_textured_quad(
      d3d_dest->display, d3d_src, tint,
      sx, sy, sw, sh, flags);

   d3d_dest->modified = true;
}
Exemplo n.º 10
0
static bool d3d_create_textures(ALLEGRO_DISPLAY_D3D *disp, int w, int h,
   int flags,
   LPDIRECT3DTEXTURE9 *video_texture, LPDIRECT3DTEXTURE9 *system_texture,
   int format)
{
   int levels;
   int autogenmipmap;
   int err;

   if (flags & ALLEGRO_MIPMAP) {
      /* "0" for all possible levels, required for auto mipmap generation. */
      levels = 0;
      autogenmipmap = D3DUSAGE_AUTOGENMIPMAP;
   }
   else {
      levels = 1;
      autogenmipmap = 0;
   }

   if (_al_d3d_render_to_texture_supported()) {
      if (video_texture) {
         err = disp->device->CreateTexture(w, h, levels,
            D3DUSAGE_RENDERTARGET | autogenmipmap,
            (D3DFORMAT)_al_format_to_d3d(format), D3DPOOL_DEFAULT,
            video_texture, NULL);
         if (err != D3D_OK && err != D3DOK_NOAUTOGEN) {
            ALLEGRO_ERROR("d3d_create_textures: Unable to create video texture.\n");
            return false;
         }
      }

      if (system_texture) {
         err = disp->device->CreateTexture(w, h, 1,
            0, (D3DFORMAT)_al_format_to_d3d(format), D3DPOOL_SYSTEMMEM,
            system_texture, NULL);
         if (err != D3D_OK) {
            ALLEGRO_ERROR("d3d_create_textures: Unable to create system texture.\n");
            if (video_texture && (*video_texture)) {
               (*video_texture)->Release();
               *video_texture = NULL;
            }
            return false;
         }
      }

      return true;
   }
   else {
      if (video_texture) {
         err = disp->device->CreateTexture(w, h, 1,
            0, (D3DFORMAT)_al_format_to_d3d(format), D3DPOOL_MANAGED,
            video_texture, NULL);
         if (err != D3D_OK) {
            ALLEGRO_ERROR("d3d_create_textures: Unable to create video texture (no render-to-texture).\n");
            return false;
         }
      }

      return true;
   }
}
Exemplo n.º 11
0
/* Copies video texture to system texture and bitmap->memory */
static bool _al_d3d_sync_bitmap(ALLEGRO_BITMAP *dest)
{
   ALLEGRO_BITMAP_D3D *d3d_dest;
   LPDIRECT3DSURFACE9 system_texture_surface;
   LPDIRECT3DSURFACE9 video_texture_surface;
   bool ok;
   UINT i;

   if (!_al_d3d_render_to_texture_supported()) {
      ALLEGRO_ERROR("Render-to-texture not supported.\n");
      return false;
   }

   if (dest->locked) {
      ALLEGRO_ERROR("Already locked.\n");
      return false;
   }

   d3d_dest = (ALLEGRO_BITMAP_D3D *)dest;

   if (d3d_dest->system_texture == NULL || d3d_dest->video_texture == NULL) {
      ALLEGRO_ERROR("A texture is null.\n");
      return false;
   }

   if (dest->parent) {
      dest = dest->parent;
   }

   ok = true;
   system_texture_surface = NULL;
   video_texture_surface = NULL;

   if (d3d_dest->system_texture->GetSurfaceLevel(
         0, &system_texture_surface) != D3D_OK) {
      ALLEGRO_ERROR("_al_d3d_sync_bitmap: GetSurfaceLevel failed while updating video texture.\n");
      ok = false;
   }

   if (ok && d3d_dest->video_texture->GetSurfaceLevel(
         0, &video_texture_surface) != D3D_OK) {
      ALLEGRO_ERROR("_al_d3d_sync_bitmap: GetSurfaceLevel failed while updating video texture.\n");
      ok = false;
   }

   if (ok && d3d_dest->display->device->GetRenderTargetData(
         video_texture_surface,
         system_texture_surface) != D3D_OK) {
      ALLEGRO_ERROR("_al_d3d_sync_bitmap: GetRenderTargetData failed.\n");
      ok = false;
   }

   if (system_texture_surface) {
       if ((i = system_texture_surface->Release()) != 0) {
	  ALLEGRO_DEBUG("_al_d3d_sync_bitmap (system) ref count == %d\n", i);
       }
   }
   if (video_texture_surface) {
       if ((i = video_texture_surface->Release()) != 0) {
	  // This can be non-zero
	  ALLEGRO_DEBUG("_al_d3d_sync_bitmap (video) ref count == %d\n", i);
       }
   }

   if (ok) {
      d3d_sync_bitmap_memory(dest);
   }

   return ok;
}