зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 12 changesets (bug 1200595) for b2g mochitest crashes in SharedBufferManagerParent CLOSED TREE
Backed out changeset cf8cf1a039dd (bug 1200595) Backed out changeset 65da564f952c (bug 1200595) Backed out changeset 7663208f1582 (bug 1200595) Backed out changeset fc1fbb97c8eb (bug 1200595) Backed out changeset 3ad5a4c457fe (bug 1200595) Backed out changeset add3fe9afc0c (bug 1200595) Backed out changeset 68aba6b39588 (bug 1200595) Backed out changeset ab326c34f1cf (bug 1200595) Backed out changeset ed34bc528a1b (bug 1200595) Backed out changeset 0dc93424546c (bug 1200595) Backed out changeset 8cc12f12f3d1 (bug 1200595) Backed out changeset bb84403701b7 (bug 1200595) --HG-- extra : commitid : AMC6i05xyTh
This commit is contained in:
Родитель
e617ebdf10
Коммит
72261b4523
|
@ -354,10 +354,10 @@ OmxDecoder::ReleaseMediaResources() {
|
|||
for (std::set<TextureClient*>::iterator it=mPendingRecycleTexutreClients.begin();
|
||||
it!=mPendingRecycleTexutreClients.end(); it++)
|
||||
{
|
||||
GrallocTextureData* client = static_cast<GrallocTextureData*>((*it)->GetInternalData());
|
||||
(*it)->ClearRecycleCallback();
|
||||
GrallocTextureClientOGL* client = static_cast<GrallocTextureClientOGL*>(*it);
|
||||
client->ClearRecycleCallback();
|
||||
if (client->GetMediaBuffer()) {
|
||||
mPendingVideoBuffers.push(BufferItem(client->GetMediaBuffer(), (*it)->GetAndResetReleaseFenceHandle()));
|
||||
mPendingVideoBuffers.push(BufferItem(client->GetMediaBuffer(), client->GetAndResetReleaseFenceHandle()));
|
||||
}
|
||||
}
|
||||
mPendingRecycleTexutreClients.clear();
|
||||
|
@ -653,7 +653,8 @@ OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
|
|||
// Manually increment reference count to keep MediaBuffer alive
|
||||
// during TextureClient is in use.
|
||||
mVideoBuffer->add_ref();
|
||||
static_cast<GrallocTextureData*>(textureClient->GetInternalData())->SetMediaBuffer(mVideoBuffer);
|
||||
GrallocTextureClientOGL* grallocClient = static_cast<GrallocTextureClientOGL*>(textureClient.get());
|
||||
grallocClient->SetMediaBuffer(mVideoBuffer);
|
||||
// Set recycle callback for TextureClient
|
||||
textureClient->SetRecycleCallback(OmxDecoder::RecycleCallback, this);
|
||||
{
|
||||
|
@ -916,9 +917,9 @@ OmxDecoder::RecycleCallbackImp(TextureClient* aClient)
|
|||
return;
|
||||
}
|
||||
mPendingRecycleTexutreClients.erase(aClient);
|
||||
GrallocTextureData* grallocData = static_cast<GrallocTextureData*>(aClient->GetInternalData());
|
||||
if (grallocData->GetMediaBuffer()) {
|
||||
mPendingVideoBuffers.push(BufferItem(grallocData->GetMediaBuffer(), aClient->GetAndResetReleaseFenceHandle()));
|
||||
GrallocTextureClientOGL* client = static_cast<GrallocTextureClientOGL*>(aClient);
|
||||
if (client->GetMediaBuffer()) {
|
||||
mPendingVideoBuffers.push(BufferItem(client->GetMediaBuffer(), client->GetAndResetReleaseFenceHandle()));
|
||||
}
|
||||
}
|
||||
sp<AMessage> notify =
|
||||
|
|
|
@ -374,14 +374,14 @@ GonkVideoDecoderManager::CreateVideoDataFromGraphicBuffer(MediaBuffer* aSource,
|
|||
aPicture.height = size.height;
|
||||
|
||||
sp<GraphicBuffer> destBuffer =
|
||||
static_cast<GrallocTextureData*>(textureClient->GetInternalData())->GetGraphicBuffer();
|
||||
|
||||
static_cast<GrallocTextureClientOGL*>(textureClient.get())->GetGraphicBuffer();
|
||||
|
||||
CopyGraphicBuffer(srcBuffer, destBuffer, aPicture);
|
||||
} else {
|
||||
textureClient = mNativeWindow->getTextureClientFromBuffer(srcBuffer.get());
|
||||
textureClient->SetRecycleCallback(GonkVideoDecoderManager::RecycleCallback, this);
|
||||
|
||||
static_cast<GrallocTextureData*>(textureClient->GetInternalData())->SetMediaBuffer(aSource);
|
||||
GrallocTextureClientOGL* grallocClient = static_cast<GrallocTextureClientOGL*>(textureClient.get());
|
||||
grallocClient->SetMediaBuffer(aSource);
|
||||
}
|
||||
|
||||
RefPtr<VideoData> data = VideoData::Create(mInfo.mVideo,
|
||||
|
@ -683,7 +683,7 @@ GonkVideoDecoderManager::RecycleCallback(TextureClient* aClient, void* aClosure)
|
|||
{
|
||||
MOZ_ASSERT(aClient && !aClient->IsDead());
|
||||
GonkVideoDecoderManager* videoManager = static_cast<GonkVideoDecoderManager*>(aClosure);
|
||||
GrallocTextureData* client = static_cast<GrallocTextureData*>(aClient->GetInternalData());
|
||||
GrallocTextureClientOGL* client = static_cast<GrallocTextureClientOGL*>(aClient);
|
||||
aClient->ClearRecycleCallback();
|
||||
FenceHandle handle = aClient->GetAndResetReleaseFenceHandle();
|
||||
videoManager->PostReleaseVideoBuffer(client->GetMediaBuffer(), handle);
|
||||
|
|
|
@ -763,8 +763,9 @@ MediaEngineGonkVideoSource::RotateImage(layers::Image* aImage, uint32_t aWidth,
|
|||
layers::TextureFlags::DEFAULT,
|
||||
layers::ALLOC_DISALLOW_BUFFERTEXTURECLIENT);
|
||||
if (textureClient) {
|
||||
android::sp<android::GraphicBuffer> destBuffer =
|
||||
static_cast<layers::GrallocTextureData*>(textureClient->GetInternalData())->GetGraphicBuffer();
|
||||
RefPtr<layers::GrallocTextureClientOGL> grallocTextureClient = textureClient->AsGrallocTextureClientOGL();
|
||||
|
||||
android::sp<android::GraphicBuffer> destBuffer = grallocTextureClient->GetGraphicBuffer();
|
||||
|
||||
void* destMem = nullptr;
|
||||
destBuffer->lock(android::GraphicBuffer::USAGE_SW_WRITE_OFTEN, &destMem);
|
||||
|
|
|
@ -355,7 +355,7 @@ SurfaceFactory::NewTexClient(const gfx::IntSize& size)
|
|||
return nullptr;
|
||||
|
||||
RefPtr<layers::SharedSurfaceTextureClient> ret;
|
||||
ret = layers::SharedSurfaceTextureClient::Create(Move(surf), this, mAllocator, mFlags);
|
||||
ret = new layers::SharedSurfaceTextureClient(mAllocator, mFlags, Move(surf), this);
|
||||
|
||||
StartRecycling(ret);
|
||||
|
||||
|
@ -391,7 +391,7 @@ SurfaceFactory::RecycleCallback(layers::TextureClient* rawTC, void* rawFactory)
|
|||
tc = static_cast<layers::SharedSurfaceTextureClient*>(rawTC);
|
||||
SurfaceFactory* factory = static_cast<SurfaceFactory*>(rawFactory);
|
||||
|
||||
if (tc->Surf()->mCanRecycle) {
|
||||
if (tc->mSurf->mCanRecycle) {
|
||||
if (factory->Recycle(tc))
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -63,17 +63,17 @@ SharedSurface_Gralloc::Create(GLContext* prodGL,
|
|||
gfxContentType type = hasAlpha ? gfxContentType::COLOR_ALPHA
|
||||
: gfxContentType::COLOR;
|
||||
|
||||
GrallocTextureData* texData = GrallocTextureData::CreateForGLRendering(
|
||||
size, gfxPlatform::GetPlatform()->Optimal2DFormatForContent(type), allocator
|
||||
);
|
||||
typedef GrallocTextureClientOGL ptrT;
|
||||
RefPtr<ptrT> grallocTC = new ptrT(allocator,
|
||||
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(type),
|
||||
gfx::BackendType::NONE, // we don't need to use it with a DrawTarget
|
||||
flags);
|
||||
|
||||
if (!texData) {
|
||||
if (!grallocTC->AllocateForGLRendering(size)) {
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
RefPtr<TextureClient> grallocTC = new TextureClient(texData, flags, allocator);
|
||||
|
||||
sp<GraphicBuffer> buffer = texData->GetGraphicBuffer();
|
||||
sp<GraphicBuffer> buffer = grallocTC->GetGraphicBuffer();
|
||||
|
||||
EGLDisplay display = egl->Display();
|
||||
EGLClientBuffer clientBuffer = buffer->getNativeBuffer();
|
||||
|
@ -119,7 +119,7 @@ SharedSurface_Gralloc::SharedSurface_Gralloc(GLContext* prodGL,
|
|||
bool hasAlpha,
|
||||
GLLibraryEGL* egl,
|
||||
layers::ISurfaceAllocator* allocator,
|
||||
layers::TextureClient* textureClient,
|
||||
layers::GrallocTextureClientOGL* textureClient,
|
||||
GLuint prodTex)
|
||||
: SharedSurface(SharedSurfaceType::Gralloc,
|
||||
AttachmentType::GLTexture,
|
||||
|
@ -279,6 +279,7 @@ SharedSurface_Gralloc::WaitForBufferOwnership()
|
|||
bool
|
||||
SharedSurface_Gralloc::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
|
||||
{
|
||||
mTextureClient->MarkShared();
|
||||
return mTextureClient->ToSurfaceDescriptor(*out_descriptor);
|
||||
}
|
||||
|
||||
|
@ -286,9 +287,7 @@ bool
|
|||
SharedSurface_Gralloc::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
|
||||
{
|
||||
MOZ_ASSERT(out_surface);
|
||||
sp<GraphicBuffer> buffer = static_cast<GrallocTextureData*>(
|
||||
mTextureClient->GetInternalData()
|
||||
)->GetGraphicBuffer();
|
||||
sp<GraphicBuffer> buffer = mTextureClient->GetGraphicBuffer();
|
||||
|
||||
const uint8_t* grallocData = nullptr;
|
||||
auto result = buffer->lock(
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
class ISurfaceAllocator;
|
||||
class TextureClient;
|
||||
class GrallocTextureClientOGL;
|
||||
}
|
||||
|
||||
namespace gl {
|
||||
|
@ -41,7 +41,7 @@ protected:
|
|||
GLLibraryEGL* const mEGL;
|
||||
EGLSync mSync;
|
||||
RefPtr<layers::ISurfaceAllocator> mAllocator;
|
||||
RefPtr<layers::TextureClient> mTextureClient;
|
||||
RefPtr<layers::GrallocTextureClientOGL> mTextureClient;
|
||||
const GLuint mProdTex;
|
||||
|
||||
SharedSurface_Gralloc(GLContext* prodGL,
|
||||
|
@ -49,7 +49,7 @@ protected:
|
|||
bool hasAlpha,
|
||||
GLLibraryEGL* egl,
|
||||
layers::ISurfaceAllocator* allocator,
|
||||
layers::TextureClient* textureClient,
|
||||
layers::GrallocTextureClientOGL* textureClient,
|
||||
GLuint prodTex);
|
||||
|
||||
static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl);
|
||||
|
@ -70,7 +70,7 @@ public:
|
|||
return mProdTex;
|
||||
}
|
||||
|
||||
layers::TextureClient* GetTextureClient() {
|
||||
layers::GrallocTextureClientOGL* GetTextureClient() {
|
||||
return mTextureClient;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "GLReadTexImageHelper.h"
|
||||
#include "GLScreenBuffer.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "mozilla/layers/BufferTexture.h"
|
||||
#include "mozilla/layers/CanvasClient.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/TextureClientSharedSurface.h"
|
||||
|
@ -148,8 +147,8 @@ void
|
|||
AsyncCanvasRenderer::CopyFromTextureClient(TextureClient* aTextureClient)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
TextureClientAutoLock texLock(aTextureClient, layers::OpenMode::OPEN_READ);
|
||||
if (!texLock.Succeeded()) {
|
||||
RefPtr<BufferTextureClient> buffer = static_cast<BufferTextureClient*>(aTextureClient);
|
||||
if (!buffer->Lock(layers::OpenMode::OPEN_READ)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -166,20 +165,16 @@ AsyncCanvasRenderer::CopyFromTextureClient(TextureClient* aTextureClient)
|
|||
mSurfaceForBasic = gfx::Factory::CreateDataSourceSurfaceWithStride(size, format, stride);
|
||||
}
|
||||
|
||||
MappedTextureData mapped;
|
||||
if (!aTextureClient->BorrowMappedData(mapped)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t* lockedBytes = mapped.data;
|
||||
const uint8_t* lockedBytes = buffer->GetLockedData();
|
||||
gfx::DataSourceSurface::ScopedMap map(mSurfaceForBasic,
|
||||
gfx::DataSourceSurface::MapType::WRITE);
|
||||
if (!map.IsMapped()) {
|
||||
buffer->Unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(map.GetStride() == mapped.stride);
|
||||
memcpy(map.GetData(), lockedBytes, map.GetStride() * mSurfaceForBasic->GetSize().height);
|
||||
buffer->Unlock();
|
||||
|
||||
if (mSurfaceForBasic->GetFormat() == gfx::SurfaceFormat::R8G8B8A8 ||
|
||||
mSurfaceForBasic->GetFormat() == gfx::SurfaceFormat::R8G8B8X8) {
|
||||
|
|
|
@ -1,449 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
// * This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BufferTexture.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/fallible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class MemoryTextureData : public BufferTextureData
|
||||
{
|
||||
public:
|
||||
static MemoryTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend,TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
virtual TextureData*
|
||||
CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator*) override;
|
||||
|
||||
MemoryTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend,
|
||||
uint8_t* aBuffer, size_t aBufferSize)
|
||||
: BufferTextureData(aSize, aFormat, aMoz2DBackend)
|
||||
, mBuffer(aBuffer)
|
||||
, mBufferSize(aBufferSize)
|
||||
{
|
||||
MOZ_ASSERT(aBuffer);
|
||||
MOZ_ASSERT(aBufferSize);
|
||||
}
|
||||
|
||||
virtual uint8_t* GetBuffer() override { return mBuffer; }
|
||||
|
||||
virtual size_t GetBufferSize() override { return mBufferSize; }
|
||||
|
||||
protected:
|
||||
uint8_t* mBuffer;
|
||||
size_t mBufferSize;
|
||||
};
|
||||
|
||||
class ShmemTextureData : public BufferTextureData
|
||||
{
|
||||
public:
|
||||
static ShmemTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
virtual TextureData*
|
||||
CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
|
||||
|
||||
ShmemTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend, mozilla::ipc::Shmem aShmem)
|
||||
: BufferTextureData(aSize, aFormat, aMoz2DBackend)
|
||||
, mShmem(aShmem)
|
||||
{
|
||||
MOZ_ASSERT(mShmem.Size<uint8_t>());
|
||||
}
|
||||
|
||||
virtual uint8_t* GetBuffer() override { return mShmem.get<uint8_t>(); }
|
||||
|
||||
virtual size_t GetBufferSize() override { return mShmem.Size<uint8_t>(); }
|
||||
|
||||
protected:
|
||||
mozilla::ipc::Shmem mShmem;
|
||||
};
|
||||
|
||||
BufferTextureData*
|
||||
BufferTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
if (!aAllocator || aAllocator->IsSameProcess()) {
|
||||
return MemoryTextureData::Create(aSize, aFormat, aMoz2DBackend, aFlags, aAllocFlags, aAllocator);
|
||||
} else {
|
||||
return ShmemTextureData::Create(aSize, aFormat, aMoz2DBackend, aFlags, aAllocFlags, aAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
BufferTextureData*
|
||||
BufferTextureData::CreateWithBufferSize(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
size_t aSize,
|
||||
TextureFlags aTextureFlags)
|
||||
{
|
||||
if (aSize == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BufferTextureData* data;
|
||||
if (!aAllocator || aAllocator->IsSameProcess()) {
|
||||
uint8_t* buffer = new (fallible) uint8_t[aSize];
|
||||
if (!buffer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
data = new MemoryTextureData(gfx::IntSize(), aFormat, gfx::BackendType::NONE, buffer, aSize);
|
||||
} else {
|
||||
ipc::Shmem shm;
|
||||
if (!aAllocator->AllocUnsafeShmem(aSize, OptimalShmemType(), &shm)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
data = new ShmemTextureData(gfx::IntSize(), aFormat, gfx::BackendType::NONE, shm);
|
||||
}
|
||||
|
||||
// Initialize the metadata with something, even if it will have to be rewritten
|
||||
// afterwards since we don't know the dimensions of the texture at this point.
|
||||
if (aFormat == gfx::SurfaceFormat::YUV) {
|
||||
YCbCrImageDataSerializer serializer(data->GetBuffer(), data->GetBufferSize());
|
||||
serializer.InitializeBufferInfo(gfx::IntSize(0,0), gfx::IntSize(0,0), StereoMode::MONO);
|
||||
} else {
|
||||
ImageDataSerializer serializer(data->GetBuffer(), data->GetBufferSize());
|
||||
serializer.InitializeBufferInfo(gfx::IntSize(0, 0), aFormat);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
BufferTextureData*
|
||||
BufferTextureData::CreateForYCbCr(ISurfaceAllocator* aAllocator,
|
||||
gfx::IntSize aYSize,
|
||||
gfx::IntSize aCbCrSize,
|
||||
StereoMode aStereoMode,
|
||||
TextureFlags aTextureFlags)
|
||||
{
|
||||
size_t bufSize = YCbCrImageDataSerializer::ComputeMinBufferSize(aYSize, aCbCrSize);
|
||||
BufferTextureData* texture = CreateWithBufferSize(aAllocator, gfx::SurfaceFormat::YUV,
|
||||
bufSize, aTextureFlags);
|
||||
if (!texture) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
YCbCrImageDataSerializer serializer(texture->GetBuffer(), texture->GetBufferSize());
|
||||
serializer.InitializeBufferInfo(aYSize, aCbCrSize, aStereoMode);
|
||||
texture->mSize = aYSize;
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
bool
|
||||
BufferTextureData::SupportsMoz2D() const
|
||||
{
|
||||
switch (mFormat) {
|
||||
case gfx::SurfaceFormat::YUV:
|
||||
case gfx::SurfaceFormat::NV12:
|
||||
case gfx::SurfaceFormat::UNKNOWN:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DrawTarget>
|
||||
BufferTextureData::BorrowDrawTarget()
|
||||
{
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget->SetTransform(gfx::Matrix());
|
||||
RefPtr<gfx::DrawTarget> dt = mDrawTarget;
|
||||
return dt.forget();
|
||||
}
|
||||
|
||||
ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
|
||||
if (!serializer.IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mDrawTarget = serializer.GetAsDrawTarget(mMoz2DBackend);
|
||||
if (mDrawTarget) {
|
||||
RefPtr<gfx::DrawTarget> dt = mDrawTarget;
|
||||
return dt.forget();
|
||||
}
|
||||
|
||||
// TODO - should we warn? should we really fallback to cairo? perhaps
|
||||
// at least update mMoz2DBackend...
|
||||
mDrawTarget = serializer.GetAsDrawTarget(gfx::BackendType::CAIRO);
|
||||
if (!mDrawTarget) {
|
||||
gfxCriticalNote << "BorrowDrawTarget failure, original backend " << (int)mMoz2DBackend;
|
||||
}
|
||||
|
||||
RefPtr<gfx::DrawTarget> dt = mDrawTarget;
|
||||
return dt.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
BufferTextureData::BorrowMappedData(MappedTextureData& aData)
|
||||
{
|
||||
if (mFormat == gfx::SurfaceFormat::YUV) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageDataDeserializer view(GetBuffer(), GetBufferSize());
|
||||
if (!view.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aData.data = view.GetData();
|
||||
aData.size = view.GetSize();
|
||||
aData.stride = view.GetStride();
|
||||
aData.format = mFormat;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BufferTextureData::BorrowMappedYCbCrData(MappedYCbCrTextureData& aMap)
|
||||
{
|
||||
if (mFormat != gfx::SurfaceFormat::YUV) {
|
||||
return false;
|
||||
}
|
||||
|
||||
YCbCrImageDataDeserializer view(GetBuffer(), GetBufferSize());
|
||||
if (!view.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aMap.stereoMode = view.GetStereoMode();
|
||||
aMap.metadata = GetBuffer();
|
||||
|
||||
aMap.y.data = view.GetYData();
|
||||
aMap.y.size = view.GetYSize();
|
||||
aMap.y.stride = view.GetYStride();
|
||||
aMap.y.skip = 0;
|
||||
|
||||
aMap.cb.data = view.GetCbData();
|
||||
aMap.cb.size = view.GetCbCrSize();
|
||||
aMap.cb.stride = view.GetCbCrStride();
|
||||
aMap.cb.skip = 0;
|
||||
|
||||
aMap.cr.data = view.GetCrData();
|
||||
aMap.cr.size = view.GetCbCrSize();
|
||||
aMap.cr.stride = view.GetCbCrStride();
|
||||
aMap.cr.skip = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BufferTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
{
|
||||
ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> surface = serializer.GetAsSurface();
|
||||
|
||||
if (!surface) {
|
||||
gfxCriticalError() << "Failed to get serializer as surface!";
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> srcSurf = aSurface->GetDataSurface();
|
||||
|
||||
if (!srcSurf) {
|
||||
gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (surface->GetSize() != srcSurf->GetSize() || surface->GetFormat() != srcSurf->GetFormat()) {
|
||||
gfxCriticalError() << "Attempt to update texture client from a surface with a different size or format! This: " << surface->GetSize() << " " << surface->GetFormat() << " Other: " << aSurface->GetSize() << " " << aSurface->GetFormat();
|
||||
return false;
|
||||
}
|
||||
|
||||
gfx::DataSourceSurface::MappedSurface sourceMap;
|
||||
gfx::DataSourceSurface::MappedSurface destMap;
|
||||
if (!srcSurf->Map(gfx::DataSourceSurface::READ, &sourceMap)) {
|
||||
gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!surface->Map(gfx::DataSourceSurface::WRITE, &destMap)) {
|
||||
srcSurf->Unmap();
|
||||
gfxCriticalError() << "Failed to map destination surface for UpdateFromSurface.";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for (int y = 0; y < srcSurf->GetSize().height; y++) {
|
||||
memcpy(destMap.mData + destMap.mStride * y,
|
||||
sourceMap.mData + sourceMap.mStride * y,
|
||||
srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
|
||||
}
|
||||
|
||||
srcSurf->Unmap();
|
||||
surface->Unmap();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MemoryTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(GetFormat() != gfx::SurfaceFormat::UNKNOWN);
|
||||
if (GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aOutDescriptor = SurfaceDescriptorMemory(reinterpret_cast<uintptr_t>(mBuffer),
|
||||
GetFormat());
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool InitBuffer(uint8_t* buf, size_t bufSize,
|
||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureAllocationFlags aAllocFlags)
|
||||
{
|
||||
if (!buf) {
|
||||
gfxDebug() << "BufferTextureData: Failed to allocate " << bufSize << " bytes";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aAllocFlags & ALLOC_CLEAR_BUFFER) {
|
||||
memset(buf, 0, bufSize);
|
||||
}
|
||||
if (aAllocFlags & ALLOC_CLEAR_BUFFER_WHITE) {
|
||||
memset(buf, 0xFF, bufSize);
|
||||
}
|
||||
|
||||
ImageDataSerializer serializer(buf, bufSize);
|
||||
serializer.InitializeBufferInfo(aSize, aFormat);
|
||||
return true;
|
||||
}
|
||||
|
||||
MemoryTextureData*
|
||||
MemoryTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags,
|
||||
ISurfaceAllocator*)
|
||||
{
|
||||
if (aSize.width <= 0 || aSize.height <= 0) {
|
||||
gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x" << aSize.height;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t bufSize = ImageDataSerializer::ComputeMinBufferSize(aSize, aFormat);
|
||||
if (!bufSize) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint8_t* buf = new (fallible) uint8_t[bufSize];
|
||||
|
||||
if (InitBuffer(buf, bufSize, aSize, aFormat, aAllocFlags)) {
|
||||
GfxMemoryImageReporter::DidAlloc(buf);
|
||||
return new MemoryTextureData(aSize, aFormat, aMoz2DBackend, buf, bufSize);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
MemoryTextureData::Deallocate(ISurfaceAllocator*)
|
||||
{
|
||||
MOZ_ASSERT(mBuffer);
|
||||
GfxMemoryImageReporter::WillFree(mBuffer);
|
||||
delete [] mBuffer;
|
||||
mBuffer = nullptr;
|
||||
}
|
||||
|
||||
TextureData*
|
||||
MemoryTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const
|
||||
{
|
||||
return MemoryTextureData::Create(mSize, mFormat, mMoz2DBackend,
|
||||
aFlags, aAllocFlags, aAllocator);
|
||||
}
|
||||
|
||||
bool
|
||||
ShmemTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(GetFormat() != gfx::SurfaceFormat::UNKNOWN);
|
||||
if (GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aOutDescriptor = SurfaceDescriptorShmem(mShmem, GetFormat());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ShmemTextureData*
|
||||
ShmemTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
MOZ_ASSERT(aAllocator);
|
||||
if (!aAllocator) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aSize.width <= 0 || aSize.height <= 0) {
|
||||
gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x" << aSize.height;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t bufSize = ImageDataSerializer::ComputeMinBufferSize(aSize, aFormat);
|
||||
if (!bufSize) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mozilla::ipc::Shmem shm;
|
||||
if (!aAllocator->AllocUnsafeShmem(bufSize, OptimalShmemType(), &shm)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint8_t* buf = shm.get<uint8_t>();
|
||||
|
||||
if (InitBuffer(buf, bufSize, aSize, aFormat, aAllocFlags)) {
|
||||
return new ShmemTextureData(aSize, aFormat, aMoz2DBackend, shm);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TextureData*
|
||||
ShmemTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const
|
||||
{
|
||||
return ShmemTextureData::Create(mSize, mFormat, mMoz2DBackend,
|
||||
aFlags, aAllocFlags, aAllocator);
|
||||
}
|
||||
|
||||
void
|
||||
ShmemTextureData::Deallocate(ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
aAllocator->DeallocShmem(mShmem);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
|
@ -1,81 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
// * This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MOZILLA_LAYERS_BUFFERETEXTURE
|
||||
#define MOZILLA_LAYERS_BUFFERETEXTURE
|
||||
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/YCbCrImageDataSerializer.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/ipc/SharedMemory.h"
|
||||
#include "mozilla/gfx/Types.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class BufferTextureData : public TextureData
|
||||
{
|
||||
public:
|
||||
static BufferTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend,TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
static BufferTextureData* CreateWithBufferSize(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
size_t aSize,
|
||||
TextureFlags aTextureFlags);
|
||||
|
||||
static BufferTextureData* CreateForYCbCr(ISurfaceAllocator* aAllocator,
|
||||
gfx::IntSize aYSize,
|
||||
gfx::IntSize aCbCrSize,
|
||||
StereoMode aStereoMode,
|
||||
TextureFlags aTextureFlags);
|
||||
|
||||
virtual bool Lock(OpenMode aMode, FenceHandle*) override { return true; }
|
||||
|
||||
virtual void Unlock() override {}
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
|
||||
|
||||
virtual bool CanExposeMappedData() const override { return true; }
|
||||
|
||||
virtual bool BorrowMappedData(MappedTextureData& aMap) override;
|
||||
|
||||
virtual bool BorrowMappedYCbCrData(MappedYCbCrTextureData& aMap) override;
|
||||
|
||||
virtual bool SupportsMoz2D() const override;
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
|
||||
// use TextureClient's default implementation
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
protected:
|
||||
virtual uint8_t* GetBuffer() = 0;
|
||||
virtual size_t GetBufferSize() = 0;
|
||||
|
||||
BufferTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, gfx::BackendType aMoz2DBackend)
|
||||
: mSize(aSize)
|
||||
, mFormat(aFormat)
|
||||
, mMoz2DBackend(aMoz2DBackend)
|
||||
{}
|
||||
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
gfx::IntSize mSize;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
gfx::BackendType mMoz2DBackend;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
#endif
|
|
@ -51,21 +51,19 @@ enum class TextureFlags : uint32_t {
|
|||
// deallocation.
|
||||
// The default behaviour is to deallocate on the host side.
|
||||
DEALLOCATE_CLIENT = 1 << 6,
|
||||
DEALLOCATE_SYNC = 1 << 6, // XXX - make it a separate flag.
|
||||
DEALLOCATE_MAIN_THREAD = 1 << 8,
|
||||
// After being shared ith the compositor side, an immutable texture is never
|
||||
// modified, it can only be read. It is safe to not Lock/Unlock immutable
|
||||
// textures.
|
||||
IMMUTABLE = 1 << 9,
|
||||
IMMUTABLE = 1 << 7,
|
||||
// The contents of the texture must be uploaded or copied immediately
|
||||
// during the transaction, because the producer may want to write
|
||||
// to it again.
|
||||
IMMEDIATE_UPLOAD = 1 << 10,
|
||||
IMMEDIATE_UPLOAD = 1 << 8,
|
||||
// The texture is part of a component-alpha pair
|
||||
COMPONENT_ALPHA = 1 << 11,
|
||||
COMPONENT_ALPHA = 1 << 9,
|
||||
|
||||
// OR union of all valid bits
|
||||
ALL_BITS = (1 << 12) - 1,
|
||||
ALL_BITS = (1 << 10) - 1,
|
||||
// the default flags
|
||||
DEFAULT = NO_FLAGS
|
||||
};
|
||||
|
|
|
@ -129,7 +129,7 @@ D3D11ShareHandleImage::GetAsSourceSurface()
|
|||
|
||||
ID3D11Texture2D*
|
||||
D3D11ShareHandleImage::GetTexture() const {
|
||||
return static_cast<D3D11TextureData*>(mTextureClient->GetInternalData())->GetD3D11Texture();
|
||||
return mTextureClient->GetD3D11Texture();
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
|
@ -139,12 +139,14 @@ D3D11RecycleAllocator::Allocate(gfx::SurfaceFormat aFormat,
|
|||
TextureFlags aTextureFlags,
|
||||
TextureAllocationFlags aAllocFlags)
|
||||
{
|
||||
return CreateD3D11TextureClientWithDevice(aSize, aFormat,
|
||||
aTextureFlags, aAllocFlags,
|
||||
mDevice, mSurfaceAllocator);
|
||||
return TextureClientD3D11::Create(mSurfaceAllocator,
|
||||
aFormat,
|
||||
TextureFlags::DEFAULT,
|
||||
mDevice,
|
||||
aSize);
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
already_AddRefed<TextureClientD3D11>
|
||||
D3D11RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
|
||||
const gfx::IntSize& aSize)
|
||||
{
|
||||
|
@ -153,7 +155,12 @@ D3D11RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
|
|||
aSize,
|
||||
BackendSelector::Content,
|
||||
layers::TextureFlags::DEFAULT);
|
||||
return textureClient.forget();
|
||||
if (!textureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<TextureClientD3D11> textureD3D11 = static_cast<TextureClientD3D11*>(textureClient.get());
|
||||
return textureD3D11.forget();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
, mDevice(aDevice)
|
||||
{}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
already_AddRefed<TextureClientD3D11>
|
||||
CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
|
||||
const gfx::IntSize& aSize);
|
||||
|
||||
|
@ -63,7 +63,7 @@ public:
|
|||
private:
|
||||
gfx::IntSize mSize;
|
||||
gfx::IntRect mPictureRect;
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
RefPtr<TextureClientD3D11> mTextureClient;
|
||||
};
|
||||
|
||||
} // namepace layers
|
||||
|
|
|
@ -56,15 +56,14 @@ D3D9SurfaceImage::AllocateAndCopy(D3D9RecycleAllocator* aAllocator,
|
|||
// DXVA surfaces aren't created sharable, so we need to copy the surface
|
||||
// to a sharable texture to that it's accessible to the layer manager's
|
||||
// device.
|
||||
RefPtr<TextureClient> textureClient =
|
||||
RefPtr<SharedTextureClientD3D9> textureClient =
|
||||
aAllocator->CreateOrRecycleClient(gfx::SurfaceFormat::B8G8R8X8, aRegion.Size());
|
||||
if (!textureClient) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Copy the image onto the texture, preforming YUV -> RGB conversion if necessary.
|
||||
RefPtr<IDirect3DSurface9> textureSurface = static_cast<DXGID3D9TextureData*>(
|
||||
textureClient->GetInternalData())->GetD3D9Surface();
|
||||
RefPtr<IDirect3DSurface9> textureSurface = textureClient->GetD3D9Surface();
|
||||
if (!textureSurface) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
@ -122,7 +121,7 @@ D3D9SurfaceImage::EnsureSynchronized()
|
|||
const D3DSURFACE_DESC&
|
||||
D3D9SurfaceImage::GetDesc() const
|
||||
{
|
||||
return static_cast<DXGID3D9TextureData*>(mTextureClient->GetInternalData())->GetDesc();
|
||||
return mTextureClient->GetDesc();
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
|
@ -143,9 +142,7 @@ D3D9SurfaceImage::GetTextureClient(CompositableClient* aClient)
|
|||
already_AddRefed<gfx::SourceSurface>
|
||||
D3D9SurfaceImage::GetAsSourceSurface()
|
||||
{
|
||||
if (!mTextureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
NS_ENSURE_TRUE(mTextureClient, nullptr);
|
||||
|
||||
HRESULT hr;
|
||||
RefPtr<gfx::DataSourceSurface> surface = gfx::Factory::CreateDataSourceSurface(mSize, gfx::SurfaceFormat::B8G8R8X8);
|
||||
|
@ -156,15 +153,14 @@ D3D9SurfaceImage::GetAsSourceSurface()
|
|||
// Ensure that the texture is ready to be used.
|
||||
EnsureSynchronized();
|
||||
|
||||
DXGID3D9TextureData* texData = static_cast<DXGID3D9TextureData*>(mTextureClient->GetInternalData());
|
||||
// Readback the texture from GPU memory into system memory, so that
|
||||
// we can copy it into the Cairo image. This is expensive.
|
||||
RefPtr<IDirect3DSurface9> textureSurface = texData->GetD3D9Surface();
|
||||
RefPtr<IDirect3DSurface9> textureSurface = mTextureClient->GetD3D9Surface();
|
||||
if (!textureSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<IDirect3DDevice9> device = texData->GetD3D9Device();
|
||||
RefPtr<IDirect3DDevice9> device = mTextureClient->GetD3D9Device();
|
||||
if (!device) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -212,20 +208,28 @@ D3D9RecycleAllocator::Allocate(gfx::SurfaceFormat aFormat,
|
|||
TextureFlags aTextureFlags,
|
||||
TextureAllocationFlags aAllocFlags)
|
||||
{
|
||||
TextureData* data = DXGID3D9TextureData::Create(aSize, aFormat, aTextureFlags, mDevice);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return MakeAndAddRef<TextureClient>(data, aTextureFlags, mSurfaceAllocator);
|
||||
return SharedTextureClientD3D9::Create(mSurfaceAllocator,
|
||||
aFormat,
|
||||
aTextureFlags,
|
||||
mDevice,
|
||||
aSize);
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
already_AddRefed<SharedTextureClientD3D9>
|
||||
D3D9RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
|
||||
const gfx::IntSize& aSize)
|
||||
{
|
||||
return CreateOrRecycle(aFormat, aSize, BackendSelector::Content,
|
||||
TextureFlags::DEFAULT);
|
||||
RefPtr<TextureClient> textureClient =
|
||||
CreateOrRecycle(aFormat,
|
||||
aSize,
|
||||
BackendSelector::Content,
|
||||
layers::TextureFlags::DEFAULT);
|
||||
if (!textureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<SharedTextureClientD3D9> textureD3D9 = static_cast<SharedTextureClientD3D9*>(textureClient.get());
|
||||
return textureD3D9.forget();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class TextureClient;
|
||||
class SharedTextureClientD3D9;
|
||||
|
||||
class D3D9RecycleAllocator : public TextureClientRecycleAllocator
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ public:
|
|||
, mDevice(aDevice)
|
||||
{}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
already_AddRefed<SharedTextureClientD3D9>
|
||||
CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
|
||||
const gfx::IntSize& aSize);
|
||||
|
||||
|
@ -73,7 +73,7 @@ private:
|
|||
|
||||
gfx::IntSize mSize;
|
||||
RefPtr<IDirect3DQuery9> mQuery;
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
RefPtr<SharedTextureClientD3D9> mTextureClient;
|
||||
bool mValid;
|
||||
bool mIsFirstFrame;
|
||||
};
|
||||
|
|
|
@ -73,21 +73,25 @@ GrallocImage::SetData(const Data& aData)
|
|||
return false;
|
||||
}
|
||||
|
||||
ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
|
||||
GrallocTextureData* texData = GrallocTextureData::Create(mData.mYSize, HAL_PIXEL_FORMAT_YV12,
|
||||
gfx::BackendType::NONE,
|
||||
GraphicBuffer::USAGE_SW_READ_OFTEN |
|
||||
GraphicBuffer::USAGE_SW_WRITE_OFTEN |
|
||||
GraphicBuffer::USAGE_HW_TEXTURE,
|
||||
allocator
|
||||
);
|
||||
|
||||
if (!texData) {
|
||||
RefPtr<GrallocTextureClientOGL> textureClient =
|
||||
new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
|
||||
gfx::SurfaceFormat::UNKNOWN,
|
||||
gfx::BackendType::NONE);
|
||||
// GrallocImages are all YUV and don't support alpha.
|
||||
textureClient->SetIsOpaque(true);
|
||||
bool result =
|
||||
textureClient->AllocateGralloc(mData.mYSize,
|
||||
HAL_PIXEL_FORMAT_YV12,
|
||||
GraphicBuffer::USAGE_SW_READ_OFTEN |
|
||||
GraphicBuffer::USAGE_SW_WRITE_OFTEN |
|
||||
GraphicBuffer::USAGE_HW_TEXTURE);
|
||||
sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
|
||||
if (!result || !graphicBuffer.get()) {
|
||||
mTextureClient = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
mTextureClient = new TextureClient(texData, TextureFlags::DEFAULT, allocator);
|
||||
sp<GraphicBuffer> graphicBuffer = texData->GetGraphicBuffer();
|
||||
mTextureClient = textureClient;
|
||||
|
||||
void* vaddr;
|
||||
if (graphicBuffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
|
||||
|
@ -146,7 +150,8 @@ GrallocImage::SetData(const Data& aData)
|
|||
void
|
||||
GrallocImage::SetData(TextureClient* aGraphicBuffer, const gfx::IntSize& aSize)
|
||||
{
|
||||
mTextureClient = aGraphicBuffer;
|
||||
MOZ_ASSERT(aGraphicBuffer->AsGrallocTextureClientOGL());
|
||||
mTextureClient = aGraphicBuffer->AsGrallocTextureClientOGL();
|
||||
mSize = aSize;
|
||||
}
|
||||
|
||||
|
@ -438,7 +443,8 @@ GrallocImage::GetAsSourceSurface()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
android::sp<GraphicBuffer> graphicBuffer = GetGraphicBuffer();
|
||||
android::sp<GraphicBuffer> graphicBuffer =
|
||||
mTextureClient->GetGraphicBuffer();
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> surface =
|
||||
GetDataSourceSurfaceFrom(graphicBuffer, mSize, mData);
|
||||
|
@ -452,7 +458,7 @@ GrallocImage::GetGraphicBuffer() const
|
|||
if (!mTextureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<GrallocTextureData*>(mTextureClient->GetInternalData())->GetGraphicBuffer();
|
||||
return mTextureClient->GetGraphicBuffer();
|
||||
}
|
||||
|
||||
void*
|
||||
|
@ -461,7 +467,8 @@ GrallocImage::GetNativeBuffer()
|
|||
if (!mTextureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
android::sp<android::GraphicBuffer> graphicBuffer = GetGraphicBuffer();
|
||||
android::sp<android::GraphicBuffer> graphicBuffer =
|
||||
mTextureClient->GetGraphicBuffer();
|
||||
if (!graphicBuffer.get()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class TextureClient;
|
||||
class GrallocTextureClientOGL;
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface>
|
||||
GetDataSourceSurfaceFrom(android::sp<android::GraphicBuffer>& aGraphicBuffer,
|
||||
|
@ -124,7 +124,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
RefPtr<GrallocTextureClientOGL> mTextureClient;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -204,15 +204,17 @@ IMFYCbCrImage::GetD3D9TextureClient(CompositableClient* aClient)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
mTextureClient = TextureClient::CreateWithData(
|
||||
DXGIYCbCrTextureData::Create(aClient->GetForwarder(),
|
||||
TextureFlags::DEFAULT,
|
||||
textureY, textureCb, textureCr,
|
||||
shareHandleY, shareHandleCb, shareHandleCr,
|
||||
GetSize(), mData.mYSize, mData.mCbCrSize),
|
||||
TextureFlags::DEFAULT,
|
||||
aClient->GetForwarder()
|
||||
);
|
||||
mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(),
|
||||
TextureFlags::DEFAULT,
|
||||
textureY,
|
||||
textureCb,
|
||||
textureCr,
|
||||
shareHandleY,
|
||||
shareHandleCb,
|
||||
shareHandleCr,
|
||||
GetSize(),
|
||||
mData.mYSize,
|
||||
mData.mCbCrSize);
|
||||
|
||||
return mTextureClient;
|
||||
}
|
||||
|
@ -271,14 +273,14 @@ IMFYCbCrImage::GetTextureClient(CompositableClient* aClient)
|
|||
mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height);
|
||||
}
|
||||
|
||||
mTextureClient = TextureClient::CreateWithData(
|
||||
DXGIYCbCrTextureData::Create(aClient->GetForwarder(),
|
||||
TextureFlags::DEFAULT,
|
||||
textureY, textureCb, textureCr,
|
||||
GetSize(), mData.mYSize, mData.mCbCrSize),
|
||||
TextureFlags::DEFAULT,
|
||||
aClient->GetForwarder()
|
||||
);
|
||||
mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(),
|
||||
TextureFlags::DEFAULT,
|
||||
textureY,
|
||||
textureCb,
|
||||
textureCr,
|
||||
GetSize(),
|
||||
mData.mYSize,
|
||||
mData.mCbCrSize);
|
||||
|
||||
return mTextureClient;
|
||||
}
|
||||
|
|
|
@ -39,8 +39,6 @@ public:
|
|||
static uint32_t ComputeMinBufferSize(gfx::IntSize aSize,
|
||||
gfx::SurfaceFormat aFormat);
|
||||
|
||||
size_t GetBufferSize() const { return mDataSize; }
|
||||
|
||||
protected:
|
||||
|
||||
ImageDataSerializerBase(uint8_t* aData, size_t aDataSize)
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "nsDebug.h" // for NS_ERROR
|
||||
#include "nsPoint.h" // for nsIntPoint
|
||||
#include "nsRect.h" // for mozilla::gfx::IntRect
|
||||
#include "base/basictypes.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
|
|
|
@ -18,11 +18,9 @@ TextureClient*
|
|||
MacIOSurfaceImage::GetTextureClient(CompositableClient* aClient)
|
||||
{
|
||||
if (!mTextureClient) {
|
||||
mTextureClient = TextureClient::CreateWithData(
|
||||
MacIOSurfaceTextureData::Create(mSurface),
|
||||
TextureFlags::DEFAULT,
|
||||
aClient->GetForwarder()
|
||||
);
|
||||
mTextureClient = MacIOSurfaceTextureClientOGL::Create(aClient->GetForwarder(),
|
||||
TextureFlags::DEFAULT,
|
||||
mSurface);
|
||||
}
|
||||
return mTextureClient;
|
||||
}
|
||||
|
|
|
@ -14,117 +14,64 @@ using namespace gfx;
|
|||
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* Can only be drawn into through Cairo.
|
||||
* The coresponding TextureHost depends on the compositor
|
||||
*/
|
||||
class MemoryDIBTextureData : public DIBTextureData
|
||||
bool
|
||||
TextureClientDIB::Lock(OpenMode)
|
||||
{
|
||||
public:
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual TextureData*
|
||||
CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
static
|
||||
DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator* aAllocator) override
|
||||
{
|
||||
mSurface = nullptr;
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
if (!IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MemoryDIBTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfxWindowsSurface* aSurface)
|
||||
: DIBTextureData(aSize, aFormat, aSurface)
|
||||
{
|
||||
MOZ_COUNT_CTOR(MemoryDIBTextureData);
|
||||
}
|
||||
|
||||
virtual ~MemoryDIBTextureData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(MemoryDIBTextureData);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Can only be drawn into through Cairo.
|
||||
* The coresponding TextureHost depends on the compositor
|
||||
*/
|
||||
class ShmemDIBTextureData : public DIBTextureData
|
||||
{
|
||||
public:
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual TextureData*
|
||||
CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
static
|
||||
DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
void DeallocateData()
|
||||
{
|
||||
if (mSurface) {
|
||||
::DeleteObject(mBitmap);
|
||||
::DeleteDC(mDC);
|
||||
::CloseHandle(mFileMapping);
|
||||
mBitmap = NULL;
|
||||
mDC = NULL;
|
||||
mFileMapping = NULL;
|
||||
mSurface = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator* aAllocator) override
|
||||
{
|
||||
DeallocateData();
|
||||
}
|
||||
|
||||
ShmemDIBTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfxWindowsSurface* aSurface,
|
||||
HANDLE aFileMapping, HANDLE aHostHandle,
|
||||
HDC aDC, HBITMAP aBitmap)
|
||||
: DIBTextureData(aSize, aFormat, aSurface)
|
||||
, mFileMapping(aFileMapping)
|
||||
, mHostHandle(aHostHandle)
|
||||
, mDC(aDC)
|
||||
, mBitmap(aBitmap)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ShmemDIBTextureData);
|
||||
}
|
||||
|
||||
virtual ~ShmemDIBTextureData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ShmemDIBTextureData);
|
||||
}
|
||||
|
||||
HANDLE mFileMapping;
|
||||
HANDLE mHostHandle;
|
||||
HDC mDC;
|
||||
HBITMAP mBitmap;
|
||||
};
|
||||
|
||||
already_AddRefed<gfx::DrawTarget>
|
||||
DIBTextureData::BorrowDrawTarget()
|
||||
{
|
||||
return gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mSurface, mSize);
|
||||
mIsLocked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DIBTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
void
|
||||
TextureClientDIB::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!");
|
||||
if (mDrawTarget) {
|
||||
if (mReadbackSink) {
|
||||
RefPtr<SourceSurface> snapshot = mDrawTarget->Snapshot();
|
||||
RefPtr<DataSourceSurface> dataSurf = snapshot->GetDataSurface();
|
||||
mReadbackSink->ProcessReadback(dataSurf);
|
||||
}
|
||||
|
||||
mDrawTarget->Flush();
|
||||
mDrawTarget = nullptr;
|
||||
}
|
||||
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
gfx::DrawTarget*
|
||||
TextureClientDIB::BorrowDrawTarget()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked && IsAllocated());
|
||||
|
||||
if (!mDrawTarget) {
|
||||
mDrawTarget =
|
||||
gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mSurface, mSize);
|
||||
}
|
||||
|
||||
if (!mDrawTarget) {
|
||||
gfxCriticalNote << "DIB failed draw target surface " << mSize << ", " << (int)mIsLocked << ", " << IsAllocated();
|
||||
}
|
||||
|
||||
return mDrawTarget;
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientDIB::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked && IsAllocated());
|
||||
|
||||
RefPtr<gfxImageSurface> imgSurf = mSurface->GetAsImageSurface();
|
||||
|
||||
RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
|
||||
|
||||
if (!srcSurf) {
|
||||
gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
DataSourceSurface::MappedSurface sourceMap;
|
||||
|
@ -137,40 +84,43 @@ DIBTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
|||
}
|
||||
|
||||
srcSurf->Unmap();
|
||||
return true;
|
||||
}
|
||||
|
||||
DIBTextureData*
|
||||
DIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
TextureClientMemoryDIB::TextureClientMemoryDIB(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags)
|
||||
: TextureClientDIB(aAllocator, aFormat, aFlags)
|
||||
{
|
||||
if (!aAllocator) {
|
||||
return nullptr;
|
||||
}
|
||||
if (aFormat == gfx::SurfaceFormat::UNKNOWN) {
|
||||
return nullptr;
|
||||
}
|
||||
if (aAllocator->IsSameProcess()) {
|
||||
return MemoryDIBTextureData::Create(aSize, aFormat);
|
||||
} else {
|
||||
return ShmemDIBTextureData::Create(aSize, aFormat, aAllocator);
|
||||
}
|
||||
MOZ_COUNT_CTOR(TextureClientMemoryDIB);
|
||||
}
|
||||
|
||||
TextureData*
|
||||
MemoryDIBTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const
|
||||
TextureClientMemoryDIB::~TextureClientMemoryDIB()
|
||||
{
|
||||
if (!aAllocator) {
|
||||
MOZ_COUNT_DTOR(TextureClientMemoryDIB);
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
TextureClientMemoryDIB::CreateSimilar(TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const
|
||||
{
|
||||
RefPtr<TextureClient> tex = new TextureClientMemoryDIB(mAllocator, mFormat,
|
||||
mFlags | aFlags);
|
||||
|
||||
if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
|
||||
return nullptr;
|
||||
}
|
||||
return MemoryDIBTextureData::Create(mSize, mFormat);
|
||||
|
||||
return tex.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
MemoryDIBTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
TextureClientMemoryDIB::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
if (!IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mSurface);
|
||||
// The host will release this ref when it receives the surface descriptor.
|
||||
// We AddRef in case we die before the host receives the pointer.
|
||||
|
@ -179,34 +129,64 @@ MemoryDIBTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
|||
return true;
|
||||
}
|
||||
|
||||
DIBTextureData*
|
||||
MemoryDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat)
|
||||
bool
|
||||
TextureClientMemoryDIB::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
|
||||
{
|
||||
RefPtr<gfxWindowsSurface> surface
|
||||
= new gfxWindowsSurface(aSize, SurfaceFormatToImageFormat(aFormat));
|
||||
if (!surface || surface->CairoStatus()) {
|
||||
NS_WARNING("Could not create DIB surface");
|
||||
return nullptr;
|
||||
MOZ_ASSERT(!IsAllocated());
|
||||
mSize = aSize;
|
||||
|
||||
mSurface = new gfxWindowsSurface(aSize, SurfaceFormatToImageFormat(mFormat));
|
||||
if (!mSurface || mSurface->CairoStatus())
|
||||
{
|
||||
NS_WARNING("Could not create surface");
|
||||
mSurface = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return new MemoryDIBTextureData(aSize, aFormat, surface);
|
||||
return true;
|
||||
}
|
||||
|
||||
TextureData*
|
||||
ShmemDIBTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const
|
||||
TextureClientShmemDIB::TextureClientShmemDIB(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags)
|
||||
: TextureClientDIB(aAllocator, aFormat, aFlags)
|
||||
, mFileMapping(NULL)
|
||||
, mHostHandle(NULL)
|
||||
, mDC(NULL)
|
||||
, mBitmap(NULL)
|
||||
{
|
||||
if (!aAllocator) {
|
||||
MOZ_COUNT_CTOR(TextureClientShmemDIB);
|
||||
}
|
||||
|
||||
TextureClientShmemDIB::~TextureClientShmemDIB()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TextureClientShmemDIB);
|
||||
|
||||
::DeleteObject(mBitmap);
|
||||
::DeleteDC(mDC);
|
||||
::CloseHandle(mFileMapping);
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
TextureClientShmemDIB::CreateSimilar(TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const
|
||||
{
|
||||
RefPtr<TextureClient> tex = new TextureClientShmemDIB(mAllocator, mFormat,
|
||||
mFlags | aFlags);
|
||||
|
||||
if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
|
||||
return nullptr;
|
||||
}
|
||||
return ShmemDIBTextureData::Create(mSize, mFormat, aAllocator);
|
||||
|
||||
return tex.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
ShmemDIBTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
TextureClientShmemDIB::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
if (GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
|
||||
MOZ_ASSERT(IsValid());
|
||||
MOZ_ASSERT(mAllocator->ParentPid() != base::ProcessId());
|
||||
if (!IsAllocated() || GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -215,33 +195,33 @@ ShmemDIBTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
|||
return true;
|
||||
}
|
||||
|
||||
DIBTextureData*
|
||||
ShmemDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
bool
|
||||
TextureClientShmemDIB::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(aAllocator->ParentPid() != base::ProcessId());
|
||||
MOZ_ASSERT(!IsAllocated());
|
||||
MOZ_ASSERT(mAllocator->ParentPid() != base::ProcessId());
|
||||
|
||||
DWORD mapSize = aSize.width * aSize.height * BytesPerPixel(aFormat);
|
||||
HANDLE fileMapping = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, mapSize, NULL);
|
||||
mSize = aSize;
|
||||
|
||||
if (!fileMapping) {
|
||||
DWORD mapSize = mSize.width * mSize.height * BytesPerPixel(mFormat);
|
||||
mFileMapping = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, mapSize, NULL);
|
||||
|
||||
if (!mFileMapping) {
|
||||
gfxCriticalError() << "Failed to create memory file mapping for " << mapSize << " bytes.";
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t* data = (uint8_t*)::MapViewOfFile(fileMapping, FILE_MAP_WRITE | FILE_MAP_READ,
|
||||
0, 0, aSize.width * aSize.height
|
||||
* BytesPerPixel(aFormat));
|
||||
uint8_t* data = (uint8_t*)::MapViewOfFile(mFileMapping, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, mSize.width * mSize.height * BytesPerPixel(mFormat));
|
||||
|
||||
memset(data, 0x80, aSize.width * aSize.height * BytesPerPixel(aFormat));
|
||||
memset(data, 0x80, mSize.width * mSize.height * BytesPerPixel(mFormat));
|
||||
|
||||
::UnmapViewOfFile(fileMapping);
|
||||
::UnmapViewOfFile(mFileMapping);
|
||||
|
||||
BITMAPV4HEADER header;
|
||||
memset(&header, 0, sizeof(BITMAPV4HEADER));
|
||||
header.bV4Size = sizeof(BITMAPV4HEADER);
|
||||
header.bV4Width = aSize.width;
|
||||
header.bV4Height = -LONG(aSize.height); // top-to-buttom DIB
|
||||
header.bV4Width = mSize.width;
|
||||
header.bV4Height = -LONG(mSize.height); // top-to-buttom DIB
|
||||
header.bV4Planes = 1;
|
||||
header.bV4BitCount = 32;
|
||||
header.bV4V4Compression = BI_BITFIELDS;
|
||||
|
@ -249,54 +229,46 @@ ShmemDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
|||
header.bV4GreenMask = 0x0000FF00;
|
||||
header.bV4BlueMask = 0x000000FF;
|
||||
|
||||
HDC dc = ::CreateCompatibleDC(::GetDC(NULL));
|
||||
mDC = ::CreateCompatibleDC(::GetDC(NULL));
|
||||
|
||||
if (!dc) {
|
||||
::CloseHandle(fileMapping);
|
||||
if (!mDC) {
|
||||
::CloseHandle(mFileMapping);
|
||||
gfxCriticalError() << "Failed to create DC for bitmap.";
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
void* bits;
|
||||
HBITMAP bitmap = ::CreateDIBSection(dc, (BITMAPINFO*)&header,
|
||||
DIB_RGB_COLORS, &bits,
|
||||
fileMapping, 0);
|
||||
mBitmap = ::CreateDIBSection(mDC, (BITMAPINFO*)&header, DIB_RGB_COLORS, &bits, mFileMapping, 0);
|
||||
|
||||
if (!bitmap) {
|
||||
gfxCriticalError() << "Failed to create DIB section for a bitmap of size "
|
||||
<< aSize;
|
||||
::CloseHandle(fileMapping);
|
||||
::DeleteDC(dc);
|
||||
return nullptr;
|
||||
if (!mBitmap) {
|
||||
gfxCriticalError() << "Failed to create DIB section for a bitmap of size " << mSize;
|
||||
::CloseHandle(mFileMapping);
|
||||
::DeleteDC(mDC);
|
||||
return false;
|
||||
}
|
||||
|
||||
::SelectObject(dc, bitmap);
|
||||
::SelectObject(mDC, mBitmap);
|
||||
|
||||
RefPtr<gfxWindowsSurface> surface = new gfxWindowsSurface(dc, 0);
|
||||
if (surface->CairoStatus())
|
||||
mSurface = new gfxWindowsSurface(mDC, 0);
|
||||
if (mSurface->CairoStatus())
|
||||
{
|
||||
::DeleteObject(bitmap);
|
||||
::DeleteDC(dc);
|
||||
::CloseHandle(fileMapping);
|
||||
gfxCriticalError() << "Could not create surface, status: "
|
||||
<< surface->CairoStatus();
|
||||
return nullptr;
|
||||
::DeleteObject(mBitmap);
|
||||
::DeleteDC(mDC);
|
||||
::CloseHandle(mFileMapping);
|
||||
gfxCriticalError() << "Could not create surface, status: " << mSurface->CairoStatus();
|
||||
mSurface = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE hostHandle = NULL;
|
||||
|
||||
if (!ipc::DuplicateHandle(fileMapping, aAllocator->ParentPid(),
|
||||
&hostHandle, 0, DUPLICATE_SAME_ACCESS)) {
|
||||
if (!ipc::DuplicateHandle(mFileMapping, mAllocator->ParentPid(), &mHostHandle, 0, DUPLICATE_SAME_ACCESS)) {
|
||||
gfxCriticalError() << "Failed to duplicate handle to parent process for surface.";
|
||||
::DeleteObject(bitmap);
|
||||
::DeleteDC(dc);
|
||||
::CloseHandle(fileMapping);
|
||||
return nullptr;
|
||||
::DeleteObject(mBitmap);
|
||||
::DeleteDC(mDC);
|
||||
::CloseHandle(mFileMapping);
|
||||
return false;
|
||||
}
|
||||
|
||||
return new ShmemDIBTextureData(aSize, aFormat, surface,
|
||||
fileMapping, hostHandle,
|
||||
dc, bitmap);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -15,42 +15,101 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class DIBTextureData : public TextureData
|
||||
class TextureClientDIB : public TextureClient
|
||||
{
|
||||
public:
|
||||
virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
|
||||
virtual bool IsAllocated() const override { return !!mSurface; }
|
||||
|
||||
virtual void Unlock() override {}
|
||||
virtual bool Lock(OpenMode aOpenMode) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual bool IsLocked() const override{ return mIsLocked; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual bool SupportsMoz2D() const override { return true; }
|
||||
virtual bool CanExposeDrawTarget() const override { return true; }
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
|
||||
virtual gfx::DrawTarget* BorrowDrawTarget() override;
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
|
||||
static
|
||||
DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
protected:
|
||||
DIBTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfxWindowsSurface* aSurface)
|
||||
: mSurface(aSurface)
|
||||
, mSize(aSize)
|
||||
, mFormat(aFormat)
|
||||
{
|
||||
MOZ_ASSERT(aSurface);
|
||||
}
|
||||
TextureClientDIB(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat, TextureFlags aFlags)
|
||||
: TextureClient(aAllocator, aFlags)
|
||||
, mFormat(aFormat)
|
||||
, mIsLocked(false)
|
||||
{ }
|
||||
|
||||
RefPtr<gfxWindowsSurface> mSurface;
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
gfx::IntSize mSize;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
bool mIsLocked;
|
||||
};
|
||||
|
||||
/**
|
||||
* Can only be drawn into through Cairo.
|
||||
* Prefer CairoTextureClient when possible.
|
||||
* The coresponding TextureHost depends on the compositor
|
||||
*/
|
||||
class TextureClientMemoryDIB : public TextureClientDIB
|
||||
{
|
||||
public:
|
||||
TextureClientMemoryDIB(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags);
|
||||
|
||||
virtual ~TextureClientMemoryDIB();
|
||||
|
||||
// TextureClient
|
||||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize,
|
||||
TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
|
||||
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Can only be drawn into through Cairo.
|
||||
* Prefer CairoTextureClient when possible.
|
||||
* The coresponding TextureHost depends on the compositor
|
||||
*/
|
||||
class TextureClientShmemDIB : public TextureClientDIB
|
||||
{
|
||||
public:
|
||||
TextureClientShmemDIB(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags);
|
||||
|
||||
virtual ~TextureClientShmemDIB();
|
||||
|
||||
// TextureClient
|
||||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize,
|
||||
TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
|
||||
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
protected:
|
||||
HANDLE mFileMapping;
|
||||
HANDLE mHostHandle;
|
||||
HDC mDC;
|
||||
HBITMAP mBitmap;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -75,7 +75,7 @@ void YCbCrImageDataDeserializerBase::Validate()
|
|||
info->mYStride,
|
||||
IntSize(info->mCbCrWidth, info->mCbCrHeight),
|
||||
info->mCbCrStride);
|
||||
mIsValid = requiredSize <= mDataSize;
|
||||
mIsValid = requiredSize && requiredSize <= mDataSize;
|
||||
|
||||
}
|
||||
|
||||
|
@ -147,15 +147,14 @@ YCbCrImageDataDeserializerBase::ComputeMinBufferSize(const gfx::IntSize& aYSize,
|
|||
uint32_t aCbCrStride)
|
||||
{
|
||||
MOZ_ASSERT(aYSize.height >= 0 && aYSize.width >= 0);
|
||||
if (aYSize.height < 0 || aYSize.width < 0 || aCbCrSize.height < 0 || aCbCrSize.width < 0) {
|
||||
if (aYSize.height <= 0 || aYSize.width <= 0 || aCbCrSize.height <= 0 || aCbCrSize.width <= 0) {
|
||||
gfxDebug() << "Non-positive YCbCr buffer size request " << aYSize.height << "x" << aYSize.width << ", " << aCbCrSize.height << "x" << aCbCrSize.width;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (aYSize != IntSize() &&
|
||||
(!gfx::Factory::AllowedSurfaceSize(aYSize) ||
|
||||
aCbCrSize.width > aYSize.width ||
|
||||
aCbCrSize.height > aYSize.height)) {
|
||||
if (!gfx::Factory::AllowedSurfaceSize(aYSize) ||
|
||||
aCbCrSize.width > aYSize.width ||
|
||||
aCbCrSize.height > aYSize.height) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
static gfx::SurfaceFormat
|
||||
static SurfaceFormat
|
||||
HalFormatToSurfaceFormat(int aHalFormat, TextureFlags aFlags)
|
||||
{
|
||||
bool swapRB = bool(aFlags & TextureFlags::RB_SWAPPED);
|
||||
|
@ -45,7 +45,7 @@ HalFormatToSurfaceFormat(int aHalFormat, TextureFlags aFlags)
|
|||
return gfx::SurfaceFormat::R5G6B5_UINT16;
|
||||
} else {
|
||||
MOZ_CRASH("Unhandled HAL pixel format");
|
||||
return gfx::SurfaceFormat::UNKNOWN; // not reached
|
||||
return SurfaceFormat::UNKNOWN; // not reached
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ GrallocTextureHostBasic::Lock()
|
|||
NS_WARNING("Couldn't lock graphic buffer");
|
||||
return false;
|
||||
}
|
||||
surf = gfx::Factory::CreateWrappingDataSourceSurface(
|
||||
surf = Factory::CreateWrappingDataSourceSurface(
|
||||
mMappedBuffer,
|
||||
graphicBuffer->getStride() * gfx::BytesPerPixel(mFormat),
|
||||
mCropSize,
|
||||
|
@ -217,7 +217,7 @@ GrallocTextureHostBasic::WaitAcquireFenceHandleSyncComplete()
|
|||
void
|
||||
GrallocTextureHostBasic::SetCropRect(nsIntRect aCropRect)
|
||||
{
|
||||
MOZ_ASSERT(aCropRect.TopLeft() == gfx::IntPoint(0, 0));
|
||||
MOZ_ASSERT(aCropRect.TopLeft() == IntPoint(0, 0));
|
||||
MOZ_ASSERT(!aCropRect.IsEmpty());
|
||||
MOZ_ASSERT(aCropRect.width <= mSize.width);
|
||||
MOZ_ASSERT(aCropRect.height <= mSize.height);
|
||||
|
|
|
@ -17,46 +17,83 @@
|
|||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::layers;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
X11TextureData::X11TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
bool aClientDeallocation, bool aIsCrossProcess,
|
||||
gfxXlibSurface* aSurface)
|
||||
: mSize(aSize)
|
||||
, mFormat(aFormat)
|
||||
, mSurface(aSurface)
|
||||
, mClientDeallocation(aClientDeallocation)
|
||||
, mIsCrossProcess(aIsCrossProcess)
|
||||
TextureClientX11::TextureClientX11(ISurfaceAllocator* aAllocator,
|
||||
SurfaceFormat aFormat,
|
||||
TextureFlags aFlags)
|
||||
: TextureClient(aAllocator, aFlags),
|
||||
mFormat(aFormat),
|
||||
mLocked(false)
|
||||
{
|
||||
MOZ_ASSERT(mSurface);
|
||||
MOZ_COUNT_CTOR(TextureClientX11);
|
||||
}
|
||||
|
||||
TextureClientX11::~TextureClientX11()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TextureClientX11);
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
TextureClientX11::CreateSimilar(TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const
|
||||
{
|
||||
RefPtr<TextureClient> tex = new TextureClientX11(mAllocator, mFormat, mFlags);
|
||||
|
||||
// mSize is guaranteed to be non-negative
|
||||
MOZ_ASSERT(mSize.width >= 0 && mSize.height >= 0);
|
||||
if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return tex.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
X11TextureData::Lock(OpenMode aMode, FenceHandle*)
|
||||
TextureClientX11::IsAllocated() const
|
||||
{
|
||||
return true;
|
||||
return !!mSurface;
|
||||
}
|
||||
|
||||
bool
|
||||
TextureClientX11::Lock(OpenMode aMode)
|
||||
{
|
||||
MOZ_ASSERT(!mLocked, "The TextureClient is already Locked!");
|
||||
mLocked = IsValid() && IsAllocated();
|
||||
return mLocked;
|
||||
}
|
||||
|
||||
void
|
||||
X11TextureData::Unlock()
|
||||
TextureClientX11::Unlock()
|
||||
{
|
||||
if (mSurface && mIsCrossProcess) {
|
||||
MOZ_ASSERT(mLocked, "The TextureClient is already Unlocked!");
|
||||
mLocked = false;
|
||||
|
||||
if (mDrawTarget) {
|
||||
// see the comment on TextureClient::BorrowDrawTarget.
|
||||
// This DrawTarget is internal to the TextureClient and is only exposed to the
|
||||
// outside world between Lock() and Unlock(). This assertion checks that no outside
|
||||
// reference remains by the time Unlock() is called.
|
||||
MOZ_ASSERT(mDrawTarget->refCount() == 1);
|
||||
|
||||
mDrawTarget->Flush();
|
||||
mDrawTarget = nullptr;
|
||||
}
|
||||
|
||||
if (mSurface && !mAllocator->IsSameProcess()) {
|
||||
FinishX(DefaultXDisplay());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
X11TextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
TextureClientX11::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(mSurface);
|
||||
MOZ_ASSERT(IsValid());
|
||||
if (!mSurface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mClientDeallocation) {
|
||||
if (!(mFlags & TextureFlags::DEALLOCATE_CLIENT)) {
|
||||
// Pass to the host the responsibility of freeing the pixmap. ReleasePixmap means
|
||||
// the underlying pixmap will not be deallocated in mSurface's destructor.
|
||||
// ToSurfaceDescriptor is at most called once per TextureClient.
|
||||
|
@ -67,79 +104,66 @@ X11TextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
|||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DrawTarget>
|
||||
X11TextureData::BorrowDrawTarget()
|
||||
{
|
||||
MOZ_ASSERT(mSurface);
|
||||
if (!mSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IntSize size = mSurface->GetSize();
|
||||
RefPtr<gfx::DrawTarget> dt = Factory::CreateDrawTargetForCairoSurface(mSurface->CairoSurface(), size);
|
||||
|
||||
return dt.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
X11TextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
TextureClientX11::AllocateForSurface(IntSize aSize, TextureAllocationFlags aTextureFlags)
|
||||
{
|
||||
RefPtr<DrawTarget> dt = BorrowDrawTarget();
|
||||
MOZ_ASSERT(IsValid());
|
||||
MOZ_ASSERT(!IsAllocated());
|
||||
//MOZ_ASSERT(mFormat != gfx::FORMAT_YUV, "This TextureClient cannot use YCbCr data");
|
||||
|
||||
if (!dt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dt->CopySurface(aSurface, IntRect(IntPoint(), aSurface->GetSize()), IntPoint());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
X11TextureData::Deallocate(ISurfaceAllocator*)
|
||||
{
|
||||
mSurface = nullptr;
|
||||
}
|
||||
|
||||
TextureData*
|
||||
X11TextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const
|
||||
{
|
||||
return X11TextureData::Create(mSize, mFormat, aFlags, aAllocator);
|
||||
}
|
||||
|
||||
X11TextureData*
|
||||
X11TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags, ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
MOZ_ASSERT(aSize.width >= 0 && aSize.height >= 0);
|
||||
if (aSize.width <= 0 || aSize.height <= 0 ||
|
||||
aSize.width > XLIB_IMAGE_SIDE_SIZE_LIMIT ||
|
||||
aSize.height > XLIB_IMAGE_SIDE_SIZE_LIMIT) {
|
||||
gfxDebug() << "Asking for X11 surface of invalid size " << aSize.width << "x" << aSize.height;
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
gfxImageFormat imageFormat = SurfaceFormatToImageFormat(aFormat);
|
||||
gfxImageFormat imageFormat = SurfaceFormatToImageFormat(mFormat);
|
||||
RefPtr<gfxASurface> surface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, imageFormat);
|
||||
if (!surface || surface->GetType() != gfxSurfaceType::Xlib) {
|
||||
NS_ERROR("creating Xlib surface failed!");
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
gfxXlibSurface* xlibSurface = static_cast<gfxXlibSurface*>(surface.get());
|
||||
mSize = aSize;
|
||||
mSurface = static_cast<gfxXlibSurface*>(surface.get());
|
||||
|
||||
bool crossProcess = !aAllocator->IsSameProcess();
|
||||
X11TextureData* texture = new X11TextureData(aSize, aFormat,
|
||||
!!(aFlags & TextureFlags::DEALLOCATE_CLIENT),
|
||||
crossProcess,
|
||||
xlibSurface);
|
||||
if (crossProcess) {
|
||||
if (!mAllocator->IsSameProcess()) {
|
||||
FinishX(DefaultXDisplay());
|
||||
}
|
||||
|
||||
return texture;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
DrawTarget*
|
||||
TextureClientX11::BorrowDrawTarget()
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
MOZ_ASSERT(mLocked);
|
||||
|
||||
if (!mSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mDrawTarget) {
|
||||
IntSize size = mSurface->GetSize();
|
||||
mDrawTarget = Factory::CreateDrawTargetForCairoSurface(mSurface->CairoSurface(), size);
|
||||
}
|
||||
|
||||
return mDrawTarget;
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientX11::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
{
|
||||
MOZ_ASSERT(CanExposeDrawTarget());
|
||||
|
||||
DrawTarget* dt = BorrowDrawTarget();
|
||||
|
||||
if (!dt) {
|
||||
gfxCriticalError() << "Failed to borrow drawtarget for TextureClientX11::UpdateFromSurface";
|
||||
return;
|
||||
}
|
||||
|
||||
dt->CopySurface(aSurface, IntRect(IntPoint(), aSurface->GetSize()), IntPoint());
|
||||
}
|
|
@ -13,47 +13,52 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class X11TextureData : public TextureData
|
||||
/**
|
||||
* A TextureClient implementation based on Xlib.
|
||||
*/
|
||||
class TextureClientX11 : public TextureClient
|
||||
{
|
||||
public:
|
||||
static X11TextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags, ISurfaceAllocator* aAllocator);
|
||||
public:
|
||||
TextureClientX11(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat format, TextureFlags aFlags = TextureFlags::DEFAULT);
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
~TextureClientX11();
|
||||
|
||||
virtual bool Lock(OpenMode aMode, FenceHandle*) override;
|
||||
// TextureClient
|
||||
|
||||
virtual void Unlock() override;
|
||||
virtual bool IsAllocated() const override;
|
||||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
virtual bool Lock(OpenMode aMode) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual bool IsLocked() const override { return mLocked; }
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags flags) override;
|
||||
|
||||
virtual bool CanExposeDrawTarget() const override { return true; }
|
||||
|
||||
virtual gfx::DrawTarget* BorrowDrawTarget() override;
|
||||
|
||||
virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
|
||||
|
||||
virtual bool SupportsMoz2D() const override { return true; }
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return false; }
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator*) override;
|
||||
|
||||
virtual TextureData*
|
||||
CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
protected:
|
||||
X11TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
bool aClientDeallocation, bool aIsCrossProcess,
|
||||
gfxXlibSurface* aSurface);
|
||||
|
||||
gfx::IntSize mSize;
|
||||
private:
|
||||
gfx::SurfaceFormat mFormat;
|
||||
gfx::IntSize mSize;
|
||||
RefPtr<gfxXlibSurface> mSurface;
|
||||
bool mClientDeallocation;
|
||||
bool mIsCrossProcess;
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
bool mLocked;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "gfxPlatform.h" // for gfxPlatform
|
||||
#include "GLReadTexImageHelper.h"
|
||||
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
||||
#include "mozilla/layers/BufferTexture.h"
|
||||
#include "mozilla/layers/AsyncCanvasRenderer.h"
|
||||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
#include "mozilla/layers/CompositorChild.h" // for CompositorChild
|
||||
|
@ -201,21 +200,21 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
already_AddRefed<TextureClient> Create(gfx::SurfaceFormat format) {
|
||||
already_AddRefed<BufferTextureClient> Create(gfx::SurfaceFormat format) {
|
||||
return TextureClient::CreateForRawBufferAccess(mAllocator, format,
|
||||
mSize, mBackendType,
|
||||
mBaseTexFlags);
|
||||
}
|
||||
|
||||
public:
|
||||
already_AddRefed<TextureClient> CreateB8G8R8AX8() {
|
||||
already_AddRefed<BufferTextureClient> CreateB8G8R8AX8() {
|
||||
gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::B8G8R8A8
|
||||
: gfx::SurfaceFormat::B8G8R8X8;
|
||||
return Create(format);
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient> CreateR8G8B8AX8() {
|
||||
RefPtr<TextureClient> ret;
|
||||
already_AddRefed<BufferTextureClient> CreateR8G8B8AX8() {
|
||||
RefPtr<BufferTextureClient> ret;
|
||||
|
||||
bool areRGBAFormatsBroken = mLayersBackend == LayersBackend::LAYERS_BASIC;
|
||||
if (!areRGBAFormatsBroken) {
|
||||
|
@ -243,7 +242,7 @@ TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
|
|||
TexClientFactory factory(allocator, src->mHasAlpha, src->mSize, backendType,
|
||||
baseFlags, layersBackend);
|
||||
|
||||
RefPtr<TextureClient> texClient;
|
||||
RefPtr<BufferTextureClient> texClient;
|
||||
|
||||
{
|
||||
gl::ScopedReadbackFB autoReadback(src);
|
||||
|
@ -289,18 +288,16 @@ TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
|
|||
DebugOnly<bool> succeeded = autoLock.Succeeded();
|
||||
MOZ_ASSERT(succeeded, "texture should have locked");
|
||||
|
||||
MappedTextureData mapped;
|
||||
texClient->BorrowMappedData(mapped);
|
||||
uint8_t* lockedBytes = texClient->GetLockedData();
|
||||
|
||||
// ReadPixels from the current FB into mapped.data.
|
||||
// ReadPixels from the current FB into lockedBits.
|
||||
auto width = src->mSize.width;
|
||||
auto height = src->mSize.height;
|
||||
|
||||
{
|
||||
ScopedPackAlignment autoAlign(gl, 4);
|
||||
|
||||
MOZ_ASSERT(mapped.stride/4 == mapped.size.width);
|
||||
gl->raw_fReadPixels(0, 0, width, height, readFormat, readType, mapped.data);
|
||||
gl->raw_fReadPixels(0, 0, width, height, readFormat, readType, lockedBytes);
|
||||
}
|
||||
|
||||
// RB_SWAPPED doesn't work with D3D11. (bug 1051010)
|
||||
|
@ -313,7 +310,7 @@ TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
|
|||
layersNeedsManualSwap)
|
||||
{
|
||||
size_t pixels = width * height;
|
||||
uint8_t* itr = mapped.data;
|
||||
uint8_t* itr = lockedBytes;
|
||||
for (size_t i = 0; i < pixels; i++) {
|
||||
SwapRB_R8G8B8A8(itr);
|
||||
itr += 4;
|
||||
|
|
|
@ -198,7 +198,7 @@ CompositableClient::GetAsyncID() const
|
|||
return 0; // zero is always an invalid async ID
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
already_AddRefed<BufferTextureClient>
|
||||
CompositableClient::CreateBufferTextureClient(gfx::SurfaceFormat aFormat,
|
||||
gfx::IntSize aSize,
|
||||
gfx::BackendType aMoz2DBackend,
|
||||
|
@ -225,7 +225,7 @@ CompositableClient::CreateTextureClientForDrawing(gfx::SurfaceFormat aFormat,
|
|||
bool
|
||||
CompositableClient::AddTextureClient(TextureClient* aClient)
|
||||
{
|
||||
if(!aClient) {
|
||||
if(!aClient || !aClient->IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
aClient->SetAddedToCompositableClient();
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace mozilla {
|
|||
namespace layers {
|
||||
|
||||
class CompositableClient;
|
||||
class BufferTextureClient;
|
||||
class ImageBridgeChild;
|
||||
class ImageContainer;
|
||||
class CompositableForwarder;
|
||||
|
@ -135,7 +136,7 @@ public:
|
|||
|
||||
LayersBackend GetCompositorBackendType() const;
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
already_AddRefed<BufferTextureClient>
|
||||
CreateBufferTextureClient(gfx::SurfaceFormat aFormat,
|
||||
gfx::IntSize aSize,
|
||||
gfx::BackendType aMoz2dBackend = gfx::BackendType::NONE,
|
||||
|
|
|
@ -192,7 +192,7 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
|
|||
return false;
|
||||
}
|
||||
|
||||
bool status = UpdateYCbCrTextureClient(texture, *data);
|
||||
bool status = texture->AsTextureClientYCbCr()->UpdateYCbCr(*data);
|
||||
MOZ_ASSERT(status);
|
||||
if (!status) {
|
||||
return false;
|
||||
|
@ -203,15 +203,16 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
|
|||
|
||||
if (image->GetFormat() == ImageFormat::EGLIMAGE) {
|
||||
EGLImageImage* typedImage = image->AsEGLImageImage();
|
||||
texture = EGLImageTextureData::CreateTextureClient(
|
||||
typedImage, size, GetForwarder(), mTextureFlags);
|
||||
texture = new EGLImageTextureClient(GetForwarder(),
|
||||
mTextureFlags,
|
||||
typedImage,
|
||||
size);
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
} else if (image->GetFormat() == ImageFormat::SURFACE_TEXTURE) {
|
||||
SurfaceTextureImage* typedImage = image->AsSurfaceTextureImage();
|
||||
texture = AndroidSurfaceTextureData::CreateTextureClient(
|
||||
typedImage->GetSurfaceTexture(), size, typedImage->GetOriginPos(),
|
||||
GetForwarder(), mTextureFlags
|
||||
);
|
||||
texture = new SurfaceTextureClient(GetForwarder(), mTextureFlags,
|
||||
typedImage->GetSurfaceTexture(), size,
|
||||
typedImage->GetOriginPos());
|
||||
#endif
|
||||
} else {
|
||||
MOZ_ASSERT(false, "Bad ImageFormat.");
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -39,10 +39,6 @@ namespace mozilla {
|
|||
#define GFX_DEBUG_TRACK_CLIENTS_IN_POOL 1
|
||||
#endif
|
||||
|
||||
namespace gl {
|
||||
class SharedSurface_Gralloc;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
class AsyncTransactionWaiter;
|
||||
|
@ -53,15 +49,14 @@ struct PlanarYCbCrData;
|
|||
class Image;
|
||||
class PTextureChild;
|
||||
class TextureChild;
|
||||
class TextureData;
|
||||
struct RawTextureBuffer;
|
||||
class RawYCbCrTextureBuffer;
|
||||
class BufferTextureClient;
|
||||
class TextureClient;
|
||||
class TextureClientRecycleAllocator;
|
||||
#ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
|
||||
class TextureClientPool;
|
||||
#endif
|
||||
class KeepAlive;
|
||||
class GrallocTextureClientOGL;
|
||||
|
||||
/**
|
||||
* TextureClient is the abstraction that allows us to share data between the
|
||||
|
@ -100,6 +95,31 @@ protected:
|
|||
SyncObject() { }
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface for TextureClients that can be updated using YCbCr data.
|
||||
*/
|
||||
class TextureClientYCbCr
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Copy aData into this texture client.
|
||||
*
|
||||
* This must never be called on a TextureClient that is not sucessfully locked.
|
||||
*/
|
||||
virtual bool UpdateYCbCr(const PlanarYCbCrData& aData) = 0;
|
||||
|
||||
/**
|
||||
* Allocates for a given surface size, taking into account the pixel format
|
||||
* which is part of the state of the TextureClient.
|
||||
*
|
||||
* Does not clear the surface, since we consider that the surface
|
||||
* be painted entirely with opaque content.
|
||||
*/
|
||||
virtual bool AllocateForYCbCr(gfx::IntSize aYSize,
|
||||
gfx::IntSize aCbCrSize,
|
||||
StereoMode aStereoMode) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class may be used to asynchronously receive an update when the content
|
||||
* drawn to this texture client is available for reading in CPU memory. This
|
||||
|
@ -127,96 +147,6 @@ enum class BackendSelector
|
|||
Canvas
|
||||
};
|
||||
|
||||
/// Temporary object providing direct access to a Texture's memory.
|
||||
///
|
||||
/// see TextureClient::CanExposeMappedData() and TextureClient::BorrowMappedData().
|
||||
struct MappedTextureData
|
||||
{
|
||||
uint8_t* data;
|
||||
gfx::IntSize size;
|
||||
int32_t stride;
|
||||
gfx::SurfaceFormat format;
|
||||
};
|
||||
|
||||
struct MappedYCbCrChannelData
|
||||
{
|
||||
uint8_t* data;
|
||||
gfx::IntSize size;
|
||||
int32_t stride;
|
||||
int32_t skip;
|
||||
|
||||
bool CopyInto(MappedYCbCrChannelData& aDst);
|
||||
};
|
||||
|
||||
struct MappedYCbCrTextureData {
|
||||
MappedYCbCrChannelData y;
|
||||
MappedYCbCrChannelData cb;
|
||||
MappedYCbCrChannelData cr;
|
||||
// Sad but because of how SharedPlanarYCbCrData is used we have to expose this for now.
|
||||
uint8_t* metadata;
|
||||
StereoMode stereoMode;
|
||||
|
||||
bool CopyInto(MappedYCbCrTextureData& aDst)
|
||||
{
|
||||
return y.CopyInto(aDst.y)
|
||||
&& cb.CopyInto(aDst.cb)
|
||||
&& cr.CopyInto(aDst.cr);
|
||||
}
|
||||
};
|
||||
|
||||
class TextureData {
|
||||
public:
|
||||
TextureData() { MOZ_COUNT_CTOR(TextureData); }
|
||||
|
||||
virtual ~TextureData() { MOZ_COUNT_DTOR(TextureData); }
|
||||
|
||||
virtual gfx::IntSize GetSize() const = 0;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const = 0;
|
||||
|
||||
virtual bool Lock(OpenMode aMode, FenceHandle* aFence) = 0;
|
||||
|
||||
virtual void Unlock() = 0;
|
||||
|
||||
virtual bool SupportsMoz2D() const { return false; }
|
||||
|
||||
virtual bool CanExposeMappedData() const { return false; }
|
||||
|
||||
virtual bool HasInternalBuffer() const = 0;
|
||||
|
||||
virtual bool HasSynchronization() const { return false; }
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() { return nullptr; }
|
||||
|
||||
virtual bool BorrowMappedData(MappedTextureData&) { return false; }
|
||||
|
||||
virtual bool BorrowMappedYCbCrData(MappedYCbCrTextureData&) { return false; }
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator* aAllocator) = 0;
|
||||
|
||||
/// Depending on the texture's flags either Deallocate or Forget is called.
|
||||
virtual void Forget(ISurfaceAllocator* aAllocator) {}
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aDescriptor) = 0;
|
||||
|
||||
virtual TextureData*
|
||||
CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const { return nullptr; }
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) { return false; };
|
||||
|
||||
virtual bool ReadBack(TextureReadbackSink* aReadbackSink) { return false; }
|
||||
|
||||
/// Ideally this should not be exposed and users of TextureClient would use Lock/Unlock
|
||||
/// preoperly but that requires a few changes to SharedSurface and maybe gonk video.
|
||||
virtual void WaitForFence(FenceHandle* aFence) {};
|
||||
|
||||
virtual void SyncWithObject(SyncObject* aFence) {};
|
||||
|
||||
virtual TextureFlags GetTextureFlags() const { return TextureFlags::NO_FLAGS; }
|
||||
};
|
||||
|
||||
/**
|
||||
* TextureClient is a thin abstraction over texture data that need to be shared
|
||||
* between the content process and the compositor process. It is the
|
||||
|
@ -244,13 +174,10 @@ class TextureClient
|
|||
: public AtomicRefCountedWithFinalize<TextureClient>
|
||||
{
|
||||
public:
|
||||
explicit TextureClient(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator);
|
||||
|
||||
explicit TextureClient(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT);
|
||||
virtual ~TextureClient();
|
||||
|
||||
static already_AddRefed<TextureClient>
|
||||
CreateWithData(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator);
|
||||
|
||||
// Creates and allocates a TextureClient usable with Moz2D.
|
||||
static already_AddRefed<TextureClient>
|
||||
CreateForDrawing(CompositableForwarder* aAllocator,
|
||||
|
@ -260,17 +187,17 @@ public:
|
|||
TextureFlags aTextureFlags,
|
||||
TextureAllocationFlags flags = ALLOC_DEFAULT);
|
||||
|
||||
// Creates and allocates a TextureClient supporting the YCbCr format.
|
||||
static already_AddRefed<TextureClient>
|
||||
// Creates and allocates a BufferTextureClient supporting the YCbCr format.
|
||||
static already_AddRefed<BufferTextureClient>
|
||||
CreateForYCbCr(ISurfaceAllocator* aAllocator,
|
||||
gfx::IntSize aYSize,
|
||||
gfx::IntSize aCbCrSize,
|
||||
StereoMode aStereoMode,
|
||||
TextureFlags aTextureFlags);
|
||||
|
||||
// Creates and allocates a TextureClient (can be accessed through raw
|
||||
// Creates and allocates a BufferTextureClient (can beaccessed through raw
|
||||
// pointers).
|
||||
static already_AddRefed<TextureClient>
|
||||
static already_AddRefed<BufferTextureClient>
|
||||
CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
gfx::IntSize aSize,
|
||||
|
@ -278,19 +205,37 @@ public:
|
|||
TextureFlags aTextureFlags,
|
||||
TextureAllocationFlags flags = ALLOC_DEFAULT);
|
||||
|
||||
// Creates and allocates a TextureClient (can beaccessed through raw
|
||||
// Creates and allocates a BufferTextureClient (can beaccessed through raw
|
||||
// pointers) with a certain buffer size. It's unfortunate that we need this.
|
||||
// providing format and sizes could let us do more optimization.
|
||||
static already_AddRefed<TextureClient>
|
||||
static already_AddRefed<BufferTextureClient>
|
||||
CreateWithBufferSize(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
size_t aSize,
|
||||
TextureFlags aTextureFlags);
|
||||
|
||||
// Creates and allocates a TextureClient of the same type.
|
||||
already_AddRefed<TextureClient>
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const;
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const = 0;
|
||||
|
||||
/**
|
||||
* Allocates for a given surface size, taking into account the pixel format
|
||||
* which is part of the state of the TextureClient.
|
||||
*
|
||||
* Does not clear the surface by default, clearing the surface can be done
|
||||
* by passing the CLEAR_BUFFER flag.
|
||||
*
|
||||
* TextureClients that can expose a DrawTarget should override this method.
|
||||
*/
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize,
|
||||
TextureAllocationFlags flags = ALLOC_DEFAULT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual TextureClientYCbCr* AsTextureClientYCbCr() { return nullptr; }
|
||||
virtual GrallocTextureClientOGL* AsGrallocTextureClientOGL() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Locks the shared data, allowing the caller to get access to it.
|
||||
|
@ -298,15 +243,13 @@ public:
|
|||
* Please always lock/unlock when accessing the shared data.
|
||||
* If Lock() returns false, you should not attempt to access the shared data.
|
||||
*/
|
||||
bool Lock(OpenMode aMode);
|
||||
virtual bool Lock(OpenMode aMode) { return IsValid(); }
|
||||
|
||||
void Unlock();
|
||||
virtual void Unlock() {}
|
||||
|
||||
bool IsLocked() const { return mIsLocked; }
|
||||
virtual bool IsLocked() const = 0;
|
||||
|
||||
bool CanExposeDrawTarget() const { return mData->SupportsMoz2D(); }
|
||||
|
||||
bool CanExposeMappedData() const { return mData->CanExposeMappedData(); }
|
||||
virtual bool CanExposeDrawTarget() const { return false; }
|
||||
|
||||
/**
|
||||
* Returns a DrawTarget to draw into the TextureClient.
|
||||
|
@ -334,28 +277,25 @@ public:
|
|||
* texture->Unlock();
|
||||
*
|
||||
*/
|
||||
gfx::DrawTarget* BorrowDrawTarget();
|
||||
|
||||
/**
|
||||
* Similar to BorrowDrawTarget but provides direct access to the texture's bits
|
||||
* instead of a DrawTarget.
|
||||
*/
|
||||
bool BorrowMappedData(MappedTextureData&);
|
||||
bool BorrowMappedYCbCrData(MappedYCbCrTextureData&);
|
||||
virtual gfx::DrawTarget* BorrowDrawTarget() { return nullptr; }
|
||||
|
||||
/**
|
||||
* This function can be used to update the contents of the TextureClient
|
||||
* off the main thread.
|
||||
*/
|
||||
void UpdateFromSurface(gfx::SourceSurface* aSurface);
|
||||
virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) { MOZ_CRASH(); }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const;
|
||||
// TextureClients that can expose a DrawTarget should override this method.
|
||||
virtual gfx::SurfaceFormat GetFormat() const
|
||||
{
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is strictly for debugging. It causes locking and
|
||||
* needless copies.
|
||||
*/
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() {
|
||||
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() {
|
||||
Lock(OpenMode::OPEN_READ);
|
||||
RefPtr<gfx::SourceSurface> surf = BorrowDrawTarget()->Snapshot();
|
||||
RefPtr<gfx::DataSourceSurface> data = surf->GetDataSurface();
|
||||
|
@ -370,25 +310,23 @@ public:
|
|||
* It is assumed that the necessary locks are in place; so this should at
|
||||
* least have a read lock and aTarget should at least have a write lock.
|
||||
*/
|
||||
bool CopyToTextureClient(TextureClient* aTarget,
|
||||
const gfx::IntRect* aRect,
|
||||
const gfx::IntPoint* aPoint);
|
||||
virtual bool CopyToTextureClient(TextureClient* aTarget,
|
||||
const gfx::IntRect* aRect,
|
||||
const gfx::IntPoint* aPoint);
|
||||
|
||||
/**
|
||||
* Returns true if this texture has a synchronization mechanism (mutex, fence, etc.).
|
||||
* Textures that do not implement synchronization should be immutable or should
|
||||
* Returns true if this texture has a lock/unlock mechanism.
|
||||
* Textures that do not implement locking should be immutable or should
|
||||
* use immediate uploads (see TextureFlags in CompositorTypes.h)
|
||||
* Even if a texture does not implement synchronization, Lock and Unlock need
|
||||
* to be used appropriately since the latter are also there to map/numap data.
|
||||
*/
|
||||
bool HasSynchronization() const { return false; }
|
||||
virtual bool ImplementsLocking() const { return false; }
|
||||
|
||||
/**
|
||||
* Indicates whether the TextureClient implementation is backed by an
|
||||
* in-memory buffer. The consequence of this is that locking the
|
||||
* TextureClient does not contend with locking the texture on the host side.
|
||||
*/
|
||||
bool HasInternalBuffer() const;
|
||||
virtual bool HasInternalBuffer() const = 0;
|
||||
|
||||
/**
|
||||
* Allocate and deallocate a TextureChild actor.
|
||||
|
@ -406,7 +344,9 @@ public:
|
|||
*/
|
||||
static TextureClient* AsTextureClient(PTextureChild* actor);
|
||||
|
||||
gfx::IntSize GetSize() const;
|
||||
virtual bool IsAllocated() const = 0;
|
||||
|
||||
virtual gfx::IntSize GetSize() const = 0;
|
||||
|
||||
/**
|
||||
* TextureFlags contain important information about various aspects
|
||||
|
@ -447,11 +387,13 @@ public:
|
|||
|
||||
bool IsSharedWithCompositor() const;
|
||||
|
||||
bool ShouldDeallocateInDestructor() const;
|
||||
|
||||
/**
|
||||
* If this method returns false users of TextureClient are not allowed
|
||||
* to access the shared data.
|
||||
*/
|
||||
bool IsValid() const { return !!mData; }
|
||||
bool IsValid() const { return mValid; }
|
||||
|
||||
/**
|
||||
* Called when TextureClient is added to CompositableClient.
|
||||
|
@ -464,6 +406,16 @@ public:
|
|||
*/
|
||||
bool IsAddedToCompositableClient() const { return mAddedToCompositableClient; }
|
||||
|
||||
/**
|
||||
* kee the passed object alive until the IPDL actor is destroyed. This can
|
||||
* help avoid race conditions in some cases.
|
||||
* It's a temporary hack to ensure that DXGI textures don't get destroyed
|
||||
* between serialization and deserialization.
|
||||
*
|
||||
* This must not be called off the texture's IPDL thread.
|
||||
*/
|
||||
void KeepUntilFullDeallocation(UniquePtr<KeepAlive> aKeep, bool aMainThreadOnly = false);
|
||||
|
||||
/**
|
||||
* Create and init the TextureChild/Parent IPDL actor pair.
|
||||
*
|
||||
|
@ -488,7 +440,7 @@ public:
|
|||
* If sync is true, the destruction will be synchronous regardless of the
|
||||
* texture's flags (bad for performance, use with care).
|
||||
*/
|
||||
void Destroy(bool sync = false);
|
||||
void ForceRemove(bool sync = false);
|
||||
|
||||
virtual void SetReleaseFenceHandle(const FenceHandle& aReleaseFenceHandle)
|
||||
{
|
||||
|
@ -515,15 +467,12 @@ public:
|
|||
/**
|
||||
* Set AsyncTransactionTracker of RemoveTextureFromCompositableAsync() transaction.
|
||||
*/
|
||||
virtual void SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter);
|
||||
virtual void SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) {}
|
||||
|
||||
/**
|
||||
* This function waits until the buffer is no longer being used.
|
||||
*
|
||||
* XXX - Ideally we shouldn't need this method because Lock the right
|
||||
* thing already.
|
||||
*/
|
||||
virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true);
|
||||
virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true) {}
|
||||
|
||||
/**
|
||||
* Track how much of this texture is wasted.
|
||||
|
@ -533,26 +482,29 @@ public:
|
|||
mWasteTracker.Update(aWasteArea, BytesPerPixel(GetFormat()));
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets the readback sink that this texture is to use. This will
|
||||
* receive the data for this texture as soon as it becomes available after
|
||||
* texture unlock.
|
||||
*/
|
||||
virtual void SetReadbackSink(TextureReadbackSink* aReadbackSink) {
|
||||
mReadbackSink = aReadbackSink;
|
||||
/**
|
||||
* This sets the readback sink that this texture is to use. This will
|
||||
* receive the data for this texture as soon as it becomes available after
|
||||
* texture unlock.
|
||||
*/
|
||||
virtual void SetReadbackSink(TextureReadbackSink* aReadbackSink) {
|
||||
mReadbackSink = aReadbackSink;
|
||||
}
|
||||
|
||||
virtual void SyncWithObject(SyncObject* aSyncObject) { }
|
||||
|
||||
void MarkShared() {
|
||||
mShared = true;
|
||||
}
|
||||
|
||||
ISurfaceAllocator* GetAllocator()
|
||||
{
|
||||
return mAllocator;
|
||||
}
|
||||
|
||||
void SyncWithObject(SyncObject* aFence) { mData->SyncWithObject(aFence); }
|
||||
|
||||
ISurfaceAllocator* GetAllocator() { return mAllocator; }
|
||||
|
||||
TextureClientRecycleAllocator* GetRecycleAllocator() { return mRecycleAllocator; }
|
||||
void SetRecycleAllocator(TextureClientRecycleAllocator* aAllocator);
|
||||
|
||||
/// If you add new code that uses this method, you are probably doing something wrong.
|
||||
TextureData* GetInternalData() { return mData; }
|
||||
const TextureData* GetInternalData() const { return mData; }
|
||||
|
||||
private:
|
||||
static void TextureClientRecycleCallback(TextureClient* aClient, void* aClosure);
|
||||
|
||||
|
@ -563,11 +515,23 @@ private:
|
|||
* Here goes the shut-down code that uses virtual methods.
|
||||
* Must only be called by Release().
|
||||
*/
|
||||
B2G_ACL_EXPORT void Finalize() {}
|
||||
B2G_ACL_EXPORT void Finalize();
|
||||
|
||||
/**
|
||||
* Called once during the destruction of the texture on the IPDL thread, if
|
||||
* the texture is shared on the compositor (otherwise it is not called at all).
|
||||
*/
|
||||
virtual void FinalizeOnIPDLThread() {}
|
||||
|
||||
friend class AtomicRefCountedWithFinalize<TextureClient>;
|
||||
friend class gl::SharedSurface_Gralloc;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* An invalid TextureClient cannot provide access to its shared data
|
||||
* anymore. This usually means it will soon be destroyed.
|
||||
*/
|
||||
void MarkInvalid() { mValid = false; }
|
||||
|
||||
/**
|
||||
* Should only be called *once* per texture, in TextureClient::InitIPDLActor.
|
||||
* Some texture implementations rely on the fact that the descriptor will be
|
||||
|
@ -576,28 +540,18 @@ protected:
|
|||
* or never constructing a TextureHost with aDescriptor may result in a memory
|
||||
* leak (see TextureClientD3D9 for example).
|
||||
*/
|
||||
bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor);
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) = 0;
|
||||
|
||||
|
||||
RefPtr<ISurfaceAllocator> mAllocator;
|
||||
RefPtr<TextureChild> mActor;
|
||||
RefPtr<ISurfaceAllocator> mAllocator;
|
||||
RefPtr<TextureClientRecycleAllocator> mRecycleAllocator;
|
||||
RefPtr<AsyncTransactionWaiter> mRemoveFromCompositableWaiter;
|
||||
|
||||
TextureData* mData;
|
||||
RefPtr<gfx::DrawTarget> mBorrowedDrawTarget;
|
||||
|
||||
TextureFlags mFlags;
|
||||
FenceHandle mReleaseFenceHandle;
|
||||
FenceHandle mAcquireFenceHandle;
|
||||
gl::GfxTextureWasteTracker mWasteTracker;
|
||||
|
||||
OpenMode mOpenMode;
|
||||
DebugOnly<uint32_t> mExpectedDtRefs;
|
||||
bool mIsLocked;
|
||||
|
||||
bool mShared;
|
||||
bool mValid;
|
||||
bool mAddedToCompositableClient;
|
||||
bool mWorkaroundAnnoyingSharedSurfaceLifetimeIssues;
|
||||
|
||||
RefPtr<TextureReadbackSink> mReadbackSink;
|
||||
|
||||
|
@ -632,6 +586,143 @@ private:
|
|||
RefPtr<TextureClient> mTextureClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* TextureClient that wraps a random access buffer such as a Shmem or raw memory.
|
||||
* This class must be inherited to implement the memory allocation and access bits.
|
||||
* (see ShmemTextureClient and MemoryTextureClient)
|
||||
*/
|
||||
class BufferTextureClient : public TextureClient
|
||||
, public TextureClientYCbCr
|
||||
{
|
||||
public:
|
||||
BufferTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aBackend, TextureFlags aFlags);
|
||||
|
||||
virtual ~BufferTextureClient();
|
||||
|
||||
virtual bool IsAllocated() const override = 0;
|
||||
|
||||
virtual uint8_t* GetBuffer() const = 0;
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
virtual bool Lock(OpenMode aMode) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual bool IsLocked() const override { return mLocked; }
|
||||
|
||||
uint8_t* GetLockedData() const;
|
||||
|
||||
virtual bool CanExposeDrawTarget() const override { return true; }
|
||||
|
||||
virtual gfx::DrawTarget* BorrowDrawTarget() override;
|
||||
|
||||
virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize,
|
||||
TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
|
||||
|
||||
// TextureClientYCbCr
|
||||
|
||||
virtual TextureClientYCbCr* AsTextureClientYCbCr() override { return this; }
|
||||
|
||||
virtual bool UpdateYCbCr(const PlanarYCbCrData& aData) override;
|
||||
|
||||
virtual bool AllocateForYCbCr(gfx::IntSize aYSize,
|
||||
gfx::IntSize aCbCrSize,
|
||||
StereoMode aStereoMode) override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
// XXX - Bug 908196 - Make Allocate(uint32_t) and GetBufferSize() protected.
|
||||
// these two methods should only be called by methods of BufferTextureClient
|
||||
// that are overridden in GrallocTextureClient (which does not implement the
|
||||
// two methods below)
|
||||
virtual bool Allocate(uint32_t aSize) = 0;
|
||||
|
||||
virtual size_t GetBufferSize() const = 0;
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
protected:
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
gfx::IntSize mSize;
|
||||
gfx::BackendType mBackend;
|
||||
OpenMode mOpenMode;
|
||||
bool mLocked;
|
||||
};
|
||||
|
||||
/**
|
||||
* TextureClient that wraps shared memory.
|
||||
* the corresponding texture on the host side is ShmemTextureHost.
|
||||
*/
|
||||
class ShmemTextureClient : public BufferTextureClient
|
||||
{
|
||||
public:
|
||||
ShmemTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aBackend, TextureFlags aFlags);
|
||||
|
||||
protected:
|
||||
~ShmemTextureClient();
|
||||
|
||||
public:
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) override;
|
||||
|
||||
virtual bool Allocate(uint32_t aSize) override;
|
||||
|
||||
virtual uint8_t* GetBuffer() const override;
|
||||
|
||||
virtual size_t GetBufferSize() const override;
|
||||
|
||||
virtual bool IsAllocated() const override { return mAllocated; }
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
|
||||
mozilla::ipc::Shmem& GetShmem() { return mShmem; }
|
||||
|
||||
protected:
|
||||
mozilla::ipc::Shmem mShmem;
|
||||
bool mAllocated;
|
||||
};
|
||||
|
||||
/**
|
||||
* TextureClient that wraps raw memory.
|
||||
* The corresponding texture on the host side is MemoryTextureHost.
|
||||
* Can obviously not be used in a cross process setup.
|
||||
*/
|
||||
class MemoryTextureClient : public BufferTextureClient
|
||||
{
|
||||
public:
|
||||
MemoryTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aBackend, TextureFlags aFlags);
|
||||
|
||||
protected:
|
||||
~MemoryTextureClient();
|
||||
|
||||
public:
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) override;
|
||||
|
||||
virtual bool Allocate(uint32_t aSize) override;
|
||||
|
||||
virtual uint8_t* GetBuffer() const override { return mBuffer; }
|
||||
|
||||
virtual size_t GetBufferSize() const override { return mBufSize; }
|
||||
|
||||
virtual bool IsAllocated() const override { return mBuffer != nullptr; }
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
|
||||
protected:
|
||||
uint8_t* mBuffer;
|
||||
size_t mBufSize;
|
||||
};
|
||||
|
||||
// Automatically lock and unlock a texture. Since texture locking is fallible,
|
||||
// Succeeded() must be checked on the guard object before proceeding.
|
||||
class MOZ_RAII TextureClientAutoLock
|
||||
|
@ -682,9 +773,6 @@ protected:
|
|||
RefPtr<T> mData;
|
||||
};
|
||||
|
||||
/// Convenience function to set the content of ycbcr texture.
|
||||
bool UpdateYCbCrTextureClient(TextureClient* aTexture, const PlanarYCbCrData& aData);
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "TextureClientPool.h"
|
||||
#include "CompositableClient.h"
|
||||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
|
||||
#include "gfxPrefs.h"
|
||||
|
||||
|
|
|
@ -23,58 +23,40 @@ using namespace mozilla::gl;
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
SharedSurfaceTextureClient::SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
UniquePtr<gl::SharedSurface> surf,
|
||||
gl::SurfaceFactory* factory)
|
||||
: TextureClient(aAllocator,
|
||||
aFlags | TextureFlags::RECYCLE | surf->GetTextureFlags())
|
||||
, mSurf(Move(surf))
|
||||
{
|
||||
}
|
||||
|
||||
SharedSurfaceTextureData::SharedSurfaceTextureData(UniquePtr<gl::SharedSurface> surf)
|
||||
: mSurf(Move(surf))
|
||||
{}
|
||||
|
||||
SharedSurfaceTextureData::~SharedSurfaceTextureData()
|
||||
{}
|
||||
|
||||
void
|
||||
SharedSurfaceTextureData::Deallocate(ISurfaceAllocator*)
|
||||
{}
|
||||
SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
|
||||
{
|
||||
// Free the ShSurf implicitly.
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
SharedSurfaceTextureData::GetSize() const
|
||||
SharedSurfaceTextureClient::GetSize() const
|
||||
{
|
||||
return mSurf->mSize;
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
SharedSurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
return mSurf->ToSurfaceDescriptor(&aOutDescriptor);
|
||||
}
|
||||
|
||||
|
||||
SharedSurfaceTextureClient::SharedSurfaceTextureClient(SharedSurfaceTextureData* aData,
|
||||
TextureFlags aFlags,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
: TextureClient(aData, aFlags, aAllocator)
|
||||
{
|
||||
mWorkaroundAnnoyingSharedSurfaceLifetimeIssues = true;
|
||||
}
|
||||
|
||||
already_AddRefed<SharedSurfaceTextureClient>
|
||||
SharedSurfaceTextureClient::Create(UniquePtr<gl::SharedSurface> surf, gl::SurfaceFactory* factory,
|
||||
ISurfaceAllocator* aAllocator, TextureFlags aFlags)
|
||||
{
|
||||
if (!surf) {
|
||||
return nullptr;
|
||||
}
|
||||
TextureFlags flags = aFlags | TextureFlags::RECYCLE | surf->GetTextureFlags();
|
||||
SharedSurfaceTextureData* data = new SharedSurfaceTextureData(Move(surf));
|
||||
return MakeAndAddRef<SharedSurfaceTextureClient>(data, flags, aAllocator);
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurfaceTextureClient::SetReleaseFenceHandle(const FenceHandle& aReleaseFenceHandle)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
gl::SharedSurface_Gralloc* surf = nullptr;
|
||||
if (Surf()->mType == gl::SharedSurfaceType::Gralloc) {
|
||||
surf = gl::SharedSurface_Gralloc::Cast(Surf());
|
||||
SharedSurface_Gralloc* surf = nullptr;
|
||||
if (mSurf->mType == SharedSurfaceType::Gralloc) {
|
||||
surf = SharedSurface_Gralloc::Cast(mSurf.get());
|
||||
}
|
||||
if (surf && surf->GetTextureClient()) {
|
||||
surf->GetTextureClient()->SetReleaseFenceHandle(aReleaseFenceHandle);
|
||||
|
@ -88,9 +70,9 @@ FenceHandle
|
|||
SharedSurfaceTextureClient::GetAndResetReleaseFenceHandle()
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
gl::SharedSurface_Gralloc* surf = nullptr;
|
||||
if (Surf()->mType == gl::SharedSurfaceType::Gralloc) {
|
||||
surf = gl::SharedSurface_Gralloc::Cast(Surf());
|
||||
SharedSurface_Gralloc* surf = nullptr;
|
||||
if (mSurf->mType == SharedSurfaceType::Gralloc) {
|
||||
surf = SharedSurface_Gralloc::Cast(mSurf.get());
|
||||
}
|
||||
if (surf && surf->GetTextureClient()) {
|
||||
return surf->GetTextureClient()->GetAndResetReleaseFenceHandle();
|
||||
|
@ -103,9 +85,9 @@ void
|
|||
SharedSurfaceTextureClient::SetAcquireFenceHandle(const FenceHandle& aAcquireFenceHandle)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
gl::SharedSurface_Gralloc* surf = nullptr;
|
||||
if (Surf()->mType == gl::SharedSurfaceType::Gralloc) {
|
||||
surf = gl::SharedSurface_Gralloc::Cast(Surf());
|
||||
SharedSurface_Gralloc* surf = nullptr;
|
||||
if (mSurf->mType == SharedSurfaceType::Gralloc) {
|
||||
surf = SharedSurface_Gralloc::Cast(mSurf.get());
|
||||
}
|
||||
if (surf && surf->GetTextureClient()) {
|
||||
return surf->GetTextureClient()->SetAcquireFenceHandle(aAcquireFenceHandle);
|
||||
|
@ -118,9 +100,9 @@ const FenceHandle&
|
|||
SharedSurfaceTextureClient::GetAcquireFenceHandle() const
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
gl::SharedSurface_Gralloc* surf = nullptr;
|
||||
if (Surf()->mType == gl::SharedSurfaceType::Gralloc) {
|
||||
surf = gl::SharedSurface_Gralloc::Cast(Surf());
|
||||
SharedSurface_Gralloc* surf = nullptr;
|
||||
if (mSurf->mType == SharedSurfaceType::Gralloc) {
|
||||
surf = SharedSurface_Gralloc::Cast(mSurf.get());
|
||||
}
|
||||
if (surf && surf->GetTextureClient()) {
|
||||
return surf->GetTextureClient()->GetAcquireFenceHandle();
|
||||
|
@ -129,29 +111,5 @@ SharedSurfaceTextureClient::GetAcquireFenceHandle() const
|
|||
return TextureClient::GetAcquireFenceHandle();
|
||||
}
|
||||
|
||||
SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
|
||||
{
|
||||
// XXX - Things break when using the proper destruction handshake with
|
||||
// SharedSurfaceTextureData because the TextureData outlives its gl
|
||||
// context. Having a strong reference to the gl context creates a cycle.
|
||||
// This needs to be fixed in a better way, though, because deleting
|
||||
// the TextureData here can race with the compositor and cause flashing.
|
||||
TextureData* data = mData;
|
||||
mData = nullptr;
|
||||
|
||||
Destroy();
|
||||
|
||||
if (data) {
|
||||
// Destroy mData right away without doing the proper deallocation handshake,
|
||||
// because SharedSurface depends on things that may not outlive the texture's
|
||||
// destructor so we can't wait until we know the compositor isn't using the
|
||||
// texture anymore.
|
||||
// It goes without saying that this is really bad and we should fix the bugs
|
||||
// that block doing the right thing such as bug 1224199 sooner rather than
|
||||
// later.
|
||||
delete data;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -26,62 +26,51 @@ class SurfaceFactory;
|
|||
|
||||
namespace layers {
|
||||
|
||||
class SharedSurfaceTextureClient;
|
||||
|
||||
class SharedSurfaceTextureData : public TextureData
|
||||
class SharedSurfaceTextureClient : public TextureClient
|
||||
{
|
||||
protected:
|
||||
const UniquePtr<gl::SharedSurface> mSurf;
|
||||
|
||||
friend class SharedSurfaceTextureClient;
|
||||
friend class gl::SurfaceFactory;
|
||||
|
||||
SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator, TextureFlags aFlags,
|
||||
UniquePtr<gl::SharedSurface> surf,
|
||||
gl::SurfaceFactory* factory);
|
||||
|
||||
~SharedSurfaceTextureClient();
|
||||
|
||||
explicit SharedSurfaceTextureData(UniquePtr<gl::SharedSurface> surf);
|
||||
public:
|
||||
|
||||
~SharedSurfaceTextureData();
|
||||
|
||||
virtual bool Lock(OpenMode, FenceHandle*) override { return false; }
|
||||
|
||||
virtual void Unlock() override {}
|
||||
|
||||
virtual bool IsAllocated() const override { return true; }
|
||||
virtual bool Lock(OpenMode) override { return false; }
|
||||
virtual bool IsLocked() const override { return false; }
|
||||
virtual bool HasInternalBuffer() const override { return false; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override {
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags, TextureAllocationFlags) const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize,
|
||||
TextureAllocationFlags) override {
|
||||
MOZ_CRASH("Should never hit this.");
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual gfx::IntSize GetSize() const override;
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator*) override;
|
||||
|
||||
gl::SharedSurface* Surf() const { return mSurf.get(); }
|
||||
};
|
||||
|
||||
class SharedSurfaceTextureClient : public TextureClient
|
||||
{
|
||||
public:
|
||||
SharedSurfaceTextureClient(SharedSurfaceTextureData* aData,
|
||||
TextureFlags aFlags,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
~SharedSurfaceTextureClient();
|
||||
|
||||
static already_AddRefed<SharedSurfaceTextureClient>
|
||||
Create(UniquePtr<gl::SharedSurface> surf, gl::SurfaceFactory* factory,
|
||||
ISurfaceAllocator* aAllocator, TextureFlags aFlags);
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual void SetReleaseFenceHandle(const FenceHandle& aReleaseFenceHandle) override;
|
||||
|
||||
virtual FenceHandle GetAndResetReleaseFenceHandle() override;
|
||||
|
||||
virtual void SetAcquireFenceHandle(const FenceHandle& aAcquireFenceHandle) override;
|
||||
|
||||
virtual const FenceHandle& GetAcquireFenceHandle() const override;
|
||||
|
||||
gl::SharedSurface* Surf() const {
|
||||
return static_cast<const SharedSurfaceTextureData*>(GetInternalData())->Surf();
|
||||
return mSurf.get();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -703,7 +703,7 @@ TileClient::DiscardBackBuffer()
|
|||
{
|
||||
if (mBackBuffer) {
|
||||
MOZ_ASSERT(mBackLock);
|
||||
if (!mBackBuffer->HasSynchronization() && mBackLock->GetReadCount() > 1) {
|
||||
if (!mBackBuffer->ImplementsLocking() && mBackLock->GetReadCount() > 1) {
|
||||
// Our current back-buffer is still locked by the compositor. This can occur
|
||||
// when the client is producing faster than the compositor can consume. In
|
||||
// this case we just want to drop it and not return it to the pool.
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -6,7 +6,6 @@
|
|||
#ifndef MOZILLA_GFX_TEXTURED3D11_H
|
||||
#define MOZILLA_GFX_TEXTURED3D11_H
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
|
@ -21,133 +20,101 @@ namespace layers {
|
|||
|
||||
class CompositorD3D11;
|
||||
|
||||
class DXGITextureData : public TextureData
|
||||
/**
|
||||
* A TextureClient to share a D3D10 texture with the compositor thread.
|
||||
* The corresponding TextureHost is DXGITextureHostD3D11
|
||||
*/
|
||||
class TextureClientD3D11 : public TextureClient
|
||||
{
|
||||
public:
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual bool SupportsMoz2D() const override { return true; }
|
||||
TextureClientD3D11(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags);
|
||||
|
||||
virtual ~TextureClientD3D11();
|
||||
|
||||
// Creates a TextureClient and init width.
|
||||
static already_AddRefed<TextureClientD3D11>
|
||||
Create(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
ID3D11Texture2D* aTexture,
|
||||
gfx::IntSize aSize);
|
||||
|
||||
static already_AddRefed<TextureClientD3D11>
|
||||
Create(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
ID3D11Device* aDevice,
|
||||
const gfx::IntSize& aSize);
|
||||
|
||||
// TextureClient
|
||||
|
||||
virtual bool IsAllocated() const override { return mTexture || mTexture10; }
|
||||
|
||||
virtual bool Lock(OpenMode aOpenMode) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual bool IsLocked() const override { return mIsLocked; }
|
||||
|
||||
virtual bool ImplementsLocking() const override { return true; }
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return false; }
|
||||
|
||||
virtual bool HasSynchronization() const override { return mHasSynchronization; }
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
static DXGITextureData*
|
||||
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
protected:
|
||||
bool PrepareDrawTargetInLock(OpenMode aMode);
|
||||
virtual bool CanExposeDrawTarget() const override { return true; }
|
||||
|
||||
DXGITextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, bool aNeedsClear, bool aNeedsClearWhite);
|
||||
virtual gfx::DrawTarget* BorrowDrawTarget() override;
|
||||
|
||||
virtual void GetDXGIResource(IDXGIResource** aOutResource) = 0;
|
||||
virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
// Hold on to the DrawTarget because it is expensive to create one each ::Lock.
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
gfx::IntSize mSize;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
bool mNeedsClear;
|
||||
bool mNeedsClearWhite;
|
||||
bool mHasSynchronization;
|
||||
};
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize,
|
||||
TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
|
||||
|
||||
class D3D11TextureData : public DXGITextureData
|
||||
{
|
||||
public:
|
||||
// If aDevice is null, use one provided by gfxWindowsPlatform.
|
||||
static DXGITextureData*
|
||||
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureAllocationFlags aAllocFlags,
|
||||
ID3D11Device* aDevice = nullptr);
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
virtual bool Lock(OpenMode aMode, FenceHandle*) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
|
||||
|
||||
virtual TextureData*
|
||||
CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const override;
|
||||
|
||||
// TODO - merge this with the FenceHandle API!
|
||||
virtual void SyncWithObject(SyncObject* aSync) override;
|
||||
virtual void SyncWithObject(SyncObject* aSyncObject) override;
|
||||
|
||||
ID3D11Texture2D* GetD3D11Texture() { return mTexture; }
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
|
||||
|
||||
~D3D11TextureData();
|
||||
protected:
|
||||
D3D11TextureData(ID3D11Texture2D* aTexture,
|
||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
bool aNeedsClear, bool aNeedsClearWhite);
|
||||
bool AllocateD3D11Surface(ID3D11Device* aDevice, const gfx::IntSize& aSize);
|
||||
|
||||
virtual void GetDXGIResource(IDXGIResource** aOutResource) override;
|
||||
virtual void FinalizeOnIPDLThread() override;
|
||||
|
||||
gfx::IntSize mSize;
|
||||
RefPtr<ID3D10Texture2D> mTexture10;
|
||||
RefPtr<ID3D11Texture2D> mTexture;
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
bool mIsLocked;
|
||||
bool mNeedsClear;
|
||||
bool mNeedsClearWhite;
|
||||
};
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
CreateD3D11extureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
|
||||
ID3D11Device* aDevice,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
|
||||
class D3D10TextureData : public DXGITextureData
|
||||
class DXGIYCbCrTextureClient : public TextureClient
|
||||
{
|
||||
public:
|
||||
static DXGITextureData*
|
||||
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
|
||||
DXGIYCbCrTextureClient(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags);
|
||||
|
||||
virtual bool Lock(OpenMode aMode, FenceHandle*) override;
|
||||
virtual ~DXGIYCbCrTextureClient();
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
|
||||
|
||||
virtual TextureData*
|
||||
CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const override;
|
||||
|
||||
// TODO - merge this with the FenceHandle API!
|
||||
virtual void SyncWithObject(SyncObject* aSync) override;
|
||||
|
||||
virtual bool ReadBack(TextureReadbackSink* aReadbackSinc) override;
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
|
||||
|
||||
~D3D10TextureData();
|
||||
protected:
|
||||
D3D10TextureData(ID3D10Texture2D* aTexture,
|
||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
bool aNeedsClear, bool aNeedsClearWhite);
|
||||
|
||||
virtual void GetDXGIResource(IDXGIResource** aOutResource) override;
|
||||
|
||||
RefPtr<ID3D10Texture2D> mTexture;
|
||||
};
|
||||
|
||||
class DXGIYCbCrTextureData : public TextureData
|
||||
{
|
||||
public:
|
||||
static DXGIYCbCrTextureData*
|
||||
// Creates a TextureClient and init width.
|
||||
static already_AddRefed<DXGIYCbCrTextureClient>
|
||||
Create(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
IUnknown* aTextureY,
|
||||
IUnknown* aTextureCb,
|
||||
IUnknown* aTextureCr,
|
||||
IDirect3DTexture9* aTextureY,
|
||||
IDirect3DTexture9* aTextureCb,
|
||||
IDirect3DTexture9* aTextureCr,
|
||||
HANDLE aHandleY,
|
||||
HANDLE aHandleCb,
|
||||
HANDLE aHandleCr,
|
||||
|
@ -155,56 +122,54 @@ public:
|
|||
const gfx::IntSize& aSizeY,
|
||||
const gfx::IntSize& aSizeCbCr);
|
||||
|
||||
static DXGIYCbCrTextureData*
|
||||
// Creates a TextureClient and init width.
|
||||
static already_AddRefed<DXGIYCbCrTextureClient>
|
||||
Create(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
ID3D11Texture2D* aTextureCb,
|
||||
ID3D11Texture2D* aTextureY,
|
||||
ID3D11Texture2D* aTextureCb,
|
||||
ID3D11Texture2D* aTextureCr,
|
||||
const gfx::IntSize& aSize,
|
||||
const gfx::IntSize& aSizeY,
|
||||
const gfx::IntSize& aSizeCbCr);
|
||||
|
||||
virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
|
||||
// TextureClient
|
||||
|
||||
virtual void Unlock() override {}
|
||||
virtual bool IsAllocated() const override{ return !!mHoldRefs[0]; }
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
virtual bool Lock(OpenMode aOpenMode) override;
|
||||
|
||||
// TODO - DXGIYCbCrTextureClient returned true but that looks like a mistake
|
||||
virtual bool HasInternalBuffer() const override{ return false; }
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
virtual bool IsLocked() const override{ return mIsLocked; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const { return gfx::SurfaceFormat::YUV; }
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual bool SupportsMoz2D() const { return false; }
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() { return nullptr; }
|
||||
|
||||
// This TextureData should not be used in a context where we use CreateSimilar
|
||||
// (ex. component alpha) because the underlying texture is always created by
|
||||
// an external producer.
|
||||
virtual DXGIYCbCrTextureData*
|
||||
CreateSimilar(ISurfaceAllocator*, TextureFlags, TextureAllocationFlags) const override { return nullptr; }
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface*) override { return false; }
|
||||
|
||||
virtual TextureFlags GetTextureFlags() const override
|
||||
virtual gfx::IntSize GetSize() const
|
||||
{
|
||||
return TextureFlags::DEALLOCATE_MAIN_THREAD;
|
||||
return mSize;
|
||||
}
|
||||
|
||||
protected:
|
||||
RefPtr<IUnknown> mHoldRefs[3];
|
||||
HANDLE mHandles[3];
|
||||
gfx::IntSize mSize;
|
||||
gfx::IntSize mSizeY;
|
||||
gfx::IntSize mSizeCbCr;
|
||||
virtual bool HasInternalBuffer() const override{ return true; }
|
||||
|
||||
// This TextureClient should not be used in a context where we use CreateSimilar
|
||||
// (ex. component alpha) because the underlying texture data is always created by
|
||||
// an external producer.
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags, TextureAllocationFlags) const override{ return nullptr; }
|
||||
|
||||
private:
|
||||
virtual void FinalizeOnIPDLThread() override;
|
||||
|
||||
RefPtr<IUnknown> mHoldRefs[3];
|
||||
HANDLE mHandles[3];
|
||||
gfx::IntSize mSize;
|
||||
gfx::IntSize mSizeY;
|
||||
gfx::IntSize mSizeCbCr;
|
||||
bool mIsLocked;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* TextureSource that provides with the necessary APIs to be composited by a
|
||||
* CompositorD3D11.
|
||||
|
@ -302,13 +267,6 @@ protected:
|
|||
|
||||
};
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
CreateD3D11TextureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
|
||||
ID3D11Device* aDevice,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
|
||||
/**
|
||||
* A TextureHost for shared D3D11 textures.
|
||||
*/
|
||||
|
@ -369,7 +327,7 @@ public:
|
|||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
virtual gfx::IntSize GetSize() const override{ return mSize; }
|
||||
|
||||
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
|
||||
{
|
||||
|
@ -415,9 +373,9 @@ class SyncObjectD3D11 : public SyncObject
|
|||
{
|
||||
public:
|
||||
SyncObjectD3D11(SyncHandle aSyncHandle);
|
||||
virtual void FinalizeFrame();
|
||||
|
||||
virtual SyncType GetSyncType() { return SyncType::D3D11; }
|
||||
virtual void FinalizeFrame();
|
||||
|
||||
void RegisterTexture(ID3D11Texture2D* aTexture);
|
||||
void RegisterTexture(ID3D10Texture2D* aTexture);
|
||||
|
|
|
@ -442,54 +442,45 @@ DataTextureSourceD3D9::GetTileRect()
|
|||
return GetTileRect(mCurrentTile);
|
||||
}
|
||||
|
||||
|
||||
D3D9TextureData::D3D9TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
IDirect3DTexture9* aTexture)
|
||||
: mTexture(aTexture)
|
||||
, mSize(aSize)
|
||||
, mFormat(aFormat)
|
||||
, mNeedsClear(false)
|
||||
, mNeedsClearWhite(false)
|
||||
TextureClientD3D9::TextureClientD3D9(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags)
|
||||
: TextureClient(aAllocator, aFlags)
|
||||
, mFormat(aFormat)
|
||||
, mIsLocked(false)
|
||||
, mNeedsClear(false)
|
||||
, mNeedsClearWhite(false)
|
||||
, mLockRect(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(D3D9TextureData);
|
||||
MOZ_COUNT_CTOR(TextureClientD3D9);
|
||||
}
|
||||
|
||||
D3D9TextureData::~D3D9TextureData()
|
||||
TextureClientD3D9::~TextureClientD3D9()
|
||||
{
|
||||
MOZ_COUNT_DTOR(D3D9TextureData);
|
||||
MOZ_COUNT_DTOR(TextureClientD3D9);
|
||||
}
|
||||
|
||||
D3D9TextureData*
|
||||
D3D9TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureAllocationFlags aAllocFlags)
|
||||
already_AddRefed<TextureClient>
|
||||
TextureClientD3D9::CreateSimilar(TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const
|
||||
{
|
||||
_D3DFORMAT format = SurfaceFormatToD3D9Format(aFormat);
|
||||
DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
|
||||
RefPtr<IDirect3DTexture9> d3d9Texture = deviceManager ? deviceManager->CreateTexture(aSize, format,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
nullptr)
|
||||
: nullptr;
|
||||
if (!d3d9Texture) {
|
||||
NS_WARNING("Could not create a d3d9 texture");
|
||||
RefPtr<TextureClient> tex = new TextureClientD3D9(mAllocator, mFormat,
|
||||
mFlags | aFlags);
|
||||
|
||||
if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
|
||||
return nullptr;
|
||||
}
|
||||
D3D9TextureData* data = new D3D9TextureData(aSize, aFormat, d3d9Texture);
|
||||
|
||||
data->mNeedsClear = aAllocFlags & ALLOC_CLEAR_BUFFER;
|
||||
data->mNeedsClearWhite = aAllocFlags & ALLOC_CLEAR_BUFFER_WHITE;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
TextureData*
|
||||
D3D9TextureData::CreateSimilar(ISurfaceAllocator*, TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const
|
||||
{
|
||||
return D3D9TextureData::Create(mSize, mFormat, aAllocFlags);
|
||||
return tex.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
D3D9TextureData::Lock(OpenMode aMode, FenceHandle*)
|
||||
TextureClientD3D9::Lock(OpenMode aMode)
|
||||
{
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
if (!IsValid() || !IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gfxWindowsPlatform::GetPlatform()->GetD3D9Device()) {
|
||||
// If the device has failed then we should not lock the surface,
|
||||
// even if we could.
|
||||
|
@ -504,44 +495,71 @@ D3D9TextureData::Lock(OpenMode aMode, FenceHandle*)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mIsLocked = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
D3D9TextureData::Unlock()
|
||||
TextureClientD3D9::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!");
|
||||
if (!mIsLocked) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget->Flush();
|
||||
mDrawTarget = nullptr;
|
||||
}
|
||||
|
||||
if (mLockRect) {
|
||||
mD3D9Surface->UnlockRect();
|
||||
mLockRect = false;
|
||||
}
|
||||
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
bool
|
||||
D3D9TextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
TextureClientD3D9::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
if (!IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mTexture->AddRef(); // Release in TextureHostD3D9::TextureHostD3D9
|
||||
aOutDescriptor = SurfaceDescriptorD3D9(reinterpret_cast<uintptr_t>(mTexture.get()));
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DrawTarget>
|
||||
D3D9TextureData::BorrowDrawTarget()
|
||||
gfx::DrawTarget*
|
||||
TextureClientD3D9::BorrowDrawTarget()
|
||||
{
|
||||
MOZ_ASSERT(mD3D9Surface);
|
||||
if (!mD3D9Surface) {
|
||||
MOZ_ASSERT(mIsLocked && mD3D9Surface);
|
||||
if (!mIsLocked || !mD3D9Surface) {
|
||||
NS_WARNING("Calling BorrowDrawTarget on an Unlocked TextureClient");
|
||||
gfxCriticalNote << "BorrowDrawTarget on an Unlocked TextureClient";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> dt;
|
||||
if (mDrawTarget) {
|
||||
return mDrawTarget;
|
||||
}
|
||||
|
||||
if (ContentForFormat(mFormat) == gfxContentType::COLOR) {
|
||||
RefPtr<gfxASurface> surface = new gfxWindowsSurface(mD3D9Surface);
|
||||
if (!surface || surface->CairoStatus()) {
|
||||
NS_WARNING("Could not create gfxASurface for d3d9 surface");
|
||||
NS_WARNING("Could not create surface for d3d9 surface");
|
||||
gfxCriticalNote << "Failed creation on D3D9";
|
||||
return nullptr;
|
||||
}
|
||||
dt = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, mSize);
|
||||
|
||||
if (!dt) {
|
||||
return nullptr;
|
||||
mDrawTarget =
|
||||
gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, mSize);
|
||||
if (!mDrawTarget) {
|
||||
gfxCriticalNote << "Bad draw target creation for surface D3D9 " << mSize;
|
||||
}
|
||||
} else {
|
||||
// gfxWindowsSurface don't support transparency so we can't use the d3d9
|
||||
|
@ -553,31 +571,31 @@ D3D9TextureData::BorrowDrawTarget()
|
|||
gfxCriticalError() << "Failed to lock rect borrowing the target in D3D9 " << hexa(hr);
|
||||
return nullptr;
|
||||
}
|
||||
dt = gfxPlatform::GetPlatform()->CreateDrawTargetForData((uint8_t*)rect.pBits, mSize,
|
||||
rect.Pitch, mFormat);
|
||||
if (!dt) {
|
||||
return nullptr;
|
||||
mDrawTarget =
|
||||
gfxPlatform::GetPlatform()->CreateDrawTargetForData((uint8_t*)rect.pBits, mSize,
|
||||
rect.Pitch, mFormat);
|
||||
if (!mDrawTarget) {
|
||||
gfxCriticalNote << "Bad draw target creation for data D3D9 " << mSize << ", " << (int)mFormat;
|
||||
}
|
||||
|
||||
mLockRect = true;
|
||||
mLockRect = true;
|
||||
}
|
||||
|
||||
if (mNeedsClear) {
|
||||
dt->ClearRect(Rect(0, 0, GetSize().width, GetSize().height));
|
||||
mDrawTarget->ClearRect(Rect(0, 0, GetSize().width, GetSize().height));
|
||||
mNeedsClear = false;
|
||||
}
|
||||
if (mNeedsClearWhite) {
|
||||
dt->FillRect(Rect(0, 0, GetSize().width, GetSize().height), ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
|
||||
mDrawTarget->FillRect(Rect(0, 0, GetSize().width, GetSize().height), ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
|
||||
mNeedsClearWhite = false;
|
||||
}
|
||||
|
||||
return dt.forget();
|
||||
return mDrawTarget;
|
||||
}
|
||||
|
||||
bool
|
||||
D3D9TextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
void
|
||||
TextureClientD3D9::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
{
|
||||
MOZ_ASSERT(mD3D9Surface);
|
||||
MOZ_ASSERT(mIsLocked && mD3D9Surface);
|
||||
|
||||
// gfxWindowsSurface don't support transparency so we can't use the d3d9
|
||||
// windows surface optimization.
|
||||
|
@ -586,21 +604,25 @@ D3D9TextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
|||
HRESULT hr = mD3D9Surface->LockRect(&rect, nullptr, 0);
|
||||
if (FAILED(hr) || !rect.pBits) {
|
||||
gfxCriticalError() << "Failed to lock rect borrowing the target in D3D9 " << hexa(hr);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
|
||||
|
||||
if (!srcSurf) {
|
||||
gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
|
||||
mD3D9Surface->UnlockRect();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSize != srcSurf->GetSize() || mFormat != srcSurf->GetFormat()) {
|
||||
gfxCriticalError() << "Attempt to update texture client from a surface with a different size or format! This: " << mSize << " " << mFormat << " Other: " << srcSurf->GetSize() << " " << srcSurf->GetFormat();
|
||||
return;
|
||||
}
|
||||
|
||||
DataSourceSurface::MappedSurface sourceMap;
|
||||
if (!srcSurf->Map(DataSourceSurface::READ, &sourceMap)) {
|
||||
gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int y = 0; y < srcSurf->GetSize().height; y++) {
|
||||
|
@ -611,65 +633,94 @@ D3D9TextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
|||
|
||||
srcSurf->Unmap();
|
||||
mD3D9Surface->UnlockRect();
|
||||
}
|
||||
|
||||
bool
|
||||
TextureClientD3D9::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(!IsAllocated());
|
||||
mSize = aSize;
|
||||
_D3DFORMAT format = SurfaceFormatToD3D9Format(mFormat);
|
||||
|
||||
DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
|
||||
if (!deviceManager ||
|
||||
!(mTexture = deviceManager->CreateTexture(mSize, format, D3DPOOL_SYSTEMMEM, nullptr))) {
|
||||
NS_WARNING("Could not create d3d9 texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
mNeedsClear = aFlags & ALLOC_CLEAR_BUFFER;
|
||||
mNeedsClearWhite = aFlags & ALLOC_CLEAR_BUFFER_WHITE;
|
||||
|
||||
MOZ_ASSERT(mTexture);
|
||||
return true;
|
||||
}
|
||||
|
||||
DXGID3D9TextureData::DXGID3D9TextureData(gfx::SurfaceFormat aFormat,
|
||||
IDirect3DTexture9* aTexture, HANDLE aHandle,
|
||||
IDirect3DDevice9* aDevice)
|
||||
: mFormat(aFormat)
|
||||
, mTexture(aTexture)
|
||||
, mHandle(aHandle)
|
||||
, mDevice(aDevice)
|
||||
SharedTextureClientD3D9::SharedTextureClientD3D9(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags)
|
||||
: TextureClient(aAllocator, aFlags)
|
||||
, mFormat(aFormat)
|
||||
, mHandle(0)
|
||||
, mIsLocked(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(DXGID3D9TextureData);
|
||||
MOZ_COUNT_CTOR(SharedTextureClientD3D9);
|
||||
}
|
||||
|
||||
DXGID3D9TextureData::~DXGID3D9TextureData()
|
||||
SharedTextureClientD3D9::~SharedTextureClientD3D9()
|
||||
{
|
||||
gfxWindowsPlatform::sD3D9SharedTextureUsed -= mDesc.Width * mDesc.Height * 4;
|
||||
MOZ_COUNT_DTOR(DXGID3D9TextureData);
|
||||
MOZ_COUNT_DTOR(SharedTextureClientD3D9);
|
||||
if (mTexture) {
|
||||
gfxWindowsPlatform::sD3D9SharedTextureUsed -= mDesc.Width * mDesc.Height * 4;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SharedTextureClientD3D9::FinalizeOnIPDLThread()
|
||||
{
|
||||
if (mTexture && mActor) {
|
||||
KeepUntilFullDeallocation(MakeUnique<TKeepAlive<IDirect3DTexture9>>(mTexture));
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
DXGID3D9TextureData*
|
||||
DXGID3D9TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
IDirect3DDevice9* aDevice)
|
||||
already_AddRefed<SharedTextureClientD3D9>
|
||||
SharedTextureClientD3D9::Create(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
IDirect3DDevice9* aDevice,
|
||||
const gfx::IntSize& aSize)
|
||||
{
|
||||
MOZ_ASSERT(aFormat == gfx::SurfaceFormat::B8G8R8X8);
|
||||
if (aFormat != gfx::SurfaceFormat::B8G8R8X8) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<IDirect3DTexture9> texture;
|
||||
HANDLE shareHandle = nullptr;
|
||||
HRESULT hr = aDevice->CreateTexture(aSize.width, aSize.height,
|
||||
HRESULT hr = aDevice->CreateTexture(aSize.width,
|
||||
aSize.height,
|
||||
1,
|
||||
D3DUSAGE_RENDERTARGET,
|
||||
D3DFMT_X8R8G8B8,
|
||||
D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(texture),
|
||||
&shareHandle);
|
||||
if (FAILED(hr) || !shareHandle) {
|
||||
return nullptr;
|
||||
}
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr) && shareHandle, nullptr);
|
||||
|
||||
D3DSURFACE_DESC surfaceDesc;
|
||||
hr = texture->GetLevelDesc(0, &surfaceDesc);
|
||||
if (FAILED(hr)) {
|
||||
return nullptr;
|
||||
}
|
||||
DXGID3D9TextureData* data = new DXGID3D9TextureData(aFormat, texture, shareHandle, aDevice);
|
||||
data->mDesc = surfaceDesc;
|
||||
RefPtr<SharedTextureClientD3D9> client =
|
||||
new SharedTextureClientD3D9(aAllocator,
|
||||
aFormat,
|
||||
aFlags);
|
||||
|
||||
client->mDevice = aDevice;
|
||||
client->mTexture = texture;
|
||||
client->mHandle = shareHandle;
|
||||
texture->GetLevelDesc(0, &client->mDesc);
|
||||
|
||||
gfxWindowsPlatform::sD3D9SharedTextureUsed += aSize.width * aSize.height * 4;
|
||||
return data;
|
||||
return client.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<IDirect3DSurface9>
|
||||
DXGID3D9TextureData::GetD3D9Surface() const
|
||||
SharedTextureClientD3D9::GetD3D9Surface() const
|
||||
{
|
||||
RefPtr<IDirect3DSurface9> textureSurface;
|
||||
HRESULT hr = mTexture->GetSurfaceLevel(0, getter_AddRefs(textureSurface));
|
||||
|
@ -679,12 +730,33 @@ DXGID3D9TextureData::GetD3D9Surface() const
|
|||
}
|
||||
|
||||
bool
|
||||
DXGID3D9TextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
SharedTextureClientD3D9::Lock(OpenMode)
|
||||
{
|
||||
aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)(mHandle), mFormat, GetSize());
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
if (!IsValid()) {
|
||||
return false;
|
||||
}
|
||||
mIsLocked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SharedTextureClientD3D9::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked, "Unlock called while the texture is not locked!");
|
||||
}
|
||||
|
||||
bool
|
||||
SharedTextureClientD3D9::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
if (!IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)(mHandle), mFormat, GetSize());
|
||||
return true;
|
||||
}
|
||||
|
||||
TextureHostD3D9::TextureHostD3D9(TextureFlags aFlags,
|
||||
const SurfaceDescriptorD3D9& aDescriptor)
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "mozilla/GfxMessageUtils.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "d3d9.h"
|
||||
#include <vector>
|
||||
|
@ -175,47 +174,52 @@ protected:
|
|||
* Needs a D3D9 context on the client side.
|
||||
* The corresponding TextureHost is TextureHostD3D9.
|
||||
*/
|
||||
class D3D9TextureData : public TextureData
|
||||
class TextureClientD3D9 : public TextureClient
|
||||
{
|
||||
public:
|
||||
~D3D9TextureData();
|
||||
TextureClientD3D9(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags);
|
||||
|
||||
virtual bool SupportsMoz2D() const override { return true; }
|
||||
virtual ~TextureClientD3D9();
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
// TextureClient
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
|
||||
virtual bool IsAllocated() const override { return !!mTexture; }
|
||||
|
||||
virtual bool Lock(OpenMode aMode, FenceHandle*) override;
|
||||
virtual bool Lock(OpenMode aOpenMode) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
|
||||
virtual bool IsLocked() const override { return mIsLocked; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
virtual gfx::IntSize GetSize() const { return mSize; }
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
virtual gfx::SurfaceFormat GetFormat() const { return mFormat; }
|
||||
|
||||
virtual TextureData*
|
||||
CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const override;
|
||||
virtual bool CanExposeDrawTarget() const override { return true; }
|
||||
|
||||
static D3D9TextureData*
|
||||
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
|
||||
virtual gfx::DrawTarget* BorrowDrawTarget() override;
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator* aAllocator) {}
|
||||
virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
protected:
|
||||
D3D9TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
IDirect3DTexture9* aTexture);
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize,
|
||||
TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
private:
|
||||
RefPtr<IDirect3DTexture9> mTexture;
|
||||
RefPtr<IDirect3DSurface9> mD3D9Surface;
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
gfx::IntSize mSize;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
bool mIsLocked;
|
||||
bool mNeedsClear;
|
||||
bool mNeedsClearWhite;
|
||||
bool mLockRect;
|
||||
|
@ -226,27 +230,49 @@ protected:
|
|||
* At the moment it is only used with D3D11 compositing, and the corresponding
|
||||
* TextureHost is DXGITextureHostD3D11.
|
||||
*/
|
||||
class DXGID3D9TextureData : public TextureData
|
||||
class SharedTextureClientD3D9 : public TextureClient
|
||||
{
|
||||
public:
|
||||
static DXGID3D9TextureData*
|
||||
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureFlags aFlags, IDirect3DDevice9* aDevice);
|
||||
SharedTextureClientD3D9(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags);
|
||||
|
||||
~DXGID3D9TextureData();
|
||||
virtual ~SharedTextureClientD3D9();
|
||||
|
||||
virtual gfx::IntSize GetSize() const { return gfx::IntSize(mDesc.Width, mDesc.Height); }
|
||||
// Creates a TextureClient and init width.
|
||||
static already_AddRefed<SharedTextureClientD3D9>
|
||||
Create(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
IDirect3DDevice9* aDevice,
|
||||
const gfx::IntSize& aSize);
|
||||
|
||||
// TextureClient
|
||||
|
||||
virtual bool IsAllocated() const override { return !!mTexture; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
|
||||
virtual bool Lock(OpenMode aOpenMode) override;
|
||||
|
||||
virtual void Unlock() override {}
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
virtual bool IsLocked() const override { return mIsLocked; }
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return false; }
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator* aAllocator) {}
|
||||
virtual gfx::IntSize GetSize() const
|
||||
{
|
||||
return gfx::IntSize(mDesc.Width, mDesc.Height);
|
||||
}
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
|
||||
// This TextureClient should not be used in a context where we use CreateSimilar
|
||||
// (ex. component alpha) because the underlying texture data is always created by
|
||||
// an external producer.
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags, TextureAllocationFlags) const override { return nullptr; }
|
||||
|
||||
IDirect3DDevice9* GetD3D9Device() { return mDevice; }
|
||||
IDirect3DTexture9* GetD3D9Texture() { return mTexture; }
|
||||
|
@ -258,16 +284,15 @@ public:
|
|||
return mDesc;
|
||||
}
|
||||
|
||||
protected:
|
||||
DXGID3D9TextureData(gfx::SurfaceFormat aFormat,
|
||||
IDirect3DTexture9* aTexture, HANDLE aHandle,
|
||||
IDirect3DDevice9* aDevice);
|
||||
private:
|
||||
virtual void FinalizeOnIPDLThread() override;
|
||||
|
||||
RefPtr<IDirect3DDevice9> mDevice;
|
||||
RefPtr<IDirect3DTexture9> mTexture;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
HANDLE mHandle;
|
||||
D3DSURFACE_DESC mDesc;
|
||||
bool mIsLocked;
|
||||
};
|
||||
|
||||
class TextureHostD3D9 : public TextureHost
|
||||
|
|
|
@ -107,6 +107,12 @@ public:
|
|||
CompositableClient* aCompositable,
|
||||
TextureClient* aTexture) {}
|
||||
|
||||
/**
|
||||
* Tell the compositor side to delete the TextureHost corresponding to the
|
||||
* TextureClient passed in parameter.
|
||||
*/
|
||||
virtual void RemoveTexture(TextureClient* aTexture) = 0;
|
||||
|
||||
/**
|
||||
* Holds a reference to a TextureClient until after the next
|
||||
* compositor transaction, and then drops it.
|
||||
|
|
|
@ -198,7 +198,7 @@ static void ImageBridgeShutdownStep1(ReentrantMonitor *aBarrier, bool *aDone)
|
|||
for (int i = textures.Length() - 1; i >= 0; --i) {
|
||||
RefPtr<TextureClient> client = TextureClient::AsTextureClient(textures[i]);
|
||||
if (client) {
|
||||
client->Destroy();
|
||||
client->ForceRemove();
|
||||
}
|
||||
}
|
||||
sImageBridgeChildSingleton->SendWillStop();
|
||||
|
@ -766,7 +766,7 @@ bool InImageBridgeChildThread()
|
|||
|
||||
MessageLoop * ImageBridgeChild::GetMessageLoop() const
|
||||
{
|
||||
return sImageBridgeChildThread ? sImageBridgeChildThread->message_loop() : nullptr;
|
||||
return sImageBridgeChildThread->message_loop();
|
||||
}
|
||||
|
||||
void ImageBridgeChild::ConnectAsync(ImageBridgeParent* aParent)
|
||||
|
@ -1130,6 +1130,38 @@ ImageBridgeChild::RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aA
|
|||
aAsyncTransactionTracker);
|
||||
}
|
||||
|
||||
static void RemoveTextureSync(TextureClient* aTexture, ReentrantMonitor* aBarrier, bool* aDone)
|
||||
{
|
||||
aTexture->ForceRemove();
|
||||
|
||||
ReentrantMonitorAutoEnter autoMon(*aBarrier);
|
||||
*aDone = true;
|
||||
aBarrier->NotifyAll();
|
||||
}
|
||||
|
||||
void ImageBridgeChild::RemoveTexture(TextureClient* aTexture)
|
||||
{
|
||||
if (InImageBridgeChildThread()) {
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
aTexture->ForceRemove();
|
||||
return;
|
||||
}
|
||||
|
||||
ReentrantMonitor barrier("RemoveTexture Lock");
|
||||
ReentrantMonitorAutoEnter autoMon(barrier);
|
||||
bool done = false;
|
||||
|
||||
sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(&RemoveTextureSync, aTexture, &barrier, &done));
|
||||
|
||||
// should stop the thread until the ImageClient has been created on
|
||||
// the other thread
|
||||
while (!done) {
|
||||
barrier.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
bool ImageBridgeChild::IsSameProcess() const
|
||||
{
|
||||
return OtherPid() == base::GetCurrentProcId();
|
||||
|
|
|
@ -259,6 +259,8 @@ public:
|
|||
CompositableClient* aCompositable,
|
||||
TextureClient* aTexture) override;
|
||||
|
||||
virtual void RemoveTexture(TextureClient* aTexture) override;
|
||||
|
||||
virtual void UseTiledLayerBuffer(CompositableClient* aCompositable,
|
||||
const SurfaceDescriptorTiles& aTileLayerDescriptor) override
|
||||
{
|
||||
|
|
|
@ -40,7 +40,7 @@ LayerTransactionChild::Destroy()
|
|||
for (auto iter = textures.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
TextureClient* texture = TextureClient::AsTextureClient(iter.Get()->GetKey());
|
||||
if (texture) {
|
||||
texture->Destroy();
|
||||
texture->ForceRemove();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -470,6 +470,38 @@ ShadowLayerForwarder::InWorkerThread()
|
|||
return MessageLoop::current() && (GetMessageLoop()->id() == MessageLoop::current()->id());
|
||||
}
|
||||
|
||||
static void RemoveTextureWorker(TextureClient* aTexture, ReentrantMonitor* aBarrier, bool* aDone)
|
||||
{
|
||||
aTexture->ForceRemove();
|
||||
|
||||
ReentrantMonitorAutoEnter autoMon(*aBarrier);
|
||||
*aDone = true;
|
||||
aBarrier->NotifyAll();
|
||||
}
|
||||
|
||||
void
|
||||
ShadowLayerForwarder::RemoveTexture(TextureClient* aTexture)
|
||||
{
|
||||
MOZ_ASSERT(aTexture);
|
||||
if (InWorkerThread()) {
|
||||
aTexture->ForceRemove();
|
||||
return;
|
||||
}
|
||||
|
||||
ReentrantMonitor barrier("ShadowLayerForwarder::RemoveTexture Lock");
|
||||
ReentrantMonitorAutoEnter autoMon(barrier);
|
||||
bool done = false;
|
||||
|
||||
GetMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(&RemoveTextureWorker, aTexture, &barrier, &done));
|
||||
|
||||
// Wait until the TextureClient has been ForceRemoved on the worker thread
|
||||
while (!done) {
|
||||
barrier.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ShadowLayerForwarder::StorePluginWidgetConfigurations(const nsTArray<nsIWidget::Configuration>&
|
||||
aConfigurations)
|
||||
|
|
|
@ -221,6 +221,8 @@ public:
|
|||
CompositableClient* aCompositable,
|
||||
TextureClient* aTexture) override;
|
||||
|
||||
virtual void RemoveTexture(TextureClient* aTexture) override;
|
||||
|
||||
/**
|
||||
* Communicate to the compositor that aRegion in the texture identified by aLayer
|
||||
* and aIdentifier has been updated to aThebesBuffer.
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
|
||||
#include "mozilla/layers/ImageClient.h" // for ImageClient
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/BufferTexture.h"
|
||||
#include "mozilla/layers/TextureClient.h" // for BufferTextureClient, etc
|
||||
#include "mozilla/layers/YCbCrImageDataSerializer.h"
|
||||
#include "mozilla/layers/ImageBridgeChild.h" // for ImageBridgeChild
|
||||
#include "mozilla/mozalloc.h" // for operator delete
|
||||
|
@ -66,9 +65,7 @@ SharedPlanarYCbCrImage::GetTextureClient(CompositableClient* aClient)
|
|||
uint8_t*
|
||||
SharedPlanarYCbCrImage::GetBuffer()
|
||||
{
|
||||
// This should never be used
|
||||
MOZ_ASSERT(false);
|
||||
return nullptr;
|
||||
return mTextureClient ? mTextureClient->GetBuffer() : nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::SourceSurface>
|
||||
|
@ -92,13 +89,15 @@ SharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData)
|
|||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mTextureClient->AsTextureClientYCbCr());
|
||||
|
||||
TextureClientAutoLock autoLock(mTextureClient, OpenMode::OPEN_WRITE_ONLY);
|
||||
if (!autoLock.Succeeded()) {
|
||||
MOZ_ASSERT(false, "Failed to lock the texture.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!UpdateYCbCrTextureClient(mTextureClient, aData)) {
|
||||
if (!mTextureClient->AsTextureClientYCbCr()->UpdateYCbCr(aData)) {
|
||||
MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient");
|
||||
return false;
|
||||
}
|
||||
|
@ -129,18 +128,8 @@ SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
|
|||
// update buffer size
|
||||
mBufferSize = size;
|
||||
|
||||
MappedYCbCrTextureData mapped;
|
||||
if (mTextureClient->BorrowMappedYCbCrData(mapped)) {
|
||||
// The caller expects a pointer to the beginning of the writable part of the
|
||||
// buffer (after the metadata) which is where the y channel starts by default.
|
||||
// The caller might choose to write the y channel at a different offset and
|
||||
// if it does so, it will also update the metadata.
|
||||
// Anyway, we return the y channel here but the intent is to obtain the start of
|
||||
// the writable part of the buffer.
|
||||
return mapped.y.data;
|
||||
} else {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
|
||||
return serializer.GetData();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -158,11 +147,7 @@ SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
|
|||
* with AllocateAndGetNewBuffer(), that we subtract from the Y, Cb, Cr
|
||||
* channels to compute 0-based offsets to pass to InitializeBufferInfo.
|
||||
*/
|
||||
MappedYCbCrTextureData mapped;
|
||||
if(!mTextureClient->BorrowMappedYCbCrData(mapped)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
YCbCrImageDataSerializer serializer(mapped.metadata, mBufferSize);
|
||||
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
|
||||
uint8_t *base = serializer.GetData();
|
||||
uint32_t yOffset = aData.mYChannel - base;
|
||||
uint32_t cbOffset = aData.mCbChannel - base;
|
||||
|
@ -198,18 +183,15 @@ SharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData)
|
|||
return false;
|
||||
}
|
||||
|
||||
MappedYCbCrTextureData mapped;
|
||||
// The locking here is sort of a lie. The SharedPlanarYCbCrImage just pulls
|
||||
// pointers out of the TextureClient and keeps them around, which works only
|
||||
// because the underlyin BufferTextureData is always mapped in memory even outside
|
||||
// of the lock/unlock interval. That's sad and new code should follow this example.
|
||||
if (!mTextureClient->Lock(OpenMode::OPEN_READ) || !mTextureClient->BorrowMappedYCbCrData(mapped)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
|
||||
serializer.InitializeBufferInfo(aData.mYSize,
|
||||
aData.mCbCrSize,
|
||||
aData.mStereoMode);
|
||||
MOZ_ASSERT(serializer.IsValid());
|
||||
|
||||
aData.mYChannel = mapped.y.data;
|
||||
aData.mCbChannel = mapped.cb.data;
|
||||
aData.mCrChannel = mapped.cr.data;
|
||||
aData.mYChannel = serializer.GetYData();
|
||||
aData.mCbChannel = serializer.GetCbData();
|
||||
aData.mCrChannel = serializer.GetCrData();
|
||||
|
||||
// copy some of aData's values in mData (most of them)
|
||||
mData.mYChannel = aData.mYChannel;
|
||||
|
@ -236,8 +218,6 @@ SharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData)
|
|||
mData.mCbCrSize);
|
||||
mSize = mData.mPicSize;
|
||||
|
||||
mTextureClient->Unlock();
|
||||
|
||||
return mBufferSize > 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class BufferTextureClient;
|
||||
class ImageClient;
|
||||
class TextureClient;
|
||||
|
||||
|
@ -50,7 +51,7 @@ public:
|
|||
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
private:
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
RefPtr<BufferTextureClient> mTextureClient;
|
||||
RefPtr<ImageClient> mCompositable;
|
||||
};
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
#include "gfx2DGlue.h" // for ImageFormatToSurfaceFormat, etc
|
||||
#include "gfxPlatform.h" // for gfxPlatform, gfxImageFormat
|
||||
#include "mozilla/gfx/Point.h" // for IntSIze
|
||||
#include "mozilla/layers/BufferTexture.h"
|
||||
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator, etc
|
||||
#include "mozilla/layers/ImageClient.h" // for ImageClient
|
||||
#include "mozilla/layers/ImageDataSerializer.h" // for ImageDataSerializer
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
|
||||
#include "mozilla/layers/TextureClient.h" // for BufferTextureClient, etc
|
||||
#include "mozilla/layers/ImageBridgeChild.h" // for ImageBridgeChild
|
||||
|
@ -87,11 +87,12 @@ SharedRGBImage::Allocate(gfx::IntSize aSize, gfx::SurfaceFormat aFormat)
|
|||
uint8_t*
|
||||
SharedRGBImage::GetBuffer()
|
||||
{
|
||||
MappedTextureData mapped;
|
||||
if (mTextureClient && mTextureClient->BorrowMappedData(mapped)) {
|
||||
return mapped.data;
|
||||
if (!mTextureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
return 0;
|
||||
|
||||
ImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
|
||||
return serializer.GetData();
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
|
@ -100,6 +101,13 @@ SharedRGBImage::GetSize()
|
|||
return mSize;
|
||||
}
|
||||
|
||||
size_t
|
||||
SharedRGBImage::GetBufferSize()
|
||||
{
|
||||
return mTextureClient ? mTextureClient->GetBufferSize()
|
||||
: 0;
|
||||
}
|
||||
|
||||
TextureClient*
|
||||
SharedRGBImage::GetTextureClient(CompositableClient* aClient)
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class BufferTextureClient;
|
||||
class ImageClient;
|
||||
class TextureClient;
|
||||
|
||||
|
@ -44,13 +45,15 @@ public:
|
|||
|
||||
gfx::IntSize GetSize() override;
|
||||
|
||||
size_t GetBufferSize();
|
||||
|
||||
already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
|
||||
|
||||
bool Allocate(gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
|
||||
private:
|
||||
gfx::IntSize mSize;
|
||||
RefPtr<ImageClient> mCompositable;
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
RefPtr<BufferTextureClient> mTextureClient;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -116,7 +116,6 @@ EXPORTS.mozilla.layers += [
|
|||
'basic/BasicCompositor.h',
|
||||
'basic/MacIOSurfaceTextureHostBasic.h',
|
||||
'basic/TextureHostBasic.h',
|
||||
'BufferTexture.h',
|
||||
'client/CanvasClient.h',
|
||||
'client/CompositableClient.h',
|
||||
'client/ContentClient.h',
|
||||
|
@ -271,7 +270,6 @@ UNIFIED_SOURCES += [
|
|||
'basic/BasicLayersImpl.cpp',
|
||||
'basic/BasicPaintedLayer.cpp',
|
||||
'basic/TextureHostBasic.cpp',
|
||||
'BufferTexture.cpp',
|
||||
'BufferUnrotate.cpp',
|
||||
'client/CanvasClient.cpp',
|
||||
'client/ClientCanvasLayer.cpp',
|
||||
|
|
|
@ -24,28 +24,153 @@ namespace layers {
|
|||
using namespace mozilla::gfx;
|
||||
using namespace android;
|
||||
|
||||
static bool
|
||||
DisableGralloc(SurfaceFormat aFormat, const gfx::IntSize& aSizeHint)
|
||||
GrallocTextureClientOGL::GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2dBackend,
|
||||
TextureFlags aFlags)
|
||||
: BufferTextureClient(aAllocator, aFormat, aMoz2dBackend, aFlags)
|
||||
, mGrallocHandle(null_t())
|
||||
, mMappedBuffer(nullptr)
|
||||
, mMediaBuffer(nullptr)
|
||||
, mIsOpaque(gfx::IsOpaque(aFormat))
|
||||
{
|
||||
if (gfxPrefs::DisableGralloc()) {
|
||||
return true;
|
||||
}
|
||||
if (aFormat == gfx::SurfaceFormat::A8) {
|
||||
return true;
|
||||
}
|
||||
#if ANDROID_VERSION <= 15
|
||||
// Adreno 200 has a problem of drawing gralloc buffer width less than 64 and
|
||||
// drawing gralloc buffer with a height 9px-16px.
|
||||
// See Bug 983971.
|
||||
if (aSizeHint.width < 64 || aSizeHint.height < 32) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
MOZ_COUNT_CTOR(GrallocTextureClientOGL);
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
GrallocTextureClientOGL::~GrallocTextureClientOGL()
|
||||
{
|
||||
MOZ_COUNT_DTOR(GrallocTextureClientOGL);
|
||||
ISurfaceAllocator* allocator = GetAllocator();
|
||||
if (ShouldDeallocateInDestructor()) {
|
||||
allocator->DeallocGrallocBuffer(&mGrallocHandle);
|
||||
} else {
|
||||
allocator->DropGrallocBuffer(&mGrallocHandle);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
GrallocTextureClientOGL::CreateSimilar(TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const
|
||||
{
|
||||
RefPtr<TextureClient> tex = new GrallocTextureClientOGL(
|
||||
mAllocator, mFormat, mBackend, mFlags | aFlags
|
||||
);
|
||||
|
||||
if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return tex.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
if (!IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aOutDescriptor = NewSurfaceDescriptorGralloc(mGrallocHandle, mIsOpaque);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureClientOGL::SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter)
|
||||
{
|
||||
mRemoveFromCompositableWaiter = aWaiter;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureClientOGL::WaitForBufferOwnership(bool aWaitReleaseFence)
|
||||
{
|
||||
if (mRemoveFromCompositableWaiter) {
|
||||
mRemoveFromCompositableWaiter->WaitComplete();
|
||||
mRemoveFromCompositableWaiter = nullptr;
|
||||
}
|
||||
|
||||
if (!aWaitReleaseFence) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
|
||||
if (mReleaseFenceHandle.IsValid()) {
|
||||
RefPtr<FenceHandle::FdObj> fdObj = mReleaseFenceHandle.GetAndResetFdObj();
|
||||
android::sp<Fence> fence = new Fence(fdObj->GetAndResetFd());
|
||||
#if ANDROID_VERSION == 17
|
||||
fence->waitForever(1000, "GrallocTextureClientOGL::Lock");
|
||||
// 1000 is what Android uses. It is a warning timeout in ms.
|
||||
// This timeout was removed in ANDROID_VERSION 18.
|
||||
#else
|
||||
fence->waitForever("GrallocTextureClientOGL::Lock");
|
||||
#endif
|
||||
mReleaseFenceHandle = FenceHandle();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureClientOGL::Lock(OpenMode aMode)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
if (!IsValid() || !IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mMappedBuffer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
|
||||
WaitForBufferOwnership(false /* aWaitReleaseFence */);
|
||||
#else
|
||||
WaitForBufferOwnership();
|
||||
#endif
|
||||
|
||||
uint32_t usage = 0;
|
||||
if (aMode & OpenMode::OPEN_READ) {
|
||||
usage |= GRALLOC_USAGE_SW_READ_OFTEN;
|
||||
}
|
||||
if (aMode & OpenMode::OPEN_WRITE) {
|
||||
usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
|
||||
}
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
|
||||
RefPtr<FenceHandle::FdObj> fdObj = mReleaseFenceHandle.GetAndResetFdObj();
|
||||
int32_t rv = mGraphicBuffer->lockAsync(usage,
|
||||
reinterpret_cast<void**>(&mMappedBuffer),
|
||||
fdObj->GetAndResetFd());
|
||||
#else
|
||||
int32_t rv = mGraphicBuffer->lock(usage,
|
||||
reinterpret_cast<void**>(&mMappedBuffer));
|
||||
#endif
|
||||
if (rv) {
|
||||
mMappedBuffer = nullptr;
|
||||
NS_WARNING("Couldn't lock graphic buffer");
|
||||
return false;
|
||||
}
|
||||
return BufferTextureClient::Lock(aMode);
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureClientOGL::Unlock()
|
||||
{
|
||||
BufferTextureClient::Unlock();
|
||||
mDrawTarget = nullptr;
|
||||
if (mMappedBuffer) {
|
||||
mMappedBuffer = nullptr;
|
||||
mGraphicBuffer->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
GrallocTextureClientOGL::GetBuffer() const
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
NS_WARN_IF_FALSE(mMappedBuffer, "Trying to get a gralloc buffer without getting the lock?");
|
||||
return mMappedBuffer;
|
||||
}
|
||||
|
||||
static gfx::SurfaceFormat
|
||||
SurfaceFormatForPixelFormat(android::PixelFormat aFormat)
|
||||
{
|
||||
switch (aFormat) {
|
||||
|
@ -60,204 +185,56 @@ SurfaceFormatForPixelFormat(android::PixelFormat aFormat)
|
|||
case HAL_PIXEL_FORMAT_YV12:
|
||||
return gfx::SurfaceFormat::YUV;
|
||||
default:
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
MOZ_CRASH("Unknown gralloc pixel format");
|
||||
}
|
||||
return gfx::SurfaceFormat::R8G8B8A8;
|
||||
}
|
||||
|
||||
bool
|
||||
IsGrallocRBSwapped(gfx::SurfaceFormat aFormat) {
|
||||
switch (aFormat) {
|
||||
case gfx::SurfaceFormat::B8G8R8A8:
|
||||
case gfx::SurfaceFormat::B8G8R8X8:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t GetAndroidFormat(gfx::SurfaceFormat aFormat)
|
||||
{
|
||||
switch (aFormat) {
|
||||
case gfx::SurfaceFormat::R8G8B8A8:
|
||||
case gfx::SurfaceFormat::B8G8R8A8:
|
||||
return android::PIXEL_FORMAT_RGBA_8888;
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
case gfx::SurfaceFormat::B8G8R8X8:
|
||||
return android::PIXEL_FORMAT_RGBX_8888;
|
||||
case gfx::SurfaceFormat::R5G6B5_UINT16:
|
||||
return android::PIXEL_FORMAT_RGB_565;
|
||||
case gfx::SurfaceFormat::YUV:
|
||||
return HAL_PIXEL_FORMAT_YV12;
|
||||
case gfx::SurfaceFormat::A8:
|
||||
NS_WARNING("gralloc does not support SurfaceFormat::A8");
|
||||
default:
|
||||
NS_WARNING("Unsupported surface format");
|
||||
return android::PIXEL_FORMAT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
GrallocTextureData::GrallocTextureData(MaybeMagicGrallocBufferHandle aGrallocHandle,
|
||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend)
|
||||
: mSize(aSize)
|
||||
, mFormat(aFormat)
|
||||
, mMoz2DBackend(aMoz2DBackend)
|
||||
, mGrallocHandle(aGrallocHandle)
|
||||
, mMappedBuffer(nullptr)
|
||||
, mMediaBuffer(nullptr)
|
||||
{
|
||||
mGraphicBuffer = GetGraphicBufferFrom(aGrallocHandle);
|
||||
MOZ_COUNT_CTOR(GrallocTextureData);
|
||||
}
|
||||
|
||||
GrallocTextureData::~GrallocTextureData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(GrallocTextureData);
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureData::Deallocate(ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
MOZ_ASSERT(aAllocator);
|
||||
if (aAllocator) {
|
||||
aAllocator->DeallocGrallocBuffer(&mGrallocHandle);
|
||||
}
|
||||
|
||||
mGrallocHandle = null_t();
|
||||
mGraphicBuffer = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureData::Forget(ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
MOZ_ASSERT(aAllocator);
|
||||
if (aAllocator) {
|
||||
aAllocator->DropGrallocBuffer(&mGrallocHandle);
|
||||
}
|
||||
|
||||
mGrallocHandle = null_t();
|
||||
mGraphicBuffer = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
aOutDescriptor = NewSurfaceDescriptorGralloc(mGrallocHandle, gfx::IsOpaque(mFormat));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureData::WaitForFence(FenceHandle* aFence)
|
||||
{
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION < 21 && ANDROID_VERSION >= 17
|
||||
if (aFence && aFence->IsValid()) {
|
||||
RefPtr<FenceHandle::FdObj> fdObj = aFence->GetAndResetFdObj();
|
||||
android::sp<Fence> fence = new Fence(fdObj->GetAndResetFd());
|
||||
#if ANDROID_VERSION == 17
|
||||
fence->waitForever(1000, "GrallocTextureData::Lock");
|
||||
// 1000 is what Android uses. It is a warning timeout in ms.
|
||||
// This timeout was removed in ANDROID_VERSION 18.
|
||||
#else
|
||||
fence->waitForever("GrallocTextureData::Lock");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureData::Lock(OpenMode aMode, FenceHandle* aReleaseFence)
|
||||
{
|
||||
MOZ_ASSERT(!mMappedBuffer);
|
||||
|
||||
uint32_t usage = 0;
|
||||
if (aMode & OpenMode::OPEN_READ) {
|
||||
usage |= GRALLOC_USAGE_SW_READ_OFTEN;
|
||||
}
|
||||
if (aMode & OpenMode::OPEN_WRITE) {
|
||||
usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
|
||||
}
|
||||
|
||||
void** mappedBufferPtr = reinterpret_cast<void**>(&mMappedBuffer);
|
||||
|
||||
int32_t rv = 0;
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
|
||||
if (aReleaseFence) {
|
||||
RefPtr<FenceHandle::FdObj> fdObj = aReleaseFence->GetAndResetFdObj();
|
||||
rv = mGraphicBuffer->lockAsync(usage, mappedBufferPtr,
|
||||
fdObj->GetAndResetFd());
|
||||
} else {
|
||||
rv = mGraphicBuffer->lock(usage, mappedBufferPtr);
|
||||
}
|
||||
#else
|
||||
// older versions of android don't have lockAsync
|
||||
WaitForFence(aReleaseFence);
|
||||
rv = mGraphicBuffer->lock(usage, mappedBufferPtr);
|
||||
#endif
|
||||
|
||||
if (rv) {
|
||||
mMappedBuffer = nullptr;
|
||||
NS_WARNING("Couldn't lock graphic buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureData::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mMappedBuffer);
|
||||
mMappedBuffer = nullptr;
|
||||
mGraphicBuffer->unlock();
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DrawTarget>
|
||||
GrallocTextureData::BorrowDrawTarget()
|
||||
{
|
||||
MOZ_ASSERT(mMappedBuffer);
|
||||
if (!mMappedBuffer) {
|
||||
return nullptr;
|
||||
}
|
||||
long byteStride = mGraphicBuffer->getStride() * BytesPerPixel(mFormat);
|
||||
return gfxPlatform::GetPlatform()->CreateDrawTargetForData(mMappedBuffer, mSize,
|
||||
byteStride, mFormat);
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureData::BorrowMappedData(MappedTextureData& aMap)
|
||||
{
|
||||
if (mFormat == gfx::SurfaceFormat::YUV || !mMappedBuffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aMap.data = mMappedBuffer;
|
||||
aMap.size = mSize;
|
||||
aMap.stride = mGraphicBuffer->getStride() * BytesPerPixel(mFormat);
|
||||
aMap.format = mFormat;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
gfx::DrawTarget*
|
||||
GrallocTextureClientOGL::BorrowDrawTarget()
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
MOZ_ASSERT(mMappedBuffer, "Calling TextureClient::BorrowDrawTarget without locking :(");
|
||||
|
||||
if (!mMappedBuffer) {
|
||||
return false;
|
||||
if (!IsValid() || !IsAllocated() || !mMappedBuffer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mDrawTarget) {
|
||||
return mDrawTarget;
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat format = SurfaceFormatForPixelFormat(mGraphicBuffer->getPixelFormat());
|
||||
long pixelStride = mGraphicBuffer->getStride();
|
||||
long byteStride = pixelStride * BytesPerPixel(format);
|
||||
mDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForData(GetBuffer(),
|
||||
mSize,
|
||||
byteStride,
|
||||
mFormat);
|
||||
return mDrawTarget;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureClientOGL::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
MOZ_ASSERT(mMappedBuffer, "Calling TextureClient::BorrowDrawTarget without locking :(");
|
||||
|
||||
if (!IsValid() || !IsAllocated() || !mMappedBuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
|
||||
|
||||
if (!srcSurf) {
|
||||
gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat format = SurfaceFormatForPixelFormat(mGraphicBuffer->getPixelFormat());
|
||||
if (mSize != srcSurf->GetSize() || mFormat != srcSurf->GetFormat()) {
|
||||
gfxCriticalError() << "Attempt to update texture client from a surface with a different size or format! This: " << mSize << " " << format << " Other: " << srcSurf->GetSize() << " " << srcSurf->GetFormat();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
long pixelStride = mGraphicBuffer->getStride();
|
||||
|
@ -267,145 +244,160 @@ GrallocTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
|||
|
||||
if (!srcSurf->Map(DataSourceSurface::READ, &sourceMap)) {
|
||||
gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t* buffer = GetBuffer();
|
||||
|
||||
for (int y = 0; y < srcSurf->GetSize().height; y++) {
|
||||
memcpy(mMappedBuffer + byteStride * y,
|
||||
memcpy(buffer + byteStride * y,
|
||||
sourceMap.mData + sourceMap.mStride * y,
|
||||
srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
|
||||
}
|
||||
|
||||
srcSurf->Unmap();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
GrallocTextureData*
|
||||
GrallocTextureData::Create(gfx::IntSize aSize, AndroidFormat aAndroidFormat,
|
||||
gfx::BackendType aMoz2dBackend, uint32_t aUsage,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
bool
|
||||
GrallocTextureClientOGL::AllocateForSurface(gfx::IntSize aSize,
|
||||
TextureAllocationFlags)
|
||||
{
|
||||
if (!aAllocator) {
|
||||
return nullptr;
|
||||
MOZ_ASSERT(IsValid());
|
||||
|
||||
uint32_t format;
|
||||
uint32_t usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN |
|
||||
android::GraphicBuffer::USAGE_SW_WRITE_OFTEN |
|
||||
android::GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
|
||||
switch (mFormat) {
|
||||
case gfx::SurfaceFormat::R8G8B8A8:
|
||||
format = android::PIXEL_FORMAT_RGBA_8888;
|
||||
break;
|
||||
case gfx::SurfaceFormat::B8G8R8A8:
|
||||
format = android::PIXEL_FORMAT_RGBA_8888;
|
||||
mFlags |= TextureFlags::RB_SWAPPED;
|
||||
break;
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
format = android::PIXEL_FORMAT_RGBX_8888;
|
||||
break;
|
||||
case gfx::SurfaceFormat::B8G8R8X8:
|
||||
format = android::PIXEL_FORMAT_RGBX_8888;
|
||||
mFlags |= TextureFlags::RB_SWAPPED;
|
||||
break;
|
||||
case gfx::SurfaceFormat::R5G6B5_UINT16:
|
||||
format = android::PIXEL_FORMAT_RGB_565;
|
||||
break;
|
||||
case gfx::SurfaceFormat::YUV:
|
||||
format = HAL_PIXEL_FORMAT_YV12;
|
||||
break;
|
||||
case gfx::SurfaceFormat::A8:
|
||||
NS_WARNING("gralloc does not support gfx::SurfaceFormat::A8");
|
||||
return false;
|
||||
default:
|
||||
NS_WARNING("Unsupported surface format");
|
||||
return false;
|
||||
}
|
||||
int32_t maxSize = aAllocator->GetMaxTextureSize();
|
||||
if (aSize.width > maxSize || aSize.height > maxSize) {
|
||||
return nullptr;
|
||||
}
|
||||
gfx::SurfaceFormat format;
|
||||
switch (aAndroidFormat) {
|
||||
case android::PIXEL_FORMAT_RGBA_8888:
|
||||
format = gfx::SurfaceFormat::B8G8R8A8;
|
||||
|
||||
return AllocateGralloc(aSize, format, usage);
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureClientOGL::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize, StereoMode aStereoMode)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
return AllocateGralloc(aYSize,
|
||||
HAL_PIXEL_FORMAT_YV12,
|
||||
android::GraphicBuffer::USAGE_SW_READ_OFTEN);
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureClientOGL::AllocateForGLRendering(gfx::IntSize aSize)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
|
||||
uint32_t format;
|
||||
uint32_t usage = android::GraphicBuffer::USAGE_HW_RENDER |
|
||||
android::GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
|
||||
switch (mFormat) {
|
||||
case gfx::SurfaceFormat::R8G8B8A8:
|
||||
case gfx::SurfaceFormat::B8G8R8A8:
|
||||
format = android::PIXEL_FORMAT_RGBA_8888;
|
||||
break;
|
||||
case android::PIXEL_FORMAT_BGRA_8888:
|
||||
format = gfx::SurfaceFormat::B8G8R8A8;
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
case gfx::SurfaceFormat::B8G8R8X8:
|
||||
// there is no android BGRX format?
|
||||
format = android::PIXEL_FORMAT_RGBX_8888;
|
||||
break;
|
||||
case android::PIXEL_FORMAT_RGBX_8888:
|
||||
format = gfx::SurfaceFormat::B8G8R8X8;
|
||||
break;
|
||||
case android::PIXEL_FORMAT_RGB_565:
|
||||
format = gfx::SurfaceFormat::R5G6B5_UINT16;
|
||||
break;
|
||||
case HAL_PIXEL_FORMAT_YV12:
|
||||
format = gfx::SurfaceFormat::YUV;
|
||||
case gfx::SurfaceFormat::R5G6B5_UINT16:
|
||||
format = android::PIXEL_FORMAT_RGB_565;
|
||||
break;
|
||||
default:
|
||||
format = gfx::SurfaceFormat::UNKNOWN;
|
||||
NS_WARNING("Unsupported surface format");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DisableGralloc(format, aSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
return AllocateGralloc(aSize, format, usage);
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureClientOGL::AllocateGralloc(gfx::IntSize aSize,
|
||||
uint32_t aAndroidFormat,
|
||||
uint32_t aUsage)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
ISurfaceAllocator* allocator = GetAllocator();
|
||||
|
||||
MaybeMagicGrallocBufferHandle handle;
|
||||
if (!aAllocator->AllocGrallocBuffer(aSize, aAndroidFormat, aUsage, &handle)) {
|
||||
return nullptr;
|
||||
bool allocateResult =
|
||||
allocator->AllocGrallocBuffer(aSize,
|
||||
aAndroidFormat,
|
||||
aUsage,
|
||||
&handle);
|
||||
if (!allocateResult) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sp<GraphicBuffer> graphicBuffer = GetGraphicBufferFrom(handle);
|
||||
if (!graphicBuffer.get()) {
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (graphicBuffer->initCheck() != NO_ERROR) {
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return new GrallocTextureData(handle, aSize, format, aMoz2dBackend);
|
||||
mGrallocHandle = handle;
|
||||
mGraphicBuffer = graphicBuffer;
|
||||
mSize = aSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
GrallocTextureData*
|
||||
GrallocTextureData::CreateForDrawing(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2dBackend,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
bool
|
||||
GrallocTextureClientOGL::IsAllocated() const
|
||||
{
|
||||
if (DisableGralloc(aFormat, aSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
uint32_t usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN |
|
||||
android::GraphicBuffer::USAGE_SW_WRITE_OFTEN |
|
||||
android::GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
auto data = GrallocTextureData::Create(aSize, GetAndroidFormat(aFormat),
|
||||
aMoz2dBackend, usage, aAllocator);
|
||||
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DebugOnly<gfx::SurfaceFormat> grallocFormat =
|
||||
SurfaceFormatForPixelFormat(data->mGraphicBuffer->getPixelFormat());
|
||||
// mFormat may be different from the format the graphic buffer reports if we
|
||||
// swap the R and B channels but we should always have at least the same bytes
|
||||
// per pixel!
|
||||
MOZ_ASSERT(BytesPerPixel(data->mFormat) == BytesPerPixel(grallocFormat));
|
||||
|
||||
return data;
|
||||
return !!mGraphicBuffer.get();
|
||||
}
|
||||
|
||||
TextureFlags
|
||||
GrallocTextureData::GetTextureFlags() const
|
||||
bool
|
||||
GrallocTextureClientOGL::Allocate(uint32_t aSize)
|
||||
{
|
||||
if (IsGrallocRBSwapped(mFormat)) {
|
||||
return TextureFlags::RB_SWAPPED;
|
||||
}
|
||||
return TextureFlags::NO_FLAGS;
|
||||
// see Bug 908196
|
||||
MOZ_CRASH("This method should never be called.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
GrallocTextureData*
|
||||
GrallocTextureData::CreateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
size_t
|
||||
GrallocTextureClientOGL::GetBufferSize() const
|
||||
{
|
||||
MOZ_ASSERT(aYSize.width == aCbCrSize.width * 2);
|
||||
MOZ_ASSERT(aYSize.height == aCbCrSize.height * 2);
|
||||
return GrallocTextureData::Create(aYSize, HAL_PIXEL_FORMAT_YV12,
|
||||
gfx::BackendType::NONE,
|
||||
android::GraphicBuffer::USAGE_SW_READ_OFTEN,
|
||||
aAllocator);
|
||||
// see Bug 908196
|
||||
MOZ_CRASH("This method should never be called.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// static
|
||||
GrallocTextureData*
|
||||
GrallocTextureData::CreateForGLRendering(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
if (aFormat == gfx::SurfaceFormat::YUV) {
|
||||
return nullptr;
|
||||
}
|
||||
uint32_t usage = android::GraphicBuffer::USAGE_HW_RENDER |
|
||||
android::GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
return GrallocTextureData::Create(aSize, GetAndroidFormat(aFormat),
|
||||
gfx::BackendType::NONE, usage, aAllocator);
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<TextureClient>
|
||||
GrallocTextureData::TextureClientFromSharedSurface(gl::SharedSurface* abstractSurf,
|
||||
TextureFlags flags)
|
||||
/*static*/ already_AddRefed<TextureClient>
|
||||
GrallocTextureClientOGL::FromSharedSurface(gl::SharedSurface* abstractSurf,
|
||||
TextureFlags flags)
|
||||
{
|
||||
auto surf = gl::SharedSurface_Gralloc::Cast(abstractSurf);
|
||||
|
||||
|
@ -426,18 +418,6 @@ GrallocTextureData::TextureClientFromSharedSurface(gl::SharedSurface* abstractSu
|
|||
return ret.forget();
|
||||
}
|
||||
|
||||
TextureData*
|
||||
GrallocTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const
|
||||
{
|
||||
if (mFormat == gfx::SurfaceFormat::YUV) {
|
||||
return GrallocTextureData::CreateForYCbCr(mSize, mSize*2, aAllocator);
|
||||
} else {
|
||||
return GrallocTextureData::CreateForDrawing(mSize, mFormat, mMoz2DBackend, aAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
} // namesapace layers
|
||||
} // namesapace mozilla
|
||||
|
||||
|
|
|
@ -25,110 +25,130 @@ class SharedSurface;
|
|||
|
||||
namespace layers {
|
||||
|
||||
/// A TextureData implementation based on android::GraphicBuffer (also referred to
|
||||
/// as "gralloc").
|
||||
///
|
||||
/// Gralloc lets us map texture data in memory (accessible through pointers)
|
||||
/// and also use it directly as an OpenGL texture without the cost of texture
|
||||
/// uploads.
|
||||
/// Gralloc buffers can also be shared accros processes.
|
||||
///
|
||||
/// More info about Gralloc here: https://wiki.mozilla.org/Platform/GFX/Gralloc
|
||||
///
|
||||
/// This is only used in Firefox OS
|
||||
class GrallocTextureData : public TextureData {
|
||||
/**
|
||||
* A TextureClient implementation based on android::GraphicBuffer (also referred to
|
||||
* as "gralloc").
|
||||
*
|
||||
* Gralloc lets us map texture data in memory (accessible through pointers)
|
||||
* and also use it directly as an OpenGL texture without the cost of texture
|
||||
* uploads.
|
||||
* Gralloc buffers can also be shared accros processes.
|
||||
*
|
||||
* More info about Gralloc here: https://wiki.mozilla.org/Platform/GFX/Gralloc
|
||||
*
|
||||
* This is only used in Firefox OS
|
||||
*/
|
||||
class GrallocTextureClientOGL : public BufferTextureClient
|
||||
{
|
||||
public:
|
||||
typedef uint32_t AndroidFormat;
|
||||
GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2dBackend,
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT);
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
~GrallocTextureClientOGL();
|
||||
|
||||
virtual bool Lock(OpenMode aMode, FenceHandle* aFence) override;
|
||||
virtual bool Lock(OpenMode aMode) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
|
||||
|
||||
virtual bool CanExposeMappedData() const override { return true; }
|
||||
|
||||
virtual bool BorrowMappedData(MappedTextureData& aMap) override;
|
||||
|
||||
virtual bool SupportsMoz2D() const override { return true; }
|
||||
virtual bool ImplementsLocking() const override { return true; }
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return false; }
|
||||
|
||||
virtual bool HasSynchronization() const override { return true; }
|
||||
virtual bool IsAllocated() const override;
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator*) override;
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual void Forget(ISurfaceAllocator*) override;
|
||||
virtual void SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) override;
|
||||
|
||||
static GrallocTextureData* CreateForDrawing(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2dBackend,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true) override;
|
||||
|
||||
static GrallocTextureData* CreateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
GrallocTextureClientOGL* AsGrallocTextureClientOGL() override {
|
||||
return this;
|
||||
}
|
||||
|
||||
static GrallocTextureData* CreateForGLRendering(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
void SetTextureFlags(TextureFlags aFlags) { AddFlags(aFlags); }
|
||||
|
||||
static GrallocTextureData* Create(gfx::IntSize aSize, AndroidFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend, uint32_t aUsage,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
android::sp<android::GraphicBuffer> GetGraphicBuffer()
|
||||
{
|
||||
return mGraphicBuffer;
|
||||
}
|
||||
|
||||
static already_AddRefed<TextureClient>
|
||||
TextureClientFromSharedSurface(gl::SharedSurface* abstractSurf, TextureFlags flags);
|
||||
android::PixelFormat GetPixelFormat()
|
||||
{
|
||||
return mGraphicBuffer->getPixelFormat();
|
||||
}
|
||||
|
||||
virtual TextureData*
|
||||
CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
virtual uint8_t* GetBuffer() const override;
|
||||
|
||||
virtual gfx::DrawTarget* BorrowDrawTarget() override;
|
||||
|
||||
virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize,
|
||||
TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
|
||||
|
||||
virtual bool AllocateForYCbCr(gfx::IntSize aYSize,
|
||||
gfx::IntSize aCbCrSize,
|
||||
StereoMode aStereoMode) override;
|
||||
|
||||
bool AllocateForGLRendering(gfx::IntSize aSize);
|
||||
|
||||
bool AllocateGralloc(gfx::IntSize aYSize, uint32_t aAndroidFormat, uint32_t aUsage);
|
||||
|
||||
void SetIsOpaque(bool aIsOpaque) { mIsOpaque = aIsOpaque; }
|
||||
|
||||
virtual bool Allocate(uint32_t aSize) override;
|
||||
|
||||
virtual size_t GetBufferSize() const override;
|
||||
|
||||
/**
|
||||
* Hold android::MediaBuffer.
|
||||
* MediaBuffer needs to be add refed to keep MediaBuffer alive
|
||||
* during TextureClient is in use.
|
||||
*/
|
||||
void SetMediaBuffer(android::MediaBuffer* aMediaBuffer)
|
||||
{
|
||||
mMediaBuffer = aMediaBuffer;
|
||||
}
|
||||
|
||||
android::MediaBuffer* GetMediaBuffer()
|
||||
{
|
||||
return mMediaBuffer;
|
||||
}
|
||||
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
// use TextureClient's default implementation
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
/// Hold android::MediaBuffer.
|
||||
/// MediaBuffer needs to be add refed to keep MediaBuffer alive while the texture
|
||||
/// is in use.
|
||||
///
|
||||
/// TODO - ideally we should be able to put the MediaBuffer in the texture's
|
||||
/// constructor and not expose these methods.
|
||||
void SetMediaBuffer(android::MediaBuffer* aMediaBuffer) { mMediaBuffer = aMediaBuffer; }
|
||||
android::MediaBuffer* GetMediaBuffer() { return mMediaBuffer; }
|
||||
|
||||
android::sp<android::GraphicBuffer> GetGraphicBuffer() { return mGraphicBuffer; }
|
||||
|
||||
virtual void WaitForFence(FenceHandle* aFence) override;
|
||||
|
||||
~GrallocTextureData();
|
||||
|
||||
virtual TextureFlags GetTextureFlags() const override;
|
||||
static already_AddRefed<TextureClient> FromSharedSurface(gl::SharedSurface* surf,
|
||||
TextureFlags flags);
|
||||
|
||||
protected:
|
||||
GrallocTextureData(MaybeMagicGrallocBufferHandle aGrallocHandle,
|
||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend);
|
||||
|
||||
gfx::IntSize mSize;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
gfx::BackendType mMoz2DBackend;
|
||||
|
||||
/**
|
||||
* Unfortunately, until bug 879681 is fixed we need to use a GrallocBufferActor.
|
||||
*/
|
||||
MaybeMagicGrallocBufferHandle mGrallocHandle;
|
||||
|
||||
RefPtr<AsyncTransactionWaiter> mRemoveFromCompositableWaiter;
|
||||
|
||||
android::sp<android::GraphicBuffer> mGraphicBuffer;
|
||||
|
||||
// Points to a mapped gralloc buffer between calls to lock and unlock.
|
||||
// Should be null outside of the lock-unlock pair.
|
||||
/**
|
||||
* Points to a mapped gralloc buffer between calls to lock and unlock.
|
||||
* Should be null outside of the lock-unlock pair.
|
||||
*/
|
||||
uint8_t* mMappedBuffer;
|
||||
|
||||
android::MediaBuffer* mMediaBuffer;
|
||||
};
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
|
||||
gfx::SurfaceFormat SurfaceFormatForPixelFormat(android::PixelFormat aFormat);
|
||||
android::MediaBuffer* mMediaBuffer;
|
||||
|
||||
bool mIsOpaque;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -4,34 +4,71 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "MacIOSurfaceTextureClientOGL.h"
|
||||
#include "mozilla/gfx/MacIOSurface.h"
|
||||
#include "mozilla/gfx/MacIOSurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
MacIOSurfaceTextureData::MacIOSurfaceTextureData(MacIOSurface* aSurface)
|
||||
: mSurface(aSurface)
|
||||
{
|
||||
MOZ_ASSERT(mSurface);
|
||||
}
|
||||
|
||||
MacIOSurfaceTextureData::~MacIOSurfaceTextureData()
|
||||
MacIOSurfaceTextureClientOGL::MacIOSurfaceTextureClientOGL(ISurfaceAllocator* aAllcator,
|
||||
TextureFlags aFlags)
|
||||
: TextureClient(aAllcator, aFlags)
|
||||
, mIsLocked(false)
|
||||
{}
|
||||
|
||||
// static
|
||||
MacIOSurfaceTextureData*
|
||||
MacIOSurfaceTextureData::Create(MacIOSurface* aSurface)
|
||||
MacIOSurfaceTextureClientOGL::~MacIOSurfaceTextureClientOGL()
|
||||
{
|
||||
MOZ_ASSERT(aSurface);
|
||||
if (!aSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureClientOGL::FinalizeOnIPDLThread()
|
||||
{
|
||||
if (mActor && mSurface) {
|
||||
KeepUntilFullDeallocation(MakeUnique<TKeepAlive<MacIOSurface>>(mSurface));
|
||||
}
|
||||
return new MacIOSurfaceTextureData(aSurface);
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<MacIOSurfaceTextureClientOGL>
|
||||
MacIOSurfaceTextureClientOGL::Create(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
MacIOSurface* aSurface)
|
||||
{
|
||||
RefPtr<MacIOSurfaceTextureClientOGL> texture =
|
||||
new MacIOSurfaceTextureClientOGL(aAllocator, aFlags);
|
||||
MOZ_ASSERT(texture->IsValid());
|
||||
MOZ_ASSERT(!texture->IsAllocated());
|
||||
texture->mSurface = aSurface;
|
||||
return texture.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
MacIOSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
MacIOSurfaceTextureClientOGL::Lock(OpenMode aMode)
|
||||
{
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
mIsLocked = true;
|
||||
return IsValid() && IsAllocated();
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureClientOGL::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
bool
|
||||
MacIOSurfaceTextureClientOGL::IsLocked() const
|
||||
{
|
||||
return mIsLocked;
|
||||
}
|
||||
|
||||
bool
|
||||
MacIOSurfaceTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
if (!IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
aOutDescriptor = SurfaceDescriptorMacIOSurface(mSurface->GetIOSurfaceID(),
|
||||
mSurface->GetContentsScaleFactor(),
|
||||
!mSurface->HasAlpha());
|
||||
|
@ -39,19 +76,13 @@ MacIOSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
|||
}
|
||||
|
||||
gfx::IntSize
|
||||
MacIOSurfaceTextureData::GetSize() const
|
||||
MacIOSurfaceTextureClientOGL::GetSize() const
|
||||
{
|
||||
return gfx::IntSize(mSurface->GetDevicePixelWidth(), mSurface->GetDevicePixelHeight());
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
MacIOSurfaceTextureData::GetFormat() const
|
||||
{
|
||||
return mSurface->GetFormat();
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface>
|
||||
MacIOSurfaceTextureData::GetAsSurface()
|
||||
MacIOSurfaceTextureClientOGL::GetAsSurface()
|
||||
{
|
||||
RefPtr<gfx::SourceSurface> surf = mSurface->GetAsSurface();
|
||||
return surf->GetDataSurface();
|
||||
|
|
|
@ -13,36 +13,47 @@ class MacIOSurface;
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class MacIOSurfaceTextureData : public TextureData
|
||||
class MacIOSurfaceTextureClientOGL : public TextureClient
|
||||
{
|
||||
public:
|
||||
static MacIOSurfaceTextureData* Create(MacIOSurface* aSurface);
|
||||
explicit MacIOSurfaceTextureClientOGL(ISurfaceAllocator* aAllcator,
|
||||
TextureFlags aFlags);
|
||||
|
||||
~MacIOSurfaceTextureData();
|
||||
virtual ~MacIOSurfaceTextureClientOGL();
|
||||
|
||||
// Creates a TextureClient and init width.
|
||||
static already_AddRefed<MacIOSurfaceTextureClientOGL>
|
||||
Create(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
MacIOSurface* aSurface);
|
||||
|
||||
virtual bool Lock(OpenMode aMode) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual bool IsLocked() const override;
|
||||
|
||||
virtual bool IsAllocated() const override { return !!mSurface; }
|
||||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual gfx::IntSize GetSize() const override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override;
|
||||
|
||||
virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
|
||||
|
||||
virtual void Unlock() override {}
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return false; }
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator* aAllocator) override { mSurface = nullptr; }
|
||||
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
|
||||
|
||||
virtual void Forget(ISurfaceAllocator* aAllocator) override { mSurface = nullptr; }
|
||||
|
||||
// For debugging purposes only.
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface();
|
||||
// This TextureClient should not be used in a context where we use CreateSimilar
|
||||
// (ex. component alpha) because the underlying texture data is always created by
|
||||
// an external producer.
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags, TextureAllocationFlags) const override { return nullptr; }
|
||||
|
||||
protected:
|
||||
explicit MacIOSurfaceTextureData(MacIOSurface* aSurface);
|
||||
virtual void FinalizeOnIPDLThread() override;
|
||||
|
||||
RefPtr<MacIOSurface> mSurface;
|
||||
bool mIsLocked;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -18,42 +18,33 @@ namespace layers {
|
|||
class CompositableForwarder;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// EGLImage
|
||||
// EGLImageTextureClient
|
||||
|
||||
EGLImageTextureData::EGLImageTextureData(EGLImageImage* aImage, gfx::IntSize aSize)
|
||||
: mImage(aImage)
|
||||
, mSize(aSize)
|
||||
{
|
||||
MOZ_ASSERT(aImage);
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
EGLImageTextureData::CreateTextureClient(EGLImageImage* aImage, gfx::IntSize aSize,
|
||||
ISurfaceAllocator* aAllocator, TextureFlags aFlags)
|
||||
EGLImageTextureClient::EGLImageTextureClient(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
EGLImageImage* aImage,
|
||||
gfx::IntSize aSize)
|
||||
: TextureClient(aAllocator, aFlags)
|
||||
, mImage(aImage)
|
||||
, mSize(aSize)
|
||||
, mIsLocked(false)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess(),
|
||||
"Can't pass an `EGLImage` between processes.");
|
||||
|
||||
if (!aImage || !XRE_IsParentProcess()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// XXX - This is quite sad and slow.
|
||||
aFlags |= TextureFlags::DEALLOCATE_CLIENT;
|
||||
AddFlags(TextureFlags::DEALLOCATE_CLIENT);
|
||||
|
||||
if (aImage->GetOriginPos() == gl::OriginPos::BottomLeft) {
|
||||
aFlags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
|
||||
AddFlags(TextureFlags::ORIGIN_BOTTOM_LEFT);
|
||||
}
|
||||
|
||||
return TextureClient::CreateWithData(
|
||||
new EGLImageTextureData(aImage, aSize),
|
||||
aFlags, aAllocator
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
EGLImageTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
EGLImageTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
MOZ_ASSERT(IsAllocated());
|
||||
|
||||
const bool hasAlpha = true;
|
||||
aOutDescriptor =
|
||||
EGLImageDescriptor((uintptr_t)mImage->GetImage(),
|
||||
|
@ -62,55 +53,84 @@ EGLImageTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
EGLImageTextureClient::Lock(OpenMode mode)
|
||||
{
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
if (!IsValid() || !IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
mIsLocked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
EGLImageTextureClient::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// AndroidSurface
|
||||
// SurfaceTextureClient
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
AndroidSurfaceTextureData::CreateTextureClient(AndroidSurfaceTexture* aSurfTex,
|
||||
gfx::IntSize aSize,
|
||||
gl::OriginPos aOriginPos,
|
||||
ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags)
|
||||
SurfaceTextureClient::SurfaceTextureClient(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
AndroidSurfaceTexture* aSurfTex,
|
||||
gfx::IntSize aSize,
|
||||
gl::OriginPos aOriginPos)
|
||||
: TextureClient(aAllocator, aFlags)
|
||||
, mSurfTex(aSurfTex)
|
||||
, mSize(aSize)
|
||||
, mIsLocked(false)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess(),
|
||||
"Can't pass an android surfaces between processes.");
|
||||
"Can't pass pointers between processes.");
|
||||
|
||||
if (!aSurfTex || !XRE_IsParentProcess()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// XXX - This is quite sad and slow.
|
||||
aFlags |= TextureFlags::DEALLOCATE_CLIENT;
|
||||
// Our data is always owned externally.
|
||||
AddFlags(TextureFlags::DEALLOCATE_CLIENT);
|
||||
|
||||
if (aOriginPos == gl::OriginPos::BottomLeft) {
|
||||
aFlags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
|
||||
AddFlags(TextureFlags::ORIGIN_BOTTOM_LEFT);
|
||||
}
|
||||
|
||||
return TextureClient::CreateWithData(
|
||||
new AndroidSurfaceTextureData(aSurfTex, aSize),
|
||||
aFlags, aAllocator
|
||||
);
|
||||
}
|
||||
|
||||
AndroidSurfaceTextureData::AndroidSurfaceTextureData(AndroidSurfaceTexture* aSurfTex,
|
||||
gfx::IntSize aSize)
|
||||
: mSurfTex(aSurfTex)
|
||||
, mSize(aSize)
|
||||
{}
|
||||
|
||||
AndroidSurfaceTextureData::~AndroidSurfaceTextureData()
|
||||
{}
|
||||
SurfaceTextureClient::~SurfaceTextureClient()
|
||||
{
|
||||
// Our data is always owned externally.
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
SurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
MOZ_ASSERT(IsAllocated());
|
||||
|
||||
aOutDescriptor = SurfaceTextureDescriptor((uintptr_t)mSurfTex.get(),
|
||||
mSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SurfaceTextureClient::Lock(OpenMode mode)
|
||||
{
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
if (!IsValid() || !IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
mIsLocked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceTextureClient::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -20,80 +20,101 @@ namespace mozilla {
|
|||
|
||||
namespace layers {
|
||||
|
||||
class EGLImageTextureData : public TextureData
|
||||
class EGLImageTextureClient : public TextureClient
|
||||
{
|
||||
public:
|
||||
EGLImageTextureClient(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
EGLImageImage* aImage,
|
||||
gfx::IntSize aSize);
|
||||
|
||||
static already_AddRefed<TextureClient>
|
||||
CreateTextureClient(EGLImageImage* aImage, gfx::IntSize aSize,
|
||||
ISurfaceAllocator* aAllocator, TextureFlags aFlags);
|
||||
virtual bool IsAllocated() const override { return true; }
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return false; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator*) override { mImage = nullptr; }
|
||||
// Useless functions.
|
||||
virtual bool Lock(OpenMode mode) override;
|
||||
|
||||
virtual void Forget(ISurfaceAllocator*) override { mImage = nullptr; }
|
||||
virtual void Unlock() override;
|
||||
|
||||
// Unused functions.
|
||||
virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
|
||||
|
||||
virtual void Unlock() override {}
|
||||
virtual bool IsLocked() const override { return mIsLocked; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override
|
||||
{
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
protected:
|
||||
EGLImageTextureData(EGLImageImage* aImage, gfx::IntSize aSize);
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
RefPtr<EGLImageImage> mImage;
|
||||
const gfx::IntSize mSize;
|
||||
bool mIsLocked;
|
||||
};
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
class AndroidSurfaceTextureData : public TextureData
|
||||
class SurfaceTextureClient : public TextureClient
|
||||
{
|
||||
public:
|
||||
static already_AddRefed<TextureClient>
|
||||
CreateTextureClient(gl::AndroidSurfaceTexture* aSurfTex,
|
||||
gfx::IntSize aSize,
|
||||
gl::OriginPos aOriginPos,
|
||||
ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags);
|
||||
SurfaceTextureClient(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
gl::AndroidSurfaceTexture* aSurfTex,
|
||||
gfx::IntSize aSize,
|
||||
gl::OriginPos aOriginPos);
|
||||
|
||||
~AndroidSurfaceTextureData();
|
||||
~SurfaceTextureClient();
|
||||
|
||||
virtual bool IsAllocated() const override { return true; }
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return false; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
virtual gfx::IntSize GetSize() const { return mSize; }
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
// Useless functions.
|
||||
virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
|
||||
virtual bool Lock(OpenMode mode) override;
|
||||
|
||||
virtual void Unlock() override {}
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual bool IsLocked() const override { return mIsLocked; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override
|
||||
{
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
// Our data is always owned externally.
|
||||
virtual void Deallocate(ISurfaceAllocator*) override {}
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
AndroidSurfaceTextureData(gl::AndroidSurfaceTexture* aSurfTex,
|
||||
gfx::IntSize aSize);
|
||||
|
||||
const RefPtr<gl::AndroidSurfaceTexture> mSurfTex;
|
||||
const gfx::IntSize mSize;
|
||||
bool mIsLocked;
|
||||
};
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "mozilla/gfx/Tools.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "mozilla/layers/BufferTexture.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "gfx2DGlue.h"
|
||||
#include "gfxImageSurface.h"
|
||||
|
@ -149,6 +148,8 @@ void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface)
|
|||
|
||||
// client allocation
|
||||
ASSERT_TRUE(texture->CanExposeDrawTarget());
|
||||
texture->AllocateForSurface(surface->GetSize());
|
||||
ASSERT_TRUE(texture->IsAllocated());
|
||||
|
||||
ASSERT_TRUE(texture->Lock(OpenMode::OPEN_READ_WRITE));
|
||||
// client painting
|
||||
|
@ -198,8 +199,18 @@ void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface)
|
|||
|
||||
// Same as above, for YCbCr surfaces
|
||||
void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) {
|
||||
client->Lock(OpenMode::OPEN_READ_WRITE);
|
||||
UpdateYCbCrTextureClient(client, ycbcrData);
|
||||
|
||||
// client allocation
|
||||
ASSERT_TRUE(client->AsTextureClientYCbCr() != nullptr);
|
||||
TextureClientYCbCr* texture = client->AsTextureClientYCbCr();
|
||||
texture->AllocateForYCbCr(ycbcrData.mYSize,
|
||||
ycbcrData.mCbCrSize,
|
||||
ycbcrData.mStereoMode);
|
||||
ASSERT_TRUE(client->IsAllocated());
|
||||
|
||||
ASSERT_TRUE(client->Lock(OpenMode::OPEN_READ_WRITE));
|
||||
// client painting
|
||||
texture->UpdateYCbCr(ycbcrData);
|
||||
client->Unlock();
|
||||
|
||||
// client serialization
|
||||
|
@ -262,15 +273,11 @@ TEST(Layers, TextureSerialization) {
|
|||
SetupSurface(surface.get());
|
||||
AssertSurfacesEqual(surface, surface);
|
||||
|
||||
auto texData = BufferTextureData::Create(surface->GetSize(),
|
||||
gfx::ImageFormatToSurfaceFormat(surface->Format()),
|
||||
gfx::BackendType::CAIRO, TextureFlags::DEALLOCATE_CLIENT, ALLOC_DEFAULT, nullptr
|
||||
);
|
||||
ASSERT_TRUE(!!texData);
|
||||
|
||||
RefPtr<TextureClient> client = new TextureClient(
|
||||
texData, TextureFlags::DEALLOCATE_CLIENT, nullptr
|
||||
);
|
||||
RefPtr<TextureClient> client
|
||||
= new MemoryTextureClient(nullptr,
|
||||
mozilla::gfx::ImageFormatToSurfaceFormat(surface->Format()),
|
||||
gfx::BackendType::CAIRO,
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
|
||||
TestTextureClientSurface(client, surface);
|
||||
|
||||
|
@ -303,8 +310,11 @@ TEST(Layers, TextureYCbCrSerialization) {
|
|||
clientData.mPicX = 0;
|
||||
clientData.mPicX = 0;
|
||||
|
||||
RefPtr<TextureClient> client = TextureClient::CreateForYCbCr(nullptr, clientData.mYSize, clientData.mCbCrSize,
|
||||
StereoMode::MONO, TextureFlags::DEALLOCATE_CLIENT);
|
||||
RefPtr<TextureClient> client
|
||||
= new MemoryTextureClient(nullptr,
|
||||
mozilla::gfx::SurfaceFormat::YUV,
|
||||
gfx::BackendType::CAIRO,
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
|
||||
TestTextureClientYCbCr(client, clientData);
|
||||
|
||||
|
|
|
@ -421,18 +421,19 @@ status_t GonkBufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence,
|
|||
|
||||
sp<GraphicBuffer> graphicBuffer;
|
||||
if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
|
||||
|
||||
RefPtr<GrallocTextureClientOGL> textureClient =
|
||||
new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
|
||||
gfx::SurfaceFormat::UNKNOWN,
|
||||
gfx::BackendType::NONE,
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
textureClient->SetIsOpaque(true);
|
||||
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
|
||||
GrallocTextureData* texData = GrallocTextureData::Create(IntSize(w,h), format,
|
||||
gfx::BackendType::NONE, usage,
|
||||
allocator);
|
||||
if (!texData) {
|
||||
bool result = textureClient->AllocateGralloc(IntSize(w, h), format, usage);
|
||||
sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
|
||||
if (!result || !graphicBuffer.get()) {
|
||||
ST_LOGE("dequeueBuffer: failed to alloc gralloc buffer");
|
||||
return -ENOMEM;
|
||||
}
|
||||
RefPtr<TextureClient> textureClient = new TextureClient(texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
sp<GraphicBuffer> graphicBuffer = texData->GetGraphicBuffer();
|
||||
|
||||
{ // Scope for the lock
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
|
|
@ -440,19 +440,22 @@ status_t GonkBufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence, bool a
|
|||
mSlots[buf].mFence = Fence::NO_FENCE;
|
||||
} // end lock scope
|
||||
|
||||
sp<GraphicBuffer> graphicBuffer;
|
||||
if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
|
||||
|
||||
ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
|
||||
RefPtr<GrallocTextureClientOGL> textureClient =
|
||||
new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
|
||||
gfx::SurfaceFormat::UNKNOWN,
|
||||
gfx::BackendType::NONE,
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
textureClient->SetIsOpaque(true);
|
||||
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
GrallocTextureData* texData = GrallocTextureData::Create(IntSize(w, h), format,
|
||||
gfx::BackendType::NONE, usage,
|
||||
allocator);
|
||||
if (!texData) {
|
||||
bool result = textureClient->AllocateGralloc(IntSize(w, h), format, usage);
|
||||
sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
|
||||
if (!result || !graphicBuffer.get()) {
|
||||
ALOGE("dequeueBuffer: failed to alloc gralloc buffer");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
RefPtr<TextureClient> textureClient = new TextureClient(texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
|
||||
{ // Scope for the lock
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
||||
|
@ -461,7 +464,7 @@ status_t GonkBufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence, bool a
|
|||
return NO_INIT;
|
||||
}
|
||||
|
||||
mSlots[buf].mGraphicBuffer = texData->GetGraphicBuffer();
|
||||
mSlots[buf].mGraphicBuffer = graphicBuffer;
|
||||
mSlots[buf].mTextureClient = textureClient;
|
||||
ALOGD("dequeueBuffer: returning slot=%d buf=%p ", buf,
|
||||
mSlots[buf].mGraphicBuffer->handle);
|
||||
|
|
|
@ -341,19 +341,19 @@ status_t GonkBufferQueueProducer::dequeueBuffer(int *outSlot,
|
|||
} // Autolock scope
|
||||
|
||||
if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
|
||||
ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
|
||||
RefPtr<GrallocTextureClientOGL> textureClient =
|
||||
new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
|
||||
gfx::SurfaceFormat::UNKNOWN,
|
||||
gfx::BackendType::NONE,
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
textureClient->SetIsOpaque(true);
|
||||
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
GrallocTextureData* texData = GrallocTextureData::Create(IntSize(width,height), format,
|
||||
gfx::BackendType::NONE,
|
||||
usage, allocator);
|
||||
if (!texData) {
|
||||
bool result = textureClient->AllocateGralloc(IntSize(width, height), format, usage);
|
||||
sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
|
||||
if (!result || !graphicBuffer.get()) {
|
||||
ALOGE("dequeueBuffer: failed to alloc gralloc buffer");
|
||||
return -ENOMEM;
|
||||
}
|
||||
RefPtr<TextureClient> textureClient = TextureClient::CreateWithData(
|
||||
texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
|
||||
sp<GraphicBuffer> graphicBuffer = texData->GetGraphicBuffer();
|
||||
|
||||
{ // Autolock scope
|
||||
Mutex::Autolock lock(mCore->mMutex);
|
||||
|
|
|
@ -318,18 +318,22 @@ status_t GonkNativeWindow::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
|
|||
}
|
||||
} // end lock scope
|
||||
|
||||
sp<GraphicBuffer> graphicBuffer;
|
||||
if (alloc) {
|
||||
ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
|
||||
RefPtr<GrallocTextureClientOGL> textureClient =
|
||||
new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
|
||||
gfx::SurfaceFormat::UNKNOWN,
|
||||
gfx::BackendType::NONE,
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
textureClient->SetIsOpaque(true);
|
||||
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
GrallocTextureData* texData = GrallocTextureData::Create(IntSize(w, h), format,
|
||||
gfx::BackendType::NONE, usage,
|
||||
allocator);
|
||||
if (!texData) {
|
||||
bool result = textureClient->AllocateGralloc(IntSize(w, h), format, usage);
|
||||
sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
|
||||
if (!result || !graphicBuffer.get()) {
|
||||
CNW_LOGE("dequeueBuffer: failed to alloc gralloc buffer");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
RefPtr<TextureClient> textureClient = new TextureClient(texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
|
||||
{ // Scope for the lock
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
||||
|
@ -341,7 +345,7 @@ status_t GonkNativeWindow::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
|
|||
if (updateFormat) {
|
||||
mPixelFormat = format;
|
||||
}
|
||||
mSlots[buf].mGraphicBuffer = texData->GetGraphicBuffer();
|
||||
mSlots[buf].mGraphicBuffer = graphicBuffer;
|
||||
mSlots[buf].mTextureClient = textureClient;
|
||||
|
||||
returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
|
||||
|
|
Загрузка…
Ссылка в новой задаче