mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 728524 - Public shared texture API + Canvas impl. r=bgirard,vlad,jgilbert
This commit is contained in:
parent
55fbefa166
commit
26b109bb23
@ -47,6 +47,7 @@ namespace mozilla {
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
|
||||
typedef uintptr_t SharedTextureHandle;
|
||||
|
||||
enum ShaderProgramType {
|
||||
RGBALayerProgramType,
|
||||
@ -98,6 +99,11 @@ public:
|
||||
ForceSingleTile = 0x4
|
||||
};
|
||||
|
||||
enum TextureShareType {
|
||||
ThreadShared = 0x0,
|
||||
ProcessShared = 0x1
|
||||
};
|
||||
|
||||
typedef gfxASurface::gfxContentType ContentType;
|
||||
|
||||
virtual ~TextureImage() {}
|
||||
@ -847,7 +853,43 @@ 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;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "gfxUtils.h"
|
||||
|
||||
#include "BasicLayersImpl.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
@ -312,13 +313,28 @@ public:
|
||||
|
||||
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);
|
||||
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);
|
||||
@ -354,6 +370,35 @@ 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) {
|
||||
@ -377,8 +422,7 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
FireDidTransactionCallback();
|
||||
|
||||
BasicManager()->PaintedCanvas(BasicManager()->Hold(this),
|
||||
mNeedsYFlip ? true : false,
|
||||
mBackBuffer);
|
||||
mNeedsYFlip, mBackBuffer);
|
||||
}
|
||||
|
||||
class BasicShadowCanvasLayer : public ShadowCanvasLayer,
|
||||
|
@ -21,6 +21,8 @@ using mozilla::layers::MagicGrallocBufferHandle;
|
||||
using mozilla::layers::SurfaceDescriptorX11;
|
||||
using mozilla::null_t;
|
||||
using mozilla::WindowsHandle;
|
||||
using mozilla::gl::SharedTextureHandle;
|
||||
using mozilla::gl::TextureImage::TextureShareType;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -34,6 +36,12 @@ struct SurfaceDescriptorD3D10 {
|
||||
WindowsHandle handle;
|
||||
};
|
||||
|
||||
struct SharedTextureDescriptor {
|
||||
TextureShareType shareType;
|
||||
SharedTextureHandle handle;
|
||||
nsIntSize size;
|
||||
};
|
||||
|
||||
struct SurfaceDescriptorGralloc {
|
||||
PGrallocBuffer buffer;
|
||||
};
|
||||
@ -47,6 +55,7 @@ union SurfaceDescriptor {
|
||||
SurfaceDescriptorD3D10;
|
||||
SurfaceDescriptorGralloc;
|
||||
SurfaceDescriptorX11;
|
||||
SharedTextureDescriptor;
|
||||
};
|
||||
|
||||
struct YUVImage {
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "IPC/IPCMessageUtils.h"
|
||||
#include "Layers.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
#if defined(MOZ_ENABLE_D3D10_LAYER)
|
||||
# include "mozilla/layers/ShadowLayerUtilsD3D10.h"
|
||||
@ -74,6 +75,29 @@ struct ParamTraits<mozilla::layers::SurfaceDescriptorX11> {
|
||||
};
|
||||
#endif // !defined(MOZ_HAVE_XSURFACEDESCRIPTORX11)
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(MOZ_HAVE_SURFACEDESCRIPTORGRALLOC)
|
||||
template <>
|
||||
struct ParamTraits<mozilla::layers::MagicGrallocBufferHandle> {
|
||||
|
@ -33,6 +33,23 @@ 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()
|
||||
{
|
||||
@ -72,7 +89,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
||||
} else {
|
||||
mLayerProgram = gl::RGBXLayerProgramType;
|
||||
}
|
||||
MakeTexture();
|
||||
MakeTextureIfNeeded(gl(), mTexture);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -98,7 +115,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
||||
GLint texSize = gl()->GetMaxTextureSize();
|
||||
if (mBounds.width > (2 + texSize) || mBounds.height > (2 + texSize)) {
|
||||
mDelayedUpdates = true;
|
||||
MakeTexture();
|
||||
MakeTextureIfNeeded(gl(), mTexture);
|
||||
// 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,
|
||||
@ -106,23 +123,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,
|
||||
* unless mDelayedUpdates is true because of a too-large surface.
|
||||
@ -157,7 +157,7 @@ CanvasLayerOGL::UpdateSurface()
|
||||
mTexture == 0)
|
||||
{
|
||||
mOGLManager->MakeCurrent();
|
||||
MakeTexture();
|
||||
MakeTextureIfNeeded(gl(), mTexture);
|
||||
}
|
||||
} else {
|
||||
nsRefPtr<gfxASurface> updatedAreaSurface;
|
||||
@ -285,11 +285,17 @@ 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);
|
||||
}
|
||||
@ -321,7 +327,20 @@ ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront,
|
||||
bool needYFlip,
|
||||
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 {
|
||||
AutoOpenSurface autoSurf(OPEN_READ_ONLY, aNewFront);
|
||||
gfxIntSize sz = autoSurf.Size();
|
||||
if (!mTexImage || mTexImage->GetSize() != sz ||
|
||||
@ -330,15 +349,23 @@ ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront,
|
||||
}
|
||||
nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height));
|
||||
mTexImage->DirectUpdate(autoSurf.Get(), 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
|
||||
@ -352,7 +379,7 @@ ShadowCanvasLayerOGL::Destroy()
|
||||
{
|
||||
if (!mDestroyed) {
|
||||
mDestroyed = true;
|
||||
mTexImage = nsnull;
|
||||
DestroyFrontBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
@ -366,16 +393,12 @@ void
|
||||
ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
||||
const nsIntPoint& aOffset)
|
||||
{
|
||||
if (!mTexImage) {
|
||||
if (!mTexImage && !IsValidSharedTexDescriptor(mFrontBufferDescriptor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mOGLManager->MakeCurrent();
|
||||
|
||||
ShaderProgramOGL *program =
|
||||
mOGLManager->GetProgram(mTexImage->GetShaderProgramType(),
|
||||
GetMaskLayer());
|
||||
|
||||
gfx3DMatrix effectiveTransform = GetEffectiveTransform();
|
||||
gfxPattern::GraphicsFilter filter = mFilter;
|
||||
#ifdef ANDROID
|
||||
@ -389,6 +412,16 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
||||
}
|
||||
#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);
|
||||
program->SetLayerOpacity(GetEffectiveOpacity());
|
||||
@ -396,30 +429,47 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
|
||||
program->SetTextureUnit(0);
|
||||
program->LoadMask(GetMaskLayer());
|
||||
|
||||
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());
|
||||
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 {
|
||||
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());
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,6 @@ protected:
|
||||
gl::ShaderProgramType mLayerProgram;
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
|
||||
void MakeTexture();
|
||||
GLuint mTexture;
|
||||
|
||||
bool mDelayedUpdates;
|
||||
@ -127,6 +126,8 @@ private:
|
||||
nsRefPtr<TextureImage> mTexImage;
|
||||
|
||||
bool mNeedsYFlip;
|
||||
SurfaceDescriptor mFrontBufferDescriptor;
|
||||
GLuint mTexture;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
|
Loading…
Reference in New Issue
Block a user