diff --git a/gfx/layers/CompositorTypes.h b/gfx/layers/CompositorTypes.h index 8d0ca0475598..aa6632010db4 100644 --- a/gfx/layers/CompositorTypes.h +++ b/gfx/layers/CompositorTypes.h @@ -269,10 +269,12 @@ struct TextureInfo * * See ShadowLayerForwarder::OpenDescriptor for example. */ -enum OpenMode { - OPEN_READ_ONLY = 0x1, - OPEN_READ_WRITE = 0x2 -}; +typedef uint32_t OpenMode; +const OpenMode OPEN_READ = 0x1; +const OpenMode OPEN_WRITE = 0x2; +const OpenMode OPEN_READ_WRITE = OPEN_READ|OPEN_WRITE; +const OpenMode OPEN_READ_ONLY = OPEN_READ; +const OpenMode OPEN_WRITE_ONLY = OPEN_WRITE; // The kinds of mask texture a shader can support // We rely on the items in this enum being sequential diff --git a/gfx/layers/ImageDataSerializer.h b/gfx/layers/ImageDataSerializer.h index f47e348d4356..28ee644b0be0 100644 --- a/gfx/layers/ImageDataSerializer.h +++ b/gfx/layers/ImageDataSerializer.h @@ -32,6 +32,7 @@ public: bool IsValid() const; uint8_t* GetData(); + uint32_t GetStride() const; gfx::IntSize GetSize() const; gfx::SurfaceFormat GetFormat() const; TemporaryRef GetAsSurface(); @@ -39,7 +40,6 @@ public: TemporaryRef GetAsDrawTarget(); protected: - uint32_t GetStride() const; ImageDataSerializerBase(uint8_t* aData) : mData(aData) {} diff --git a/gfx/layers/basic/BasicCompositor.cpp b/gfx/layers/basic/BasicCompositor.cpp index 736443176e2b..01cfcaa5ac20 100644 --- a/gfx/layers/basic/BasicCompositor.cpp +++ b/gfx/layers/basic/BasicCompositor.cpp @@ -44,7 +44,6 @@ public: } virtual bool Update(gfx::DataSourceSurface* aSurface, - TextureFlags aFlags, nsIntRegion* aDestRegion = nullptr, gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE { diff --git a/gfx/layers/client/CanvasClient.cpp b/gfx/layers/client/CanvasClient.cpp index 26553b3e5b94..ce0073d36f0e 100644 --- a/gfx/layers/client/CanvasClient.cpp +++ b/gfx/layers/client/CanvasClient.cpp @@ -77,7 +77,7 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) bufferCreated = true; } - if (!mBuffer->Lock(OPEN_READ_WRITE)) { + if (!mBuffer->Lock(OPEN_WRITE_ONLY)) { return; } diff --git a/gfx/layers/client/CompositableClient.cpp b/gfx/layers/client/CompositableClient.cpp index 630068967b07..93aff538a443 100644 --- a/gfx/layers/client/CompositableClient.cpp +++ b/gfx/layers/client/CompositableClient.cpp @@ -207,11 +207,11 @@ CompositableClient::CreateTextureClientForDrawing(SurfaceFormat aFormat, #ifdef XP_WIN LayersBackend parentBackend = GetForwarder()->GetCompositorBackendType(); - // XXX[nrc] uncomment once we have new texture clients for windows if (parentBackend == LAYERS_D3D11 && gfxWindowsPlatform::GetPlatform()->GetD2DDevice() && !(aTextureFlags & TEXTURE_ALLOC_FALLBACK)) { - //result = new TextureClientD3D11(GetForwarder(), GetTextureInfo()); + result = new TextureClientD3D11(aFormat, aTextureFlags); } + // XXX[nrc] uncomment once we have new texture clients for D3D9 if (parentBackend == LAYERS_D3D9 && !GetForwarder()->ForwardsToDifferentProcess() && !(aTextureFlags & TEXTURE_ALLOC_FALLBACK)) { diff --git a/gfx/layers/client/ImageClient.cpp b/gfx/layers/client/ImageClient.cpp index 51b95753db6e..ef9df3716076 100644 --- a/gfx/layers/client/ImageClient.cpp +++ b/gfx/layers/client/ImageClient.cpp @@ -32,10 +32,13 @@ #include "nsDebug.h" // for NS_WARNING, NS_ASSERTION #include "nsISupportsImpl.h" // for Image::Release, etc #include "nsRect.h" // for nsIntRect +#include "mozilla/gfx/2D.h" #ifdef MOZ_WIDGET_GONK #include "GrallocImages.h" #endif +using namespace mozilla::gfx; + namespace mozilla { namespace layers { @@ -177,7 +180,7 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, bufferCreated = true; } - if (!mFrontBuffer->Lock(OPEN_READ_WRITE)) { + if (!mFrontBuffer->Lock(OPEN_WRITE_ONLY)) { return false; } bool status = mFrontBuffer->AsTextureClientYCbCr()->UpdateYCbCr(*data); @@ -233,18 +236,29 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, if (!mFrontBuffer) { gfxImageFormat format = gfxPlatform::GetPlatform()->OptimalFormatForContent(surface->GetContentType()); - mFrontBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format), - TEXTURE_FLAGS_DEFAULT); - MOZ_ASSERT(mFrontBuffer->AsTextureClientSurface()); - mFrontBuffer->AsTextureClientSurface()->AllocateForSurface(size); + mFrontBuffer = CreateTextureClientForDrawing(gfx::ImageFormatToSurfaceFormat(format), + mTextureFlags); + MOZ_ASSERT(mFrontBuffer->AsTextureClientDrawTarget()); + if (!mFrontBuffer->AsTextureClientDrawTarget()->AllocateForSurface(size)) { + mFrontBuffer = nullptr; + return false; + } bufferCreated = true; } - if (!mFrontBuffer->Lock(OPEN_READ_WRITE)) { + if (!mFrontBuffer->Lock(OPEN_WRITE_ONLY)) { return false; } - bool status = mFrontBuffer->AsTextureClientSurface()->UpdateSurface(surface); + + { + // We must not keep a reference to the DrawTarget after it has been unlocked. + RefPtr dt = mFrontBuffer->AsTextureClientDrawTarget()->GetAsDrawTarget(); + RefPtr source = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, surface); + MOZ_ASSERT(source.get()); + dt->CopySurface(source, IntRect(IntPoint(), source->GetSize()), IntPoint()); + } + mFrontBuffer->Unlock(); if (bufferCreated) { @@ -254,12 +268,8 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, } } - if (status) { - GetForwarder()->UpdatedTexture(this, mFrontBuffer, nullptr); - GetForwarder()->UseTexture(this, mFrontBuffer); - } else { - return false; - } + GetForwarder()->UpdatedTexture(this, mFrontBuffer, nullptr); + GetForwarder()->UseTexture(this, mFrontBuffer); } UpdatePictureRect(image->GetPictureRect()); diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index 74fa1f0b43c0..9e4f9e21e79a 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -337,7 +337,7 @@ ShmemTextureClient::GetAllocator() const bool ShmemTextureClient::Allocate(uint32_t aSize) { - MOZ_ASSERT(IsValid()); + MOZ_ASSERT(mValid); ipc::SharedMemory::SharedMemoryType memType = OptimalShmemType(); mAllocated = GetAllocator()->AllocUnsafeShmem(aSize, memType, &mShmem); return mAllocated; @@ -433,6 +433,8 @@ BufferTextureClient::BufferTextureClient(CompositableClient* aCompositable, : TextureClient(aFlags) , mCompositable(aCompositable) , mFormat(aFormat) + , mUsingFallbackDrawTarget(false) + , mLocked(false) {} BufferTextureClient::~BufferTextureClient() @@ -451,10 +453,13 @@ BufferTextureClient::UpdateSurface(gfxASurface* aSurface) } if (gfxPlatform::GetPlatform()->SupportsAzureContent()) { - RefPtr dt = serializer.GetAsDrawTarget(); + RefPtr dt = GetAsDrawTarget(); RefPtr source = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aSurface); dt->CopySurface(source, IntRect(IntPoint(), serializer.GetSize()), IntPoint()); + // XXX - if the Moz2D backend is D2D, we would be much better off memcpying + // the content of the surface directly because with D2D, GetAsDrawTarget is + // very expensive. } else { RefPtr surf = serializer.GetAsThebesSurface(); if (!surf) { @@ -467,7 +472,6 @@ BufferTextureClient::UpdateSurface(gfxASurface* aSurface) serializer.GetSize().height)); } - if (TextureRequiresLocking(mFlags) && !ImplementsLocking()) { // We don't have support for proper locking yet, so we'll // have to be immutable instead. @@ -496,6 +500,7 @@ BufferTextureClient::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFla { MOZ_ASSERT(IsValid()); MOZ_ASSERT(mFormat != gfx::FORMAT_YUV, "This textureClient cannot use YCbCr data"); + MOZ_ASSERT(aSize.width * aSize.height); int bufSize = ImageDataSerializer::ComputeMinBufferSize(aSize, mFormat); @@ -517,13 +522,86 @@ TemporaryRef BufferTextureClient::GetAsDrawTarget() { MOZ_ASSERT(IsValid()); + // XXX - uncomment when ContentClient's locking is fixed + // MOZ_ASSERT(mLocked); + + if (mDrawTarget) { + return mDrawTarget; + } ImageDataSerializer serializer(GetBuffer()); if (!serializer.IsValid()) { return nullptr; } - return serializer.GetAsDrawTarget(); + MOZ_ASSERT(mUsingFallbackDrawTarget == false); + mDrawTarget = serializer.GetAsDrawTarget(); + if (mDrawTarget) { + return mDrawTarget; + } + + // fallback path, probably because the Moz2D backend can't create a + // DrawTarget around raw memory. This is going to be slow :( + mDrawTarget = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget( + serializer.GetSize(), serializer.GetFormat()); + if (!mDrawTarget) { + return nullptr; + } + + mUsingFallbackDrawTarget = true; + if (mOpenMode & OPEN_READ) { + RefPtr surface = serializer.GetAsSurface(); + IntRect rect(0, 0, surface->GetSize().width, surface->GetSize().height); + mDrawTarget->CopySurface(surface, rect, IntPoint(0,0)); + } + return mDrawTarget; +} + +bool +BufferTextureClient::Lock(OpenMode aMode) +{ + MOZ_ASSERT(!mLocked); + mOpenMode = aMode; + mLocked = true; + return true; +} + +void +BufferTextureClient::Unlock() +{ + MOZ_ASSERT(mLocked); + mLocked = false; + if (!mDrawTarget) { + mUsingFallbackDrawTarget = false; + return; + } + + mDrawTarget->Flush(); + if (mUsingFallbackDrawTarget && (mOpenMode & OPEN_WRITE)) { + // When we are using a fallback DrawTarget, it means we could not create + // a DrawTarget wrapping the TextureClient's shared memory. In this scenario + // we need to put the content of the fallback draw target back into our shared + // memory. + RefPtr snapshot = mDrawTarget->Snapshot(); + RefPtr surface = snapshot->GetDataSurface(); + ImageDataSerializer serializer(GetBuffer()); + if (!serializer.IsValid() || serializer.GetSize() != surface->GetSize()) { + NS_WARNING("Could not write the data back into the texture."); + mDrawTarget = nullptr; + mUsingFallbackDrawTarget = false; + return; + } + MOZ_ASSERT(surface->GetSize() == serializer.GetSize()); + MOZ_ASSERT(surface->GetFormat() == serializer.GetFormat()); + int bpp = BytesPerPixel(surface->GetFormat()); + for (int i = 0; i < surface->GetSize().height; ++i) { + memcpy(serializer.GetData() + i*serializer.GetStride(), + surface->GetData() + i*surface->Stride(), + surface->GetSize().width * bpp); + } + } + mDrawTarget = nullptr; + mUsingFallbackDrawTarget = false; } bool diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index edd11c606580..98eb5f35b717 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -309,6 +309,10 @@ public: virtual gfx::IntSize GetSize() const { return mSize; } + virtual bool Lock(OpenMode aMode) MOZ_OVERRIDE; + + virtual void Unlock() MOZ_OVERRIDE; + // TextureClientSurface virtual TextureClientSurface* AsTextureClientSurface() MOZ_OVERRIDE { return this; } @@ -347,9 +351,13 @@ public: virtual size_t GetBufferSize() const = 0; protected: + RefPtr mDrawTarget; CompositableClient* mCompositable; gfx::SurfaceFormat mFormat; gfx::IntSize mSize; + OpenMode mOpenMode; + bool mUsingFallbackDrawTarget; + bool mLocked; }; /** diff --git a/gfx/layers/composite/ContentHost.cpp b/gfx/layers/composite/ContentHost.cpp index 403694de2963..819428d331b9 100644 --- a/gfx/layers/composite/ContentHost.cpp +++ b/gfx/layers/composite/ContentHost.cpp @@ -73,6 +73,10 @@ ContentHostBase::Composite(EffectChain& aEffectChain, RefPtr effect = CreateTexturedEffect(source, sourceOnWhite, aFilter); + if (!effect) { + return; + } + aEffectChain.mPrimaryEffect = effect; nsIntRegion tmpRegion; diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index 79ffb17b538b..cdaf5e92c367 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -371,7 +371,7 @@ BufferTextureHost::Updated(const nsIntRegion* aRegion) } if (GetFlags() & TEXTURE_IMMEDIATE_UPLOAD) { DebugOnly result = MaybeUpload(mPartialUpdate ? &mMaybeUpdatedRegion : nullptr); - MOZ_ASSERT(result); + NS_WARN_IF_FALSE(result, "Failed to upload a texture"); } } @@ -381,7 +381,11 @@ BufferTextureHost::SetCompositor(Compositor* aCompositor) if (mCompositor == aCompositor) { return; } - DeallocateDeviceData(); + RefPtr it = mFirstSource; + while (it) { + it->SetCompositor(aCompositor); + it = it->GetNextSibling(); + } mCompositor = aCompositor; } @@ -475,7 +479,7 @@ BufferTextureHost::Upload(nsIntRegion *aRegion) if (!mFirstSource) { mFirstSource = mCompositor->CreateDataTextureSource(mFlags); } - mFirstSource->Update(surf, mFlags, aRegion); + mFirstSource->Update(surf, aRegion); return true; } @@ -520,9 +524,9 @@ BufferTextureHost::Upload(nsIntRegion *aRegion) gfx::FORMAT_A8); // We don't support partial updates for Y U V textures NS_ASSERTION(!aRegion, "Unsupported partial updates for YCbCr textures"); - if (!srcY->Update(tempY, mFlags) || - !srcU->Update(tempCb, mFlags) || - !srcV->Update(tempCr, mFlags)) { + if (!srcY->Update(tempY) || + !srcU->Update(tempCb) || + !srcV->Update(tempCr)) { NS_WARNING("failed to update the DataTextureSource"); return false; } @@ -542,7 +546,7 @@ BufferTextureHost::Upload(nsIntRegion *aRegion) return false; } - if (!mFirstSource->Update(surf.get(), mFlags, aRegion)) { + if (!mFirstSource->Update(surf.get(), aRegion)) { NS_WARNING("failed to update the DataTextureSource"); return false; } diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index 9aa8be122852..cc01ee4e1d23 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -149,6 +149,8 @@ public: */ virtual void DeallocateDeviceData() = 0; + virtual void SetCompositor(Compositor* aCompositor) {} + void SetNextSibling(NewTextureSource* aTexture) { mNextSibling = aTexture; @@ -195,7 +197,6 @@ public: * the device texture it uploads to internally. */ virtual bool Update(gfx::DataSourceSurface* aSurface, - TextureFlags aFlags, nsIntRegion* aDestRegion = nullptr, gfx::IntPoint* aSrcOffset = nullptr) = 0; diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index 879ab09edf42..7020646576e7 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -516,6 +516,11 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect, static_cast(aEffectChain.mSecondaryEffects[EFFECT_MASK].get()); TextureSourceD3D11* source = maskEffect->mMaskTexture->AsSourceD3D11(); + if (!source) { + NS_WARNING("Missing texture source!"); + return; + } + RefPtr view; mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view)); @@ -562,6 +567,11 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect, TextureSourceD3D11* source = texturedEffect->mTexture->AsSourceD3D11(); + if (!source) { + NS_WARNING("Missing texture source!"); + return; + } + RefPtr view; mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view)); @@ -586,6 +596,18 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect, const int Y = 0, Cb = 1, Cr = 2; TextureSource* source = ycbcrEffect->mTexture; + + if (!source) { + NS_WARNING("No texture to composite"); + return; + } + + if (!source->GetSubSource(Y) || !source->GetSubSource(Cb) || !source->GetSubSource(Cr)) { + // This can happen if we failed to upload the textures, most likely + // because of unsupported dimensions (we don't tile YCbCr textures). + return; + } + TextureSourceD3D11* sourceY = source->GetSubSource(Y)->AsSourceD3D11(); TextureSourceD3D11* sourceCb = source->GetSubSource(Cb)->AsSourceD3D11(); TextureSourceD3D11* sourceCr = source->GetSubSource(Cr)->AsSourceD3D11(); @@ -610,6 +632,12 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect, static_cast(aEffectChain.mPrimaryEffect.get()); TextureSourceD3D11* sourceOnWhite = effectComponentAlpha->mOnWhite->AsSourceD3D11(); TextureSourceD3D11* sourceOnBlack = effectComponentAlpha->mOnBlack->AsSourceD3D11(); + + if (!sourceOnWhite || !sourceOnBlack) { + NS_WARNING("Missing texture source(s)!"); + return; + } + SetSamplerForFilter(effectComponentAlpha->mFilter); mVSConstants.textureCoords = effectComponentAlpha->mTextureCoords; diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp index 657acdeb215a..f477915770a0 100644 --- a/gfx/layers/d3d11/TextureD3D11.cpp +++ b/gfx/layers/d3d11/TextureD3D11.cpp @@ -62,12 +62,37 @@ GetTileRectD3D11(uint32_t aID, IntSize aSize, uint32_t aMaxSize) DataTextureSourceD3D11::DataTextureSourceD3D11(SurfaceFormat aFormat, CompositorD3D11* aCompositor) - : mFormat(aFormat) - , mCompositor(aCompositor) + : mCompositor(aCompositor) + , mFormat(aFormat) + , mFlags(0) + , mCurrentTile(0) + , mIsTiled(false) + , mIterating(false) { MOZ_COUNT_CTOR(DataTextureSourceD3D11); } +DataTextureSourceD3D11::DataTextureSourceD3D11(SurfaceFormat aFormat, + CompositorD3D11* aCompositor, + ID3D11Texture2D* aTexture) +: mCompositor(aCompositor) +, mFormat(aFormat) +, mFlags(0) +, mCurrentTile(0) +, mIsTiled(false) +, mIterating(false) +{ + MOZ_COUNT_CTOR(DataTextureSourceD3D11); + + mTexture = aTexture; + D3D11_TEXTURE2D_DESC desc; + aTexture->GetDesc(&desc); + + mSize = IntSize(desc.Width, desc.Height); +} + + + DataTextureSourceD3D11::~DataTextureSourceD3D11() { MOZ_COUNT_DTOR(DataTextureSourceD3D11); @@ -116,6 +141,15 @@ CreateTextureHostD3D11(const SurfaceDescriptor& aDesc, return result; } +TextureClientD3D11::TextureClientD3D11(gfx::SurfaceFormat aFormat, TextureFlags aFlags) + : TextureClient(aFlags) + , mFormat(aFormat) + , mIsLocked(false) +{} + +TextureClientD3D11::~TextureClientD3D11() +{} + bool TextureClientD3D11::Lock(OpenMode aMode) { @@ -129,50 +163,108 @@ void TextureClientD3D11::Unlock() { MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!"); + if (mDrawTarget) { + mDrawTarget->Flush(); + mDrawTarget = nullptr; + } UnlockD3DTexture(mTexture.get()); mIsLocked = false; } -DataTextureSourceD3D11::DataTextureSourceD3D11(ID3D11Texture2D* aTexture, - SurfaceFormat aFormat) -: mFormat(aFormat) +TemporaryRef +TextureClientD3D11::GetAsDrawTarget() { - mTexture = aTexture; - D3D11_TEXTURE2D_DESC desc; - aTexture->GetDesc(&desc); + MOZ_ASSERT(mIsLocked, "Calling TextureClient::GetAsDrawTarget without locking :("); - mSize = IntSize(desc.Width, desc.Height); + if (mDrawTarget) { + return mDrawTarget; + } + + mDrawTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture, mFormat); + return mDrawTarget; +} + +bool +TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags) +{ + mSize = aSize; + ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device(); + + CD3D10_TEXTURE2D_DESC newDesc(SurfaceFormatToDXGIFormat(mFormat), + aSize.width, aSize.height, 1, 1, + D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE); + + newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX; + + HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture)); + + if (FAILED(hr)) { + LOGD3D11("Error creating texture for client!"); + return false; + } + + return true; +} + +bool +TextureClientD3D11::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) +{ + if (!IsAllocated()) { + return false; + } + + RefPtr resource; + mTexture->QueryInterface((IDXGIResource**)byRef(resource)); + HANDLE sharedHandle; + HRESULT hr = resource->GetSharedHandle(&sharedHandle); + + if (FAILED(hr)) { + LOGD3D11("Error getting shared handle for texture."); + return false; + } + + aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, mFormat); + return true; } DXGITextureHostD3D11::DXGITextureHostD3D11(TextureFlags aFlags, const SurfaceDescriptorD3D10& aDescriptor) : TextureHost(aFlags) , mHandle(aDescriptor.handle()) - , mFormat(aDescriptor.hasAlpha() ? FORMAT_B8G8R8A8 : FORMAT_B8G8R8X8) + , mFormat(aDescriptor.format()) , mIsLocked(false) {} +ID3D11Device* +DXGITextureHostD3D11::GetDevice() +{ + return mCompositor ? mCompositor->GetDevice() : nullptr; +} + void DXGITextureHostD3D11::SetCompositor(Compositor* aCompositor) { - CompositorD3D11 *d3dCompositor = static_cast(aCompositor); - mDevice = d3dCompositor ? d3dCompositor->GetDevice() : nullptr; + mCompositor = static_cast(aCompositor); } bool DXGITextureHostD3D11::Lock() { - if (!mDevice) { + if (!GetDevice()) { NS_WARNING("trying to lock a TextureHost without a D3D device"); return false; } if (!mTextureSource) { RefPtr tex; - mDevice->OpenSharedResource((HANDLE)mHandle, - __uuidof(ID3D11Texture2D), - (void**)(ID3D11Texture2D**)byRef(tex)); + HRESULT hr = GetDevice()->OpenSharedResource((HANDLE)mHandle, + __uuidof(ID3D11Texture2D), + (void**)(ID3D11Texture2D**)byRef(tex)); + if (FAILED(hr)) { + NS_WARNING("Failed to open shared texture"); + return false; + } - mTextureSource = new DataTextureSourceD3D11(tex, mFormat); + mTextureSource = new DataTextureSourceD3D11(mFormat, mCompositor, tex); D3D11_TEXTURE2D_DESC desc; tex->GetDesc(&desc); mSize = IntSize(desc.Width, desc.Height); @@ -200,7 +292,6 @@ DXGITextureHostD3D11::GetTextureSources() bool DataTextureSourceD3D11::Update(DataSourceSurface* aSurface, - TextureFlags aFlags, nsIntRegion* aDestRegion, IntPoint* aSrcOffset) { @@ -218,25 +309,32 @@ DataTextureSourceD3D11::Update(DataSourceSurface* aSurface, DXGI_FORMAT dxgiFormat = SurfaceFormatToDXGIFormat(aSurface->GetFormat()); mSize = aSurface->GetSize(); + mFormat = aSurface->GetFormat(); CD3D11_TEXTURE2D_DESC desc(dxgiFormat, mSize.width, mSize.height, 1, 1, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_IMMUTABLE); int32_t maxSize = mCompositor->GetMaxTextureSize(); - if (mSize.width <= maxSize && mSize.height <= maxSize) { + if ((mSize.width <= maxSize && mSize.height <= maxSize) || + (mFlags & TEXTURE_DISALLOW_BIGIMAGE)) { D3D11_SUBRESOURCE_DATA initData; initData.pSysMem = aSurface->GetData(); initData.SysMemPitch = aSurface->Stride(); mCompositor->GetDevice()->CreateTexture2D(&desc, &initData, byRef(mTexture)); mIsTiled = false; + if (!mTexture) { + Reset(); + return false; + } } else { mIsTiled = true; uint32_t tileCount = GetRequiredTilesD3D11(mSize.width, maxSize) * GetRequiredTilesD3D11(mSize.height, maxSize); mTileTextures.resize(tileCount); + mTexture = nullptr; for (uint32_t i = 0; i < tileCount; i++) { IntRect tileRect = GetTileRect(i); @@ -251,11 +349,32 @@ DataTextureSourceD3D11::Update(DataSourceSurface* aSurface, initData.SysMemPitch = aSurface->Stride(); mCompositor->GetDevice()->CreateTexture2D(&desc, &initData, byRef(mTileTextures[i])); + if (!mTileTextures[i]) { + Reset(); + return false; + } } } return true; } +ID3D11Texture2D* +DataTextureSourceD3D11::GetD3D11Texture() const +{ + return mIterating ? mTileTextures[mCurrentTile] + : mTexture; +} + +void +DataTextureSourceD3D11::Reset() +{ + mTexture = nullptr; + mTileTextures.resize(0); + mIsTiled = false; + mSize.width = 0; + mSize.height = 0; +} + IntRect DataTextureSourceD3D11::GetTileRect(uint32_t aIndex) const { @@ -274,8 +393,7 @@ DataTextureSourceD3D11::SetCompositor(Compositor* aCompositor) { CompositorD3D11* d3dCompositor = static_cast(aCompositor); if (mCompositor != d3dCompositor) { - mTexture = nullptr; - mTileTextures.resize(0); + Reset(); } mCompositor = d3dCompositor; } @@ -296,7 +414,7 @@ CreateDeprecatedTextureHostD3D11(SurfaceDescriptorType aDescriptorType, result->SetFlags(aTextureFlags); - return result.forget(); + return result; } @@ -387,7 +505,7 @@ DeprecatedTextureClientD3D11::EnsureAllocated(gfx::IntSize aSize, } mDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, - aType == GFX_CONTENT_COLOR_ALPHA); + gfxPlatform::GetPlatform()->Optimal2DFormatForContent(aType)); mContentType = aType; return true; @@ -677,7 +795,7 @@ DeprecatedTextureHostDXGID3D11::UpdateImpl(const SurfaceDescriptor& aImage, return; } - mFormat = aImage.get_SurfaceDescriptorD3D10().hasAlpha() ? FORMAT_B8G8R8A8 : FORMAT_B8G8R8X8; + mFormat = aImage.get_SurfaceDescriptorD3D10().format(); D3D11_TEXTURE2D_DESC desc; mTexture->GetDesc(&desc); @@ -786,11 +904,11 @@ DeprecatedTextureHostYCbCrD3D11::UpdateImpl(const SurfaceDescriptor& aImage, yuvDeserializer.GetCbCrStride(), yuvDeserializer.GetCbCrSize(), FORMAT_A8); - // We don't support partial updates for Y U V textures + // We don't support partial updates for YCbCr textures NS_ASSERTION(!aRegion, "Unsupported partial updates for YCbCr textures"); - if (!srcY->Update(wrapperY, TEXTURE_FLAGS_DEFAULT) || - !srcCb->Update(wrapperCb, TEXTURE_FLAGS_DEFAULT) || - !srcCr->Update(wrapperCr, TEXTURE_FLAGS_DEFAULT)) { + if (!srcY->Update(wrapperY) || + !srcCb->Update(wrapperCb) || + !srcCr->Update(wrapperCr)) { NS_WARNING("failed to update the DataTextureSource"); mFirstSource = nullptr; mSize.width = 0; diff --git a/gfx/layers/d3d11/TextureD3D11.h b/gfx/layers/d3d11/TextureD3D11.h index 4b9bfeab9fcb..fb5577eaaaf8 100644 --- a/gfx/layers/d3d11/TextureD3D11.h +++ b/gfx/layers/d3d11/TextureD3D11.h @@ -25,18 +25,44 @@ class CompositorD3D11; * A TextureClient to share a D3D10 texture with the compositor thread. * The corresponding TextureHost is DXGITextureHostD3D11 */ -class TextureClientD3D11 : public TextureClient +class TextureClientD3D11 : public TextureClient, + public TextureClientDrawTarget { public: - virtual bool IsAllocated() const MOZ_OVERRIDE; + TextureClientD3D11(gfx::SurfaceFormat aFormat, TextureFlags aFlags); + + virtual ~TextureClientD3D11(); + + // TextureClient + + virtual bool IsAllocated() const MOZ_OVERRIDE { return !!mTexture; } virtual bool Lock(OpenMode aOpenMode) MOZ_OVERRIDE; virtual void Unlock() MOZ_OVERRIDE; virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE; + + virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } + + virtual TextureClientData* DropTextureData() MOZ_OVERRIDE { return nullptr; } + + // TextureClientDrawTarget + + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } + + virtual TextureClientDrawTarget* AsTextureClientDrawTarget() MOZ_OVERRIDE { return this; } + + virtual TemporaryRef GetAsDrawTarget() MOZ_OVERRIDE; + + virtual bool AllocateForSurface(gfx::IntSize aSize, + TextureAllocationFlags aFlags = ALLOC_DEFAULT) MOZ_OVERRIDE; + protected: + gfx::IntSize mSize; RefPtr mTexture; + RefPtr mDrawTarget; + gfx::SurfaceFormat mFormat; bool mIsLocked; }; @@ -71,17 +97,15 @@ class DataTextureSourceD3D11 : public DataTextureSource public: DataTextureSourceD3D11(gfx::SurfaceFormat aFormat, CompositorD3D11* aCompositor); - DataTextureSourceD3D11(ID3D11Texture2D* aTexture, - gfx::SurfaceFormat aFormat); + DataTextureSourceD3D11(gfx::SurfaceFormat aFormat, CompositorD3D11* aCompositor, + ID3D11Texture2D* aTexture); virtual ~DataTextureSourceD3D11(); - void SetCompositor(Compositor* aCompositor); // DataTextureSource virtual bool Update(gfx::DataSourceSurface* aSurface, - TextureFlags aFlags, nsIntRegion* aDestRegion = nullptr, gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE; @@ -89,6 +113,8 @@ public: virtual TextureSourceD3D11* AsSourceD3D11() MOZ_OVERRIDE { return this; } + virtual ID3D11Texture2D* GetD3D11Texture() const MOZ_OVERRIDE; + virtual DataTextureSource* AsDataTextureSource() MOZ_OVERRIDE { return this; } virtual void DeallocateDeviceData() MOZ_OVERRIDE { mTexture = nullptr; } @@ -97,6 +123,8 @@ public: virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; + // TileIterator virtual TileIterator* AsTileIterator() MOZ_OVERRIDE { return mIsTiled ? this : nullptr; } @@ -118,6 +146,8 @@ public: protected: gfx::IntRect GetTileRect(uint32_t aIndex) const; + void Reset(); + std::vector< RefPtr > mTileTextures; RefPtr mCompositor; gfx::SurfaceFormat mFormat; @@ -157,8 +187,10 @@ public: } protected: + ID3D11Device* GetDevice(); + RefPtr mTextureSource; - RefPtr mDevice; + RefPtr mCompositor; gfx::IntSize mSize; WindowsHandle mHandle; gfx::SurfaceFormat mFormat; diff --git a/gfx/layers/d3d9/CompositorD3D9.cpp b/gfx/layers/d3d9/CompositorD3D9.cpp index 28865ffb6b14..bdecc8fc2c17 100644 --- a/gfx/layers/d3d9/CompositorD3D9.cpp +++ b/gfx/layers/d3d9/CompositorD3D9.cpp @@ -333,10 +333,23 @@ CompositorD3D9::DrawQuad(const gfx::Rect &aRect, const int Y = 0, Cb = 1, Cr = 2; TextureSource* source = ycbcrEffect->mTexture; + + if (!source) { + NS_WARNING("No texture to composite"); + return; + } + + if (!source->GetSubSource(Y) || !source->GetSubSource(Cb) || !source->GetSubSource(Cr)) { + // This can happen if we failed to upload the textures, most likely + // because of unsupported dimensions (we don't tile YCbCr textures). + return; + } + TextureSourceD3D9* sourceY = source->GetSubSource(Y)->AsSourceD3D9(); TextureSourceD3D9* sourceCb = source->GetSubSource(Cb)->AsSourceD3D9(); TextureSourceD3D9* sourceCr = source->GetSubSource(Cr)->AsSourceD3D9(); + MOZ_ASSERT(sourceY->GetD3D9Texture()); MOZ_ASSERT(sourceCb->GetD3D9Texture()); MOZ_ASSERT(sourceCr->GetD3D9Texture()); diff --git a/gfx/layers/d3d9/TextureD3D9.cpp b/gfx/layers/d3d9/TextureD3D9.cpp index b24d1a11bd97..2e11df43fcd1 100644 --- a/gfx/layers/d3d9/TextureD3D9.cpp +++ b/gfx/layers/d3d9/TextureD3D9.cpp @@ -36,7 +36,7 @@ CreateDeprecatedTextureHostD3D9(SurfaceDescriptorType aDescriptorType, } result->SetFlags(aTextureFlags); - return result.forget(); + return result; } TextureSourceD3D9::~TextureSourceD3D9() @@ -264,7 +264,7 @@ TextureSourceD3D9::DataToTexture(DeviceManagerD3D9* aDeviceManager, FinishTextures(aDeviceManager, texture, surface); - return texture.forget(); + return texture; } void @@ -415,21 +415,24 @@ DeprecatedTextureHostYCbCrD3D9::UpdateImpl(const SurfaceDescriptor& aImage, DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager(); RefPtr srcY; - RefPtr srcU; - RefPtr srcV; + RefPtr srcCb; + RefPtr srcCr; if (!mFirstSource) { - srcY = new DataTextureSourceD3D9(FORMAT_A8, mCompositor, false, mStereoMode); - srcU = new DataTextureSourceD3D9(FORMAT_A8, mCompositor, false, mStereoMode); - srcV = new DataTextureSourceD3D9(FORMAT_A8, mCompositor, false, mStereoMode); + srcY = new DataTextureSourceD3D9(FORMAT_A8, mCompositor, + TEXTURE_DISALLOW_BIGIMAGE, mStereoMode); + srcCb = new DataTextureSourceD3D9(FORMAT_A8, mCompositor, + TEXTURE_DISALLOW_BIGIMAGE, mStereoMode); + srcCr = new DataTextureSourceD3D9(FORMAT_A8, mCompositor, + TEXTURE_DISALLOW_BIGIMAGE, mStereoMode); mFirstSource = srcY; - srcY->SetNextSibling(srcU); - srcU->SetNextSibling(srcV); + srcY->SetNextSibling(srcCb); + srcCb->SetNextSibling(srcCr); } else { MOZ_ASSERT(mFirstSource->GetNextSibling()); MOZ_ASSERT(mFirstSource->GetNextSibling()->GetNextSibling()); srcY = mFirstSource; - srcU = mFirstSource->GetNextSibling()->AsDataTextureSource(); - srcV = mFirstSource->GetNextSibling()->GetNextSibling()->AsDataTextureSource(); + srcCb = mFirstSource->GetNextSibling()->AsDataTextureSource(); + srcCr = mFirstSource->GetNextSibling()->GetNextSibling()->AsDataTextureSource(); } RefPtr wrapperY = @@ -447,11 +450,11 @@ DeprecatedTextureHostYCbCrD3D9::UpdateImpl(const SurfaceDescriptor& aImage, yuvDeserializer.GetCbCrStride(), yuvDeserializer.GetCbCrSize(), FORMAT_A8); - // We don't support partial updates for Y U V textures + // We don't support partial updates for YCbCr textures NS_ASSERTION(!aRegion, "Unsupported partial updates for YCbCr textures"); - if (!srcY->Update(wrapperY, TEXTURE_FLAGS_DEFAULT) || - !srcU->Update(wrapperCb, TEXTURE_FLAGS_DEFAULT) || - !srcV->Update(wrapperCr, TEXTURE_FLAGS_DEFAULT)) { + if (!srcY->Update(wrapperY) || + !srcCb->Update(wrapperCb) || + !srcCr->Update(wrapperCr)) { NS_WARNING("failed to update the DataTextureSource"); mSize.width = 0; mSize.height = 0; @@ -481,7 +484,7 @@ TextureSourceD3D9::TextureToTexture(DeviceManagerD3D9* aDeviceManager, return nullptr; } - return texture.forget(); + return texture; } void @@ -605,7 +608,7 @@ TextureSourceD3D9::SurfaceToTexture(DeviceManagerD3D9* aDeviceManager, FinishTextures(aDeviceManager, texture, surface); - return texture.forget(); + return texture; } void @@ -952,12 +955,12 @@ DeprecatedTextureClientDIB::SetDescriptor(const SurfaceDescriptor& aDescriptor) DataTextureSourceD3D9::DataTextureSourceD3D9(gfx::SurfaceFormat aFormat, CompositorD3D9* aCompositor, - bool aDisallowBigImage, + TextureFlags aFlags, StereoMode aStereoMode) : mFormat(aFormat) , mCompositor(aCompositor) , mCurrentTile(0) - , mDisallowBigImage(aDisallowBigImage) + , mFlags(aFlags) , mIsTiled(false) , mIterating(false) { @@ -970,9 +973,15 @@ DataTextureSourceD3D9::~DataTextureSourceD3D9() MOZ_COUNT_DTOR(DataTextureSourceD3D9); } +IDirect3DTexture9* +DataTextureSourceD3D9::GetD3D9Texture() +{ + return mIterating ? mTileTextures[mCurrentTile] + : mTexture; +} + bool DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface, - TextureFlags aFlags, nsIntRegion* aDestRegion, gfx::IntPoint* aSrcOffset) { @@ -982,6 +991,7 @@ DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface, MOZ_ASSERT(!aDestRegion && !aSrcOffset); if (!mCompositor || !mCompositor->device()) { + NS_WARNING("No D3D device to update the texture."); return false; } mSize = aSurface->GetSize(); @@ -1010,7 +1020,8 @@ DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface, int32_t maxSize = mCompositor->GetMaxTextureSize(); DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager(); - if (mSize.width <= maxSize && mSize.height <= maxSize) { + if ((mSize.width <= maxSize && mSize.height <= maxSize) || + (mFlags & TEXTURE_DISALLOW_BIGIMAGE)) { mTexture = DataToTexture(deviceManager, aSurface->GetData(), aSurface->Stride(), ThebesIntSize(mSize), format, bpp); @@ -1025,6 +1036,7 @@ DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface, uint32_t tileCount = GetRequiredTilesD3D9(mSize.width, maxSize) * GetRequiredTilesD3D9(mSize.height, maxSize); mTileTextures.resize(tileCount); + mTexture = nullptr; for (uint32_t i = 0; i < tileCount; i++) { IntRect tileRect = GetTileRect(i); @@ -1048,6 +1060,17 @@ DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface, return true; } +void +DataTextureSourceD3D9::SetCompositor(Compositor* aCompositor) +{ + CompositorD3D9* d3dCompositor = static_cast(aCompositor); + + if (d3dCompositor != mCompositor) { + Reset(); + mCompositor = d3dCompositor; + } +} + void DataTextureSourceD3D9::Reset() { @@ -1055,6 +1078,7 @@ DataTextureSourceD3D9::Reset() mSize.height = 0; mIsTiled = false; mTexture = nullptr; + mTileTextures.clear(); } IntRect diff --git a/gfx/layers/d3d9/TextureD3D9.h b/gfx/layers/d3d9/TextureD3D9.h index f147754a39ef..baf2d95169c0 100644 --- a/gfx/layers/d3d9/TextureD3D9.h +++ b/gfx/layers/d3d9/TextureD3D9.h @@ -100,7 +100,7 @@ class DataTextureSourceD3D9 : public DataTextureSource public: DataTextureSourceD3D9(gfx::SurfaceFormat aFormat, CompositorD3D9* aCompositor, - bool aAllowBigImage = true, + TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT, StereoMode aStereoMode = STEREO_MODE_MONO); virtual ~DataTextureSourceD3D9(); @@ -108,7 +108,6 @@ public: // DataTextureSource virtual bool Update(gfx::DataSourceSurface* aSurface, - TextureFlags aFlags, nsIntRegion* aDestRegion = nullptr, gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE; @@ -116,6 +115,8 @@ public: virtual TextureSourceD3D9* AsSourceD3D9() MOZ_OVERRIDE { return this; } + virtual IDirect3DTexture9* GetD3D9Texture() MOZ_OVERRIDE; + virtual DataTextureSource* AsDataTextureSource() MOZ_OVERRIDE { return this; } virtual void DeallocateDeviceData() MOZ_OVERRIDE { mTexture = nullptr; } @@ -124,6 +125,8 @@ public: virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; + // TileIterator virtual TileIterator* AsTileIterator() MOZ_OVERRIDE { return mIsTiled ? this : nullptr; } @@ -151,7 +154,7 @@ protected: RefPtr mCompositor; gfx::SurfaceFormat mFormat; uint32_t mCurrentTile; - bool mDisallowBigImage; + TextureFlags mFlags; bool mIsTiled; bool mIterating; }; diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh index b3b7ea20f826..a77d1bcacb45 100644 --- a/gfx/layers/ipc/LayersSurfaces.ipdlh +++ b/gfx/layers/ipc/LayersSurfaces.ipdlh @@ -39,7 +39,7 @@ struct SurfaceDescriptorDIB { struct SurfaceDescriptorD3D10 { WindowsHandle handle; - bool hasAlpha; + SurfaceFormat format; }; struct SurfaceDescriptorMacIOSurface { diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 6616732cea06..8cb34cdb3f98 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -1555,8 +1555,7 @@ TemporaryRef CompositorOGL::CreateDataTextureSource(TextureFlags aFlags) { RefPtr result = - new TextureImageTextureSourceOGL(mGLContext, - !(aFlags & TEXTURE_DISALLOW_BIGIMAGE)); + new TextureImageTextureSourceOGL(mGLContext, aFlags); return result; } diff --git a/gfx/layers/opengl/GrallocTextureClient.cpp b/gfx/layers/opengl/GrallocTextureClient.cpp index 37d2f01c4df3..6dcdffe7b48e 100644 --- a/gfx/layers/opengl/GrallocTextureClient.cpp +++ b/gfx/layers/opengl/GrallocTextureClient.cpp @@ -171,11 +171,13 @@ GrallocTextureClientOGL::Lock(OpenMode aMode) NS_WARNING("Couldn't lock graphic buffer"); return false; } - return true; + return BufferTextureClient::Lock(aMode); } + void GrallocTextureClientOGL::Unlock() { + BufferTextureClient::Unlock(); mMappedBuffer = nullptr; mGraphicBuffer->unlock(); } diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp index 7c3c8187d092..84afa1b803a1 100644 --- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -225,7 +225,6 @@ CompositableDataGonkOGL::DeleteTextureIfPresent() bool TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface, - TextureFlags aFlags, nsIntRegion* aDestRegion, gfx::IntPoint* aSrcOffset) { @@ -240,7 +239,13 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface, if (!mTexImage || mTexImage->GetSize() != size || mTexImage->GetContentType() != gfx::ContentForFormat(aSurface->GetFormat())) { - if (mAllowBigImage) { + if (mFlags & TEXTURE_DISALLOW_BIGIMAGE) { + mTexImage = CreateBasicTextureImage(mGL, size, + gfx::ContentForFormat(aSurface->GetFormat()), + WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT), + FlagsToGLFlags(mFlags), + SurfaceFormatToImageFormat(aSurface->GetFormat())); + } else { // XXX - clarify which size we want to use. IncrementalContentHost will // require the size of the destination surface to be different from // the size of aSurface. @@ -248,16 +253,7 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface, mTexImage = CreateTextureImage(mGL, size, gfx::ContentForFormat(aSurface->GetFormat()), - WrapMode(mGL, aFlags & TEXTURE_ALLOW_REPEAT), - FlagsToGLFlags(aFlags), SurfaceFormatToImageFormat(aSurface->GetFormat())); - } else { - mTexImage = CreateBasicTextureImage(mGL, - size, - gfx::ContentForFormat(aSurface->GetFormat()), - WrapMode(mGL, aFlags & TEXTURE_ALLOW_REPEAT), - FlagsToGLFlags(aFlags), - SurfaceFormatToImageFormat(aSurface->GetFormat())); } } @@ -269,6 +265,17 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface, return true; } +void +TextureImageTextureSourceOGL::SetCompositor(Compositor* aCompositor) +{ + CompositorOGL* glCompositor = static_cast(aCompositor); + + if (!glCompositor || (mGL != glCompositor->gl())) { + DeallocateDeviceData(); + mGL = glCompositor ? glCompositor->gl() : nullptr; + } +} + gfx::IntSize TextureImageTextureSourceOGL::GetSize() const { diff --git a/gfx/layers/opengl/TextureHostOGL.h b/gfx/layers/opengl/TextureHostOGL.h index 23743453edb2..94a270b3eeb1 100644 --- a/gfx/layers/opengl/TextureHostOGL.h +++ b/gfx/layers/opengl/TextureHostOGL.h @@ -154,16 +154,16 @@ class TextureImageTextureSourceOGL : public DataTextureSource , public TileIterator { public: - TextureImageTextureSourceOGL(gl::GLContext* aGL, bool aAllowBiImage = true) + TextureImageTextureSourceOGL(gl::GLContext* aGL, + TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT) : mGL(aGL) - , mAllowBigImage(aAllowBiImage) + , mFlags(aFlags) , mIterating(false) {} // DataTextureSource virtual bool Update(gfx::DataSourceSurface* aSurface, - TextureFlags aFlags, nsIntRegion* aDestRegion = nullptr, gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE; @@ -185,6 +185,8 @@ public: virtual bool IsValid() const MOZ_OVERRIDE { return !!mTexImage; } + virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; + virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return mTexImage->GetWrapMode(); @@ -220,7 +222,7 @@ public: protected: nsRefPtr mTexImage; gl::GLContext* mGL; - bool mAllowBigImage; + TextureFlags mFlags; bool mIterating; };