Backout 6087689a0745, 153e82923805, 255445a0a851 (bug 728524) on suspicion of causing bug 772405

This commit is contained in:
Ed Morley 2012-07-10 16:06:42 +01:00
Родитель 0b58e6703a
Коммит 0dd4a2cd88
8 изменённых файлов: 63 добавлений и 400 удалений

Просмотреть файл

@ -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 */