Bug 728524 - Public shared texture API + Canvas impl. r=bgirard,vlad,jgilbert
This commit is contained in:
@@ -47,6 +47,7 @@ namespace mozilla {
|
|||||||
namespace gl {
|
namespace gl {
|
||||||
class GLContext;
|
class GLContext;
|
||||||
|
|
||||||
|
typedef uintptr_t SharedTextureHandle;
|
||||||
|
|
||||||
enum ShaderProgramType {
|
enum ShaderProgramType {
|
||||||
RGBALayerProgramType,
|
RGBALayerProgramType,
|
||||||
@@ -98,6 +99,11 @@ public:
|
|||||||
ForceSingleTile = 0x4
|
ForceSingleTile = 0x4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TextureShareType {
|
||||||
|
ThreadShared = 0x0,
|
||||||
|
ProcessShared = 0x1
|
||||||
|
};
|
||||||
|
|
||||||
typedef gfxASurface::gfxContentType ContentType;
|
typedef gfxASurface::gfxContentType ContentType;
|
||||||
|
|
||||||
virtual ~TextureImage() {}
|
virtual ~TextureImage() {}
|
||||||
@@ -847,7 +853,43 @@ public:
|
|||||||
return IsExtensionSupported(EXT_framebuffer_blit) || IsExtensionSupported(ANGLE_framebuffer_blit);
|
return IsExtensionSupported(EXT_framebuffer_blit) || IsExtensionSupported(ANGLE_framebuffer_blit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new shared GLContext content handle, must be released by ReleaseSharedHandle.
|
||||||
|
*/
|
||||||
|
virtual SharedTextureHandle CreateSharedHandle(TextureImage::TextureShareType aType) { return nsnull; }
|
||||||
|
/**
|
||||||
|
* Publish GLContext content to intermediate buffer attached to shared handle.
|
||||||
|
* Shared handle content is ready to be used after call returns, and no need extra Flush/Finish are required.
|
||||||
|
* GLContext must be current before this call
|
||||||
|
*/
|
||||||
|
virtual void UpdateSharedHandle(TextureImage::TextureShareType aType,
|
||||||
|
SharedTextureHandle aSharedHandle) { }
|
||||||
|
/**
|
||||||
|
* - It is better to call ReleaseSharedHandle before original GLContext destroyed,
|
||||||
|
* otherwise warning will be thrown on attempt to destroy Texture associated with SharedHandle, depends on backend implementation.
|
||||||
|
* - It does not require to be called on context where it was created,
|
||||||
|
* because SharedHandle suppose to keep Context reference internally,
|
||||||
|
* or don't require specific context at all, for example IPC SharedHandle.
|
||||||
|
* - Not recommended to call this between AttachSharedHandle and Draw Target call.
|
||||||
|
* if it is really required for some special backend, then DetachSharedHandle API must be added with related implementation.
|
||||||
|
* - It is recommended to stop any possible access to SharedHandle (Attachments, pending GL calls) before calling Release,
|
||||||
|
* otherwise some artifacts might appear or even crash if API backend implementation does not expect that.
|
||||||
|
* SharedHandle (currently EGLImage) does not require GLContext because it is EGL call, and can be destroyed
|
||||||
|
* at any time, unless EGLImage have siblings (which are not expected with current API).
|
||||||
|
*/
|
||||||
|
virtual void ReleaseSharedHandle(TextureImage::TextureShareType aType,
|
||||||
|
SharedTextureHandle aSharedHandle) { }
|
||||||
|
/**
|
||||||
|
* Attach Shared GL Handle to GL_TEXTURE_2D target
|
||||||
|
* GLContext must be current before this call
|
||||||
|
*/
|
||||||
|
virtual bool AttachSharedHandle(TextureImage::TextureShareType aType,
|
||||||
|
SharedTextureHandle aSharedHandle) { return false; }
|
||||||
|
/**
|
||||||
|
* Detach Shared GL Handle from GL_TEXTURE_2D target
|
||||||
|
*/
|
||||||
|
virtual void DetachSharedHandle(TextureImage::TextureShareType aType,
|
||||||
|
SharedTextureHandle aSharedHandle) { return; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint mUserBoundDrawFBO;
|
GLuint mUserBoundDrawFBO;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "gfxUtils.h"
|
#include "gfxUtils.h"
|
||||||
|
|
||||||
#include "BasicLayersImpl.h"
|
#include "BasicLayersImpl.h"
|
||||||
|
#include "nsXULAppAPI.h"
|
||||||
|
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
|
|
||||||
@@ -312,13 +313,28 @@ public:
|
|||||||
|
|
||||||
void DestroyBackBuffer()
|
void DestroyBackBuffer()
|
||||||
{
|
{
|
||||||
if (IsSurfaceDescriptorValid(mBackBuffer)) {
|
if (mBackBuffer.type() == SurfaceDescriptor::TSharedTextureDescriptor) {
|
||||||
|
SharedTextureDescriptor handle = mBackBuffer.get_SharedTextureDescriptor();
|
||||||
|
if (mGLContext && handle.handle()) {
|
||||||
|
mGLContext->ReleaseSharedHandle(handle.shareType(), handle.handle());
|
||||||
|
mBackBuffer = SurfaceDescriptor();
|
||||||
|
}
|
||||||
|
} else if (IsSurfaceDescriptorValid(mBackBuffer)) {
|
||||||
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer);
|
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer);
|
||||||
mBackBuffer = SurfaceDescriptor();
|
mBackBuffer = SurfaceDescriptor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef mozilla::gl::SharedTextureHandle SharedTextureHandle;
|
||||||
|
typedef mozilla::gl::TextureImage TextureImage;
|
||||||
|
SharedTextureHandle GetSharedBackBufferHandle()
|
||||||
|
{
|
||||||
|
if (mBackBuffer.type() == SurfaceDescriptor::TSharedTextureDescriptor)
|
||||||
|
return mBackBuffer.get_SharedTextureDescriptor().handle();
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
BasicShadowLayerManager* BasicManager()
|
BasicShadowLayerManager* BasicManager()
|
||||||
{
|
{
|
||||||
return static_cast<BasicShadowLayerManager*>(mManager);
|
return static_cast<BasicShadowLayerManager*>(mManager);
|
||||||
@@ -355,6 +371,35 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mGLContext &&
|
||||||
|
BasicManager()->GetParentBackendType() == LayerManager::LAYERS_OPENGL) {
|
||||||
|
TextureImage::TextureShareType flags;
|
||||||
|
// if process type is default, then it is single-process (non-e10s)
|
||||||
|
if (XRE_GetProcessType() == GeckoProcessType_Default)
|
||||||
|
flags = TextureImage::ThreadShared;
|
||||||
|
else
|
||||||
|
flags = TextureImage::ProcessShared;
|
||||||
|
|
||||||
|
SharedTextureHandle handle = GetSharedBackBufferHandle();
|
||||||
|
if (!handle) {
|
||||||
|
handle = mGLContext->CreateSharedHandle(flags);
|
||||||
|
if (handle) {
|
||||||
|
mBackBuffer = SharedTextureDescriptor(flags, handle, mBounds.Size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (handle) {
|
||||||
|
mGLContext->MakeCurrent();
|
||||||
|
mGLContext->UpdateSharedHandle(flags, handle);
|
||||||
|
FireDidTransactionCallback();
|
||||||
|
BasicManager()->PaintedCanvas(BasicManager()->Hold(this),
|
||||||
|
mNeedsYFlip,
|
||||||
|
mBackBuffer);
|
||||||
|
// Move SharedTextureHandle ownership to ShadowLayer
|
||||||
|
mBackBuffer = SurfaceDescriptor();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool isOpaque = (GetContentFlags() & CONTENT_OPAQUE);
|
bool isOpaque = (GetContentFlags() & CONTENT_OPAQUE);
|
||||||
if (!IsSurfaceDescriptorValid(mBackBuffer) ||
|
if (!IsSurfaceDescriptorValid(mBackBuffer) ||
|
||||||
isOpaque != mBufferIsOpaque) {
|
isOpaque != mBufferIsOpaque) {
|
||||||
@@ -380,8 +425,7 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
|||||||
FireDidTransactionCallback();
|
FireDidTransactionCallback();
|
||||||
|
|
||||||
BasicManager()->PaintedCanvas(BasicManager()->Hold(this),
|
BasicManager()->PaintedCanvas(BasicManager()->Hold(this),
|
||||||
mNeedsYFlip ? true : false,
|
mNeedsYFlip, mBackBuffer);
|
||||||
mBackBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class BasicShadowCanvasLayer : public ShadowCanvasLayer,
|
class BasicShadowCanvasLayer : public ShadowCanvasLayer,
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ using mozilla::layers::FrameMetrics;
|
|||||||
using mozilla::layers::SurfaceDescriptorX11;
|
using mozilla::layers::SurfaceDescriptorX11;
|
||||||
using mozilla::null_t;
|
using mozilla::null_t;
|
||||||
using mozilla::WindowsHandle;
|
using mozilla::WindowsHandle;
|
||||||
|
using mozilla::gl::SharedTextureHandle;
|
||||||
|
using mozilla::gl::TextureImage::TextureShareType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The layers protocol is spoken between thread contexts that manage
|
* The layers protocol is spoken between thread contexts that manage
|
||||||
@@ -46,10 +48,17 @@ struct SurfaceDescriptorD3D10 {
|
|||||||
WindowsHandle handle;
|
WindowsHandle handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SharedTextureDescriptor {
|
||||||
|
TextureShareType shareType;
|
||||||
|
SharedTextureHandle handle;
|
||||||
|
nsIntSize size;
|
||||||
|
};
|
||||||
|
|
||||||
union SurfaceDescriptor {
|
union SurfaceDescriptor {
|
||||||
Shmem;
|
Shmem;
|
||||||
SurfaceDescriptorD3D10;
|
SurfaceDescriptorD3D10;
|
||||||
SurfaceDescriptorX11;
|
SurfaceDescriptorX11;
|
||||||
|
SharedTextureDescriptor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct YUVImage {
|
struct YUVImage {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "IPC/IPCMessageUtils.h"
|
#include "IPC/IPCMessageUtils.h"
|
||||||
#include "Layers.h"
|
#include "Layers.h"
|
||||||
|
#include "GLContext.h"
|
||||||
|
|
||||||
#if defined(MOZ_ENABLE_D3D10_LAYER)
|
#if defined(MOZ_ENABLE_D3D10_LAYER)
|
||||||
# include "mozilla/layers/ShadowLayerUtilsD3D10.h"
|
# include "mozilla/layers/ShadowLayerUtilsD3D10.h"
|
||||||
@@ -64,6 +65,29 @@ struct ParamTraits<mozilla::layers::SurfaceDescriptorX11> {
|
|||||||
};
|
};
|
||||||
#endif // !defined(MOZ_HAVE_XSURFACEDESCRIPTOR)
|
#endif // !defined(MOZ_HAVE_XSURFACEDESCRIPTOR)
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ParamTraits<mozilla::gl::TextureImage::TextureShareType>
|
||||||
|
{
|
||||||
|
typedef mozilla::gl::TextureImage::TextureShareType paramType;
|
||||||
|
|
||||||
|
static void Write(Message* msg, const paramType& param)
|
||||||
|
{
|
||||||
|
MOZ_STATIC_ASSERT(sizeof(paramType) <= sizeof(int32),
|
||||||
|
"TextureShareType assumes to be int32");
|
||||||
|
WriteParam(msg, int32(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||||
|
{
|
||||||
|
int32 type;
|
||||||
|
if (!ReadParam(msg, iter, &type))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*result = paramType(type);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // IPC_ShadowLayerUtils_h
|
#endif // IPC_ShadowLayerUtils_h
|
||||||
|
|||||||
@@ -32,6 +32,23 @@ using namespace mozilla;
|
|||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
using namespace mozilla::gl;
|
using namespace mozilla::gl;
|
||||||
|
|
||||||
|
static void
|
||||||
|
MakeTextureIfNeeded(GLContext* gl, GLuint& aTexture)
|
||||||
|
{
|
||||||
|
if (aTexture != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gl->fGenTextures(1, &aTexture);
|
||||||
|
|
||||||
|
gl->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||||
|
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
|
||||||
|
|
||||||
|
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
|
||||||
|
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
|
||||||
|
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
|
||||||
|
gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CanvasLayerOGL::Destroy()
|
CanvasLayerOGL::Destroy()
|
||||||
{
|
{
|
||||||
@@ -71,7 +88,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
|||||||
} else {
|
} else {
|
||||||
mLayerProgram = gl::RGBXLayerProgramType;
|
mLayerProgram = gl::RGBXLayerProgramType;
|
||||||
}
|
}
|
||||||
MakeTexture();
|
MakeTextureIfNeeded(gl(), mTexture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -97,7 +114,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
|||||||
GLint texSize = gl()->GetMaxTextureSize();
|
GLint texSize = gl()->GetMaxTextureSize();
|
||||||
if (mBounds.width > (2 + texSize) || mBounds.height > (2 + texSize)) {
|
if (mBounds.width > (2 + texSize) || mBounds.height > (2 + texSize)) {
|
||||||
mDelayedUpdates = true;
|
mDelayedUpdates = true;
|
||||||
MakeTexture();
|
MakeTextureIfNeeded(gl(), mTexture);
|
||||||
// This should only ever occur with 2d canvas, WebGL can't already have a texture
|
// This should only ever occur with 2d canvas, WebGL can't already have a texture
|
||||||
// of this size can it?
|
// of this size can it?
|
||||||
NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget,
|
NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget,
|
||||||
@@ -105,23 +122,6 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CanvasLayerOGL::MakeTexture()
|
|
||||||
{
|
|
||||||
if (mTexture != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gl()->fGenTextures(1, &mTexture);
|
|
||||||
|
|
||||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
|
||||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
|
|
||||||
|
|
||||||
gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
|
|
||||||
gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
|
|
||||||
gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
|
|
||||||
gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Following UpdateSurface(), mTexture on context this->gl() should contain the data we want,
|
* Following UpdateSurface(), mTexture on context this->gl() should contain the data we want,
|
||||||
* unless mDelayedUpdates is true because of a too-large surface.
|
* unless mDelayedUpdates is true because of a too-large surface.
|
||||||
@@ -156,7 +156,7 @@ CanvasLayerOGL::UpdateSurface()
|
|||||||
mTexture == 0)
|
mTexture == 0)
|
||||||
{
|
{
|
||||||
mOGLManager->MakeCurrent();
|
mOGLManager->MakeCurrent();
|
||||||
MakeTexture();
|
MakeTextureIfNeeded(gl(), mTexture);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nsRefPtr<gfxASurface> updatedAreaSurface;
|
nsRefPtr<gfxASurface> updatedAreaSurface;
|
||||||
@@ -284,11 +284,17 @@ CanvasLayerOGL::CleanupResources()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
IsValidSharedTexDescriptor(const SurfaceDescriptor& aDescriptor)
|
||||||
|
{
|
||||||
|
return aDescriptor.type() == SurfaceDescriptor::TSharedTextureDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
ShadowCanvasLayerOGL::ShadowCanvasLayerOGL(LayerManagerOGL* aManager)
|
ShadowCanvasLayerOGL::ShadowCanvasLayerOGL(LayerManagerOGL* aManager)
|
||||||
: ShadowCanvasLayer(aManager, nsnull)
|
: ShadowCanvasLayer(aManager, nsnull)
|
||||||
, LayerOGL(aManager)
|
, LayerOGL(aManager)
|
||||||
, mNeedsYFlip(false)
|
, mNeedsYFlip(false)
|
||||||
|
, mTexture(0)
|
||||||
{
|
{
|
||||||
mImplData = static_cast<LayerOGL*>(this);
|
mImplData = static_cast<LayerOGL*>(this);
|
||||||
}
|
}
|
||||||
@@ -320,7 +326,20 @@ ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront,
|
|||||||
bool needYFlip,
|
bool needYFlip,
|
||||||
CanvasSurface* aNewBack)
|
CanvasSurface* aNewBack)
|
||||||
{
|
{
|
||||||
if (!mDestroyed) {
|
if (mDestroyed) {
|
||||||
|
*aNewBack = aNewFront;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsValidSharedTexDescriptor(aNewFront)) {
|
||||||
|
MakeTextureIfNeeded(gl(), mTexture);
|
||||||
|
if (!IsValidSharedTexDescriptor(mFrontBufferDescriptor)) {
|
||||||
|
mFrontBufferDescriptor = SharedTextureDescriptor(TextureImage::ThreadShared, 0, nsIntSize(0, 0));
|
||||||
|
}
|
||||||
|
*aNewBack = mFrontBufferDescriptor;
|
||||||
|
mFrontBufferDescriptor = aNewFront;
|
||||||
|
mNeedsYFlip = needYFlip;
|
||||||
|
} else {
|
||||||
nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront);
|
nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront);
|
||||||
gfxIntSize sz = surf->GetSize();
|
gfxIntSize sz = surf->GetSize();
|
||||||
if (!mTexImage || mTexImage->GetSize() != sz ||
|
if (!mTexImage || mTexImage->GetSize() != sz ||
|
||||||
@@ -329,15 +348,23 @@ ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront,
|
|||||||
}
|
}
|
||||||
nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height));
|
nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height));
|
||||||
mTexImage->DirectUpdate(surf, updateRegion);
|
mTexImage->DirectUpdate(surf, updateRegion);
|
||||||
}
|
|
||||||
|
|
||||||
*aNewBack = aNewFront;
|
*aNewBack = aNewFront;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShadowCanvasLayerOGL::DestroyFrontBuffer()
|
ShadowCanvasLayerOGL::DestroyFrontBuffer()
|
||||||
{
|
{
|
||||||
mTexImage = nsnull;
|
mTexImage = nsnull;
|
||||||
|
if (mTexture) {
|
||||||
|
gl()->MakeCurrent();
|
||||||
|
gl()->fDeleteTextures(1, &mTexture);
|
||||||
|
}
|
||||||
|
if (IsValidSharedTexDescriptor(mFrontBufferDescriptor)) {
|
||||||
|
SharedTextureDescriptor texDescriptor = mFrontBufferDescriptor.get_SharedTextureDescriptor();
|
||||||
|
gl()->ReleaseSharedHandle(texDescriptor.shareType(), texDescriptor.handle());
|
||||||
|
mFrontBufferDescriptor = SurfaceDescriptor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -351,7 +378,7 @@ ShadowCanvasLayerOGL::Destroy()
|
|||||||
{
|
{
|
||||||
if (!mDestroyed) {
|
if (!mDestroyed) {
|
||||||
mDestroyed = true;
|
mDestroyed = true;
|
||||||
mTexImage = nsnull;
|
DestroyFrontBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,10 +394,6 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
|||||||
{
|
{
|
||||||
mOGLManager->MakeCurrent();
|
mOGLManager->MakeCurrent();
|
||||||
|
|
||||||
ShaderProgramOGL *program =
|
|
||||||
mOGLManager->GetProgram(mTexImage->GetShaderProgramType(),
|
|
||||||
GetMaskLayer());
|
|
||||||
|
|
||||||
gfx3DMatrix effectiveTransform = GetEffectiveTransform();
|
gfx3DMatrix effectiveTransform = GetEffectiveTransform();
|
||||||
gfxPattern::GraphicsFilter filter = mFilter;
|
gfxPattern::GraphicsFilter filter = mFilter;
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
@@ -384,6 +407,16 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ShaderProgramOGL *program;
|
||||||
|
if (IsValidSharedTexDescriptor(mFrontBufferDescriptor)) {
|
||||||
|
program = mOGLManager->GetBasicLayerProgram(CanUseOpaqueSurface(),
|
||||||
|
true,
|
||||||
|
GetMaskLayer() ? Mask2d : MaskNone);
|
||||||
|
} else {
|
||||||
|
program = mOGLManager->GetProgram(mTexImage->GetShaderProgramType(),
|
||||||
|
GetMaskLayer());
|
||||||
|
}
|
||||||
|
|
||||||
program->Activate();
|
program->Activate();
|
||||||
program->SetLayerTransform(effectiveTransform);
|
program->SetLayerTransform(effectiveTransform);
|
||||||
program->SetLayerOpacity(GetEffectiveOpacity());
|
program->SetLayerOpacity(GetEffectiveOpacity());
|
||||||
@@ -391,6 +424,22 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
|||||||
program->SetTextureUnit(0);
|
program->SetTextureUnit(0);
|
||||||
program->LoadMask(GetMaskLayer());
|
program->LoadMask(GetMaskLayer());
|
||||||
|
|
||||||
|
if (IsValidSharedTexDescriptor(mFrontBufferDescriptor)) {
|
||||||
|
// Shared texture handle rendering path, single texture rendering
|
||||||
|
SharedTextureDescriptor texDescriptor = mFrontBufferDescriptor.get_SharedTextureDescriptor();
|
||||||
|
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||||
|
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
|
||||||
|
if (!gl()->AttachSharedHandle(texDescriptor.shareType(), texDescriptor.handle())) {
|
||||||
|
NS_ERROR("Failed to attach shared texture handle");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gl()->ApplyFilterToBoundTexture(filter);
|
||||||
|
program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), texDescriptor.size()));
|
||||||
|
mOGLManager->BindAndDrawQuad(program, mNeedsYFlip);
|
||||||
|
gl()->DetachSharedHandle(texDescriptor.shareType(), texDescriptor.handle());
|
||||||
|
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, 0);
|
||||||
|
} else {
|
||||||
|
// Tiled texture image rendering path
|
||||||
mTexImage->SetFilter(filter);
|
mTexImage->SetFilter(filter);
|
||||||
mTexImage->BeginTileIteration();
|
mTexImage->BeginTileIteration();
|
||||||
if (gl()->CanUploadNonPowerOfTwo()) {
|
if (gl()->CanUploadNonPowerOfTwo()) {
|
||||||
@@ -416,6 +465,7 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
|||||||
mNeedsYFlip);
|
mNeedsYFlip);
|
||||||
} while (mTexImage->NextTile());
|
} while (mTexImage->NextTile());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ protected:
|
|||||||
gl::ShaderProgramType mLayerProgram;
|
gl::ShaderProgramType mLayerProgram;
|
||||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||||
|
|
||||||
void MakeTexture();
|
|
||||||
GLuint mTexture;
|
GLuint mTexture;
|
||||||
|
|
||||||
bool mDelayedUpdates;
|
bool mDelayedUpdates;
|
||||||
@@ -127,6 +126,8 @@ private:
|
|||||||
nsRefPtr<TextureImage> mTexImage;
|
nsRefPtr<TextureImage> mTexImage;
|
||||||
|
|
||||||
bool mNeedsYFlip;
|
bool mNeedsYFlip;
|
||||||
|
SurfaceDescriptor mFrontBufferDescriptor;
|
||||||
|
GLuint mTexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* layers */
|
} /* layers */
|
||||||
|
|||||||
Reference in New Issue
Block a user