--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -656,16 +656,17 @@ CreateOffscreen(GLContext* gl,
layers::ISurfaceAllocator* surfAllocator)
{
SurfaceCaps baseCaps;
baseCaps.color = true;
baseCaps.alpha = options.alpha;
baseCaps.antialias = options.antialias;
baseCaps.depth = options.depth;
+ baseCaps.premultAlpha = options.premultipliedAlpha;
baseCaps.preserve = options.preserveDrawingBuffer;
baseCaps.stencil = options.stencil;
// we should really have this behind a
// |gfxPlatform::GetPlatform()->GetScreenDepth() == 16| check, but
// for now it's just behind a pref for testing/evaluation.
baseCaps.bpp16 = Preferences::GetBool("webgl.prefer-16bpp", false);
@@ -1416,20 +1417,25 @@ WebGLContext::PresentScreenBuffer()
{
if (IsContextLost()) {
return false;
}
if (!mShouldPresent) {
return false;
}
+ MOZ_ASSERT(!mBackbufferNeedsClear);
gl->MakeCurrent();
- MOZ_ASSERT(!mBackbufferNeedsClear);
- if (!gl->PublishFrame()) {
+
+ auto screen = gl->Screen();
+ MOZ_ASSERT(screen);
+
+ auto size = screen->Size();
+ if (!screen->PublishFrame(size)) {
ForceLoseContext();
return false;
}
if (!mOptions.preserveDrawingBuffer) {
mBackbufferNeedsClear = true;
}
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -1987,36 +1987,16 @@ GLContext::AssembleOffscreenFBs(const GL
} else if (readFB) {
NS_RUNTIMEABORT("readFB created when not requested!");
}
return isComplete;
}
-
-bool
-GLContext::PublishFrame()
-{
- MOZ_ASSERT(mScreen);
-
- return mScreen->PublishFrame(OffscreenSize());
-}
-
-SharedSurface*
-GLContext::RequestFrame()
-{
- MOZ_ASSERT(mScreen);
- MOZ_CRASH("Not anymore!");
-
- return nullptr;
-}
-
-
-
void
GLContext::ClearSafely()
{
// bug 659349 --- we must be very careful here: clearing a GL framebuffer is nontrivial, relies on a lot of state,
// and in the case of the backbuffer of a WebGL context, state is exposed to scripts.
//
// The code here is taken from WebGLContext::ForceClearFramebufferWithDefaultValues, but I didn't find a good way of
// sharing code with it. WebGL's code is somewhat performance-critical as it is typically called on every frame, so
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -3524,19 +3524,16 @@ public:
bool IsOffscreen() const {
return mScreen;
}
GLScreenBuffer* Screen() const {
return mScreen.get();
}
- bool PublishFrame();
- SharedSurface* RequestFrame();
-
/* Clear to transparent black, with 0 depth and stencil,
* while preserving current ClearColor etc. values.
* Useful for resizing offscreen buffers.
*/
void ClearSafely();
bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
--- a/gfx/gl/GLReadTexImageHelper.cpp
+++ b/gfx/gl/GLReadTexImageHelper.cpp
@@ -187,18 +187,21 @@ GetActualReadFormats(GLContext* gl,
} else {
switch (destFormat) {
case LOCAL_GL_RGB: {
if (destType == LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV)
fallback = false;
break;
}
case LOCAL_GL_BGRA: {
- if (destType == LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV)
+ if (destType == LOCAL_GL_UNSIGNED_BYTE ||
+ destType == LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV)
+ {
fallback = false;
+ }
break;
}
}
}
if (fallback) {
*out_readFormat = LOCAL_GL_RGBA;
*out_readType = LOCAL_GL_UNSIGNED_BYTE;
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -1,16 +1,17 @@
/* -*- 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 "GLScreenBuffer.h"
#include <cstring>
+#include "CompositorTypes.h"
#include "GLContext.h"
#include "GLBlitHelper.h"
#include "GLReadTexImageHelper.h"
#include "SharedSurfaceGL.h"
#include "SurfaceStream.h"
#ifdef MOZ_WIDGET_GONK
#include "SharedSurfaceGralloc.h"
#include "nsXULAppAPI.h"
@@ -38,21 +39,29 @@ GLScreenBuffer::Create(GLContext* gl,
{
return Move(ret);
}
UniquePtr<SurfaceFactory> factory;
#ifdef MOZ_WIDGET_GONK
/* On B2G, we want a Gralloc factory, and we want one right at the start */
+ auto allocator = caps.surfaceAllocator;
if (!factory &&
- caps.surfaceAllocator &&
+ allocator &&
XRE_GetProcessType() != GeckoProcessType_Default)
{
- factory = MakeUnique<SurfaceFactory_Gralloc>(gl, caps);
+ layers::TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT |
+ TextureFlags::NEEDS_Y_FLIP;
+ if (!caps.premultAlpha) {
+ flags |= TextureFlags::NON_PREMULTIPLIED;
+ }
+
+ factory = MakeUnique<SurfaceFactory_Gralloc>(gl, caps, flags,
+ allocator);
}
#endif
#ifdef XP_MACOSX
/* On OSX, we want an IOSurface factory, and we want one right at the start */
if (!factory) {
factory = SurfaceFactory_IOSurface::Create(gl, caps);
}
#endif
--- a/gfx/gl/GLUploadHelpers.cpp
+++ b/gfx/gl/GLUploadHelpers.cpp
@@ -425,16 +425,17 @@ UploadImageDataToTexture(GLContext* gl,
GLenum format = 0;
GLenum internalFormat = 0;
GLenum type = 0;
int32_t pixelSize = BytesPerPixel(aFormat);
SurfaceFormat surfaceFormat = gfx::SurfaceFormat::UNKNOWN;
MOZ_ASSERT(gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA ||
gl->GetPreferredARGB32Format() == LOCAL_GL_RGBA);
+
switch (aFormat) {
case SurfaceFormat::B8G8R8A8:
if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
format = LOCAL_GL_BGRA;
surfaceFormat = SurfaceFormat::R8G8B8A8;
type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
} else {
format = LOCAL_GL_RGBA;
@@ -452,16 +453,42 @@ UploadImageDataToTexture(GLContext* gl,
type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
} else {
format = LOCAL_GL_RGBA;
surfaceFormat = SurfaceFormat::B8G8R8X8;
type = LOCAL_GL_UNSIGNED_BYTE;
}
internalFormat = LOCAL_GL_RGBA;
break;
+ case SurfaceFormat::R8G8B8A8:
+ if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
+ format = LOCAL_GL_BGRA;
+ type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
+ surfaceFormat = SurfaceFormat::B8G8R8A8;
+ } else {
+ format = LOCAL_GL_RGBA;
+ type = LOCAL_GL_UNSIGNED_BYTE;
+ surfaceFormat = SurfaceFormat::R8G8B8A8;
+ }
+ internalFormat = LOCAL_GL_RGBA;
+ break;
+ case SurfaceFormat::R8G8B8X8:
+ // Treat RGBX surfaces as RGBA except for the surface
+ // format used.
+ if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
+ format = LOCAL_GL_BGRA;
+ type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
+ surfaceFormat = SurfaceFormat::B8G8R8X8;
+ } else {
+ format = LOCAL_GL_RGBA;
+ type = LOCAL_GL_UNSIGNED_BYTE;
+ surfaceFormat = SurfaceFormat::R8G8B8X8;
+ }
+ internalFormat = LOCAL_GL_RGBA;
+ break;
case SurfaceFormat::R5G6B5:
internalFormat = format = LOCAL_GL_RGB;
type = LOCAL_GL_UNSIGNED_SHORT_5_6_5;
surfaceFormat = SurfaceFormat::R5G6B5;
break;
case SurfaceFormat::A8:
internalFormat = format = LOCAL_GL_LUMINANCE;
type = LOCAL_GL_UNSIGNED_BYTE;
--- a/gfx/gl/SharedSurfaceGralloc.cpp
+++ b/gfx/gl/SharedSurfaceGralloc.cpp
@@ -32,33 +32,31 @@
namespace mozilla {
namespace gl {
using namespace mozilla::layers;
using namespace android;
SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL,
const SurfaceCaps& caps,
+ layers::TextureFlags flags,
layers::ISurfaceAllocator* allocator)
: SurfaceFactory(prodGL, SharedSurfaceType::Gralloc, caps)
+ , mFlags(flags)
+ , mAllocator(allocator)
{
- if (caps.surfaceAllocator) {
- allocator = caps.surfaceAllocator;
- }
-
- MOZ_ASSERT(allocator);
-
- mAllocator = allocator;
+ MOZ_ASSERT(mAllocator);
}
/*static*/ UniquePtr<SharedSurface_Gralloc>
SharedSurface_Gralloc::Create(GLContext* prodGL,
const GLFormats& formats,
const gfx::IntSize& size,
bool hasAlpha,
+ layers::TextureFlags flags,
ISurfaceAllocator* allocator)
{
GLLibraryEGL* egl = &sEGLLibrary;
MOZ_ASSERT(egl);
UniquePtr<SharedSurface_Gralloc> ret;
DEBUG_PRINT("SharedSurface_Gralloc::Create -------\n");
@@ -72,17 +70,17 @@ SharedSurface_Gralloc::Create(GLContext*
gfxImageFormat format
= gfxPlatform::GetPlatform()->OptimalFormatForContent(type);
RefPtr<GrallocTextureClientOGL> grallocTC =
new GrallocTextureClientOGL(
allocator,
gfx::ImageFormatToSurfaceFormat(format),
gfx::BackendType::NONE, // we don't need to use it with a DrawTarget
- layers::TextureFlags::DEFAULT);
+ flags);
if (!grallocTC->AllocateForGLRendering(size)) {
return Move(ret);
}
sp<GraphicBuffer> buffer = grallocTC->GetGraphicBuffer();
EGLDisplay display = egl->Display();
--- a/gfx/gl/SharedSurfaceGralloc.h
+++ b/gfx/gl/SharedSurfaceGralloc.h
@@ -1,16 +1,17 @@
/* -*- 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 "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/LayersSurfaces.h"
#include "SharedSurface.h"
namespace mozilla {
namespace layers {
class ISurfaceAllocator;
class GrallocTextureClientOGL;
}
@@ -22,16 +23,17 @@ class GLLibraryEGL;
class SharedSurface_Gralloc
: public SharedSurface
{
public:
static UniquePtr<SharedSurface_Gralloc> Create(GLContext* prodGL,
const GLFormats& formats,
const gfx::IntSize& size,
bool hasAlpha,
+ layers::TextureFlags flags,
layers::ISurfaceAllocator* allocator);
static SharedSurface_Gralloc* Cast(SharedSurface* surf) {
MOZ_ASSERT(surf->mType == SharedSurfaceType::Gralloc);
return (SharedSurface_Gralloc*)surf;
}
@@ -72,30 +74,32 @@ public:
return mTextureClient;
}
};
class SurfaceFactory_Gralloc
: public SurfaceFactory
{
protected:
+ const layers::TextureFlags mFlags;
RefPtr<layers::ISurfaceAllocator> mAllocator;
public:
SurfaceFactory_Gralloc(GLContext* prodGL,
const SurfaceCaps& caps,
- layers::ISurfaceAllocator* allocator = nullptr);
+ layers::TextureFlags flags,
+ layers::ISurfaceAllocator* allocator);
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
bool hasAlpha = mReadCaps.alpha;
UniquePtr<SharedSurface> ret;
if (mAllocator) {
- ret = SharedSurface_Gralloc::Create(mGL, mFormats, size,
- hasAlpha, mAllocator);
+ ret = SharedSurface_Gralloc::Create(mGL, mFormats, size, hasAlpha,
+ mFlags, mAllocator);
}
return Move(ret);
}
};
} /* namespace gl */
} /* namespace mozilla */
--- a/gfx/gl/SurfaceTypes.cpp
+++ b/gfx/gl/SurfaceTypes.cpp
@@ -25,32 +25,34 @@ SurfaceCaps::operator=(const SurfaceCaps
{
any = other.any;
color = other.color;
alpha = other.alpha;
bpp16 = other.bpp16;
depth = other.depth;
stencil = other.stencil;
antialias = other.antialias;
+ premultAlpha = other.premultAlpha;
preserve = other.preserve;
surfaceAllocator = other.surfaceAllocator;
return *this;
}
void
SurfaceCaps::Clear()
{
any = false;
color = false;
alpha = false;
bpp16 = false;
depth = false;
stencil = false;
antialias = false;
+ premultAlpha = false;
preserve = false;
surfaceAllocator = nullptr;
}
SurfaceCaps::~SurfaceCaps()
{
}
--- a/gfx/gl/SurfaceTypes.h
+++ b/gfx/gl/SurfaceTypes.h
@@ -20,16 +20,17 @@ namespace gl {
struct SurfaceCaps MOZ_FINAL
{
bool any;
bool color, alpha;
bool bpp16;
bool depth, stencil;
bool antialias;
+ bool premultAlpha;
bool preserve;
// The surface allocator that we want to create this
// for. May be null.
RefPtr<layers::ISurfaceAllocator> surfaceAllocator;
SurfaceCaps();
SurfaceCaps(const SurfaceCaps& other);
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -43,17 +43,17 @@ CanvasClient::CreateCanvasClient(CanvasC
if (XRE_GetProcessType() != GeckoProcessType_Default) {
NS_WARNING("Most platforms still need an optimized way to share GL cross process.");
return new CanvasClient2D(aForwarder, aFlags);
}
#endif
switch (aType) {
case CanvasClientTypeShSurf:
- return new CanvasClientShSurf(aForwarder, aFlags);
+ return new CanvasClientSharedSurface(aForwarder, aFlags);
case CanvasClientGLContext:
aFlags |= TextureFlags::DEALLOCATE_CLIENT;
return new CanvasClientSurfaceStream(aForwarder, aFlags);
default:
return new CanvasClient2D(aForwarder, aFlags);
}
@@ -235,41 +235,39 @@ CanvasClientSurfaceStream::Update(gfx::I
}
#endif
aLayer->Painted();
}
////////////////////////////////////////////////////////////////////////
-CanvasClientShSurf::CanvasClientShSurf(CompositableForwarder* aLayerForwarder,
- TextureFlags aFlags)
+CanvasClientSharedSurface::CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder,
+ TextureFlags aFlags)
: CanvasClient(aLayerForwarder, aFlags)
{
}
////////////////////////////////////////
// Accelerated backends
static TemporaryRef<TextureClient>
-TexClientFromShSurf(SharedSurface* surf, TextureFlags baseFlags)
+TexClientFromShSurf(SharedSurface* surf, TextureFlags flags)
{
- TextureFlags flags = baseFlags | TextureFlags::DEALLOCATE_CLIENT;
-
switch (surf->mType) {
case SharedSurfaceType::Basic:
return nullptr;
#ifdef MOZ_WIDGET_GONK
case SharedSurfaceType::Gralloc:
return GrallocTextureClientOGL::FromShSurf(surf, flags);
#endif
default:
- return new ShSurfTexClient(flags, surf);
+ return new SharedSurfaceTextureClient(flags, surf);
}
}
////////////////////////////////////////
// Readback
// For formats compatible with R8G8B8A8.
static inline void SwapRB_R8G8B8A8(uint8_t* pixel) {
@@ -279,26 +277,28 @@ static inline void SwapRB_R8G8B8A8(uint8
class TexClientFactory
{
ISurfaceAllocator* const mAllocator;
const bool mHasAlpha;
const gfx::IntSize mSize;
const gfx::BackendType mBackendType;
const TextureFlags mBaseTexFlags;
+ const LayersBackend mLayersBackend;
public:
TexClientFactory(ISurfaceAllocator* allocator, bool hasAlpha,
const gfx::IntSize& size, gfx::BackendType backendType,
- TextureFlags baseTexFlags)
+ TextureFlags baseTexFlags, LayersBackend layersBackend)
: mAllocator(allocator)
, mHasAlpha(hasAlpha)
, mSize(size)
, mBackendType(backendType)
, mBaseTexFlags(baseTexFlags)
+ , mLayersBackend(layersBackend)
{
}
protected:
TemporaryRef<BufferTextureClient> Create(gfx::SurfaceFormat format) {
return TextureClient::CreateForRawBufferAccess(mAllocator, format,
mSize, mBackendType,
mBaseTexFlags);
@@ -307,34 +307,43 @@ protected:
public:
TemporaryRef<BufferTextureClient> CreateB8G8R8AX8() {
gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::B8G8R8A8
: gfx::SurfaceFormat::B8G8R8X8;
return Create(format);
}
TemporaryRef<BufferTextureClient> CreateR8G8B8AX8() {
- // For now, assume that all RGBA formats are broken.
- RefPtr<BufferTextureClient> ret = CreateB8G8R8AX8();
+ RefPtr<BufferTextureClient> ret;
- if (ret) {
- ret->AddFlags(TextureFlags::RB_SWAPPED);
+ bool areRGBAFormatsBroken = mLayersBackend == LayersBackend::LAYERS_BASIC;
+ if (!areRGBAFormatsBroken) {
+ gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
+ : gfx::SurfaceFormat::R8G8B8X8;
+ ret = Create(format);
+ }
+
+ if (!ret) {
+ ret = CreateB8G8R8AX8();
+ if (ret) {
+ ret->AddFlags(TextureFlags::RB_SWAPPED);
+ }
}
return ret.forget();
}
};
static TemporaryRef<TextureClient>
TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
TextureFlags baseFlags, LayersBackend layersBackend)
{
auto backendType = gfx::BackendType::CAIRO;
TexClientFactory factory(allocator, src->mHasAlpha, src->mSize, backendType,
- baseFlags);
+ baseFlags, layersBackend);
RefPtr<BufferTextureClient> texClient;
{
gl::ScopedReadbackFB autoReadback(src);
// We have a source FB, now we need a format.
GLenum destFormat = LOCAL_GL_BGRA;
@@ -384,18 +393,20 @@ TexClientFromReadback(SharedSurface* src
{
ScopedPackAlignment autoAlign(gl, 4);
gl->raw_fReadPixels(0, 0, width, height, readFormat, readType, lockedBytes);
}
// RB_SWAPPED doesn't work with D3D11. (bug 1051010)
// RB_SWAPPED doesn't work with Basic. (bug ???????)
- bool layersNeedsManualSwap = layersBackend == LayersBackend::LAYERS_D3D11 ||
- layersBackend == LayersBackend::LAYERS_BASIC;
+ // RB_SWAPPED doesn't work with D3D9. (bug ???????)
+ bool layersNeedsManualSwap = layersBackend == LayersBackend::LAYERS_BASIC ||
+ layersBackend == LayersBackend::LAYERS_D3D9 ||
+ layersBackend == LayersBackend::LAYERS_D3D11;
if (texClient->HasFlags(TextureFlags::RB_SWAPPED) &&
layersNeedsManualSwap)
{
size_t pixels = width * height;
uint8_t* itr = lockedBytes;
for (size_t i = 0; i < pixels; i++) {
SwapRB_R8G8B8A8(itr);
itr += 4;
@@ -408,28 +419,27 @@ TexClientFromReadback(SharedSurface* src
}
return texClient.forget();
}
////////////////////////////////////////
void
-CanvasClientShSurf::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
+CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
{
aLayer->mGLContext->MakeCurrent();
GLScreenBuffer* screen = aLayer->mGLContext->Screen();
if (mFront) {
mPrevFront = mFront;
mFront = nullptr;
}
mFront = screen->Front();
-
if (!mFront)
return;
// Alright, now sort out the IPC goop.
SharedSurface* surf = mFront->Surf();
auto forwarder = GetForwarder();
auto flags = GetTextureFlags() | TextureFlags::IMMUTABLE;
--- a/gfx/layers/client/CanvasClient.h
+++ b/gfx/layers/client/CanvasClient.h
@@ -137,42 +137,42 @@ public:
}
private:
RefPtr<TextureClient> mBuffer;
};
// Used for GL canvases where we don't need to do any readback, i.e., with a
// GL backend.
-class CanvasClientShSurf : public CanvasClient
+class CanvasClientSharedSurface : public CanvasClient
{
private:
RefPtr<gl::ShSurfHandle> mFront;
RefPtr<gl::ShSurfHandle> mPrevFront;
RefPtr<TextureClient> mFrontTex;
public:
- CanvasClientShSurf(CompositableForwarder* aLayerForwarder,
- TextureFlags aFlags);
+ CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder,
+ TextureFlags aFlags);
virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE {
return TextureInfo(CompositableType::IMAGE);
}
virtual void Clear() MOZ_OVERRIDE {
mFront = nullptr;
mPrevFront = nullptr;
mFrontTex = nullptr;
}
virtual void Update(gfx::IntSize aSize,
ClientCanvasLayer* aLayer) MOZ_OVERRIDE;
virtual void OnDetach() MOZ_OVERRIDE {
- CanvasClientShSurf::Clear();
+ CanvasClientSharedSurface::Clear();
}
};
}
}
#endif
--- a/gfx/layers/client/ClientCanvasLayer.cpp
+++ b/gfx/layers/client/ClientCanvasLayer.cpp
@@ -72,18 +72,24 @@ ClientCanvasLayer::Initialize(const Data
UniquePtr<SurfaceFactory> factory;
if (!gfxPrefs::WebGLForceLayersReadback()) {
switch (ClientManager()->AsShadowForwarder()->GetCompositorBackendType()) {
case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
if (mGLContext->GetContextType() == GLContextType::EGL) {
#ifdef MOZ_WIDGET_GONK
+ TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT |
+ TextureFlags::NEEDS_Y_FLIP;
+ if (!aData.mIsGLAlphaPremult) {
+ flags |= TextureFlags::NON_PREMULTIPLIED;
+ }
factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext,
caps,
+ flags,
ClientManager()->AsShadowForwarder());
#else
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
if (!isCrossProcess) {
// [Basic/OGL Layers, OMTC] WebGL layer init.
factory = SurfaceFactory_EGLImage::Create(mGLContext, caps);
} else {
// we could do readback here maybe
--- a/gfx/layers/client/ClientCanvasLayer.h
+++ b/gfx/layers/client/ClientCanvasLayer.h
@@ -97,14 +97,14 @@ protected:
UniquePtr<gl::SharedSurface> mTextureSurface;
UniquePtr<gl::SurfaceFactory> mFactory;
friend class DeprecatedCanvasClient2D;
friend class CanvasClient2D;
friend class DeprecatedCanvasClientSurfaceStream;
friend class CanvasClientSurfaceStream;
- friend class CanvasClientShSurf;
+ friend class CanvasClientSharedSurface;
};
}
}
#endif
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -856,33 +856,34 @@ StreamTextureClient::InitWith(gl::Surfac
bool
StreamTextureClient::IsAllocated() const
{
return mStream != 0;
}
////////////////////////////////////////////////////////////////////////
-// ShSurfTexClient
+// SharedSurfaceTextureClient
-ShSurfTexClient::ShSurfTexClient(TextureFlags aFlags, gl::SharedSurface* surf)
+SharedSurfaceTextureClient::SharedSurfaceTextureClient(TextureFlags aFlags,
+ gl::SharedSurface* surf)
: TextureClient(aFlags)
, mIsLocked(false)
, mSurf(surf)
, mGL(mSurf->mGL)
{
mSurf->Fence();
}
-ShSurfTexClient::~ShSurfTexClient()
+SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
{
// the data is owned externally.
}
bool
-ShSurfTexClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
+SharedSurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
{
- aOutDescriptor = ShSurfDescriptor((uintptr_t)mSurf);
+ aOutDescriptor = SharedSurfaceDescriptor((uintptr_t)mSurf);
return true;
}
}
}
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -677,23 +677,23 @@ protected:
bool mIsLocked;
RefPtr<gl::SurfaceStream> mStream;
RefPtr<gl::GLContext> mGL; // Just for reference holding.
};
/**
* A TextureClient implementation to share SharedSurfaces.
*/
-class ShSurfTexClient : public TextureClient
+class SharedSurfaceTextureClient : public TextureClient
{
public:
- explicit ShSurfTexClient(TextureFlags aFlags, gl::SharedSurface* surf);
+ SharedSurfaceTextureClient(TextureFlags aFlags, gl::SharedSurface* surf);
protected:
- ~ShSurfTexClient();
+ ~SharedSurfaceTextureClient();
public:
// Boilerplate start
virtual bool IsAllocated() const MOZ_OVERRIDE { return true; }
virtual bool Lock(OpenMode) MOZ_OVERRIDE {
MOZ_ASSERT(!mIsLocked);
mIsLocked = true;
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -198,18 +198,18 @@ TextureHost::Create(const SurfaceDescrip
case SurfaceDescriptor::TEGLImageDescriptor:
case SurfaceDescriptor::TNewSurfaceDescriptorGralloc:
case SurfaceDescriptor::TSurfaceTextureDescriptor:
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
case SurfaceDescriptor::TSurfaceStreamDescriptor:
return new StreamTextureHost(aFlags, aDesc.get_SurfaceStreamDescriptor());
- case SurfaceDescriptor::TShSurfDescriptor:
- return new ShSurfTexHost(aFlags, aDesc.get_ShSurfDescriptor());
+ case SurfaceDescriptor::TSharedSurfaceDescriptor:
+ return new SharedSurfaceTextureHost(aFlags, aDesc.get_SharedSurfaceDescriptor());
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
if (Compositor::GetBackend() == LayersBackend::LAYERS_OPENGL) {
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
} else {
return CreateTextureHostBasic(aDesc, aDeallocator, aFlags);
}
@@ -1084,43 +1084,44 @@ ShSurfToTexSource(gl::SharedSurface* abs
break;
}
MOZ_ASSERT(texSource.get(), "TextureSource creation failed.");
return texSource;
}
////////////////////////////////////////////////////////////////////////////////
-// ShSurfTexHost
+// SharedSurfaceTextureHost
-ShSurfTexHost::ShSurfTexHost(TextureFlags aFlags, const ShSurfDescriptor& aDesc)
+SharedSurfaceTextureHost::SharedSurfaceTextureHost(TextureFlags aFlags,
+ const SharedSurfaceDescriptor& aDesc)
: TextureHost(aFlags)
, mIsLocked(false)
, mSurf((gl::SharedSurface*)aDesc.surf())
, mCompositor(nullptr)
{
MOZ_ASSERT(mSurf);
}
gfx::SurfaceFormat
-ShSurfTexHost::GetFormat() const
+SharedSurfaceTextureHost::GetFormat() const
{
MOZ_ASSERT(mTexSource);
return mTexSource->GetFormat();
}
gfx::IntSize
-ShSurfTexHost::GetSize() const
+SharedSurfaceTextureHost::GetSize() const
{
MOZ_ASSERT(mTexSource);
return mTexSource->GetSize();
}
void
-ShSurfTexHost::EnsureTexSource()
+SharedSurfaceTextureHost::EnsureTexSource()
{
MOZ_ASSERT(mIsLocked);
if (mTexSource)
return;
mSurf->WaitSync();
mTexSource = ShSurfToTexSource(mSurf, mCompositor);
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -45,17 +45,17 @@ class Shmem;
namespace layers {
class Compositor;
class CompositableHost;
class CompositableBackendSpecificData;
class CompositableParentManager;
class SurfaceDescriptor;
class SurfaceStreamDescriptor;
-class ShSurfDescriptor;
+class SharedSurfaceDescriptor;
class ISurfaceAllocator;
class TextureHostOGL;
class TextureSourceOGL;
class TextureSourceD3D9;
class TextureSourceD3D11;
class TextureSourceBasic;
class DataTextureSource;
class PTextureParent;
@@ -615,22 +615,22 @@ protected:
gl::SurfaceStream* mStream;
RefPtr<TextureSource> mTextureSource;
RefPtr<DataTextureSource> mDataTextureSource;
};
/**
* A TextureHost for SharedSurfaces
*/
-class ShSurfTexHost : public TextureHost
+class SharedSurfaceTextureHost : public TextureHost
{
public:
- ShSurfTexHost(TextureFlags aFlags, const ShSurfDescriptor& aDesc);
+ SharedSurfaceTextureHost(TextureFlags aFlags, const ShSurfDescriptor& aDesc);
- virtual ~ShSurfTexHost() {};
+ virtual ~SharedSurfaceTextureHost() {};
virtual void DeallocateDeviceData() MOZ_OVERRIDE {};
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE {
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
}
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE {
@@ -662,17 +662,17 @@ public:
return mTexSource;
}
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
#ifdef MOZ_LAYERS_HAVE_LOG
- virtual const char* Name() { return "ShSurfTexHost"; }
+ virtual const char* Name() { return "SharedSurfaceTextureHost"; }
#endif
protected:
void EnsureTexSource();
bool mIsLocked;
gl::SharedSurface* const mSurf;
Compositor* mCompositor;
--- a/gfx/layers/d3d10/CanvasLayerD3D10.cpp
+++ b/gfx/layers/d3d10/CanvasLayerD3D10.cpp
@@ -113,20 +113,23 @@ CanvasLayerD3D10::UpdateSurface()
return;
}
if (!mTexture) {
return;
}
if (mGLContext) {
- SharedSurface* surf = mGLContext->RequestFrame();
- if (!surf) {
+ auto screen = mGLContext->Screen();
+ MOZ_ASSERT(screen);
+
+ SharedSurface* surf = screen->Front()->Surf();
+ if (!surf)
return;
- }
+ surf->WaitSync();
switch (surf->mType) {
case SharedSurfaceType::EGLSurfaceANGLE: {
SharedSurface_ANGLEShareHandle* shareSurf = SharedSurface_ANGLEShareHandle::Cast(surf);
HANDLE shareHandle = shareSurf->GetShareHandle();
HRESULT hr = device()->OpenSharedResource(shareHandle,
__uuidof(ID3D10Texture2D),
--- a/gfx/layers/d3d9/CanvasLayerD3D9.cpp
+++ b/gfx/layers/d3d9/CanvasLayerD3D9.cpp
@@ -75,19 +75,23 @@ CanvasLayerD3D9::UpdateSurface()
NS_WARNING("CanvasLayerD3D9::Updated called but no texture present and creation failed!");
return;
}
}
RefPtr<SourceSurface> surface;
if (mGLContext) {
- SharedSurface* surf = mGLContext->RequestFrame();
+ auto screen = mGLContext->Screen();
+ MOZ_ASSERT(screen);
+
+ SharedSurface* surf = screen->Front()->Surf();
if (!surf)
- return;
+ return;
+ surf->WaitSync();
SharedSurface_Basic* shareSurf = SharedSurface_Basic::Cast(surf);
surface = shareSurf->GetData();
} else {
surface = mDrawTarget->Snapshot();
}
// WebGL reads entire surface.
--- a/gfx/layers/ipc/LayersSurfaces.ipdlh
+++ b/gfx/layers/ipc/LayersSurfaces.ipdlh
@@ -76,17 +76,17 @@ struct NewSurfaceDescriptorGralloc {
IntSize size;
};
struct SurfaceStreamDescriptor {
uintptr_t surfStream;
bool yflip;
};
-struct ShSurfDescriptor {
+struct SharedSurfaceDescriptor {
uintptr_t surf;
};
/**
* Used for shmem-backed YCbCr and (flavors of) RGBA textures
*/
struct SurfaceDescriptorShmem {
Shmem data;
@@ -108,14 +108,14 @@ union SurfaceDescriptor {
SurfaceDescriptorDIB;
SurfaceDescriptorD3D10;
SurfaceDescriptorX11;
SurfaceTextureDescriptor;
EGLImageDescriptor;
SurfaceStreamDescriptor;
SurfaceDescriptorMacIOSurface;
NewSurfaceDescriptorGralloc;
- ShSurfDescriptor;
+ SharedSurfaceDescriptor;
null_t;
};
} // namespace
} // namespace
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -12,32 +12,34 @@ EXPORTS += [
'basic/BasicPaintedLayer.h',
'client/ClientCanvasLayer.h',
'client/ClientContainerLayer.h',
'client/ClientLayerManager.h',
'client/ClientPaintedLayer.h',
'client/ClientTiledPaintedLayer.h',
'composite/CompositableHost.h',
'composite/ImageHost.h',
+ 'CompositorTypes.h',
'CopyableCanvasLayer.h',
'D3D9SurfaceImage.h',
'FrameMetrics.h',
'GLImages.h',
'GrallocImages.h',
'ImageContainer.h',
'ImageLayers.h',
'ImageTypes.h',
'ipc/CompositorChild.h',
'ipc/CompositorParent.h',
'ipc/ShadowLayersManager.h',
'ipc/ThreadSafeRefcountingWithMainThreadDestruction.h',
'Layers.h',
'LayerScope.h',
'LayersLogging.h',
'LayerSorter.h',
+ 'LayersTypes.h',
'LayerTreeInvalidation.h',
'opengl/Composer2D.h',
'opengl/OGLShaderProgram.h',
'opengl/TexturePoolOGL.h',
'protobuf/LayerScopePacket.pb.h',
'ReadbackLayer.h',
'TiledLayerBuffer.h',
]
@@ -93,17 +95,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
'd3d10/PaintedLayerD3D10.cpp',
'd3d10/ReadbackManagerD3D10.cpp',
'd3d11/TextureD3D11.cpp',
'ipc/ShadowLayerUtilsD3D10.cpp',
]
SOURCES += [
'd3d11/CompositorD3D11.cpp',
'd3d11/ReadbackManagerD3D11.cpp',
- ]
+ ]
if CONFIG['MOZ_ENABLE_DIRECT2D1_1']:
DEFINES['USE_D2D1_1'] = True
EXPORTS.gfxipc += [
'ipc/ShadowLayerUtils.h',
]
EXPORTS.mozilla.layers += [
--- a/gfx/layers/opengl/GrallocTextureClient.cpp
+++ b/gfx/layers/opengl/GrallocTextureClient.cpp
@@ -7,16 +7,17 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
#include "mozilla/layers/GrallocTextureClient.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/ShadowLayerUtilsGralloc.h"
#include "gfx2DGlue.h"
+#include "SharedSurfaceGralloc.h"
namespace mozilla {
namespace layers {
using namespace mozilla::gfx;
using namespace android;
GrallocTextureClientOGL::GrallocTextureClientOGL(MaybeMagicGrallocBufferHandle buffer,
@@ -107,17 +108,17 @@ GrallocTextureClientOGL::WaitForBufferOw
}
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
if (mReleaseFenceHandle.IsValid()) {
android::sp<Fence> fence = mReleaseFenceHandle.mFence;
#if ANDROID_VERSION == 17
fence->waitForever(1000, "GrallocTextureClientOGL::Lock");
// 1000 is what Android uses. It is warning timeout ms.
- // This timeous is removed since ANDROID_VERSION 18.
+ // This timeous is removed since ANDROID_VERSION 18.
#else
fence->waitForever("GrallocTextureClientOGL::Lock");
#endif
mReleaseFenceHandle = FenceHandle();
}
#endif
}
@@ -341,12 +342,35 @@ GrallocTextureClientOGL::Allocate(uint32
size_t
GrallocTextureClientOGL::GetBufferSize() const
{
// see Bug 908196
MOZ_CRASH("This method should never be called.");
return 0;
}
+/*static*/ TemporaryRef<TextureClient>
+GrallocTextureClientOGL::FromShSurf(gl::SharedSurface* abstractSurf,
+ TextureFlags flags)
+{
+ auto surf = gl::SharedSurface_Gralloc::Cast(abstractSurf);
+
+ RefPtr<TextureClient> ret = surf->GetTextureClient();
+
+ TextureFlags mask = TextureFlags::NEEDS_Y_FLIP |
+ TextureFlags::RB_SWAPPED |
+ TextureFlags::NON_PREMULTIPLIED;
+ TextureFlags required = flags & mask;
+ TextureFlags present = ret->GetFlags() & mask;
+
+ if (present != required) {
+ printf_stderr("Present flags: 0x%x. Required: 0x%x.\n",
+ (uint32_t)present,
+ (uint32_t)required);
+ MOZ_CRASH("Flag requirement mismatch.");
+ }
+ return ret.forget();
+}
+
} // namesapace layers
} // namesapace mozilla
#endif // MOZ_WIDGET_GONK
--- a/gfx/layers/opengl/GrallocTextureClient.h
+++ b/gfx/layers/opengl/GrallocTextureClient.h
@@ -113,16 +113,19 @@ public:
{
return mMediaBuffer;
}
virtual TemporaryRef<TextureClient>
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const MOZ_OVERRIDE;
+ static TemporaryRef<TextureClient> FromShSurf(gl::SharedSurface* surf,
+ TextureFlags flags);
+
protected:
/**
* Unfortunately, until bug 879681 is fixed we need to use a GrallocBufferActor.
*/
MaybeMagicGrallocBufferHandle mGrallocHandle;
RefPtr<AsyncTransactionTracker> mRemoveFromCompositableTracker;