зеркало из https://github.com/mozilla/gecko-dev.git
Backout 6087689a0745, 153e82923805, 255445a0a851 (bug 728524) on suspicion of causing bug 772405
This commit is contained in:
Родитель
0b58e6703a
Коммит
0dd4a2cd88
|
@ -47,7 +47,6 @@ namespace mozilla {
|
|||
namespace gl {
|
||||
class GLContext;
|
||||
|
||||
typedef uintptr_t SharedTextureHandle;
|
||||
|
||||
enum ShaderProgramType {
|
||||
RGBALayerProgramType,
|
||||
|
@ -99,11 +98,6 @@ public:
|
|||
ForceSingleTile = 0x4
|
||||
};
|
||||
|
||||
enum TextureShareType {
|
||||
ThreadShared = 0x0,
|
||||
ProcessShared = 0x1
|
||||
};
|
||||
|
||||
typedef gfxASurface::gfxContentType ContentType;
|
||||
|
||||
virtual ~TextureImage() {}
|
||||
|
@ -853,43 +847,7 @@ public:
|
|||
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:
|
||||
GLuint mUserBoundDrawFBO;
|
||||
|
|
|
@ -258,7 +258,6 @@ public:
|
|||
, mIsPBuffer(false)
|
||||
, mIsDoubleBuffered(false)
|
||||
, mCanBindToTexture(false)
|
||||
, mShareWithEGLImage(false)
|
||||
{
|
||||
// any EGL contexts will always be GLESv2
|
||||
SetIsGLES2(true);
|
||||
|
@ -328,10 +327,6 @@ public:
|
|||
PR_STATIC_ASSERT(sizeof(GLint) >= sizeof(int32_t));
|
||||
mMaxTextureImageSize = PR_INT32_MAX;
|
||||
|
||||
mShareWithEGLImage = sEGLLibrary.HasKHRImageBase() &&
|
||||
sEGLLibrary.HasKHRImageTexture2D() &&
|
||||
IsExtensionSupported(OES_EGL_image);
|
||||
|
||||
if (ok)
|
||||
InitFramebuffers();
|
||||
|
||||
|
@ -589,13 +584,6 @@ public:
|
|||
return sEGLLibrary.HasKHRLockSurface();
|
||||
}
|
||||
|
||||
virtual SharedTextureHandle CreateSharedHandle(TextureImage::TextureShareType aType);
|
||||
virtual void UpdateSharedHandle(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle);
|
||||
virtual void ReleaseSharedHandle(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle);
|
||||
virtual bool AttachSharedHandle(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle);
|
||||
protected:
|
||||
friend class GLContextProviderEGL;
|
||||
|
||||
|
@ -609,7 +597,6 @@ protected:
|
|||
bool mIsPBuffer;
|
||||
bool mIsDoubleBuffered;
|
||||
bool mCanBindToTexture;
|
||||
bool mShareWithEGLImage;
|
||||
|
||||
static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
|
||||
EGLenum bindToTextureFormat,
|
||||
|
@ -655,161 +642,6 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
class EGLTextureWrapper
|
||||
{
|
||||
public:
|
||||
EGLTextureWrapper(GLContext* aContext, GLuint aTexture)
|
||||
: mContext(aContext)
|
||||
, mTexture(aTexture)
|
||||
, mEGLImage(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
bool CreateEGLImage() {
|
||||
MOZ_ASSERT(!mEGLImage && mTexture && sEGLLibrary.HasKHRImageBase());
|
||||
static const EGLint eglAttributes[] = {
|
||||
LOCAL_EGL_NONE
|
||||
};
|
||||
GLContextEGL* ctx = static_cast<GLContextEGL*>(mContext.get());
|
||||
mEGLImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), ctx->Context(), LOCAL_EGL_GL_TEXTURE_2D,
|
||||
(EGLClientBuffer)mTexture, eglAttributes);
|
||||
if (!mEGLImage) {
|
||||
#ifdef DEBUG
|
||||
printf_stderr("Could not create EGL images: ERROR (0x%04x)\n", sEGLLibrary.fGetError());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual ~EGLTextureWrapper() {
|
||||
if (mEGLImage) {
|
||||
sEGLLibrary.fDestroyImage(EGL_DISPLAY(), mEGLImage);
|
||||
mEGLImage = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
GLuint GetTextureID() {
|
||||
return mTexture;
|
||||
}
|
||||
|
||||
GLContext* GetContext() {
|
||||
return mContext.get();
|
||||
}
|
||||
|
||||
const EGLImage GetEGLImage() {
|
||||
return mEGLImage;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<GLContext> mContext;
|
||||
GLuint mTexture;
|
||||
EGLImage mEGLImage;
|
||||
};
|
||||
|
||||
void
|
||||
GLContextEGL::UpdateSharedHandle(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle)
|
||||
{
|
||||
if (aType != TextureImage::ThreadShared) {
|
||||
NS_ERROR("Implementation not available for this sharing type");
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
|
||||
|
||||
EGLTextureWrapper* wrap = (EGLTextureWrapper*)aSharedHandle;
|
||||
// We need to copy the current GLContext drawing buffer to the texture
|
||||
// exported by the EGLImage. Need to save both the read FBO and the texture
|
||||
// binding, because we're going to munge them to do this.
|
||||
GLuint prevRead = GetUserBoundReadFBO();
|
||||
GLint oldtex = -1;
|
||||
BindUserReadFBO(0);
|
||||
fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &oldtex);
|
||||
MOZ_ASSERT(oldtex != -1);
|
||||
fBindTexture(LOCAL_GL_TEXTURE_2D, wrap->GetTextureID());
|
||||
|
||||
// CopyTexSubImage2D, is ~2x slower than simple FBO render to texture with draw quads,
|
||||
// but render with draw quads require complex and hard to maintain context save/restore code
|
||||
fCopyTexSubImage2D(LOCAL_GL_TEXTURE_2D, 0, 0, 0,
|
||||
0, 0, mOffscreenActualSize.width,
|
||||
mOffscreenActualSize.height);
|
||||
|
||||
fBindTexture(LOCAL_GL_TEXTURE_2D, oldtex);
|
||||
BindUserReadFBO(prevRead);
|
||||
|
||||
// Make Shared Handle fully resolved in order to
|
||||
// guarantee content ready to draw in different thread GLContext
|
||||
GuaranteeResolve();
|
||||
}
|
||||
|
||||
SharedTextureHandle
|
||||
GLContextEGL::CreateSharedHandle(TextureImage::TextureShareType aType)
|
||||
{
|
||||
if (aType != TextureImage::ThreadShared)
|
||||
return nsnull;
|
||||
|
||||
if (!mShareWithEGLImage)
|
||||
return nsnull;
|
||||
|
||||
MakeCurrent();
|
||||
GLuint texture = 0;
|
||||
ContextFormat fmt = ActualFormat();
|
||||
CreateTextureForOffscreen(ChooseGLFormats(fmt), mOffscreenSize, texture);
|
||||
// texture ownership moved to EGLTextureWrapper after this point
|
||||
// and texture will be deleted in EGLTextureWrapper dtor
|
||||
EGLTextureWrapper* tex = new EGLTextureWrapper(this, texture);
|
||||
if (!tex->CreateEGLImage()) {
|
||||
NS_ERROR("EGLImage creation for EGLTextureWrapper failed");
|
||||
ReleaseSharedHandle(aType, (SharedTextureHandle)tex);
|
||||
|
||||
// Stop trying to create shared image Handle
|
||||
mShareWithEGLImage = false;
|
||||
return nsnull;
|
||||
}
|
||||
// Raw pointer shared across threads
|
||||
return (SharedTextureHandle)tex;
|
||||
}
|
||||
|
||||
void GLContextEGL::ReleaseSharedHandle(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle)
|
||||
{
|
||||
if (aType != TextureImage::ThreadShared) {
|
||||
NS_ERROR("Implementation not available for this sharing type");
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
|
||||
|
||||
EGLTextureWrapper* wrap = (EGLTextureWrapper*)aSharedHandle;
|
||||
GLContext *ctx = wrap->GetContext();
|
||||
if (ctx->IsDestroyed() || !ctx->IsOwningThreadCurrent()) {
|
||||
ctx = ctx->GetSharedContext();
|
||||
}
|
||||
// If we have a context, then we need to delete the texture;
|
||||
// if we don't have a context (either real or shared),
|
||||
// then they went away when the contex was deleted, because it
|
||||
// was the only one that had access to it.
|
||||
if (ctx && !ctx->IsDestroyed() && ctx->MakeCurrent()) {
|
||||
GLuint texture = wrap->GetTextureID();
|
||||
ctx->fDeleteTextures(1, &texture);
|
||||
}
|
||||
delete wrap;
|
||||
}
|
||||
|
||||
bool GLContextEGL::AttachSharedHandle(TextureImage::TextureShareType aType,
|
||||
SharedTextureHandle aSharedHandle)
|
||||
{
|
||||
if (aType != TextureImage::ThreadShared)
|
||||
return false;
|
||||
|
||||
NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime");
|
||||
|
||||
EGLTextureWrapper* wrap = (EGLTextureWrapper*)aSharedHandle;
|
||||
sEGLLibrary.fImageTargetTexture2DOES(LOCAL_GL_TEXTURE_2D, wrap->GetEGLImage());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GLContextEGL::BindTex2DOffscreen(GLContext *aOffscreen)
|
||||
{
|
||||
|
|
|
@ -3253,9 +3253,6 @@ typedef void* GLeglImage;
|
|||
#define LOCAL_EGL_DRAW 0x3059
|
||||
#define LOCAL_EGL_CONTEXT_LOST 0x300E
|
||||
|
||||
// EGL_KHR_gl_texture_2D_image
|
||||
#define LOCAL_EGL_GL_TEXTURE_2D 0x30B1
|
||||
|
||||
// EGL_KHR_fence_sync
|
||||
#define LOCAL_EGL_SYNC_FENCE 0x30F9
|
||||
#define LOCAL_EGL_SYNC_TYPE 0x30F7
|
||||
|
|
|
@ -9,13 +9,12 @@
|
|||
#include "gfxUtils.h"
|
||||
|
||||
#include "BasicLayersImpl.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
namespace layers {
|
||||
|
||||
class BasicCanvasLayer : public CanvasLayer,
|
||||
public BasicImplData
|
||||
{
|
||||
|
@ -313,28 +312,13 @@ public:
|
|||
|
||||
void DestroyBackBuffer()
|
||||
{
|
||||
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)) {
|
||||
if (IsSurfaceDescriptorValid(mBackBuffer)) {
|
||||
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer);
|
||||
mBackBuffer = SurfaceDescriptor();
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
return static_cast<BasicShadowLayerManager*>(mManager);
|
||||
|
@ -371,35 +355,6 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
|||
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);
|
||||
if (!IsSurfaceDescriptorValid(mBackBuffer) ||
|
||||
isOpaque != mBufferIsOpaque) {
|
||||
|
@ -425,7 +380,8 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
|||
FireDidTransactionCallback();
|
||||
|
||||
BasicManager()->PaintedCanvas(BasicManager()->Hold(this),
|
||||
mNeedsYFlip, mBackBuffer);
|
||||
mNeedsYFlip ? true : false,
|
||||
mBackBuffer);
|
||||
}
|
||||
|
||||
class BasicShadowCanvasLayer : public ShadowCanvasLayer,
|
||||
|
|
|
@ -23,8 +23,6 @@ using mozilla::layers::FrameMetrics;
|
|||
using mozilla::layers::SurfaceDescriptorX11;
|
||||
using mozilla::null_t;
|
||||
using mozilla::WindowsHandle;
|
||||
using mozilla::gl::SharedTextureHandle;
|
||||
using mozilla::gl::TextureImage::TextureShareType;
|
||||
|
||||
/**
|
||||
* The layers protocol is spoken between thread contexts that manage
|
||||
|
@ -48,17 +46,10 @@ struct SurfaceDescriptorD3D10 {
|
|||
WindowsHandle handle;
|
||||
};
|
||||
|
||||
struct SharedTextureDescriptor {
|
||||
TextureShareType shareType;
|
||||
SharedTextureHandle handle;
|
||||
nsIntSize size;
|
||||
};
|
||||
|
||||
union SurfaceDescriptor {
|
||||
Shmem;
|
||||
SurfaceDescriptorD3D10;
|
||||
SurfaceDescriptorX11;
|
||||
SharedTextureDescriptor;
|
||||
};
|
||||
|
||||
struct YUVImage {
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
#include "IPC/IPCMessageUtils.h"
|
||||
#include "Layers.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
#if defined(MOZ_ENABLE_D3D10_LAYER)
|
||||
# include "mozilla/layers/ShadowLayerUtilsD3D10.h"
|
||||
|
@ -65,29 +64,6 @@ struct ParamTraits<mozilla::layers::SurfaceDescriptorX11> {
|
|||
};
|
||||
#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
|
||||
|
|
|
@ -32,23 +32,6 @@ using namespace mozilla;
|
|||
using namespace mozilla::layers;
|
||||
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
|
||||
CanvasLayerOGL::Destroy()
|
||||
{
|
||||
|
@ -88,7 +71,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
|||
} else {
|
||||
mLayerProgram = gl::RGBXLayerProgramType;
|
||||
}
|
||||
MakeTextureIfNeeded(gl(), mTexture);
|
||||
MakeTexture();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -114,7 +97,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
|||
GLint texSize = gl()->GetMaxTextureSize();
|
||||
if (mBounds.width > (2 + texSize) || mBounds.height > (2 + texSize)) {
|
||||
mDelayedUpdates = true;
|
||||
MakeTextureIfNeeded(gl(), mTexture);
|
||||
MakeTexture();
|
||||
// This should only ever occur with 2d canvas, WebGL can't already have a texture
|
||||
// of this size can it?
|
||||
NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget,
|
||||
|
@ -122,6 +105,23 @@ 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,
|
||||
* unless mDelayedUpdates is true because of a too-large surface.
|
||||
|
@ -156,7 +156,7 @@ CanvasLayerOGL::UpdateSurface()
|
|||
mTexture == 0)
|
||||
{
|
||||
mOGLManager->MakeCurrent();
|
||||
MakeTextureIfNeeded(gl(), mTexture);
|
||||
MakeTexture();
|
||||
}
|
||||
} else {
|
||||
nsRefPtr<gfxASurface> updatedAreaSurface;
|
||||
|
@ -284,17 +284,11 @@ CanvasLayerOGL::CleanupResources()
|
|||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
IsValidSharedTexDescriptor(const SurfaceDescriptor& aDescriptor)
|
||||
{
|
||||
return aDescriptor.type() == SurfaceDescriptor::TSharedTextureDescriptor;
|
||||
}
|
||||
|
||||
ShadowCanvasLayerOGL::ShadowCanvasLayerOGL(LayerManagerOGL* aManager)
|
||||
: ShadowCanvasLayer(aManager, nsnull)
|
||||
, LayerOGL(aManager)
|
||||
, mNeedsYFlip(false)
|
||||
, mTexture(0)
|
||||
{
|
||||
mImplData = static_cast<LayerOGL*>(this);
|
||||
}
|
||||
|
@ -326,20 +320,7 @@ ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront,
|
|||
bool needYFlip,
|
||||
CanvasSurface* aNewBack)
|
||||
{
|
||||
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 {
|
||||
if (!mDestroyed) {
|
||||
nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront);
|
||||
gfxIntSize sz = surf->GetSize();
|
||||
if (!mTexImage || mTexImage->GetSize() != sz ||
|
||||
|
@ -348,23 +329,15 @@ ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront,
|
|||
}
|
||||
nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height));
|
||||
mTexImage->DirectUpdate(surf, updateRegion);
|
||||
*aNewBack = aNewFront;
|
||||
}
|
||||
|
||||
*aNewBack = aNewFront;
|
||||
}
|
||||
|
||||
void
|
||||
ShadowCanvasLayerOGL::DestroyFrontBuffer()
|
||||
{
|
||||
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
|
||||
|
@ -378,7 +351,7 @@ ShadowCanvasLayerOGL::Destroy()
|
|||
{
|
||||
if (!mDestroyed) {
|
||||
mDestroyed = true;
|
||||
DestroyFrontBuffer();
|
||||
mTexImage = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,8 +367,12 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
|||
{
|
||||
mOGLManager->MakeCurrent();
|
||||
|
||||
ShaderProgramOGL *program =
|
||||
mOGLManager->GetProgram(mTexImage->GetShaderProgramType(),
|
||||
GetMaskLayer());
|
||||
|
||||
|
||||
gfx3DMatrix effectiveTransform = GetEffectiveTransform();
|
||||
gfxPattern::GraphicsFilter filter = mFilter;
|
||||
#ifdef ANDROID
|
||||
// Bug 691354
|
||||
// Using the LINEAR filter we get unexplained artifacts.
|
||||
|
@ -403,19 +380,14 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
|||
gfxMatrix matrix;
|
||||
bool is2D = GetEffectiveTransform().Is2D(&matrix);
|
||||
if (is2D && !matrix.HasNonTranslationOrFlip()) {
|
||||
filter = gfxPattern::FILTER_NEAREST;
|
||||
mTexImage->SetFilter(gfxPattern::FILTER_NEAREST);
|
||||
} else {
|
||||
mTexImage->SetFilter(mFilter);
|
||||
}
|
||||
#else
|
||||
mTexImage->SetFilter(mFilter);
|
||||
#endif
|
||||
|
||||
ShaderProgramOGL *program;
|
||||
if (IsValidSharedTexDescriptor(mFrontBufferDescriptor)) {
|
||||
program = mOGLManager->GetBasicLayerProgram(CanUseOpaqueSurface(),
|
||||
true,
|
||||
GetMaskLayer() ? Mask2d : MaskNone);
|
||||
} else {
|
||||
program = mOGLManager->GetProgram(mTexImage->GetShaderProgramType(),
|
||||
GetMaskLayer());
|
||||
}
|
||||
|
||||
program->Activate();
|
||||
program->SetLayerTransform(effectiveTransform);
|
||||
|
@ -424,47 +396,29 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
|||
program->SetTextureUnit(0);
|
||||
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);
|
||||
mTexImage->BeginTileIteration();
|
||||
if (gl()->CanUploadNonPowerOfTwo()) {
|
||||
do {
|
||||
TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0);
|
||||
program->SetLayerQuadRect(mTexImage->GetTileRect());
|
||||
mOGLManager->BindAndDrawQuad(program, mNeedsYFlip); // FIXME flip order of tiles?
|
||||
} while (mTexImage->NextTile());
|
||||
} else {
|
||||
// Tiled texture image rendering path
|
||||
mTexImage->SetFilter(filter);
|
||||
mTexImage->BeginTileIteration();
|
||||
if (gl()->CanUploadNonPowerOfTwo()) {
|
||||
do {
|
||||
TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0);
|
||||
program->SetLayerQuadRect(mTexImage->GetTileRect());
|
||||
mOGLManager->BindAndDrawQuad(program, mNeedsYFlip); // FIXME flip order of tiles?
|
||||
} while (mTexImage->NextTile());
|
||||
} else {
|
||||
do {
|
||||
TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0);
|
||||
program->SetLayerQuadRect(mTexImage->GetTileRect());
|
||||
// We can't use BindAndDrawQuad because that always uploads the whole texture from 0.0f -> 1.0f
|
||||
// in x and y. We use BindAndDrawQuadWithTextureRect to actually draw a subrect of the texture
|
||||
// We need to reset the origin to 0,0 from the tile rect because the tile originates at 0,0 in the
|
||||
// actual texture, even though its origin in the composed (tiled) texture is not 0,0
|
||||
// FIXME: we need to handle mNeedsYFlip, Bug #728625
|
||||
mOGLManager->BindAndDrawQuadWithTextureRect(program,
|
||||
nsIntRect(0, 0, mTexImage->GetTileRect().width,
|
||||
mTexImage->GetTileRect().height),
|
||||
mTexImage->GetTileRect().Size(),
|
||||
mTexImage->GetWrapMode(),
|
||||
mNeedsYFlip);
|
||||
} while (mTexImage->NextTile());
|
||||
}
|
||||
do {
|
||||
TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0);
|
||||
program->SetLayerQuadRect(mTexImage->GetTileRect());
|
||||
// We can't use BindAndDrawQuad because that always uploads the whole texture from 0.0f -> 1.0f
|
||||
// in x and y. We use BindAndDrawQuadWithTextureRect to actually draw a subrect of the texture
|
||||
// We need to reset the origin to 0,0 from the tile rect because the tile originates at 0,0 in the
|
||||
// actual texture, even though its origin in the composed (tiled) texture is not 0,0
|
||||
// FIXME: we need to handle mNeedsYFlip, Bug #728625
|
||||
mOGLManager->BindAndDrawQuadWithTextureRect(program,
|
||||
nsIntRect(0, 0, mTexImage->GetTileRect().width,
|
||||
mTexImage->GetTileRect().height),
|
||||
mTexImage->GetTileRect().Size(),
|
||||
mTexImage->GetWrapMode(),
|
||||
mNeedsYFlip);
|
||||
} while (mTexImage->NextTile());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ protected:
|
|||
gl::ShaderProgramType mLayerProgram;
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
|
||||
void MakeTexture();
|
||||
GLuint mTexture;
|
||||
|
||||
bool mDelayedUpdates;
|
||||
|
@ -126,8 +127,6 @@ private:
|
|||
nsRefPtr<TextureImage> mTexImage;
|
||||
|
||||
bool mNeedsYFlip;
|
||||
SurfaceDescriptor mFrontBufferDescriptor;
|
||||
GLuint mTexture;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
|
|
Загрузка…
Ссылка в новой задаче