Bug 593268 - Part 3: Implement CreateOptimalSurface for D3D9 layers and use interop in CanvasLayerD3D9. r=jrmuizel

This commit is contained in:
Bas Schouten 2010-09-08 05:27:36 +02:00
Родитель 87fc80cd17
Коммит 9f3321e5ee
4 изменённых файлов: 78 добавлений и 0 удалений

Просмотреть файл

@ -40,6 +40,7 @@
#include "gfxImageSurface.h"
#include "gfxWindowsSurface.h"
#include "gfxWindowsPlatform.h"
namespace mozilla {
namespace layers {
@ -71,6 +72,17 @@ CanvasLayerD3D9::Initialize(const Data& aData)
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
if (mSurface && mSurface->GetType() == gfxASurface::SurfaceTypeD2D) {
void *data = mSurface->GetData(&gKeyD3D9Texture);
if (data) {
mTexture = static_cast<IDirect3DTexture9*>(data);
mIsInteropTexture = true;
return;
}
}
mIsInteropTexture = false;
if (mD3DManager->deviceManager()->HasDynamicTextures()) {
device()->CreateTexture(mBounds.width, mBounds.height, 1, D3DUSAGE_DYNAMIC,
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
@ -92,6 +104,14 @@ CanvasLayerD3D9::Updated(const nsIntRect& aRect)
return;
}
#ifdef CAIRO_HAS_D2D_SURFACE
if (mIsInteropTexture) {
mSurface->Flush();
cairo_d2d_finish_device(gfxWindowsPlatform::GetPlatform()->GetD2DDevice());
return;
}
#endif
if (mGLContext) {
// WebGL reads entire surface.
D3DLOCKED_RECT r;

Просмотреть файл

@ -74,6 +74,9 @@ public:
protected:
typedef mozilla::gl::GLContext GLContext;
// Indicates whether our texture was obtained through D2D interop.
bool mIsInteropTexture;
nsRefPtr<gfxASurface> mSurface;
nsRefPtr<GLContext> mGLContext;

Просмотреть файл

@ -44,6 +44,10 @@
#include "CanvasLayerD3D9.h"
#include "nsIServiceManager.h"
#include "nsIPrefService.h"
#include "gfxWindowsPlatform.h"
#ifdef CAIRO_HAS_D2D_SURFACE
#include "gfxD2DSurface.h"
#endif
namespace mozilla {
namespace layers {
@ -184,6 +188,51 @@ LayerManagerD3D9::CreateImageContainer()
return container.forget();
}
cairo_user_data_key_t gKeyD3D9Texture;
void ReleaseTexture(void *texture)
{
static_cast<IDirect3DTexture9*>(texture)->Release();
}
already_AddRefed<gfxASurface>
LayerManagerD3D9::CreateOptimalSurface(const gfxIntSize &aSize,
gfxASurface::gfxImageFormat aFormat)
{
#ifdef CAIRO_HAS_D2D_SURFACE
if ((aFormat != gfxASurface::ImageFormatRGB24 &&
aFormat != gfxASurface::ImageFormatARGB32) ||
gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
gfxWindowsPlatform::RENDER_DIRECT2D ||
!deviceManager()->IsD3D9Ex()) {
return LayerManager::CreateOptimalSurface(aSize, aFormat);
}
nsRefPtr<IDirect3DTexture9> texture;
HANDLE sharedHandle = 0;
device()->CreateTexture(aSize.width, aSize.height, 1,
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, getter_AddRefs(texture), &sharedHandle);
nsRefPtr<gfxD2DSurface> surface =
new gfxD2DSurface(sharedHandle, aFormat == gfxASurface::ImageFormatRGB24 ?
gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA);
if (!surface || surface->CairoStatus()) {
return LayerManager::CreateOptimalSurface(aSize, aFormat);
}
surface->SetData(&gKeyD3D9Texture,
texture.forget().get(),
ReleaseTexture);
return surface.forget();
#else
return LayerManager::CreateOptimalSurface(aSize, aFormat);
#endif
}
void
LayerManagerD3D9::Render()
{

Просмотреть файл

@ -51,6 +51,8 @@
namespace mozilla {
namespace layers {
extern cairo_user_data_key_t gKeyD3D9Texture;
class LayerD3D9;
class ThebesLayerD3D9;
@ -117,6 +119,10 @@ public:
virtual already_AddRefed<ImageContainer> CreateImageContainer();
virtual already_AddRefed<gfxASurface>
CreateOptimalSurface(const gfxIntSize &aSize,
gfxASurface::gfxImageFormat imageFormat);
virtual LayersBackend GetBackendType() { return LAYERS_D3D9; }
virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Direct3D 9"); }