зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1200595 - Gralloc TextureData implementation. r=sotaro
This commit is contained in:
Родитель
71d9215e93
Коммит
94c7acf9ef
|
@ -354,10 +354,10 @@ OmxDecoder::ReleaseMediaResources() {
|
|||
for (std::set<TextureClient*>::iterator it=mPendingRecycleTexutreClients.begin();
|
||||
it!=mPendingRecycleTexutreClients.end(); it++)
|
||||
{
|
||||
GrallocTextureClientOGL* client = static_cast<GrallocTextureClientOGL*>(*it);
|
||||
client->ClearRecycleCallback();
|
||||
GrallocTextureData* client = static_cast<GrallocTextureData*>((*it)->GetInternalData());
|
||||
(*it)->ClearRecycleCallback();
|
||||
if (client->GetMediaBuffer()) {
|
||||
mPendingVideoBuffers.push(BufferItem(client->GetMediaBuffer(), client->GetAndResetReleaseFenceHandle()));
|
||||
mPendingVideoBuffers.push(BufferItem(client->GetMediaBuffer(), (*it)->GetAndResetReleaseFenceHandle()));
|
||||
}
|
||||
}
|
||||
mPendingRecycleTexutreClients.clear();
|
||||
|
@ -653,8 +653,7 @@ OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
|
|||
// Manually increment reference count to keep MediaBuffer alive
|
||||
// during TextureClient is in use.
|
||||
mVideoBuffer->add_ref();
|
||||
GrallocTextureClientOGL* grallocClient = static_cast<GrallocTextureClientOGL*>(textureClient.get());
|
||||
grallocClient->SetMediaBuffer(mVideoBuffer);
|
||||
static_cast<GrallocTextureData*>(textureClient->GetInternalData())->SetMediaBuffer(mVideoBuffer);
|
||||
// Set recycle callback for TextureClient
|
||||
textureClient->SetRecycleCallback(OmxDecoder::RecycleCallback, this);
|
||||
{
|
||||
|
@ -917,9 +916,9 @@ OmxDecoder::RecycleCallbackImp(TextureClient* aClient)
|
|||
return;
|
||||
}
|
||||
mPendingRecycleTexutreClients.erase(aClient);
|
||||
GrallocTextureClientOGL* client = static_cast<GrallocTextureClientOGL*>(aClient);
|
||||
if (client->GetMediaBuffer()) {
|
||||
mPendingVideoBuffers.push(BufferItem(client->GetMediaBuffer(), client->GetAndResetReleaseFenceHandle()));
|
||||
GrallocTextureData* grallocData = static_cast<GrallocTextureData*>(aClient->GetInternalData());
|
||||
if (grallocData->GetMediaBuffer()) {
|
||||
mPendingVideoBuffers.push(BufferItem(grallocData->GetMediaBuffer(), aClient->GetAndResetReleaseFenceHandle()));
|
||||
}
|
||||
}
|
||||
sp<AMessage> notify =
|
||||
|
|
|
@ -374,14 +374,14 @@ GonkVideoDecoderManager::CreateVideoDataFromGraphicBuffer(MediaBuffer* aSource,
|
|||
aPicture.height = size.height;
|
||||
|
||||
sp<GraphicBuffer> destBuffer =
|
||||
static_cast<GrallocTextureClientOGL*>(textureClient.get())->GetGraphicBuffer();
|
||||
|
||||
static_cast<GrallocTextureData*>(textureClient->GetInternalData())->GetGraphicBuffer();
|
||||
|
||||
CopyGraphicBuffer(srcBuffer, destBuffer, aPicture);
|
||||
} else {
|
||||
textureClient = mNativeWindow->getTextureClientFromBuffer(srcBuffer.get());
|
||||
textureClient->SetRecycleCallback(GonkVideoDecoderManager::RecycleCallback, this);
|
||||
GrallocTextureClientOGL* grallocClient = static_cast<GrallocTextureClientOGL*>(textureClient.get());
|
||||
grallocClient->SetMediaBuffer(aSource);
|
||||
|
||||
static_cast<GrallocTextureData*>(textureClient->GetInternalData())->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);
|
||||
GrallocTextureClientOGL* client = static_cast<GrallocTextureClientOGL*>(aClient);
|
||||
GrallocTextureData* client = static_cast<GrallocTextureData*>(aClient->GetInternalData());
|
||||
aClient->ClearRecycleCallback();
|
||||
FenceHandle handle = aClient->GetAndResetReleaseFenceHandle();
|
||||
videoManager->PostReleaseVideoBuffer(client->GetMediaBuffer(), handle);
|
||||
|
|
|
@ -763,9 +763,8 @@ MediaEngineGonkVideoSource::RotateImage(layers::Image* aImage, uint32_t aWidth,
|
|||
layers::TextureFlags::DEFAULT,
|
||||
layers::ALLOC_DISALLOW_BUFFERTEXTURECLIENT);
|
||||
if (textureClient) {
|
||||
RefPtr<layers::GrallocTextureClientOGL> grallocTextureClient = textureClient->AsGrallocTextureClientOGL();
|
||||
|
||||
android::sp<android::GraphicBuffer> destBuffer = grallocTextureClient->GetGraphicBuffer();
|
||||
android::sp<android::GraphicBuffer> destBuffer =
|
||||
static_cast<layers::GrallocTextureData*>(textureClient->GetInternalData())->GetGraphicBuffer();
|
||||
|
||||
void* destMem = nullptr;
|
||||
destBuffer->lock(android::GraphicBuffer::USAGE_SW_WRITE_OFTEN, &destMem);
|
||||
|
|
|
@ -63,17 +63,17 @@ SharedSurface_Gralloc::Create(GLContext* prodGL,
|
|||
gfxContentType type = hasAlpha ? gfxContentType::COLOR_ALPHA
|
||||
: gfxContentType::COLOR;
|
||||
|
||||
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);
|
||||
GrallocTextureData* texData = GrallocTextureData::CreateForGLRendering(
|
||||
size, gfxPlatform::GetPlatform()->Optimal2DFormatForContent(type), allocator
|
||||
);
|
||||
|
||||
if (!grallocTC->AllocateForGLRendering(size)) {
|
||||
if (!texData) {
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
sp<GraphicBuffer> buffer = grallocTC->GetGraphicBuffer();
|
||||
RefPtr<TextureClient> grallocTC = new ClientTexture(texData, flags, allocator);
|
||||
|
||||
sp<GraphicBuffer> buffer = texData->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::GrallocTextureClientOGL* textureClient,
|
||||
layers::TextureClient* textureClient,
|
||||
GLuint prodTex)
|
||||
: SharedSurface(SharedSurfaceType::Gralloc,
|
||||
AttachmentType::GLTexture,
|
||||
|
@ -287,7 +287,9 @@ bool
|
|||
SharedSurface_Gralloc::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
|
||||
{
|
||||
MOZ_ASSERT(out_surface);
|
||||
sp<GraphicBuffer> buffer = mTextureClient->GetGraphicBuffer();
|
||||
sp<GraphicBuffer> buffer = static_cast<GrallocTextureData*>(
|
||||
mTextureClient->GetInternalData()
|
||||
)->GetGraphicBuffer();
|
||||
|
||||
const uint8_t* grallocData = nullptr;
|
||||
auto result = buffer->lock(
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
class ISurfaceAllocator;
|
||||
class GrallocTextureClientOGL;
|
||||
class TextureClient;
|
||||
}
|
||||
|
||||
namespace gl {
|
||||
|
@ -41,7 +41,7 @@ protected:
|
|||
GLLibraryEGL* const mEGL;
|
||||
EGLSync mSync;
|
||||
RefPtr<layers::ISurfaceAllocator> mAllocator;
|
||||
RefPtr<layers::GrallocTextureClientOGL> mTextureClient;
|
||||
RefPtr<layers::TextureClient> mTextureClient;
|
||||
const GLuint mProdTex;
|
||||
|
||||
SharedSurface_Gralloc(GLContext* prodGL,
|
||||
|
@ -49,7 +49,7 @@ protected:
|
|||
bool hasAlpha,
|
||||
GLLibraryEGL* egl,
|
||||
layers::ISurfaceAllocator* allocator,
|
||||
layers::GrallocTextureClientOGL* textureClient,
|
||||
layers::TextureClient* textureClient,
|
||||
GLuint prodTex);
|
||||
|
||||
static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl);
|
||||
|
@ -70,7 +70,7 @@ public:
|
|||
return mProdTex;
|
||||
}
|
||||
|
||||
layers::GrallocTextureClientOGL* GetTextureClient() {
|
||||
layers::TextureClient* GetTextureClient() {
|
||||
return mTextureClient;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
StereoMode aStereoMode,
|
||||
TextureFlags aTextureFlags);
|
||||
|
||||
virtual bool Lock(OpenMode aMode) override { return true; }
|
||||
virtual bool Lock(OpenMode aMode, FenceHandle*) override { return true; }
|
||||
|
||||
virtual void Unlock() override {}
|
||||
|
||||
|
|
|
@ -73,25 +73,21 @@ GrallocImage::SetData(const Data& aData)
|
|||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mTextureClient = textureClient;
|
||||
mTextureClient = new ClientTexture(texData, TextureFlags::DEFAULT, allocator);
|
||||
sp<GraphicBuffer> graphicBuffer = texData->GetGraphicBuffer();
|
||||
|
||||
void* vaddr;
|
||||
if (graphicBuffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
|
||||
|
@ -150,8 +146,7 @@ GrallocImage::SetData(const Data& aData)
|
|||
void
|
||||
GrallocImage::SetData(TextureClient* aGraphicBuffer, const gfx::IntSize& aSize)
|
||||
{
|
||||
MOZ_ASSERT(aGraphicBuffer->AsGrallocTextureClientOGL());
|
||||
mTextureClient = aGraphicBuffer->AsGrallocTextureClientOGL();
|
||||
mTextureClient = aGraphicBuffer;
|
||||
mSize = aSize;
|
||||
}
|
||||
|
||||
|
@ -443,8 +438,7 @@ GrallocImage::GetAsSourceSurface()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
android::sp<GraphicBuffer> graphicBuffer =
|
||||
mTextureClient->GetGraphicBuffer();
|
||||
android::sp<GraphicBuffer> graphicBuffer = GetGraphicBuffer();
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> surface =
|
||||
GetDataSourceSurfaceFrom(graphicBuffer, mSize, mData);
|
||||
|
@ -458,7 +452,7 @@ GrallocImage::GetGraphicBuffer() const
|
|||
if (!mTextureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
return mTextureClient->GetGraphicBuffer();
|
||||
return static_cast<GrallocTextureData*>(mTextureClient->GetInternalData())->GetGraphicBuffer();
|
||||
}
|
||||
|
||||
void*
|
||||
|
@ -467,8 +461,7 @@ GrallocImage::GetNativeBuffer()
|
|||
if (!mTextureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
android::sp<android::GraphicBuffer> graphicBuffer =
|
||||
mTextureClient->GetGraphicBuffer();
|
||||
android::sp<android::GraphicBuffer> graphicBuffer = GetGraphicBuffer();
|
||||
if (!graphicBuffer.get()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class GrallocTextureClientOGL;
|
||||
class TextureClient;
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface>
|
||||
GetDataSourceSurfaceFrom(android::sp<android::GraphicBuffer>& aGraphicBuffer,
|
||||
|
@ -124,7 +124,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
RefPtr<GrallocTextureClientOGL> mTextureClient;
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
static SurfaceFormat
|
||||
static gfx::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 SurfaceFormat::UNKNOWN; // not reached
|
||||
return gfx::SurfaceFormat::UNKNOWN; // not reached
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ GrallocTextureHostBasic::Lock()
|
|||
NS_WARNING("Couldn't lock graphic buffer");
|
||||
return false;
|
||||
}
|
||||
surf = Factory::CreateWrappingDataSourceSurface(
|
||||
surf = gfx::Factory::CreateWrappingDataSourceSurface(
|
||||
mMappedBuffer,
|
||||
graphicBuffer->getStride() * gfx::BytesPerPixel(mFormat),
|
||||
mCropSize,
|
||||
|
@ -217,7 +217,7 @@ GrallocTextureHostBasic::WaitAcquireFenceHandleSyncComplete()
|
|||
void
|
||||
GrallocTextureHostBasic::SetCropRect(nsIntRect aCropRect)
|
||||
{
|
||||
MOZ_ASSERT(aCropRect.TopLeft() == IntPoint(0, 0));
|
||||
MOZ_ASSERT(aCropRect.TopLeft() == gfx::IntPoint(0, 0));
|
||||
MOZ_ASSERT(!aCropRect.IsEmpty());
|
||||
MOZ_ASSERT(aCropRect.width <= mSize.width);
|
||||
MOZ_ASSERT(aCropRect.height <= mSize.height);
|
||||
|
|
|
@ -45,7 +45,7 @@ X11TextureData::X11TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
|||
}
|
||||
|
||||
bool
|
||||
X11TextureData::Lock(OpenMode aMode)
|
||||
X11TextureData::Lock(OpenMode aMode, FenceHandle*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual bool Lock(OpenMode aMode) override;
|
||||
virtual bool Lock(OpenMode aMode, FenceHandle*) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ ClientTexture::Lock(OpenMode aMode)
|
|||
return mOpenMode == aMode;
|
||||
}
|
||||
|
||||
mIsLocked = mData->Lock(aMode);
|
||||
mIsLocked = mData->Lock(aMode, mReleaseFenceHandle.IsValid() ? &mReleaseFenceHandle : nullptr);
|
||||
mOpenMode = aMode;
|
||||
|
||||
return mIsLocked;
|
||||
|
@ -270,8 +270,12 @@ ClientTexture::~ClientTexture()
|
|||
{
|
||||
// All the destruction code that may lead to virtual method calls must
|
||||
// be in Finalize() which is called just before the destructor.
|
||||
|
||||
// TODO[nical] temporarily integrate this with FinalizeOnIPDLThred
|
||||
if (ShouldDeallocateInDestructor()) {
|
||||
mData->Deallocate(mAllocator);
|
||||
} else {
|
||||
mData->Forget(mAllocator);
|
||||
}
|
||||
delete mData;
|
||||
}
|
||||
|
@ -371,6 +375,20 @@ ClientTexture::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
|||
return mData->Serialize(aOutDescriptor);
|
||||
}
|
||||
|
||||
void
|
||||
ClientTexture::WaitForBufferOwnership(bool aWaitReleaseFence)
|
||||
{
|
||||
if (mRemoveFromCompositableWaiter) {
|
||||
mRemoveFromCompositableWaiter->WaitComplete();
|
||||
mRemoveFromCompositableWaiter = nullptr;
|
||||
}
|
||||
|
||||
if (aWaitReleaseFence && mReleaseFenceHandle.IsValid()) {
|
||||
mData->WaitForFence(&mReleaseFenceHandle);
|
||||
mReleaseFenceHandle = FenceHandle();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
PTextureChild*
|
||||
TextureClient::CreateIPDLActor()
|
||||
|
@ -496,30 +514,6 @@ TextureClient::GetIPDLActor()
|
|||
return mActor;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
static bool
|
||||
DisableGralloc(SurfaceFormat aFormat, const gfx::IntSize& aSizeHint)
|
||||
{
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline gfx::BackendType
|
||||
BackendTypeForBackendSelector(LayersBackend aLayersBackend, BackendSelector aSelector)
|
||||
{
|
||||
|
@ -557,7 +551,7 @@ TextureClient::CreateForDrawing(CompositableForwarder* aAllocator,
|
|||
|
||||
RefPtr<TextureClient> texture;
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) || defined(XP_WIN)
|
||||
#if defined(XP_WIN)
|
||||
int32_t maxTextureSize = aAllocator->GetMaxTextureSize();
|
||||
#endif
|
||||
|
||||
|
@ -621,13 +615,10 @@ TextureClient::CreateForDrawing(CompositableForwarder* aAllocator,
|
|||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (!DisableGralloc(aFormat, aSize)) {
|
||||
// Don't allow Gralloc texture clients to exceed the maximum texture size.
|
||||
// BufferTextureClients have code to handle tiling the surface client-side.
|
||||
if (aSize.width <= maxTextureSize && aSize.height <= maxTextureSize) {
|
||||
texture = new GrallocTextureClientOGL(aAllocator, aFormat, moz2DBackend,
|
||||
aTextureFlags);
|
||||
}
|
||||
texture = CreateGrallocTextureClientForDrawing(aSize, aFormat, moz2DBackend,
|
||||
aTextureFlags, aAllocator);
|
||||
if (texture) {
|
||||
return texture.forget();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -843,6 +834,11 @@ TextureClient::ShouldDeallocateInDestructor() const
|
|||
return !mShared || (GetFlags() & TextureFlags::DEALLOCATE_CLIENT);
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) {
|
||||
mRemoveFromCompositableWaiter = aWaiter;
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
||||
{
|
||||
|
|
|
@ -39,6 +39,10 @@ namespace mozilla {
|
|||
#define GFX_DEBUG_TRACK_CLIENTS_IN_POOL 1
|
||||
#endif
|
||||
|
||||
namespace gl {
|
||||
class SharedSurface_Gralloc;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
class AsyncTransactionWaiter;
|
||||
|
@ -49,6 +53,7 @@ struct PlanarYCbCrData;
|
|||
class Image;
|
||||
class PTextureChild;
|
||||
class TextureChild;
|
||||
class TextureData;
|
||||
struct RawTextureBuffer;
|
||||
class RawYCbCrTextureBuffer;
|
||||
class TextureClient;
|
||||
|
@ -57,7 +62,6 @@ class TextureClientRecycleAllocator;
|
|||
class TextureClientPool;
|
||||
#endif
|
||||
class KeepAlive;
|
||||
class GrallocTextureClientOGL;
|
||||
|
||||
/**
|
||||
* TextureClient is the abstraction that allows us to share data between the
|
||||
|
@ -247,8 +251,6 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual GrallocTextureClientOGL* AsGrallocTextureClientOGL() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Locks the shared data, allowing the caller to get access to it.
|
||||
*
|
||||
|
@ -490,7 +492,7 @@ 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.
|
||||
|
@ -505,20 +507,20 @@ 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) { }
|
||||
virtual void SyncWithObject(SyncObject* aSyncObject) { }
|
||||
|
||||
void MarkShared() {
|
||||
mShared = true;
|
||||
}
|
||||
void MarkShared() {
|
||||
mShared = true;
|
||||
}
|
||||
|
||||
ISurfaceAllocator* GetAllocator()
|
||||
{
|
||||
|
@ -528,6 +530,9 @@ public:
|
|||
TextureClientRecycleAllocator* GetRecycleAllocator() { return mRecycleAllocator; }
|
||||
void SetRecycleAllocator(TextureClientRecycleAllocator* aAllocator);
|
||||
|
||||
/// If you add new code that uses this funtion, you are probably doing something wrong.
|
||||
virtual TextureData* GetInternalData() { return nullptr; }
|
||||
|
||||
private:
|
||||
static void TextureClientRecycleCallback(TextureClient* aClient, void* aClosure);
|
||||
|
||||
|
@ -547,7 +552,7 @@ private:
|
|||
virtual void FinalizeOnIPDLThread() {}
|
||||
|
||||
friend class AtomicRefCountedWithFinalize<TextureClient>;
|
||||
|
||||
friend class gl::SharedSurface_Gralloc;
|
||||
protected:
|
||||
/**
|
||||
* An invalid TextureClient cannot provide access to its shared data
|
||||
|
@ -568,6 +573,8 @@ protected:
|
|||
RefPtr<TextureChild> mActor;
|
||||
RefPtr<ISurfaceAllocator> mAllocator;
|
||||
RefPtr<TextureClientRecycleAllocator> mRecycleAllocator;
|
||||
RefPtr<AsyncTransactionWaiter> mRemoveFromCompositableWaiter;
|
||||
|
||||
TextureFlags mFlags;
|
||||
FenceHandle mReleaseFenceHandle;
|
||||
FenceHandle mAcquireFenceHandle;
|
||||
|
@ -600,7 +607,7 @@ public:
|
|||
|
||||
virtual gfx::SurfaceFormat GetFormat() const = 0;
|
||||
|
||||
virtual bool Lock(OpenMode aMode) = 0;
|
||||
virtual bool Lock(OpenMode aMode, FenceHandle* aFence) = 0;
|
||||
|
||||
virtual void Unlock() = 0;
|
||||
|
||||
|
@ -620,6 +627,9 @@ public:
|
|||
|
||||
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*
|
||||
|
@ -628,6 +638,10 @@ public:
|
|||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const { return nullptr; }
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) { 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) {};
|
||||
};
|
||||
|
||||
/// temporary class that will be merged back into TextureClient when all texture implementations
|
||||
|
@ -670,9 +684,14 @@ public:
|
|||
|
||||
virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
// TODO - we should be able to make this implicit and not expose the method.
|
||||
virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true) override;
|
||||
|
||||
// by construction, ClientTexture cannot be created without successful allocation.
|
||||
virtual bool IsAllocated() const override { return true; }
|
||||
|
||||
/// If you add new code that uses this method, you are probably doing something wrong.
|
||||
virtual TextureData* GetInternalData() override { return mData; }
|
||||
protected:
|
||||
TextureData* mData;
|
||||
RefPtr<gfx::DrawTarget> mBorrowedDrawTarget;
|
||||
|
|
|
@ -54,9 +54,9 @@ void
|
|||
SharedSurfaceTextureClient::SetReleaseFenceHandle(const FenceHandle& aReleaseFenceHandle)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
SharedSurface_Gralloc* surf = nullptr;
|
||||
if (mSurf->mType == SharedSurfaceType::Gralloc) {
|
||||
surf = SharedSurface_Gralloc::Cast(mSurf.get());
|
||||
gl::SharedSurface_Gralloc* surf = nullptr;
|
||||
if (mSurf->mType == gl::SharedSurfaceType::Gralloc) {
|
||||
surf = gl::SharedSurface_Gralloc::Cast(mSurf.get());
|
||||
}
|
||||
if (surf && surf->GetTextureClient()) {
|
||||
surf->GetTextureClient()->SetReleaseFenceHandle(aReleaseFenceHandle);
|
||||
|
@ -70,9 +70,9 @@ FenceHandle
|
|||
SharedSurfaceTextureClient::GetAndResetReleaseFenceHandle()
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
SharedSurface_Gralloc* surf = nullptr;
|
||||
if (mSurf->mType == SharedSurfaceType::Gralloc) {
|
||||
surf = SharedSurface_Gralloc::Cast(mSurf.get());
|
||||
gl::SharedSurface_Gralloc* surf = nullptr;
|
||||
if (mSurf->mType == gl::SharedSurfaceType::Gralloc) {
|
||||
surf = gl::SharedSurface_Gralloc::Cast(mSurf.get());
|
||||
}
|
||||
if (surf && surf->GetTextureClient()) {
|
||||
return surf->GetTextureClient()->GetAndResetReleaseFenceHandle();
|
||||
|
@ -85,9 +85,9 @@ void
|
|||
SharedSurfaceTextureClient::SetAcquireFenceHandle(const FenceHandle& aAcquireFenceHandle)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
SharedSurface_Gralloc* surf = nullptr;
|
||||
if (mSurf->mType == SharedSurfaceType::Gralloc) {
|
||||
surf = SharedSurface_Gralloc::Cast(mSurf.get());
|
||||
gl::SharedSurface_Gralloc* surf = nullptr;
|
||||
if (mSurf->mType == gl::SharedSurfaceType::Gralloc) {
|
||||
surf = gl::SharedSurface_Gralloc::Cast(mSurf.get());
|
||||
}
|
||||
if (surf && surf->GetTextureClient()) {
|
||||
return surf->GetTextureClient()->SetAcquireFenceHandle(aAcquireFenceHandle);
|
||||
|
@ -100,9 +100,9 @@ const FenceHandle&
|
|||
SharedSurfaceTextureClient::GetAcquireFenceHandle() const
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
SharedSurface_Gralloc* surf = nullptr;
|
||||
if (mSurf->mType == SharedSurfaceType::Gralloc) {
|
||||
surf = SharedSurface_Gralloc::Cast(mSurf.get());
|
||||
gl::SharedSurface_Gralloc* surf = nullptr;
|
||||
if (mSurf->mType == gl::SharedSurfaceType::Gralloc) {
|
||||
surf = gl::SharedSurface_Gralloc::Cast(mSurf.get());
|
||||
}
|
||||
if (surf && surf->GetTextureClient()) {
|
||||
return surf->GetTextureClient()->GetAcquireFenceHandle();
|
||||
|
|
|
@ -24,148 +24,28 @@ namespace layers {
|
|||
using namespace mozilla::gfx;
|
||||
using namespace android;
|
||||
|
||||
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))
|
||||
static bool
|
||||
DisableGralloc(SurfaceFormat aFormat, const gfx::IntSize& aSizeHint)
|
||||
{
|
||||
MOZ_COUNT_CTOR(GrallocTextureClientOGL);
|
||||
}
|
||||
|
||||
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(!mIsLocked);
|
||||
MOZ_ASSERT(IsValid());
|
||||
if (!IsValid() || !IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mMappedBuffer) {
|
||||
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;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
mIsLocked = true;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureClientOGL::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
mIsLocked = false;
|
||||
mDrawTarget = nullptr;
|
||||
if (mMappedBuffer) {
|
||||
mMappedBuffer = nullptr;
|
||||
mGraphicBuffer->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
static gfx::SurfaceFormat
|
||||
gfx::SurfaceFormat
|
||||
SurfaceFormatForPixelFormat(android::PixelFormat aFormat)
|
||||
{
|
||||
switch (aFormat) {
|
||||
|
@ -180,56 +60,188 @@ SurfaceFormatForPixelFormat(android::PixelFormat aFormat)
|
|||
case HAL_PIXEL_FORMAT_YV12:
|
||||
return gfx::SurfaceFormat::YUV;
|
||||
default:
|
||||
MOZ_CRASH("Unknown gralloc pixel format");
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
return gfx::SurfaceFormat::R8G8B8A8;
|
||||
}
|
||||
|
||||
gfx::DrawTarget*
|
||||
GrallocTextureClientOGL::BorrowDrawTarget()
|
||||
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)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
MOZ_ASSERT(mMappedBuffer, "Calling TextureClient::BorrowDrawTarget without locking :(");
|
||||
|
||||
if (!IsValid() || !IsAllocated() || !mMappedBuffer) {
|
||||
return nullptr;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (mDrawTarget) {
|
||||
return mDrawTarget;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
GrallocTextureData::~GrallocTextureData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(GrallocTextureData);
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureClientOGL::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
GrallocTextureData::Deallocate(ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
aAllocator->DeallocGrallocBuffer(&mGrallocHandle);
|
||||
mGrallocHandle = null_t();
|
||||
mGraphicBuffer = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureData::Forget(ISurfaceAllocator* 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->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);
|
||||
|
||||
WaitForFence(aReleaseFence);
|
||||
|
||||
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 = aReleaseFence->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 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)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
MOZ_ASSERT(mMappedBuffer, "Calling TextureClient::BorrowDrawTarget without locking :(");
|
||||
|
||||
if (!IsValid() || !IsAllocated() || !mMappedBuffer) {
|
||||
return;
|
||||
if (!mMappedBuffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
|
||||
|
||||
if (!srcSurf) {
|
||||
gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
|
||||
long pixelStride = mGraphicBuffer->getStride();
|
||||
|
@ -239,144 +251,149 @@ GrallocTextureClientOGL::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
|||
|
||||
if (!srcSurf->Map(DataSourceSurface::READ, &sourceMap)) {
|
||||
gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t* buffer = GetBuffer();
|
||||
|
||||
for (int y = 0; y < srcSurf->GetSize().height; y++) {
|
||||
memcpy(buffer + byteStride * y,
|
||||
memcpy(mMappedBuffer + byteStride * y,
|
||||
sourceMap.mData + sourceMap.mStride * y,
|
||||
srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
|
||||
}
|
||||
|
||||
srcSurf->Unmap();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureClientOGL::AllocateForSurface(gfx::IntSize aSize,
|
||||
TextureAllocationFlags)
|
||||
// static
|
||||
GrallocTextureData*
|
||||
GrallocTextureData::Create(gfx::IntSize aSize, AndroidFormat aAndroidFormat,
|
||||
gfx::BackendType aMoz2dBackend, uint32_t aUsage,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
gfx::SurfaceFormat format;
|
||||
switch (aAndroidFormat) {
|
||||
case android::PIXEL_FORMAT_RGBA_8888:
|
||||
format = gfx::SurfaceFormat::B8G8R8A8;
|
||||
break;
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
case gfx::SurfaceFormat::B8G8R8X8:
|
||||
// there is no android BGRX format?
|
||||
format = android::PIXEL_FORMAT_RGBX_8888;
|
||||
case android::PIXEL_FORMAT_BGRA_8888:
|
||||
format = gfx::SurfaceFormat::B8G8R8A8;
|
||||
break;
|
||||
case gfx::SurfaceFormat::R5G6B5_UINT16:
|
||||
format = android::PIXEL_FORMAT_RGB_565;
|
||||
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;
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Unsupported surface format");
|
||||
return false;
|
||||
format = gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
return AllocateGralloc(aSize, format, usage);
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureClientOGL::AllocateGralloc(gfx::IntSize aSize,
|
||||
uint32_t aAndroidFormat,
|
||||
uint32_t aUsage)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
ISurfaceAllocator* allocator = GetAllocator();
|
||||
if (DisableGralloc(format, aSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MaybeMagicGrallocBufferHandle handle;
|
||||
bool allocateResult =
|
||||
allocator->AllocGrallocBuffer(aSize,
|
||||
aAndroidFormat,
|
||||
aUsage,
|
||||
&handle);
|
||||
if (!allocateResult) {
|
||||
return false;
|
||||
if (!aAllocator->AllocGrallocBuffer(aSize, aAndroidFormat, aUsage, &handle)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sp<GraphicBuffer> graphicBuffer = GetGraphicBufferFrom(handle);
|
||||
if (!graphicBuffer.get()) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (graphicBuffer->initCheck() != NO_ERROR) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mGrallocHandle = handle;
|
||||
mGraphicBuffer = graphicBuffer;
|
||||
mSize = aSize;
|
||||
return true;
|
||||
return new GrallocTextureData(handle, aSize, format, aMoz2dBackend);
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureClientOGL::IsAllocated() const
|
||||
// static
|
||||
GrallocTextureData*
|
||||
GrallocTextureData::CreateForDrawing(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2dBackend,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
return !!mGraphicBuffer.get();
|
||||
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;
|
||||
}
|
||||
|
||||
/*static*/ already_AddRefed<TextureClient>
|
||||
GrallocTextureClientOGL::FromSharedSurface(gl::SharedSurface* abstractSurf,
|
||||
TextureFlags flags)
|
||||
already_AddRefed<TextureClient>
|
||||
CreateGrallocTextureClientForDrawing(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2dBackend,
|
||||
TextureFlags aFlags,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
TextureData* data = GrallocTextureData::CreateForDrawing(aSize, aFormat, aMoz2dBackend,
|
||||
aAllocator);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
if (IsGrallocRBSwapped(aFormat)) {
|
||||
aFlags |= TextureFlags::RB_SWAPPED;
|
||||
}
|
||||
return MakeAndAddRef<ClientTexture>(data, aFlags, aAllocator);
|
||||
}
|
||||
|
||||
// static
|
||||
GrallocTextureData*
|
||||
GrallocTextureData::CreateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
auto surf = gl::SharedSurface_Gralloc::Cast(abstractSurf);
|
||||
|
||||
|
@ -397,6 +414,18 @@ GrallocTextureClientOGL::FromSharedSurface(gl::SharedSurface* abstractSurf,
|
|||
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,131 +25,113 @@ class SharedSurface;
|
|||
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* 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 TextureClient
|
||||
{
|
||||
/// 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 {
|
||||
public:
|
||||
GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2dBackend,
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT);
|
||||
typedef uint32_t AndroidFormat;
|
||||
|
||||
~GrallocTextureClientOGL();
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual bool Lock(OpenMode aMode) override;
|
||||
virtual bool Lock(OpenMode aMode, FenceHandle* aFence) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual bool ImplementsLocking() const override { return true; }
|
||||
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 HasInternalBuffer() const override { return false; }
|
||||
|
||||
virtual bool IsAllocated() const override;
|
||||
virtual bool HasSynchronization() const override { return true; }
|
||||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
virtual void Deallocate(ISurfaceAllocator*) override;
|
||||
|
||||
virtual void SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) override;
|
||||
virtual void Forget(ISurfaceAllocator*) override;
|
||||
|
||||
virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true) override;
|
||||
static GrallocTextureData* CreateForDrawing(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2dBackend,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
GrallocTextureClientOGL* AsGrallocTextureClientOGL() override {
|
||||
return this;
|
||||
}
|
||||
static GrallocTextureData* CreateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
void SetTextureFlags(TextureFlags aFlags) { AddFlags(aFlags); }
|
||||
static GrallocTextureData* CreateForGLRendering(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
gfx::IntSize GetSize() const override { return mSize; }
|
||||
static GrallocTextureData* Create(gfx::IntSize aSize, AndroidFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend, uint32_t aUsage,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
android::sp<android::GraphicBuffer> GetGraphicBuffer()
|
||||
{
|
||||
return mGraphicBuffer;
|
||||
}
|
||||
|
||||
android::PixelFormat GetPixelFormat()
|
||||
{
|
||||
return mGraphicBuffer->getPixelFormat();
|
||||
}
|
||||
static already_AddRefed<TextureClient>
|
||||
TextureClientFromSharedSurface(gl::SharedSurface* abstractSurf, TextureFlags flags);
|
||||
|
||||
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);
|
||||
|
||||
bool AllocateForGLRendering(gfx::IntSize aSize);
|
||||
|
||||
bool AllocateGralloc(gfx::IntSize aYSize, uint32_t aAndroidFormat, uint32_t aUsage);
|
||||
|
||||
void SetIsOpaque(bool aIsOpaque) { mIsOpaque = aIsOpaque; }
|
||||
|
||||
/**
|
||||
* 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,
|
||||
virtual TextureData*
|
||||
CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
|
||||
static already_AddRefed<TextureClient> FromSharedSurface(gl::SharedSurface* surf,
|
||||
TextureFlags flags);
|
||||
// use ClientTexture'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();
|
||||
|
||||
protected:
|
||||
gfx::SurfaceFormat mFormat;
|
||||
GrallocTextureData(MaybeMagicGrallocBufferHandle aGrallocHandle,
|
||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend);
|
||||
|
||||
gfx::IntSize mSize;
|
||||
gfx::BackendType mBackend;
|
||||
OpenMode mOpenMode;
|
||||
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;
|
||||
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
|
||||
android::MediaBuffer* mMediaBuffer;
|
||||
|
||||
bool mIsOpaque;
|
||||
bool mLocked;
|
||||
};
|
||||
|
||||
gfx::SurfaceFormat SurfaceFormatForPixelFormat(android::PixelFormat aFormat);
|
||||
|
||||
already_AddRefed<TextureClient> CreateGrallocTextureClientForDrawing(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2dBackend, TextureFlags aFlags,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -421,19 +421,18 @@ 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;
|
||||
bool result = textureClient->AllocateGralloc(IntSize(w, h), format, usage);
|
||||
sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
|
||||
if (!result || !graphicBuffer.get()) {
|
||||
ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
|
||||
GrallocTextureData* texData = GrallocTextureData::Create(IntSize(w,h), format,
|
||||
gfx::BackendType::NONE, usage,
|
||||
allocator);
|
||||
if (!texData) {
|
||||
ST_LOGE("dequeueBuffer: failed to alloc gralloc buffer");
|
||||
return -ENOMEM;
|
||||
}
|
||||
RefPtr<TextureClient> textureClient = new ClientTexture(texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
sp<GraphicBuffer> graphicBuffer = texData->GetGraphicBuffer();
|
||||
|
||||
{ // Scope for the lock
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
|
|
@ -440,22 +440,19 @@ 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) {
|
||||
RefPtr<GrallocTextureClientOGL> textureClient =
|
||||
new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
|
||||
gfx::SurfaceFormat::UNKNOWN,
|
||||
gfx::BackendType::NONE,
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
textureClient->SetIsOpaque(true);
|
||||
|
||||
ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
|
||||
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
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");
|
||||
GrallocTextureData* texData = GrallocTextureData::Create(IntSize(w, h), format,
|
||||
gfx::BackendType::NONE, usage,
|
||||
allocator);
|
||||
if (!texData) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
RefPtr<TextureClient> textureClient = new ClientTexture(texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
|
||||
{ // Scope for the lock
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
||||
|
@ -464,7 +461,7 @@ status_t GonkBufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence, bool a
|
|||
return NO_INIT;
|
||||
}
|
||||
|
||||
mSlots[buf].mGraphicBuffer = graphicBuffer;
|
||||
mSlots[buf].mGraphicBuffer = texData->GetGraphicBuffer();
|
||||
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) {
|
||||
RefPtr<GrallocTextureClientOGL> textureClient =
|
||||
new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
|
||||
gfx::SurfaceFormat::UNKNOWN,
|
||||
gfx::BackendType::NONE,
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
textureClient->SetIsOpaque(true);
|
||||
ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
|
||||
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
bool result = textureClient->AllocateGralloc(IntSize(width, height), format, usage);
|
||||
sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
|
||||
if (!result || !graphicBuffer.get()) {
|
||||
GrallocTextureData* texData = GrallocTextureData::Create(IntSize(width,height), format,
|
||||
gfx::BackendType::NONE,
|
||||
usage, allocator);
|
||||
if (!texData) {
|
||||
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,22 +318,18 @@ status_t GonkNativeWindow::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
|
|||
}
|
||||
} // end lock scope
|
||||
|
||||
sp<GraphicBuffer> graphicBuffer;
|
||||
if (alloc) {
|
||||
RefPtr<GrallocTextureClientOGL> textureClient =
|
||||
new GrallocTextureClientOGL(ImageBridgeChild::GetSingleton(),
|
||||
gfx::SurfaceFormat::UNKNOWN,
|
||||
gfx::BackendType::NONE,
|
||||
TextureFlags::DEALLOCATE_CLIENT);
|
||||
textureClient->SetIsOpaque(true);
|
||||
ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
|
||||
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
|
||||
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");
|
||||
GrallocTextureData* texData = GrallocTextureData::Create(IntSize(w, h), format,
|
||||
gfx::BackendType::NONE, usage,
|
||||
allocator);
|
||||
if (!texData) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
RefPtr<TextureClient> textureClient = new ClientTexture(texData, TextureFlags::DEALLOCATE_CLIENT, allocator);
|
||||
|
||||
{ // Scope for the lock
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
||||
|
@ -345,7 +341,7 @@ status_t GonkNativeWindow::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
|
|||
if (updateFormat) {
|
||||
mPixelFormat = format;
|
||||
}
|
||||
mSlots[buf].mGraphicBuffer = graphicBuffer;
|
||||
mSlots[buf].mGraphicBuffer = texData->GetGraphicBuffer();
|
||||
mSlots[buf].mTextureClient = textureClient;
|
||||
|
||||
returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
|
||||
|
|
Загрузка…
Ссылка в новой задаче