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:
Wes Kocher 2015-11-24 10:07:02 -08:00
Родитель e617ebdf10
Коммит 72261b4523
62 изменённых файлов: 3081 добавлений и 3212 удалений

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

@ -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;