mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-06 12:43:53 +00:00
Backed out 4 changesets (bug 1012407) for b2g reftest5 orange on an otherwise CLOSED TREE
Backed out changeset 08e17f48aed1 (bug 1012407) Backed out changeset b17b7b59cf88 (bug 1012407) Backed out changeset 1c692df3f080 (bug 1012407) Backed out changeset 560bd45d52de (bug 1012407)
This commit is contained in:
parent
1df17c8b4b
commit
fd7188a2e3
@ -37,6 +37,25 @@ RectTriangles::addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
|
||||
AppendRectToCoordArray(mTexCoords, tx0, ty0, tx1, ty1);
|
||||
}
|
||||
|
||||
bool
|
||||
RectTriangles::isSimpleQuad(gfx3DMatrix& aOutTextureTransform) const
|
||||
{
|
||||
if (mVertexCoords.Length() == 6 &&
|
||||
mVertexCoords[0].x == 0.0f &&
|
||||
mVertexCoords[0].y == 0.0f &&
|
||||
mVertexCoords[5].x == 1.0f &&
|
||||
mVertexCoords[5].y == 1.0f)
|
||||
{
|
||||
GLfloat tx0 = mTexCoords[0].x;
|
||||
GLfloat ty0 = mTexCoords[0].y;
|
||||
GLfloat tx1 = mTexCoords[5].x;
|
||||
GLfloat ty1 = mTexCoords[5].y;
|
||||
aOutTextureTransform = gfx3DMatrix::From2D(gfxMatrix(tx1 - tx0, 0, 0, ty1 - ty0, tx0, ty0));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static GLfloat
|
||||
WrapTexCoord(GLfloat v)
|
||||
{
|
||||
|
@ -28,6 +28,13 @@ public:
|
||||
GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1,
|
||||
bool flip_y = false);
|
||||
|
||||
// Returns whether this object is made of only one rect that can be drawn
|
||||
// with a pre-buffered unity quad which has 0,0,1,1 as both vertex
|
||||
// positions and texture coordinates.
|
||||
// aOutTextureTransform returns the transform that maps 0,0,1,1 texture
|
||||
// coordinates to the correct ones.
|
||||
bool isSimpleQuad(gfx3DMatrix& aOutTextureTransform) const;
|
||||
|
||||
/**
|
||||
* these return a float pointer to the start of each array respectively.
|
||||
* Use it for glVertexAttribPointer calls.
|
||||
|
37
gfx/gl/VBOArena.cpp
Normal file
37
gfx/gl/VBOArena.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 "VBOArena.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla::gl;
|
||||
|
||||
GLuint VBOArena::Allocate(GLContext *aGLContext)
|
||||
{
|
||||
if (!mAvailableVBOs.size()) {
|
||||
GLuint vbo;
|
||||
aGLContext->fGenBuffers(1, &vbo);
|
||||
mAllocatedVBOs.push_back(vbo);
|
||||
return vbo;
|
||||
}
|
||||
GLuint vbo = mAvailableVBOs.back();
|
||||
mAvailableVBOs.pop_back();
|
||||
return vbo;
|
||||
}
|
||||
|
||||
void VBOArena::Reset()
|
||||
{
|
||||
mAvailableVBOs = mAllocatedVBOs;
|
||||
}
|
||||
|
||||
void VBOArena::Flush(GLContext *aGLContext)
|
||||
{
|
||||
if (mAvailableVBOs.size()) {
|
||||
#ifdef DEBUG
|
||||
printf_stderr("VBOArena::Flush for %u VBOs\n", mAvailableVBOs.size());
|
||||
#endif
|
||||
aGLContext->fDeleteBuffers(mAvailableVBOs.size(), &mAvailableVBOs[0]);
|
||||
}
|
||||
}
|
35
gfx/gl/VBOArena.h
Normal file
35
gfx/gl/VBOArena.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 VBOARENA_H_
|
||||
#define VBOARENA_H_
|
||||
|
||||
#include "GLTypes.h"
|
||||
#include <vector>
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class GLContext;
|
||||
|
||||
class VBOArena {
|
||||
public:
|
||||
// Allocate a new VBO.
|
||||
GLuint Allocate(GLContext *aGLContext);
|
||||
|
||||
// Re-use previously allocated VBOs.
|
||||
void Reset();
|
||||
|
||||
// Throw away all allocated VBOs.
|
||||
void Flush(GLContext *aGLContext);
|
||||
private:
|
||||
std::vector<GLuint> mAllocatedVBOs;
|
||||
std::vector<GLuint> mAvailableVBOs;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -55,6 +55,7 @@ EXPORTS += [
|
||||
'SurfaceStream.h',
|
||||
'SurfaceTypes.h',
|
||||
'TextureGarbageBin.h',
|
||||
'VBOArena.h',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_X11']:
|
||||
@ -139,6 +140,7 @@ UNIFIED_SOURCES += [
|
||||
'SurfaceTypes.cpp',
|
||||
'TextureGarbageBin.cpp',
|
||||
'TextureImageEGL.cpp',
|
||||
'VBOArena.cpp',
|
||||
]
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "mozilla/RefPtr.h" // for TemporaryRef, RefCounted
|
||||
#include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
|
||||
#include "nsTArray.h" // for nsAutoTArray, nsTArray_Impl, etc
|
||||
#include "VBOArena.h" // for gl::VBOArena
|
||||
#include "prio.h" // for NSPR file i/o
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "nsRect.h" // for nsIntRect
|
||||
#include "nsServiceManagerUtils.h" // for do_GetService
|
||||
#include "nsString.h" // for nsString, nsAutoCString, etc
|
||||
#include "DecomposeIntoNoRepeatTriangles.h"
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "GLReadTexImageHelper.h"
|
||||
#include "TiledLayerBuffer.h" // for TiledLayerComposer
|
||||
@ -81,6 +82,65 @@ BindMaskForProgram(ShaderProgramOGL* aProgram, TextureSourceOGL* aSourceMask,
|
||||
aProgram->SetMaskLayerTransform(aTransform);
|
||||
}
|
||||
|
||||
// Draw the given quads with the already selected shader. Texture coordinates
|
||||
// are supplied if the shader requires them.
|
||||
static void
|
||||
DrawQuads(GLContext *aGLContext,
|
||||
VBOArena &aVBOs,
|
||||
ShaderProgramOGL *aProg,
|
||||
GLenum aMode,
|
||||
RectTriangles &aRects)
|
||||
{
|
||||
NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized");
|
||||
GLuint vertAttribIndex =
|
||||
aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib);
|
||||
GLuint texCoordAttribIndex =
|
||||
aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
|
||||
bool texCoords = (texCoordAttribIndex != GLuint(-1));
|
||||
|
||||
GLsizei bytes = aRects.elements() * 2 * sizeof(GLfloat);
|
||||
|
||||
GLsizei total = bytes;
|
||||
if (texCoords) {
|
||||
total *= 2;
|
||||
}
|
||||
|
||||
aGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER,
|
||||
aVBOs.Allocate(aGLContext));
|
||||
aGLContext->fBufferData(LOCAL_GL_ARRAY_BUFFER,
|
||||
total,
|
||||
nullptr,
|
||||
LOCAL_GL_STREAM_DRAW);
|
||||
|
||||
aGLContext->fBufferSubData(LOCAL_GL_ARRAY_BUFFER,
|
||||
0,
|
||||
bytes,
|
||||
aRects.vertCoords().Elements());
|
||||
aGLContext->fEnableVertexAttribArray(vertAttribIndex);
|
||||
aGLContext->fVertexAttribPointer(vertAttribIndex,
|
||||
2, LOCAL_GL_FLOAT,
|
||||
LOCAL_GL_FALSE,
|
||||
0, BUFFER_OFFSET(0));
|
||||
|
||||
if (texCoords) {
|
||||
aGLContext->fBufferSubData(LOCAL_GL_ARRAY_BUFFER,
|
||||
bytes,
|
||||
bytes,
|
||||
aRects.texCoords().Elements());
|
||||
aGLContext->fEnableVertexAttribArray(texCoordAttribIndex);
|
||||
aGLContext->fVertexAttribPointer(texCoordAttribIndex,
|
||||
2, LOCAL_GL_FLOAT,
|
||||
LOCAL_GL_FALSE,
|
||||
0, BUFFER_OFFSET(bytes));
|
||||
} else {
|
||||
aGLContext->fDisableVertexAttribArray(texCoordAttribIndex);
|
||||
}
|
||||
|
||||
aGLContext->fDrawArrays(aMode, 0, aRects.elements());
|
||||
|
||||
aGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
CompositorOGL::CompositorOGL(nsIWidget *aWidget, int aSurfaceWidth,
|
||||
int aSurfaceHeight, bool aUseExternalSurfaceSize)
|
||||
: mWidget(aWidget)
|
||||
@ -127,6 +187,10 @@ CompositorOGL::CreateContext()
|
||||
void
|
||||
CompositorOGL::Destroy()
|
||||
{
|
||||
if (gl() && gl()->MakeCurrent()) {
|
||||
mVBOs.Flush(gl());
|
||||
}
|
||||
|
||||
if (mTexturePool) {
|
||||
mTexturePool->Clear();
|
||||
mTexturePool = nullptr;
|
||||
@ -303,24 +367,11 @@ CompositorOGL::Initialize()
|
||||
mGLContext->fGenBuffers(1, &mQuadVBO);
|
||||
mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO);
|
||||
|
||||
// 4 quads, with the number of the quad (vertexID) encoded in w.
|
||||
GLfloat vertices[] = {
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.0f, 1.0f, 0.0f, 1.0f,
|
||||
1.0f, 1.0f, 0.0f, 1.0f,
|
||||
0.0f, 0.0f, 0.0f, 2.0f,
|
||||
1.0f, 0.0f, 0.0f, 2.0f,
|
||||
0.0f, 1.0f, 0.0f, 2.0f,
|
||||
1.0f, 1.0f, 0.0f, 2.0f,
|
||||
0.0f, 0.0f, 0.0f, 3.0f,
|
||||
1.0f, 0.0f, 0.0f, 3.0f,
|
||||
0.0f, 1.0f, 0.0f, 3.0f,
|
||||
1.0f, 1.0f, 0.0f, 3.0f,
|
||||
/* First quad vertices */
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
/* Then quad texcoords */
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
HeapCopyOfStackArray<GLfloat> verticesOnHeap(vertices);
|
||||
mGLContext->fBufferData(LOCAL_GL_ARRAY_BUFFER,
|
||||
@ -356,45 +407,52 @@ CompositorOGL::Initialize()
|
||||
return true;
|
||||
}
|
||||
|
||||
static GLfloat
|
||||
WrapTexCoord(GLfloat v)
|
||||
// |aTextureTransform| is the texture transform that will be set on
|
||||
// aProg, possibly multiplied with another texture transform of our
|
||||
// own.
|
||||
// |aTexCoordRect| is the rectangle from the texture that we want to
|
||||
// draw using the given program. The program already has a necessary
|
||||
// offset and scale, so the geometry that needs to be drawn is a unit
|
||||
// square from 0,0 to 1,1.
|
||||
//
|
||||
// |aTexture| is the texture we are drawing. Its actual size can be
|
||||
// larger than the rectangle given by |aTexCoordRect|.
|
||||
void
|
||||
CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
|
||||
const Rect& aRect,
|
||||
const gfx3DMatrix& aTextureTransform,
|
||||
const Rect& aTexCoordRect,
|
||||
TextureSource *aTexture)
|
||||
{
|
||||
// fmodf gives negative results for negative numbers;
|
||||
// that is, fmodf(0.75, 1.0) == 0.75, but
|
||||
// fmodf(-0.75, 1.0) == -0.75. For the negative case,
|
||||
// the result we need is 0.25, so we add 1.0f.
|
||||
if (v < 0.0f) {
|
||||
return 1.0f + fmodf(v, 1.0f);
|
||||
}
|
||||
// Given what we know about these textures and coordinates, we can
|
||||
// compute fmod(t, 1.0f) to get the same texture coordinate out. If
|
||||
// the texCoordRect dimension is < 0 or > width/height, then we have
|
||||
// wraparound that we need to deal with by drawing multiple quads,
|
||||
// because we can't rely on full non-power-of-two texture support
|
||||
// (which is required for the REPEAT wrap mode).
|
||||
|
||||
return fmodf(v, 1.0f);
|
||||
}
|
||||
RectTriangles rects;
|
||||
|
||||
static void
|
||||
SetRects(int n,
|
||||
Rect* aLayerRects,
|
||||
Rect* aTextureRects,
|
||||
GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
|
||||
GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1,
|
||||
bool flip_y /* = false */)
|
||||
{
|
||||
if (flip_y) {
|
||||
std::swap(ty0, ty1);
|
||||
GLenum wrapMode = aTexture->AsSourceOGL()->GetWrapMode();
|
||||
|
||||
IntSize realTexSize = aTexture->GetSize();
|
||||
if (!CanUploadNonPowerOfTwo(mGLContext)) {
|
||||
realTexSize = IntSize(NextPowerOfTwo(realTexSize.width),
|
||||
NextPowerOfTwo(realTexSize.height));
|
||||
}
|
||||
aLayerRects[n] = Rect(x0, y0, x1 - x0, y1 - y0);
|
||||
aTextureRects[n] = Rect(tx0, ty0, tx1 - tx0, ty1 - ty0);
|
||||
}
|
||||
|
||||
static int
|
||||
DecomposeIntoNoRepeatRects(const Rect& aRect,
|
||||
const Rect& aTexCoordRect,
|
||||
Rect* aLayerRects,
|
||||
Rect* aTextureRects)
|
||||
{
|
||||
Rect texCoordRect = aTexCoordRect;
|
||||
// We need to convert back to actual texels here to get proper behaviour with
|
||||
// our GL helper functions. Should fix this sometime.
|
||||
// I want to vomit.
|
||||
IntRect texCoordRect = IntRect(NS_roundf(aTexCoordRect.x * aTexture->GetSize().width),
|
||||
NS_roundf(aTexCoordRect.y * aTexture->GetSize().height),
|
||||
NS_roundf(aTexCoordRect.width * aTexture->GetSize().width),
|
||||
NS_roundf(aTexCoordRect.height * aTexture->GetSize().height));
|
||||
|
||||
// If the texture should be flipped, it will have negative height. Detect that
|
||||
// here and compensate for it. We will flip each rect as we emit it.
|
||||
// This is fairly disgusting - if the texture should be flipped it will have a
|
||||
// negative height, in which case we un-invert the texture coords and pass the
|
||||
// flipped 'flag' to the functions below. We can't just use the inverted coords
|
||||
// because our GL funtions use an explicit flag.
|
||||
bool flipped = false;
|
||||
if (texCoordRect.height < 0) {
|
||||
flipped = true;
|
||||
@ -402,130 +460,36 @@ DecomposeIntoNoRepeatRects(const Rect& aRect,
|
||||
texCoordRect.height = -texCoordRect.height;
|
||||
}
|
||||
|
||||
Point tl = texCoordRect.TopLeft();
|
||||
Point br = texCoordRect.BottomRight();
|
||||
|
||||
// Chen check if we wrap in either the x or y axis; if we do,
|
||||
// then also use fmod to figure out the "true" non-wrapping
|
||||
// texture coordinates.
|
||||
bool xwrap = false, ywrap = false;
|
||||
|
||||
if (texCoordRect.x < 0 ||
|
||||
texCoordRect.x > 1.0f ||
|
||||
texCoordRect.XMost() < 0 ||
|
||||
texCoordRect.XMost() > 1.0f) {
|
||||
xwrap = true;
|
||||
tl = Point(WrapTexCoord(tl.x), tl.y);
|
||||
br = Point(WrapTexCoord(br.x), br.y);
|
||||
if (wrapMode == LOCAL_GL_REPEAT) {
|
||||
rects.addRect(/* dest rectangle */
|
||||
0.0f, 0.0f, 1.0f, 1.0f,
|
||||
/* tex coords */
|
||||
texCoordRect.x / GLfloat(realTexSize.width),
|
||||
texCoordRect.y / GLfloat(realTexSize.height),
|
||||
texCoordRect.XMost() / GLfloat(realTexSize.width),
|
||||
texCoordRect.YMost() / GLfloat(realTexSize.height),
|
||||
flipped);
|
||||
} else {
|
||||
nsIntRect tcRect(texCoordRect.x, texCoordRect.y,
|
||||
texCoordRect.width, texCoordRect.height);
|
||||
DecomposeIntoNoRepeatTriangles(tcRect,
|
||||
nsIntSize(realTexSize.width, realTexSize.height),
|
||||
rects, flipped);
|
||||
}
|
||||
|
||||
if (texCoordRect.y < 0 ||
|
||||
texCoordRect.y > 1.0f ||
|
||||
texCoordRect.YMost() < 0 ||
|
||||
texCoordRect.YMost() > 1.0f) {
|
||||
ywrap = true;
|
||||
tl = Point(tl.x, WrapTexCoord(tl.y));
|
||||
br = Point(br.x, WrapTexCoord(br.y));
|
||||
gfx3DMatrix textureTransform;
|
||||
if (rects.isSimpleQuad(textureTransform)) {
|
||||
Matrix4x4 transform;
|
||||
ToMatrix4x4(aTextureTransform * textureTransform, transform);
|
||||
aProg->SetTextureTransform(transform);
|
||||
BindAndDrawQuad(aProg, aRect);
|
||||
} else {
|
||||
Matrix4x4 transform;
|
||||
ToMatrix4x4(aTextureTransform, transform);
|
||||
aProg->SetTextureTransform(transform);
|
||||
aProg->SetLayerQuadRect(aRect);
|
||||
DrawQuads(mGLContext, mVBOs, aProg, LOCAL_GL_TRIANGLES, rects);
|
||||
}
|
||||
|
||||
NS_ASSERTION(tl.x >= 0.0f && tl.x <= 1.0f &&
|
||||
tl.y >= 0.0f && tl.y <= 1.0f &&
|
||||
br.x >= 0.0f && br.x <= 1.0f &&
|
||||
br.y >= 0.0f && br.y <= 1.0f,
|
||||
"Somehow generated invalid texture coordinates");
|
||||
|
||||
// If xwrap is false, the texture will be sampled from tl.x
|
||||
// .. br.x. If xwrap is true, then it will be split into tl.x
|
||||
// .. 1.0, and 0.0 .. br.x. Same for the Y axis. The
|
||||
// destination rectangle is also split appropriately, according
|
||||
// to the calculated xmid/ymid values.
|
||||
|
||||
// There isn't a 1:1 mapping between tex coords and destination coords;
|
||||
// when computing midpoints, we have to take that into account. We
|
||||
// need to map the texture coords, which are (in the wrap case):
|
||||
// |tl->1| and |0->br| to the |0->1| range of the vertex coords. So
|
||||
// we have the length (1-tl)+(br) that needs to map into 0->1.
|
||||
// These are only valid if there is wrap involved, they won't be used
|
||||
// otherwise.
|
||||
GLfloat xlen = (1.0f - tl.x) + br.x;
|
||||
GLfloat ylen = (1.0f - tl.y) + br.y;
|
||||
|
||||
NS_ASSERTION(!xwrap || xlen > 0.0f, "xlen isn't > 0, what's going on?");
|
||||
NS_ASSERTION(!ywrap || ylen > 0.0f, "ylen isn't > 0, what's going on?");
|
||||
|
||||
if (!xwrap && !ywrap) {
|
||||
SetRects(0, aLayerRects, aTextureRects,
|
||||
aRect.x, aRect.y, aRect.XMost(), aRect.YMost(),
|
||||
tl.x, tl.y, br.x, br.y,
|
||||
flipped);
|
||||
return 1;
|
||||
}
|
||||
|
||||
GLfloat xmid = aRect.x + (1.0f - tl.x) / xlen * aRect.width;
|
||||
GLfloat ymid = aRect.y + (1.0f - tl.y) / ylen * aRect.height;
|
||||
|
||||
if (!xwrap && ywrap) {
|
||||
SetRects(0, aLayerRects, aTextureRects,
|
||||
aRect.x, aRect.y, aRect.XMost(), ymid,
|
||||
tl.x, tl.y, br.x, 1.0f,
|
||||
flipped);
|
||||
SetRects(1, aLayerRects, aTextureRects,
|
||||
aRect.x, ymid, aRect.XMost(), aRect.YMost(),
|
||||
tl.x, 0.0f, br.x, br.y,
|
||||
flipped);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (xwrap && !ywrap) {
|
||||
SetRects(0, aLayerRects, aTextureRects,
|
||||
aRect.x, aRect.y, xmid, aRect.YMost(),
|
||||
tl.x, tl.y, 1.0f, br.y,
|
||||
flipped);
|
||||
SetRects(1, aLayerRects, aTextureRects,
|
||||
xmid, aRect.y, aRect.XMost(), aRect.YMost(),
|
||||
0.0f, tl.y, br.x, br.y,
|
||||
flipped);
|
||||
return 2;
|
||||
}
|
||||
|
||||
SetRects(0, aLayerRects, aTextureRects,
|
||||
aRect.x, aRect.y, xmid, ymid,
|
||||
tl.x, tl.y, 1.0f, 1.0f,
|
||||
flipped);
|
||||
SetRects(1, aLayerRects, aTextureRects,
|
||||
xmid, aRect.y, aRect.XMost(), ymid,
|
||||
0.0f, tl.y, br.x, 1.0f,
|
||||
flipped);
|
||||
SetRects(2, aLayerRects, aTextureRects,
|
||||
aRect.x, ymid, xmid, aRect.YMost(),
|
||||
tl.x, 0.0f, 1.0f, br.y,
|
||||
flipped);
|
||||
SetRects(3, aLayerRects, aTextureRects,
|
||||
xmid, ymid, aRect.XMost(), aRect.YMost(),
|
||||
0.0f, 0.0f, br.x, br.y,
|
||||
flipped);
|
||||
return 4;
|
||||
}
|
||||
|
||||
// |aRect| is the rectangle we want to draw to. We will draw it with
|
||||
// up to 4 draw commands if necessary to avoid wrapping.
|
||||
// |aTexCoordRect| is the rectangle from the texture that we want to
|
||||
// draw using the given program.
|
||||
// |aTexture| is the texture we are drawing. Its actual size can be
|
||||
// larger than the rectangle given by |texCoordRect|.
|
||||
void
|
||||
CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
|
||||
const Rect& aRect,
|
||||
const Rect& aTexCoordRect,
|
||||
TextureSource *aTexture)
|
||||
{
|
||||
Rect layerRects[4];
|
||||
Rect textureRects[4];
|
||||
int rects = DecomposeIntoNoRepeatRects(aRect,
|
||||
aTexCoordRect,
|
||||
layerRects,
|
||||
textureRects);
|
||||
BindAndDrawQuads(aProg, rects, layerRects, textureRects);
|
||||
}
|
||||
|
||||
void
|
||||
@ -670,6 +634,8 @@ CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
|
||||
LayerScope::BeginFrame(mGLContext, PR_Now());
|
||||
|
||||
mVBOs.Reset();
|
||||
|
||||
mFrameInProgress = true;
|
||||
gfx::Rect rect;
|
||||
if (mUseExternalSurfaceSize) {
|
||||
@ -1089,15 +1055,13 @@ CompositorOGL::DrawQuad(const Rect& aRect,
|
||||
source->AsSourceOGL()->BindTexture(LOCAL_GL_TEXTURE0, filter);
|
||||
|
||||
program->SetTextureUnit(0);
|
||||
Matrix4x4 transform;
|
||||
ToMatrix4x4(textureTransform, transform);
|
||||
program->SetTextureTransform(transform);
|
||||
|
||||
if (maskType != MaskType::MaskNone) {
|
||||
BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE1, maskQuadTransform);
|
||||
}
|
||||
|
||||
BindAndDrawQuadWithTextureRect(program, aRect, texturedEffect->mTextureCoords, source);
|
||||
BindAndDrawQuadWithTextureRect(program, aRect, textureTransform,
|
||||
texturedEffect->mTextureCoords, source);
|
||||
}
|
||||
break;
|
||||
case EffectTypes::YCBCR: {
|
||||
@ -1119,7 +1083,6 @@ CompositorOGL::DrawQuad(const Rect& aRect,
|
||||
sourceCr->BindTexture(LOCAL_GL_TEXTURE2, effectYCbCr->mFilter);
|
||||
|
||||
program->SetYCbCrTextureUnits(Y, Cb, Cr);
|
||||
program->SetTextureTransform(Matrix4x4());
|
||||
|
||||
if (maskType != MaskType::MaskNone) {
|
||||
BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE3, maskQuadTransform);
|
||||
@ -1127,6 +1090,7 @@ CompositorOGL::DrawQuad(const Rect& aRect,
|
||||
didSetBlendMode = SetBlendMode(gl(), blendMode);
|
||||
BindAndDrawQuadWithTextureRect(program,
|
||||
aRect,
|
||||
gfx3DMatrix(),
|
||||
effectYCbCr->mTextureCoords,
|
||||
sourceYCbCr->GetSubSource(Y));
|
||||
}
|
||||
@ -1184,7 +1148,7 @@ CompositorOGL::DrawQuad(const Rect& aRect,
|
||||
|
||||
program->SetBlackTextureUnit(0);
|
||||
program->SetWhiteTextureUnit(1);
|
||||
program->SetTextureTransform(Matrix4x4());
|
||||
program->SetTextureTransform(gfx::Matrix4x4());
|
||||
|
||||
if (maskType != MaskType::MaskNone) {
|
||||
BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE2, maskQuadTransform);
|
||||
@ -1195,6 +1159,7 @@ CompositorOGL::DrawQuad(const Rect& aRect,
|
||||
program->SetTexturePass2(false);
|
||||
BindAndDrawQuadWithTextureRect(program,
|
||||
aRect,
|
||||
gfx3DMatrix(),
|
||||
effectComponentAlpha->mTextureCoords,
|
||||
effectComponentAlpha->mOnBlack);
|
||||
|
||||
@ -1204,6 +1169,7 @@ CompositorOGL::DrawQuad(const Rect& aRect,
|
||||
program->SetTexturePass2(true);
|
||||
BindAndDrawQuadWithTextureRect(program,
|
||||
aRect,
|
||||
gfx3DMatrix(),
|
||||
effectComponentAlpha->mTextureCoords,
|
||||
effectComponentAlpha->mOnBlack);
|
||||
|
||||
@ -1487,27 +1453,24 @@ CompositorOGL::BindQuadVBO() {
|
||||
|
||||
void
|
||||
CompositorOGL::QuadVBOVerticesAttrib(GLuint aAttribIndex) {
|
||||
mGLContext->fVertexAttribPointer(aAttribIndex, 4,
|
||||
LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
|
||||
(GLvoid*) 0);
|
||||
mGLContext->fVertexAttribPointer(aAttribIndex, 2,
|
||||
LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
|
||||
(GLvoid*) QuadVBOVertexOffset());
|
||||
}
|
||||
|
||||
void
|
||||
CompositorOGL::QuadVBOTexCoordsAttrib(GLuint aAttribIndex) {
|
||||
mGLContext->fVertexAttribPointer(aAttribIndex, 4,
|
||||
LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
|
||||
(GLvoid*) 0);
|
||||
mGLContext->fVertexAttribPointer(aAttribIndex, 2,
|
||||
LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
|
||||
(GLvoid*) QuadVBOTexCoordOffset());
|
||||
}
|
||||
|
||||
void
|
||||
CompositorOGL::BindAndDrawQuads(ShaderProgramOGL *aProg,
|
||||
int aQuads,
|
||||
const Rect* aLayerRects,
|
||||
const Rect* aTextureRects)
|
||||
CompositorOGL::BindAndDrawQuad(ShaderProgramOGL *aProg, const Rect& aRect)
|
||||
{
|
||||
NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized");
|
||||
|
||||
aProg->SetLayerRects(aLayerRects);
|
||||
aProg->SetLayerQuadRect(aRect);
|
||||
|
||||
GLuint vertAttribIndex = aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib);
|
||||
GLuint texCoordAttribIndex = aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
|
||||
@ -1518,12 +1481,10 @@ CompositorOGL::BindAndDrawQuads(ShaderProgramOGL *aProg,
|
||||
if (texCoordAttribIndex != GLuint(-1)) {
|
||||
QuadVBOTexCoordsAttrib(texCoordAttribIndex);
|
||||
mGLContext->fEnableVertexAttribArray(texCoordAttribIndex);
|
||||
|
||||
aProg->SetTextureRects(aTextureRects);
|
||||
}
|
||||
|
||||
mGLContext->fEnableVertexAttribArray(vertAttribIndex);
|
||||
mGLContext->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4 * aQuads);
|
||||
mGLContext->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
GLuint
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "nsThreadUtils.h" // for nsRunnable
|
||||
#include "nsXULAppAPI.h" // for XRE_GetProcessType
|
||||
#include "nscore.h" // for NS_IMETHOD
|
||||
#include "VBOArena.h" // for gl::VBOArena
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <ui/GraphicBuffer.h>
|
||||
#endif
|
||||
@ -311,6 +312,11 @@ private:
|
||||
*/
|
||||
GLuint mQuadVBO;
|
||||
|
||||
/**
|
||||
* When we can't use mQuadVBO, we allocate VBOs from this arena instead.
|
||||
*/
|
||||
gl::VBOArena mVBOs;
|
||||
|
||||
bool mHasBGRA;
|
||||
|
||||
/**
|
||||
@ -356,24 +362,17 @@ private:
|
||||
GLuint aSourceFrameBuffer,
|
||||
GLuint *aFBO, GLuint *aTexture);
|
||||
|
||||
GLintptr QuadVBOVertexOffset() { return 0; }
|
||||
GLintptr QuadVBOTexCoordOffset() { return sizeof(float)*4*2; }
|
||||
|
||||
void BindQuadVBO();
|
||||
void QuadVBOVerticesAttrib(GLuint aAttribIndex);
|
||||
void QuadVBOTexCoordsAttrib(GLuint aAttribIndex);
|
||||
void BindAndDrawQuads(ShaderProgramOGL *aProg,
|
||||
int aQuads,
|
||||
const gfx::Rect* aLayerRect,
|
||||
const gfx::Rect* aTextureRect);
|
||||
void BindAndDrawQuad(ShaderProgramOGL *aProg,
|
||||
const gfx::Rect& aLayerRect,
|
||||
const gfx::Rect& aTextureRect = gfx::Rect(0.0f, 0.0f, 1.0f, 1.0f)) {
|
||||
gfx::Rect layerRects[4];
|
||||
gfx::Rect textureRects[4];
|
||||
layerRects[0] = aLayerRect;
|
||||
textureRects[0] = aTextureRect;
|
||||
BindAndDrawQuads(aProg, 1, layerRects, textureRects);
|
||||
}
|
||||
const gfx::Rect& aRect);
|
||||
void BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
|
||||
const gfx::Rect& aRect,
|
||||
const gfx3DMatrix& aTextureTransform,
|
||||
const gfx::Rect& aTexCoordRect,
|
||||
TextureSource *aTexture);
|
||||
|
||||
|
@ -43,11 +43,9 @@ public:
|
||||
return mImpl->GetProjMatrix();
|
||||
}
|
||||
|
||||
virtual void BindAndDrawQuad(ShaderProgramOGL *aProg,
|
||||
const gfx::Rect& aLayerRect,
|
||||
const gfx::Rect& aTextureRect) MOZ_OVERRIDE
|
||||
virtual void BindAndDrawQuad(ShaderProgramOGL *aProg, const gfx::Rect& aRect) MOZ_OVERRIDE
|
||||
{
|
||||
mImpl->BindAndDrawQuad(aProg, aLayerRect, aTextureRect);
|
||||
mImpl->BindAndDrawQuad(aProg, aRect);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -33,8 +33,7 @@ public:
|
||||
virtual gl::GLContext* gl() const = 0;
|
||||
virtual ShaderProgramOGL* GetProgram(GLenum aTarget, gfx::SurfaceFormat aFormat) = 0;
|
||||
virtual const gfx::Matrix4x4& GetProjMatrix() const = 0;
|
||||
virtual void BindAndDrawQuad(ShaderProgramOGL *aProg, const gfx::Rect& aLayerRect,
|
||||
const gfx::Rect& aTextureRect) = 0;
|
||||
virtual void BindAndDrawQuad(ShaderProgramOGL *aProg, const gfx::Rect& aRect) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -31,11 +31,10 @@ AddUniforms(ProgramProfileOGL& aProfile)
|
||||
{
|
||||
static const char *sKnownUniformNames[] = {
|
||||
"uLayerTransform",
|
||||
"uMaskTransform",
|
||||
"uLayerRects",
|
||||
"uMaskQuadTransform",
|
||||
"uLayerQuadRect",
|
||||
"uMatrixProj",
|
||||
"uTextureTransform",
|
||||
"uTextureRects",
|
||||
"uRenderTargetOffset",
|
||||
"uLayerOpacity",
|
||||
"uTexture",
|
||||
@ -146,7 +145,7 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig)
|
||||
AddUniforms(result);
|
||||
|
||||
vs << "uniform mat4 uMatrixProj;" << endl;
|
||||
vs << "uniform vec4 uLayerRects[4];" << endl;
|
||||
vs << "uniform vec4 uLayerQuadRect;" << endl;
|
||||
vs << "uniform mat4 uLayerTransform;" << endl;
|
||||
vs << "uniform vec4 uRenderTargetOffset;" << endl;
|
||||
|
||||
@ -154,31 +153,28 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig)
|
||||
|
||||
if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) {
|
||||
vs << "uniform mat4 uTextureTransform;" << endl;
|
||||
vs << "uniform vec4 uTextureRects[4];" << endl;
|
||||
vs << "attribute vec4 aTexCoord;" << endl;
|
||||
vs << "attribute vec2 aTexCoord;" << endl;
|
||||
vs << "varying vec2 vTexCoord;" << endl;
|
||||
}
|
||||
|
||||
if (aConfig.mFeatures & ENABLE_MASK_2D ||
|
||||
aConfig.mFeatures & ENABLE_MASK_3D) {
|
||||
vs << "uniform mat4 uMaskTransform;" << endl;
|
||||
vs << "uniform mat4 uMaskQuadTransform;" << endl;
|
||||
vs << "varying vec3 vMaskCoord;" << endl;
|
||||
}
|
||||
|
||||
vs << "void main() {" << endl;
|
||||
vs << " int vertexID = int(aVertexCoord.w);" << endl;
|
||||
vs << " vec4 layerRect = uLayerRects[vertexID];" << endl;
|
||||
vs << " vec4 finalPosition = vec4(aVertexCoord.xy * layerRect.zw + layerRect.xy, 0.0, 1.0);" << endl;
|
||||
vs << " vec4 finalPosition = vec4(aVertexCoord.xy * uLayerQuadRect.zw + uLayerQuadRect.xy, 0.0, 1.0);" << endl;
|
||||
vs << " finalPosition = uLayerTransform * finalPosition;" << endl;
|
||||
vs << " finalPosition.xyz /= finalPosition.w;" << endl;
|
||||
|
||||
if (aConfig.mFeatures & ENABLE_MASK_3D) {
|
||||
vs << " vMaskCoord.xy = (uMaskTransform * vec4(finalPosition.xyz, 1.0)).xy;" << endl;
|
||||
vs << " vMaskCoord.xy = (uMaskQuadTransform * vec4(finalPosition.xyz, 1.0)).xy;" << endl;
|
||||
// correct for perspective correct interpolation, see comment in D3D10 shader
|
||||
vs << " vMaskCoord.z = 1.0;" << endl;
|
||||
vs << " vMaskCoord *= finalPosition.w;" << endl;
|
||||
} else if (aConfig.mFeatures & ENABLE_MASK_2D) {
|
||||
vs << " vMaskCoord.xy = (uMaskTransform * finalPosition).xy;" << endl;
|
||||
vs << " vMaskCoord.xy = (uMaskQuadTransform * finalPosition).xy;" << endl;
|
||||
}
|
||||
|
||||
vs << " finalPosition = finalPosition - uRenderTargetOffset;" << endl;
|
||||
@ -186,9 +182,7 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig)
|
||||
vs << " finalPosition = uMatrixProj * finalPosition;" << endl;
|
||||
|
||||
if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) {
|
||||
vs << " vec4 textureRect = uTextureRects[vertexID];" << endl;
|
||||
vs << " vec2 texCoord = aTexCoord.xy * textureRect.zw + textureRect.xy;" << endl;
|
||||
vs << " vTexCoord = (uTextureTransform * vec4(texCoord, 0.0, 1.0)).xy;" << endl;
|
||||
vs << " vTexCoord = (uTextureTransform * vec4(aTexCoord.x, aTexCoord.y, 0.0, 1.0)).xy;" << endl;
|
||||
}
|
||||
|
||||
vs << " gl_Position = finalPosition;" << endl;
|
||||
|
@ -51,11 +51,10 @@ public:
|
||||
NotAKnownUniform = -1,
|
||||
|
||||
LayerTransform = 0,
|
||||
MaskTransform,
|
||||
LayerRects,
|
||||
MaskQuadTransform,
|
||||
LayerQuadRect,
|
||||
MatrixProj,
|
||||
TextureTransform,
|
||||
TextureRects,
|
||||
RenderTargetOffset,
|
||||
LayerOpacity,
|
||||
Texture,
|
||||
@ -319,15 +318,12 @@ public:
|
||||
}
|
||||
|
||||
void SetMaskLayerTransform(const gfx::Matrix4x4& aMatrix) {
|
||||
SetMatrixUniform(KnownUniform::MaskTransform, aMatrix);
|
||||
SetMatrixUniform(KnownUniform::MaskQuadTransform, aMatrix);
|
||||
}
|
||||
|
||||
void SetLayerRects(const gfx::Rect* aRects) {
|
||||
float vals[16] = { aRects[0].x, aRects[0].y, aRects[0].width, aRects[0].height,
|
||||
aRects[1].x, aRects[1].y, aRects[1].width, aRects[1].height,
|
||||
aRects[2].x, aRects[2].y, aRects[2].width, aRects[2].height,
|
||||
aRects[3].x, aRects[3].y, aRects[3].width, aRects[3].height };
|
||||
SetUniform(KnownUniform::LayerRects, 16, vals);
|
||||
void SetLayerQuadRect(const gfx::Rect& aRect) {
|
||||
float vals[4] = { float(aRect.x), float(aRect.y), float(aRect.width), float(aRect.height) };
|
||||
SetUniform(KnownUniform::LayerQuadRect, 4, vals);
|
||||
}
|
||||
|
||||
void SetProjectionMatrix(const gfx::Matrix4x4& aMatrix) {
|
||||
@ -339,14 +335,6 @@ public:
|
||||
SetMatrixUniform(KnownUniform::TextureTransform, aMatrix);
|
||||
}
|
||||
|
||||
void SetTextureRects(const gfx::Rect* aRects) {
|
||||
float vals[16] = { aRects[0].x, aRects[0].y, aRects[0].width, aRects[0].height,
|
||||
aRects[1].x, aRects[1].y, aRects[1].width, aRects[1].height,
|
||||
aRects[2].x, aRects[2].y, aRects[2].width, aRects[2].height,
|
||||
aRects[3].x, aRects[3].y, aRects[3].width, aRects[3].height };
|
||||
SetUniform(KnownUniform::TextureRects, 16, vals);
|
||||
}
|
||||
|
||||
void SetRenderOffset(const nsIntPoint& aOffset) {
|
||||
float vals[4] = { float(aOffset.x), float(aOffset.y), 0.0f, 0.0f };
|
||||
SetUniform(KnownUniform::RenderTargetOffset, 4, vals);
|
||||
@ -477,7 +465,6 @@ protected:
|
||||
case 2: mGL->fUniform2fv(ku.mLocation, 1, ku.mValue.f16v); break;
|
||||
case 3: mGL->fUniform3fv(ku.mLocation, 1, ku.mValue.f16v); break;
|
||||
case 4: mGL->fUniform4fv(ku.mLocation, 1, ku.mValue.f16v); break;
|
||||
case 16: mGL->fUniform4fv(ku.mLocation, 4, ku.mValue.f16v); break;
|
||||
default:
|
||||
NS_NOTREACHED("Bogus aLength param");
|
||||
}
|
||||
|
@ -345,9 +345,7 @@ public:
|
||||
{
|
||||
return mProjMatrix;
|
||||
}
|
||||
virtual void BindAndDrawQuad(ShaderProgramOGL *aProg,
|
||||
const gfx::Rect& aLayerRect,
|
||||
const gfx::Rect& aTextureRect) MOZ_OVERRIDE;
|
||||
virtual void BindAndDrawQuad(ShaderProgramOGL *aProg, const gfx::Rect& aRect) MOZ_OVERRIDE;
|
||||
|
||||
void BeginFrame(nsIntSize aRenderSize);
|
||||
void EndFrame();
|
||||
@ -2762,9 +2760,7 @@ RectTextureImage::Draw(GLManager* aManager,
|
||||
program->SetTexCoordMultiplier(mUsedSize.width, mUsedSize.height);
|
||||
program->SetTextureUnit(0);
|
||||
|
||||
aManager->BindAndDrawQuad(program,
|
||||
gfx::Rect(0.0, 0.0, mUsedSize.width, mUsedSize.height),
|
||||
gfx::Rect(0.0, 0.0, 1.0f, 1.0f));
|
||||
aManager->BindAndDrawQuad(program, gfx::Rect(0, 0, mUsedSize.width, mUsedSize.height));
|
||||
|
||||
aManager->gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||
}
|
||||
@ -2804,20 +2800,11 @@ GLPresenter::~GLPresenter()
|
||||
}
|
||||
|
||||
void
|
||||
GLPresenter::BindAndDrawQuad(ShaderProgramOGL *aProgram,
|
||||
const gfx::Rect& aLayerRect,
|
||||
const gfx::Rect& aTextureRect)
|
||||
GLPresenter::BindAndDrawQuad(ShaderProgramOGL *aProgram, const gfx::Rect& aRect)
|
||||
{
|
||||
mGLContext->MakeCurrent();
|
||||
|
||||
gfx::Rect layerRects[4];
|
||||
gfx::Rect textureRects[4];
|
||||
|
||||
layerRects[0] = aLayerRect;
|
||||
textureRects[0] = aTextureRect;
|
||||
|
||||
aProgram->SetLayerRects(layerRects);
|
||||
aProgram->SetTextureRects(textureRects);
|
||||
aProgram->SetLayerQuadRect(aRect);
|
||||
|
||||
GLuint vertAttribIndex = aProgram->AttribLocation(ShaderProgramOGL::VertexCoordAttrib);
|
||||
GLuint texCoordAttribIndex = aProgram->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
|
||||
|
Loading…
Reference in New Issue
Block a user