mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-13 18:27:35 +00:00
b=843599; use gralloc buffers for WebGL streaming on B2G; r=nical,jgilbert,jrmuizel
This commit is contained in:
parent
6abeb68348
commit
8969f99b17
@ -39,8 +39,8 @@ namespace layers {
|
||||
|
||||
VideoGraphicBuffer::VideoGraphicBuffer(const android::wp<android::OmxDecoder> aOmxDecoder,
|
||||
android::MediaBuffer *aBuffer,
|
||||
SurfaceDescriptor *aDescriptor)
|
||||
: GraphicBufferLocked(*aDescriptor),
|
||||
SurfaceDescriptor& aDescriptor)
|
||||
: GraphicBufferLocked(aDescriptor),
|
||||
mMediaBuffer(aBuffer),
|
||||
mOmxDecoder(aOmxDecoder)
|
||||
{
|
||||
@ -591,11 +591,11 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
|
||||
// Change the descriptor's size to video's size. There are cases that
|
||||
// GraphicBuffer's size and actual video size is different.
|
||||
// See Bug 850566.
|
||||
const mozilla::layers::SurfaceDescriptorGralloc& grallocDesc = descriptor->get_SurfaceDescriptorGralloc();
|
||||
mozilla::layers::SurfaceDescriptor newDescriptor = mozilla::layers::SurfaceDescriptorGralloc(grallocDesc.bufferParent(),
|
||||
grallocDesc.bufferChild(), nsIntSize(mVideoWidth, mVideoHeight), grallocDesc.external());
|
||||
mozilla::layers::SurfaceDescriptorGralloc newDescriptor = descriptor->get_SurfaceDescriptorGralloc();
|
||||
newDescriptor.size() = nsIntSize(mVideoWidth, mVideoHeight);
|
||||
|
||||
aFrame->mGraphicBuffer = new mozilla::layers::VideoGraphicBuffer(this, mVideoBuffer, &newDescriptor);
|
||||
mozilla::layers::SurfaceDescriptor descWrapper(newDescriptor);
|
||||
aFrame->mGraphicBuffer = new mozilla::layers::VideoGraphicBuffer(this, mVideoBuffer, descWrapper);
|
||||
aFrame->mRotation = mVideoRotation;
|
||||
aFrame->mTimeUs = timeUs;
|
||||
aFrame->mKeyFrame = keyFrame;
|
||||
|
@ -27,7 +27,7 @@ class VideoGraphicBuffer : public GraphicBufferLocked {
|
||||
public:
|
||||
VideoGraphicBuffer(const android::wp<android::OmxDecoder> aOmxDecoder,
|
||||
android::MediaBuffer *aBuffer,
|
||||
SurfaceDescriptor *aDescriptor);
|
||||
SurfaceDescriptor& aDescriptor);
|
||||
~VideoGraphicBuffer();
|
||||
void Unlock();
|
||||
};
|
||||
|
@ -10,6 +10,10 @@
|
||||
#include "GLContext.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "SurfaceStream.h"
|
||||
#ifdef MOZ_B2G
|
||||
#include "SharedSurfaceGralloc.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
@ -27,7 +31,20 @@ GLScreenBuffer::Create(GLContext* gl,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SurfaceFactory_GL* factory = new SurfaceFactory_Basic(gl, caps);
|
||||
SurfaceFactory_GL* factory = nullptr;
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
/* On B2G, we want a Gralloc factory, and we want one right at the start */
|
||||
if (!factory &&
|
||||
XRE_GetProcessType() != GeckoProcessType_Default)
|
||||
{
|
||||
factory = new SurfaceFactory_Gralloc(gl, caps);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!factory)
|
||||
factory = new SurfaceFactory_Basic(gl, caps);
|
||||
|
||||
SurfaceStream* stream = SurfaceStream::CreateForType(
|
||||
SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread,
|
||||
caps.preserve),
|
||||
|
@ -37,6 +37,11 @@ CPPSRCS = \
|
||||
SurfaceStream.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_B2G
|
||||
CPPSRCS += SharedSurfaceGralloc.cpp
|
||||
EXPORTS += SharedSurfaceGralloc.h
|
||||
endif
|
||||
|
||||
GL_PROVIDER = Null
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
@ -110,6 +115,8 @@ endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
|
||||
DEFINES := $(filter-out -DUNICODE,$(DEFINES))
|
||||
|
||||
CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
|
||||
|
165
gfx/gl/SharedSurfaceGralloc.cpp
Normal file
165
gfx/gl/SharedSurfaceGralloc.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
|
||||
/* 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 "mozilla/Preferences.h"
|
||||
|
||||
#include "SharedSurfaceGralloc.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "SurfaceFactory.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
|
||||
#include "ui/GraphicBuffer.h"
|
||||
#include "../layers/ipc/ShadowLayers.h"
|
||||
|
||||
#define DEBUG_GRALLOC
|
||||
#ifdef DEBUG_GRALLOC
|
||||
#define DEBUG_PRINT(...) do { printf_stderr(__VA_ARGS__); } while (0)
|
||||
#else
|
||||
#define DEBUG_PRINT(...) do { } while (0)
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace gl;
|
||||
using namespace layers;
|
||||
using namespace android;
|
||||
|
||||
static bool sForceReadPixelsToFence = false;
|
||||
|
||||
|
||||
SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL,
|
||||
const SurfaceCaps& caps,
|
||||
layers::ISurfaceAllocator* allocator)
|
||||
: SurfaceFactory_GL(prodGL, SharedSurfaceType::Gralloc, caps)
|
||||
{
|
||||
if (!allocator) {
|
||||
allocator = layers::ShadowLayerForwarder::GetActiveForwarder();
|
||||
}
|
||||
|
||||
mAllocator = allocator;
|
||||
}
|
||||
|
||||
SharedSurface_Gralloc*
|
||||
SharedSurface_Gralloc::Create(GLContext* prodGL,
|
||||
const GLFormats& formats,
|
||||
const gfxIntSize& size,
|
||||
bool hasAlpha,
|
||||
ISurfaceAllocator* allocator)
|
||||
{
|
||||
static bool runOnce = true;
|
||||
if (runOnce) {
|
||||
sForceReadPixelsToFence = false;
|
||||
mozilla::Preferences::AddBoolVarCache(&sForceReadPixelsToFence,
|
||||
"gfx.gralloc.fence-with-readpixels");
|
||||
runOnce = false;
|
||||
}
|
||||
|
||||
GLLibraryEGL* egl = prodGL->GetLibraryEGL();
|
||||
MOZ_ASSERT(egl);
|
||||
|
||||
DEBUG_PRINT("SharedSurface_Gralloc::Create -------\n");
|
||||
|
||||
if (!HasExtensions(egl, prodGL))
|
||||
return nullptr;
|
||||
|
||||
SurfaceDescriptor baseDesc;
|
||||
SurfaceDescriptorGralloc desc;
|
||||
|
||||
gfxASurface::gfxContentType type = hasAlpha ? gfxASurface::CONTENT_COLOR_ALPHA
|
||||
: gfxASurface::CONTENT_COLOR;
|
||||
if (!allocator->AllocSurfaceDescriptorWithCaps(size, type, USING_GL_RENDERING_ONLY, &baseDesc))
|
||||
return false;
|
||||
|
||||
if (baseDesc.type() != SurfaceDescriptor::TSurfaceDescriptorGralloc) {
|
||||
allocator->DestroySharedSurface(&baseDesc);
|
||||
return false;
|
||||
}
|
||||
|
||||
desc = baseDesc.get_SurfaceDescriptorGralloc();
|
||||
|
||||
sp<GraphicBuffer> buffer = GrallocBufferActor::GetFrom(desc);
|
||||
|
||||
EGLDisplay display = egl->Display();
|
||||
EGLClientBuffer clientBuffer = buffer->getNativeBuffer();
|
||||
EGLint attrs[] = {
|
||||
LOCAL_EGL_NONE, LOCAL_EGL_NONE
|
||||
};
|
||||
EGLImage image = egl->fCreateImage(display,
|
||||
EGL_NO_CONTEXT,
|
||||
LOCAL_EGL_NATIVE_BUFFER_ANDROID,
|
||||
clientBuffer, attrs);
|
||||
if (!image) {
|
||||
allocator->DestroySharedSurface(&baseDesc);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
prodGL->MakeCurrent();
|
||||
GLuint prodTex = 0;
|
||||
prodGL->fGenTextures(1, &prodTex);
|
||||
ScopedBindTexture autoTex(prodGL, prodTex);
|
||||
prodGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, image);
|
||||
|
||||
egl->fDestroyImage(display, image);
|
||||
|
||||
SharedSurface_Gralloc *surf = new SharedSurface_Gralloc(prodGL, size, hasAlpha, egl, allocator, desc, prodTex);
|
||||
|
||||
DEBUG_PRINT("SharedSurface_Gralloc::Create: success -- surface %p, GraphicBuffer %p.\n", surf, buffer.get());
|
||||
|
||||
return surf;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SharedSurface_Gralloc::HasExtensions(GLLibraryEGL* egl, GLContext* gl)
|
||||
{
|
||||
return egl->HasKHRImageBase() &&
|
||||
gl->IsExtensionSupported(GLContext::OES_EGL_image);
|
||||
}
|
||||
|
||||
SharedSurface_Gralloc::~SharedSurface_Gralloc()
|
||||
{
|
||||
|
||||
DEBUG_PRINT("[SharedSurface_Gralloc %p] destroyed\n", this);
|
||||
|
||||
mGL->MakeCurrent();
|
||||
mGL->fDeleteTextures(1, (GLuint*)&mProdTex);
|
||||
|
||||
SurfaceDescriptor desc(mDesc);
|
||||
mAllocator->DestroySharedSurface(&desc);
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_Gralloc::Fence()
|
||||
{
|
||||
// We should be able to rely on genlock write locks/read locks.
|
||||
// But they're broken on some configs, and even a glFinish doesn't
|
||||
// work. glReadPixels seems to, though.
|
||||
if (sForceReadPixelsToFence) {
|
||||
mGL->MakeCurrent();
|
||||
// read a 1x1 pixel
|
||||
unsigned char pixels[4];
|
||||
mGL->fReadPixels(0, 0, 1, 1, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, &pixels[0]);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurface_Gralloc::WaitSync()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_Gralloc::LockProdImpl()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_Gralloc::UnlockProdImpl()
|
||||
{
|
||||
}
|
||||
|
111
gfx/gl/SharedSurfaceGralloc.h
Normal file
111
gfx/gl/SharedSurfaceGralloc.h
Normal file
@ -0,0 +1,111 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
|
||||
/* 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 SHARED_SURFACE_GRALLOC_H_
|
||||
#define SHARED_SURFACE_GRALLOC_H_
|
||||
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "mozilla/layers/LayersSurfaces.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class ISurfaceAllocator;
|
||||
class SurfaceDescriptorGralloc;
|
||||
}
|
||||
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
class GLLibraryEGL;
|
||||
|
||||
class SharedSurface_Gralloc
|
||||
: public SharedSurface_GL
|
||||
{
|
||||
public:
|
||||
static SharedSurface_Gralloc* Create(GLContext* prodGL,
|
||||
const GLFormats& formats,
|
||||
const gfxIntSize& size,
|
||||
bool hasAlpha,
|
||||
layers::ISurfaceAllocator* allocator);
|
||||
|
||||
static SharedSurface_Gralloc* Cast(SharedSurface* surf) {
|
||||
MOZ_ASSERT(surf->Type() == SharedSurfaceType::Gralloc);
|
||||
|
||||
return (SharedSurface_Gralloc*)surf;
|
||||
}
|
||||
|
||||
protected:
|
||||
GLLibraryEGL* const mEGL;
|
||||
layers::ISurfaceAllocator* const mAllocator;
|
||||
// We keep the SurfaceDescriptor around, because we'll end up
|
||||
// using it often and it's handy to do so. The actual
|
||||
// GraphicBuffer is kept alive by the sp<GraphicBuffer> in
|
||||
// GrallocBufferActor; the actor will stay alive until we
|
||||
// explicitly destroy this descriptor (and thus deallocate the
|
||||
// actor) it in the destructor of this class. This is okay to do
|
||||
// on the client, but is very bad to do on the server (because on
|
||||
// the client, the actor has no chance of going away unless the
|
||||
// whole app died).
|
||||
layers::SurfaceDescriptorGralloc mDesc;
|
||||
const GLuint mProdTex;
|
||||
|
||||
SharedSurface_Gralloc(GLContext* prodGL,
|
||||
const gfxIntSize& size,
|
||||
bool hasAlpha,
|
||||
GLLibraryEGL* egl,
|
||||
layers::ISurfaceAllocator* allocator,
|
||||
layers::SurfaceDescriptorGralloc& desc,
|
||||
GLuint prodTex)
|
||||
: SharedSurface_GL(SharedSurfaceType::Gralloc,
|
||||
AttachmentType::GLTexture,
|
||||
prodGL,
|
||||
size,
|
||||
hasAlpha)
|
||||
, mEGL(egl)
|
||||
, mAllocator(allocator)
|
||||
, mDesc(desc)
|
||||
, mProdTex(prodTex)
|
||||
{}
|
||||
|
||||
static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl);
|
||||
|
||||
public:
|
||||
virtual ~SharedSurface_Gralloc();
|
||||
|
||||
virtual void Fence();
|
||||
virtual bool WaitSync();
|
||||
|
||||
virtual void LockProdImpl();
|
||||
virtual void UnlockProdImpl();
|
||||
|
||||
virtual GLuint Texture() const {
|
||||
return mProdTex;
|
||||
}
|
||||
|
||||
layers::SurfaceDescriptorGralloc& GetDescriptor() {
|
||||
return mDesc;
|
||||
}
|
||||
};
|
||||
|
||||
class SurfaceFactory_Gralloc
|
||||
: public SurfaceFactory_GL
|
||||
{
|
||||
protected:
|
||||
layers::ISurfaceAllocator* mAllocator;
|
||||
|
||||
public:
|
||||
SurfaceFactory_Gralloc(GLContext* prodGL,
|
||||
const SurfaceCaps& caps,
|
||||
layers::ISurfaceAllocator* allocator = nullptr);
|
||||
|
||||
virtual SharedSurface* CreateShared(const gfxIntSize& size) {
|
||||
bool hasAlpha = mReadCaps.alpha;
|
||||
return SharedSurface_Gralloc::Create(mGL, mFormats, size, hasAlpha, mAllocator);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif /* SHARED_SURFACE_GRALLOC_H_ */
|
@ -36,6 +36,9 @@ const TextureFlags NewTile = 0x10;
|
||||
const TextureFlags HostRelease = 0x20;
|
||||
// The texture is part of a component-alpha pair
|
||||
const TextureFlags ComponentAlpha = 0x40;
|
||||
// The shared resources are owned by client
|
||||
const TextureFlags OwnByClient = 0x80;
|
||||
|
||||
|
||||
/**
|
||||
* The kind of memory held by the texture client/host pair. This will
|
||||
|
@ -14,6 +14,9 @@
|
||||
#include "SurfaceStream.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "SharedSurfaceEGL.h"
|
||||
#ifdef MOZ_B2G
|
||||
#include "SharedSurfaceGralloc.h"
|
||||
#endif
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
#include "nsXULAppAPI.h"
|
||||
|
@ -11,6 +11,10 @@
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "GLContext.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "SharedSurface.h"
|
||||
#ifdef MOZ_B2G
|
||||
#include "SharedSurfaceGralloc.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla::gl;
|
||||
|
||||
@ -95,9 +99,33 @@ CanvasClientWebGL::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
mTextureClient->EnsureAllocated(aSize, gfxASurface::CONTENT_COLOR);
|
||||
|
||||
GLScreenBuffer* screen = aLayer->mGLContext->Screen();
|
||||
SurfaceStreamHandle handle = screen->Stream()->GetShareHandle();
|
||||
SurfaceStream* stream = screen->Stream();
|
||||
|
||||
mTextureClient->SetDescriptor(SurfaceStreamDescriptor(handle, false));
|
||||
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
if (isCrossProcess) {
|
||||
// swap staging -> consumer so we can send it to the compositor
|
||||
SharedSurface* surf = stream->SwapConsumer();
|
||||
if (!surf) {
|
||||
printf_stderr("surf is null post-SwapConsumer!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
if (surf->Type() != SharedSurfaceType::Gralloc) {
|
||||
printf_stderr("Unexpected non-Gralloc SharedSurface in IPC path!");
|
||||
return;
|
||||
}
|
||||
|
||||
SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf);
|
||||
mTextureClient->SetDescriptor(grallocSurf->GetDescriptor());
|
||||
#else
|
||||
printf_stderr("isCrossProcess, but not MOZ_B2G! Someone needs to write some code!");
|
||||
MOZ_ASSERT(false);
|
||||
#endif
|
||||
} else {
|
||||
SurfaceStreamHandle handle = stream->GetShareHandle();
|
||||
mTextureClient->SetDescriptor(SurfaceStreamDescriptor(handle, false));
|
||||
}
|
||||
|
||||
aLayer->Painted();
|
||||
}
|
||||
|
@ -8,6 +8,9 @@
|
||||
#include "SurfaceStream.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "SharedSurfaceEGL.h"
|
||||
#ifdef MOZ_B2G
|
||||
#include "SharedSurfaceGralloc.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla::gl;
|
||||
|
||||
@ -37,7 +40,12 @@ ClientCanvasLayer::Initialize(const Data& aData)
|
||||
factory = SurfaceFactory_EGLImage::Create(mGLContext, screen->Caps());
|
||||
} else {
|
||||
// [Basic/OGL Layers, OOPC] WebGL layer init. (Out Of Process Compositing)
|
||||
// Fall back to readback.
|
||||
#ifdef MOZ_B2G
|
||||
factory = new SurfaceFactory_Gralloc(mGLContext, screen->Caps(), ClientManager());
|
||||
#else
|
||||
// we could do readback here maybe
|
||||
NS_NOTREACHED("isCrossProcess but not on B2G!");
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
// [Basic Layers, OMTC] WebGL layer init.
|
||||
@ -70,6 +78,15 @@ ClientCanvasLayer::RenderLayer()
|
||||
if (mNeedsYFlip) {
|
||||
flags |= NeedsYFlip;
|
||||
}
|
||||
|
||||
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
//Append OwnByClient flag for streaming buffer under OOPC case
|
||||
if (isCrossProcess && mGLContext) {
|
||||
GLScreenBuffer* screen = mGLContext->Screen();
|
||||
if (screen && screen->Stream()) {
|
||||
flags |= OwnByClient;
|
||||
}
|
||||
}
|
||||
mCanvasClient = CanvasClient::CreateCanvasClient(GetCompositableClientType(),
|
||||
ClientManager(), flags);
|
||||
if (!mCanvasClient) {
|
||||
|
@ -73,7 +73,7 @@ protected:
|
||||
|
||||
CompositableType GetCompositableClientType()
|
||||
{
|
||||
if (mGLContext && XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
if (mGLContext) {
|
||||
return BUFFER_IMAGE_BUFFERED;
|
||||
}
|
||||
return BUFFER_IMAGE_SINGLE;
|
||||
|
@ -77,10 +77,12 @@ TextureHost::TextureHost()
|
||||
TextureHost::~TextureHost()
|
||||
{
|
||||
if (mBuffer) {
|
||||
if (mDeAllocator) {
|
||||
mDeAllocator->DestroySharedSurface(mBuffer);
|
||||
} else {
|
||||
MOZ_ASSERT(mBuffer->type() == SurfaceDescriptor::Tnull_t);
|
||||
if (!(mFlags & OwnByClient)) {
|
||||
if (mDeAllocator) {
|
||||
mDeAllocator->DestroySharedSurface(mBuffer);
|
||||
} else {
|
||||
MOZ_ASSERT(mBuffer->type() == SurfaceDescriptor::Tnull_t);
|
||||
}
|
||||
}
|
||||
delete mBuffer;
|
||||
}
|
||||
|
@ -44,7 +44,11 @@ enum BufferCapabilities {
|
||||
* The allocated buffer must be efficiently mappable as a
|
||||
* gfxImageSurface.
|
||||
*/
|
||||
MAP_AS_IMAGE_SURFACE = 1 << 0
|
||||
MAP_AS_IMAGE_SURFACE = 1 << 0,
|
||||
/**
|
||||
* The allocated buffer will be used for GL rendering only
|
||||
*/
|
||||
USING_GL_RENDERING_ONLY = 1 << 1
|
||||
};
|
||||
|
||||
class SurfaceDescriptor;
|
||||
@ -114,8 +118,11 @@ protected:
|
||||
gfxASurface::gfxContentType aContent,
|
||||
uint32_t aCaps,
|
||||
SurfaceDescriptor* aBuffer);
|
||||
|
||||
// method that does the actual allocation work
|
||||
virtual PGrallocBufferChild* AllocGrallocBuffer(const gfxIntSize& aSize,
|
||||
gfxASurface::gfxContentType aContent,
|
||||
uint32_t aFormat,
|
||||
uint32_t aUsage,
|
||||
MaybeMagicGrallocBufferHandle* aHandle)
|
||||
{
|
||||
return nullptr;
|
||||
|
@ -577,7 +577,7 @@ ImageBridgeChild::AllocSurfaceDescriptorGrallocNow(const gfxIntSize& aSize,
|
||||
GrallocBufferActor* gba = static_cast<GrallocBufferActor*>(gc);
|
||||
gba->InitFromHandle(handle.get_MagicGrallocBufferHandle());
|
||||
|
||||
*aBuffer = SurfaceDescriptorGralloc(nullptr, gc, aSize, /* external */ false);
|
||||
*aBuffer = SurfaceDescriptorGralloc(nullptr, gc, aSize, /* external */ false, /* swapRB */ false);
|
||||
return true;
|
||||
#else
|
||||
NS_RUNTIMEABORT("No gralloc buffers for you");
|
||||
@ -744,13 +744,14 @@ ImageBridgeChild::DeallocShmem(ipc::Shmem& aShmem)
|
||||
|
||||
PGrallocBufferChild*
|
||||
ImageBridgeChild::AllocGrallocBuffer(const gfxIntSize& aSize,
|
||||
gfxASurface::gfxContentType aContent,
|
||||
uint32_t aFormat,
|
||||
uint32_t aUsage,
|
||||
MaybeMagicGrallocBufferHandle* aHandle)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
return SendPGrallocBufferConstructor(aSize,
|
||||
aContent,
|
||||
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
|
||||
aFormat,
|
||||
aUsage,
|
||||
aHandle);
|
||||
#else
|
||||
NS_RUNTIMEABORT("not implemented");
|
||||
|
@ -199,7 +199,7 @@ public:
|
||||
*/
|
||||
bool
|
||||
AllocSurfaceDescriptorGrallocNow(const gfxIntSize& aSize,
|
||||
const uint32_t& aContent,
|
||||
const uint32_t& aFormat,
|
||||
const uint32_t& aUsage,
|
||||
SurfaceDescriptor* aBuffer);
|
||||
|
||||
@ -337,8 +337,9 @@ protected:
|
||||
|
||||
CompositableTransaction* mTxn;
|
||||
|
||||
// ISurfaceAllocator
|
||||
virtual PGrallocBufferChild* AllocGrallocBuffer(const gfxIntSize& aSize,
|
||||
gfxASurface::gfxContentType aContent,
|
||||
uint32_t aFormat, uint32_t aUsage,
|
||||
MaybeMagicGrallocBufferHandle* aHandle) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
|
@ -24,8 +24,9 @@ LayerTransactionChild::Destroy()
|
||||
|
||||
PGrallocBufferChild*
|
||||
LayerTransactionChild::AllocPGrallocBuffer(const gfxIntSize&,
|
||||
const gfxContentType&,
|
||||
MaybeMagicGrallocBufferHandle*)
|
||||
const uint32_t&,
|
||||
const uint32_t&,
|
||||
MaybeMagicGrallocBufferHandle*)
|
||||
{
|
||||
#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
|
||||
return GrallocBufferActor::Create();
|
||||
|
@ -30,7 +30,8 @@ public:
|
||||
|
||||
protected:
|
||||
virtual PGrallocBufferChild*
|
||||
AllocPGrallocBuffer(const gfxIntSize&, const gfxContentType&,
|
||||
AllocPGrallocBuffer(const gfxIntSize&,
|
||||
const uint32_t&, const uint32_t&,
|
||||
MaybeMagicGrallocBufferHandle*) MOZ_OVERRIDE;
|
||||
virtual bool
|
||||
DeallocPGrallocBuffer(PGrallocBufferChild* actor) MOZ_OVERRIDE;
|
||||
|
@ -464,11 +464,12 @@ LayerTransactionParent::RecvClearCachedResources()
|
||||
|
||||
PGrallocBufferParent*
|
||||
LayerTransactionParent::AllocPGrallocBuffer(const gfxIntSize& aSize,
|
||||
const gfxContentType& aContent,
|
||||
const uint32_t& aFormat,
|
||||
const uint32_t& aUsage,
|
||||
MaybeMagicGrallocBufferHandle* aOutHandle)
|
||||
{
|
||||
#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
|
||||
return GrallocBufferActor::Create(aSize, aContent, aOutHandle);
|
||||
return GrallocBufferActor::Create(aSize, aFormat, aUsage, aOutHandle);
|
||||
#else
|
||||
NS_RUNTIMEABORT("No gralloc buffers for you");
|
||||
return nullptr;
|
||||
|
@ -78,7 +78,8 @@ protected:
|
||||
virtual bool RecvClearCachedResources() MOZ_OVERRIDE;
|
||||
|
||||
virtual PGrallocBufferParent*
|
||||
AllocPGrallocBuffer(const gfxIntSize& aSize, const gfxContentType& aContent,
|
||||
AllocPGrallocBuffer(const gfxIntSize& aSize,
|
||||
const uint32_t& aFormat, const uint32_t& aUsage,
|
||||
MaybeMagicGrallocBufferHandle* aOutHandle) MOZ_OVERRIDE;
|
||||
virtual bool
|
||||
DeallocPGrallocBuffer(PGrallocBufferParent* actor) MOZ_OVERRIDE;
|
||||
|
@ -62,6 +62,17 @@ struct SurfaceDescriptorGralloc {
|
||||
* prevent its consumer from mistakenly freeing the buffer.
|
||||
*/
|
||||
bool external;
|
||||
|
||||
/**
|
||||
* This gralloc buffer will be treated as if the RB bytes are swapped.
|
||||
* This is useful for rendering using Cairo/Thebes, because there is no
|
||||
* BGRX Android pixel format, and so we have to do byte swapping.
|
||||
*
|
||||
* For example, if the GraphicBuffer has an Android pixel format of
|
||||
* PIXEL_FORMAT_RGBA_8888 and isRBSwapped is true, when it is sampled
|
||||
* (for example, with GL), a BGRA shader should be used.
|
||||
*/
|
||||
bool isRBSwapped;
|
||||
};
|
||||
|
||||
struct SurfaceStreamDescriptor {
|
||||
|
@ -43,8 +43,30 @@ parent:
|
||||
* Only the parent side has privileges to allocate the buffer.
|
||||
* Allocation may fail (pmem is a scarce resource), and if so null_t
|
||||
* is returned.
|
||||
*
|
||||
* |format| is an Android PixelFormat (see PixelFormat.h)
|
||||
*
|
||||
* commonly used PixelFormats are:
|
||||
* PIXEL_FORMAT_RGBA_8888
|
||||
* PIXEL_FORMAT_RGBX_8888
|
||||
* PIXEL_FORMAT_BGRA_8888
|
||||
*
|
||||
* Note that SurfaceDescriptorGralloc has a "isRBSwapped" boolean
|
||||
* that can treat the R/B bytes as swapped when they are rendered
|
||||
* to the screen, to help with matching the native pixel format
|
||||
* of other rendering engines.
|
||||
*
|
||||
* |usage| is a USAGE_* mask (see GraphicBuffer.h)
|
||||
*
|
||||
* commonly used USAGE flags are:
|
||||
* USAGE_SW_READ_OFTEN | USAGE_SW_WRITE_OFTEN | USAGE_HW_TEXTURE
|
||||
* - used for software rendering to a buffer which the compositor
|
||||
* treats as a texture
|
||||
* USAGE_HW_RENDER | USAGE_HW_TEXTURE
|
||||
* - used for GL rendering to a buffer which the compositor
|
||||
* treats as a texture
|
||||
*/
|
||||
sync PGrallocBuffer(gfxIntSize size, gfxContentType content)
|
||||
sync PGrallocBuffer(gfxIntSize size, uint32_t format, uint32_t usage)
|
||||
returns (MaybeMagicGrallocBufferHandle handle);
|
||||
async PLayer();
|
||||
async PCompositable(TextureInfo aTextureInfo);
|
||||
|
@ -146,6 +146,31 @@ PixelFormatForImageFormat(gfxASurface::gfxImageFormat aFormat)
|
||||
return gfxASurface::ImageFormatARGB32;
|
||||
}
|
||||
|
||||
static size_t
|
||||
BytesPerPixelForPixelFormat(android::PixelFormat aFormat)
|
||||
{
|
||||
switch (aFormat) {
|
||||
case PIXEL_FORMAT_RGBA_8888:
|
||||
case PIXEL_FORMAT_RGBX_8888:
|
||||
case PIXEL_FORMAT_BGRA_8888:
|
||||
return 4;
|
||||
case PIXEL_FORMAT_RGB_888:
|
||||
return 3;
|
||||
case PIXEL_FORMAT_RGB_565:
|
||||
case PIXEL_FORMAT_RGBA_5551:
|
||||
case PIXEL_FORMAT_RGBA_4444:
|
||||
case PIXEL_FORMAT_LA_88:
|
||||
return 2;
|
||||
case PIXEL_FORMAT_L_8:
|
||||
case PIXEL_FORMAT_A_8:
|
||||
case PIXEL_FORMAT_RGB_332:
|
||||
return 1;
|
||||
default:
|
||||
MOZ_NOT_REACHED("Unknown gralloc pixel format");
|
||||
}
|
||||
return gfxASurface::ImageFormatARGB32;
|
||||
}
|
||||
|
||||
static android::PixelFormat
|
||||
PixelFormatForContentType(gfxASurface::gfxContentType aContentType)
|
||||
{
|
||||
@ -197,28 +222,32 @@ GrallocBufferActor::~GrallocBufferActor()
|
||||
|
||||
/*static*/ PGrallocBufferParent*
|
||||
GrallocBufferActor::Create(const gfxIntSize& aSize,
|
||||
const gfxContentType& aContent,
|
||||
const uint32_t& aFormat,
|
||||
const uint32_t& aUsage,
|
||||
MaybeMagicGrallocBufferHandle* aOutHandle)
|
||||
{
|
||||
PROFILER_LABEL("GrallocBufferActor", "Create");
|
||||
GrallocBufferActor* actor = new GrallocBufferActor();
|
||||
*aOutHandle = null_t();
|
||||
android::PixelFormat format = PixelFormatForContentType(aContent);
|
||||
sp<GraphicBuffer> buffer(
|
||||
new GraphicBuffer(aSize.width, aSize.height, format,
|
||||
GraphicBuffer::USAGE_SW_READ_OFTEN |
|
||||
GraphicBuffer::USAGE_SW_WRITE_OFTEN |
|
||||
GraphicBuffer::USAGE_HW_TEXTURE));
|
||||
uint32_t format = aFormat;
|
||||
uint32_t usage = aUsage;
|
||||
|
||||
if (format == 0 || usage == 0) {
|
||||
printf_stderr("GrallocBufferActor::Create -- format and usage must be non-zero");
|
||||
return actor;
|
||||
}
|
||||
|
||||
sp<GraphicBuffer> buffer(new GraphicBuffer(aSize.width, aSize.height, format, usage));
|
||||
if (buffer->initCheck() != OK)
|
||||
return actor;
|
||||
|
||||
size_t bpp = gfxASurface::BytePerPixelFromFormat(
|
||||
gfxPlatform::GetPlatform()->OptimalFormatForContent(aContent));
|
||||
size_t bpp = BytesPerPixelForPixelFormat(format);
|
||||
actor->mAllocBytes = aSize.width * aSize.height * bpp;
|
||||
sCurrentAlloc += actor->mAllocBytes;
|
||||
|
||||
actor->mGraphicBuffer = buffer;
|
||||
*aOutHandle = MagicGrallocBufferHandle(buffer);
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
@ -261,24 +290,6 @@ LayerManagerComposite::PlatformSyncBeforeReplyUpdate()
|
||||
// Nothing to be done for gralloc.
|
||||
}
|
||||
|
||||
/*static*/ PGrallocBufferParent*
|
||||
GrallocBufferActor::Create(const gfxIntSize& aSize,
|
||||
const uint32_t& aFormat,
|
||||
const uint32_t& aUsage,
|
||||
MaybeMagicGrallocBufferHandle* aOutHandle)
|
||||
{
|
||||
GrallocBufferActor* actor = new GrallocBufferActor();
|
||||
*aOutHandle = null_t();
|
||||
sp<GraphicBuffer> buffer(
|
||||
new GraphicBuffer(aSize.width, aSize.height, aFormat, aUsage));
|
||||
if (buffer->initCheck() != OK)
|
||||
return actor;
|
||||
|
||||
actor->mGraphicBuffer = buffer;
|
||||
*aOutHandle = MagicGrallocBufferHandle(buffer);
|
||||
return actor;
|
||||
}
|
||||
|
||||
bool
|
||||
ISurfaceAllocator::PlatformDestroySharedSurface(SurfaceDescriptor* aSurface)
|
||||
{
|
||||
@ -322,10 +333,11 @@ GrallocBufferActor::InitFromHandle(const MagicGrallocBufferHandle& aHandle)
|
||||
|
||||
PGrallocBufferChild*
|
||||
ShadowLayerForwarder::AllocGrallocBuffer(const gfxIntSize& aSize,
|
||||
gfxASurface::gfxContentType aContent,
|
||||
uint32_t aFormat,
|
||||
uint32_t aUsage,
|
||||
MaybeMagicGrallocBufferHandle* aHandle)
|
||||
{
|
||||
return mShadowManager->SendPGrallocBufferConstructor(aSize, aContent, aHandle);
|
||||
return mShadowManager->SendPGrallocBufferConstructor(aSize, aFormat, aUsage, aHandle);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -345,7 +357,31 @@ ISurfaceAllocator::PlatformAllocSurfaceDescriptor(const gfxIntSize& aSize,
|
||||
// Gralloc buffers are efficiently mappable as gfxImageSurface, so
|
||||
// no need to check |aCaps & MAP_AS_IMAGE_SURFACE|.
|
||||
MaybeMagicGrallocBufferHandle handle;
|
||||
PGrallocBufferChild* gc = AllocGrallocBuffer(aSize, aContent, &handle);
|
||||
PGrallocBufferChild* gc;
|
||||
bool defaultRBSwap;
|
||||
|
||||
if (aCaps & USING_GL_RENDERING_ONLY) {
|
||||
gc = AllocGrallocBuffer(aSize,
|
||||
PixelFormatForContentType(aContent),
|
||||
GraphicBuffer::USAGE_HW_RENDER |
|
||||
GraphicBuffer::USAGE_HW_TEXTURE,
|
||||
&handle);
|
||||
// If you're allocating for USING_GL_RENDERING_ONLY, then we don't flag
|
||||
// this for RB swap.
|
||||
defaultRBSwap = false;
|
||||
} else {
|
||||
gc = AllocGrallocBuffer(aSize,
|
||||
PixelFormatForContentType(aContent),
|
||||
GraphicBuffer::USAGE_SW_READ_OFTEN |
|
||||
GraphicBuffer::USAGE_SW_WRITE_OFTEN |
|
||||
GraphicBuffer::USAGE_HW_TEXTURE,
|
||||
&handle);
|
||||
// But if you're allocating for non-GL-only rendering, we flag for
|
||||
// RB swap to preserve old behaviour and proper interaction with
|
||||
// cairo.
|
||||
defaultRBSwap = true;
|
||||
}
|
||||
|
||||
if (!gc) {
|
||||
NS_ERROR("GrallocBufferConstructor failed by returned null");
|
||||
return false;
|
||||
@ -358,7 +394,9 @@ ISurfaceAllocator::PlatformAllocSurfaceDescriptor(const gfxIntSize& aSize,
|
||||
GrallocBufferActor* gba = static_cast<GrallocBufferActor*>(gc);
|
||||
gba->InitFromHandle(handle.get_MagicGrallocBufferHandle());
|
||||
|
||||
*aBuffer = SurfaceDescriptorGralloc(nullptr, gc, aSize, /* external */ false);
|
||||
*aBuffer = SurfaceDescriptorGralloc(nullptr, gc, aSize,
|
||||
/* external */ false,
|
||||
defaultRBSwap);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -71,10 +71,6 @@ class GrallocBufferActor : public PGrallocBufferChild
|
||||
public:
|
||||
virtual ~GrallocBufferActor();
|
||||
|
||||
static PGrallocBufferParent*
|
||||
Create(const gfxIntSize& aSize, const gfxContentType& aContent,
|
||||
MaybeMagicGrallocBufferHandle* aOutHandle);
|
||||
|
||||
static PGrallocBufferParent*
|
||||
Create(const gfxIntSize& aSize, const uint32_t& aFormat, const uint32_t& aUsage,
|
||||
MaybeMagicGrallocBufferHandle* aOutHandle);
|
||||
|
@ -36,6 +36,9 @@ using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
// static
|
||||
ShadowLayerForwarder* ShadowLayerForwarder::sActiveForwarder = nullptr;
|
||||
|
||||
typedef nsTArray<SurfaceDescriptor> BufferArray;
|
||||
typedef std::vector<Edit> EditVector;
|
||||
typedef std::set<ShadowableLayer*> ShadowableLayerSet;
|
||||
@ -170,12 +173,18 @@ ShadowLayerForwarder::ShadowLayerForwarder()
|
||||
, mDrawColoredBorders(false)
|
||||
{
|
||||
mTxn = new Transaction();
|
||||
|
||||
MOZ_ASSERT(!sActiveForwarder);
|
||||
sActiveForwarder = this;
|
||||
}
|
||||
|
||||
ShadowLayerForwarder::~ShadowLayerForwarder()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mTxn->Finished(), "unfinished transaction?");
|
||||
delete mTxn;
|
||||
|
||||
MOZ_ASSERT(this == sActiveForwarder);
|
||||
sActiveForwarder = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -138,6 +138,14 @@ class ShadowLayerForwarder : public CompositableForwarder
|
||||
friend class TextureClientShmem;
|
||||
friend class ContentClientIncremental;
|
||||
|
||||
private:
|
||||
static ShadowLayerForwarder* sActiveForwarder;
|
||||
|
||||
public:
|
||||
static ShadowLayerForwarder* GetActiveForwarder() {
|
||||
return sActiveForwarder;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~ShadowLayerForwarder();
|
||||
|
||||
@ -388,8 +396,10 @@ protected:
|
||||
PLayerTransactionChild* mShadowManager;
|
||||
|
||||
#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
|
||||
// from ISurfaceAllocator
|
||||
virtual PGrallocBufferChild* AllocGrallocBuffer(const gfxIntSize& aSize,
|
||||
gfxASurface::gfxContentType aContent,
|
||||
uint32_t aFormat,
|
||||
uint32_t aUsage,
|
||||
MaybeMagicGrallocBufferHandle* aHandle) MOZ_OVERRIDE;
|
||||
#endif
|
||||
|
||||
|
@ -639,13 +639,16 @@ TiledTextureHostOGL::Lock()
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
static gfx::SurfaceFormat
|
||||
SurfaceFormatForAndroidPixelFormat(android::PixelFormat aFormat)
|
||||
SurfaceFormatForAndroidPixelFormat(android::PixelFormat aFormat,
|
||||
bool swapRB = false)
|
||||
{
|
||||
switch (aFormat) {
|
||||
case android::PIXEL_FORMAT_BGRA_8888:
|
||||
return swapRB ? FORMAT_R8G8B8A8 : FORMAT_B8G8R8A8;
|
||||
case android::PIXEL_FORMAT_RGBA_8888:
|
||||
return FORMAT_B8G8R8A8;
|
||||
return swapRB ? FORMAT_B8G8R8A8 : FORMAT_R8G8B8A8;
|
||||
case android::PIXEL_FORMAT_RGBX_8888:
|
||||
return FORMAT_B8G8R8X8;
|
||||
return swapRB ? FORMAT_B8G8R8X8 : FORMAT_R8G8B8X8;
|
||||
case android::PIXEL_FORMAT_RGB_565:
|
||||
return FORMAT_R5G6B5;
|
||||
case android::PIXEL_FORMAT_A_8:
|
||||
@ -757,7 +760,8 @@ GrallocTextureHostOGL::SwapTexturesImpl(const SurfaceDescriptor& aImage,
|
||||
|
||||
const SurfaceDescriptorGralloc& desc = aImage.get_SurfaceDescriptorGralloc();
|
||||
mGraphicBuffer = GrallocBufferActor::GetFrom(desc);
|
||||
mFormat = SurfaceFormatForAndroidPixelFormat(mGraphicBuffer->getPixelFormat());
|
||||
mFormat = SurfaceFormatForAndroidPixelFormat(mGraphicBuffer->getPixelFormat(),
|
||||
desc.isRBSwapped());
|
||||
mTextureTarget = TextureTargetForAndroidPixelFormat(mGraphicBuffer->getPixelFormat());
|
||||
|
||||
DeleteTextures();
|
||||
|
@ -3957,6 +3957,9 @@ pref("webgl.default-no-alpha", false);
|
||||
pref("webgl.force-layers-readback", false);
|
||||
pref("webgl.lose-context-on-heap-minimize", false);
|
||||
pref("webgl.can-lose-context-in-foreground", true);
|
||||
#ifdef MOZ_B2G
|
||||
pref("gfx.gralloc.fence-with-readpixels", false);
|
||||
#endif
|
||||
|
||||
// Stagefright prefs
|
||||
pref("stagefright.force-enabled", false);
|
||||
|
Loading…
Reference in New Issue
Block a user