зеркало из https://github.com/mozilla/gecko-dev.git
Bug 905589 - Use VBO instead of client side rendering. r=bas
This commit is contained in:
Родитель
2f01c65368
Коммит
15c39ccfd7
|
@ -0,0 +1,36 @@
|
||||||
|
/* -*- 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"
|
||||||
|
|
||||||
|
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.data());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* -*- 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 "GLContext.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace gl {
|
||||||
|
|
||||||
|
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
|
|
@ -53,6 +53,7 @@ EXPORTS += [
|
||||||
'SurfaceFactory.h',
|
'SurfaceFactory.h',
|
||||||
'SurfaceStream.h',
|
'SurfaceStream.h',
|
||||||
'SurfaceTypes.h',
|
'SurfaceTypes.h',
|
||||||
|
'VBOArena.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG['MOZ_X11']:
|
if CONFIG['MOZ_X11']:
|
||||||
|
@ -112,6 +113,7 @@ CPP_SOURCES += [
|
||||||
'SharedSurfaceGL.cpp',
|
'SharedSurfaceGL.cpp',
|
||||||
'SurfaceFactory.cpp',
|
'SurfaceFactory.cpp',
|
||||||
'SurfaceStream.cpp',
|
'SurfaceStream.cpp',
|
||||||
|
'VBOArena.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
FAIL_ON_WARNINGS = True
|
FAIL_ON_WARNINGS = True
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <stdlib.h> // for free, malloc
|
#include <stdlib.h> // for free, malloc
|
||||||
#include "FPSCounter.h" // for FPSState, FPSCounter
|
#include "FPSCounter.h" // for FPSState, FPSCounter
|
||||||
#include "GLContextProvider.h" // for GLContextProvider
|
#include "GLContextProvider.h" // for GLContextProvider
|
||||||
|
#include "LayerManagerOGL.h" // for BUFFER_OFFSET
|
||||||
#include "Layers.h" // for WriteSnapshotToDumpFile
|
#include "Layers.h" // for WriteSnapshotToDumpFile
|
||||||
#include "gfx2DGlue.h" // for ThebesFilter
|
#include "gfx2DGlue.h" // for ThebesFilter
|
||||||
#include "gfx3DMatrix.h" // for gfx3DMatrix
|
#include "gfx3DMatrix.h" // for gfx3DMatrix
|
||||||
|
@ -56,6 +57,51 @@ static inline IntSize ns2gfxSize(const nsIntSize& s) {
|
||||||
return IntSize(s.width, s.height);
|
return IntSize(s.width, s.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw the supplied geometry with the already selected shader. Both aArray1
|
||||||
|
// and aArray2 are expected to have a stride of 2 * sizeof(GLfloat).
|
||||||
|
static void
|
||||||
|
DrawWithVertexBuffer2(GLContext *aGLContext, VBOArena &aVBOs,
|
||||||
|
GLenum aMode, GLsizei aElements,
|
||||||
|
GLint aAttr1, GLfloat *aArray1,
|
||||||
|
GLint aAttr2, GLfloat *aArray2)
|
||||||
|
{
|
||||||
|
GLsizei bytes = aElements * 2 * sizeof(GLfloat);
|
||||||
|
|
||||||
|
aGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER,
|
||||||
|
aVBOs.Allocate(aGLContext));
|
||||||
|
aGLContext->fBufferData(LOCAL_GL_ARRAY_BUFFER,
|
||||||
|
2 * bytes,
|
||||||
|
nullptr,
|
||||||
|
LOCAL_GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
aGLContext->fBufferSubData(LOCAL_GL_ARRAY_BUFFER,
|
||||||
|
0,
|
||||||
|
bytes,
|
||||||
|
aArray1);
|
||||||
|
aGLContext->fBufferSubData(LOCAL_GL_ARRAY_BUFFER,
|
||||||
|
bytes,
|
||||||
|
bytes,
|
||||||
|
aArray2);
|
||||||
|
|
||||||
|
aGLContext->fEnableVertexAttribArray(aAttr1);
|
||||||
|
aGLContext->fEnableVertexAttribArray(aAttr2);
|
||||||
|
|
||||||
|
aGLContext->fVertexAttribPointer(aAttr1,
|
||||||
|
2, LOCAL_GL_FLOAT,
|
||||||
|
LOCAL_GL_FALSE,
|
||||||
|
0, BUFFER_OFFSET(0));
|
||||||
|
aGLContext->fVertexAttribPointer(aAttr2,
|
||||||
|
2, LOCAL_GL_FLOAT,
|
||||||
|
LOCAL_GL_FALSE,
|
||||||
|
0, BUFFER_OFFSET(bytes));
|
||||||
|
|
||||||
|
aGLContext->fDrawArrays(aMode, 0, aElements);
|
||||||
|
|
||||||
|
aGLContext->fDisableVertexAttribArray(aAttr1);
|
||||||
|
aGLContext->fDisableVertexAttribArray(aAttr2);
|
||||||
|
|
||||||
|
aGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FPSState::DrawFPS(TimeStamp aNow,
|
FPSState::DrawFPS(TimeStamp aNow,
|
||||||
|
@ -98,6 +144,8 @@ FPSState::DrawFPS(TimeStamp aNow,
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mVBOs.Reset();
|
||||||
|
|
||||||
struct Vertex2D {
|
struct Vertex2D {
|
||||||
float x,y;
|
float x,y;
|
||||||
};
|
};
|
||||||
|
@ -191,44 +239,21 @@ FPSState::DrawFPS(TimeStamp aNow,
|
||||||
copyprog->Activate();
|
copyprog->Activate();
|
||||||
copyprog->SetTextureUnit(0);
|
copyprog->SetTextureUnit(0);
|
||||||
|
|
||||||
// we're going to use client-side vertex arrays for this.
|
|
||||||
context->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
// "COPY"
|
// "COPY"
|
||||||
context->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ZERO,
|
context->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ZERO,
|
||||||
LOCAL_GL_ONE, LOCAL_GL_ZERO);
|
LOCAL_GL_ONE, LOCAL_GL_ZERO);
|
||||||
|
|
||||||
// enable our vertex attribs; we'll call glVertexPointer below
|
|
||||||
// to fill with the correct data.
|
|
||||||
GLint vcattr = copyprog->AttribLocation(ShaderProgramOGL::VertexCoordAttrib);
|
GLint vcattr = copyprog->AttribLocation(ShaderProgramOGL::VertexCoordAttrib);
|
||||||
GLint tcattr = copyprog->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
|
GLint tcattr = copyprog->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
|
||||||
|
|
||||||
context->fEnableVertexAttribArray(vcattr);
|
DrawWithVertexBuffer2(context, mVBOs,
|
||||||
context->fEnableVertexAttribArray(tcattr);
|
LOCAL_GL_TRIANGLE_STRIP, 12,
|
||||||
|
vcattr, (GLfloat *) vertices,
|
||||||
context->fVertexAttribPointer(vcattr,
|
tcattr, (GLfloat *) texCoords);
|
||||||
2, LOCAL_GL_FLOAT,
|
DrawWithVertexBuffer2(context, mVBOs,
|
||||||
LOCAL_GL_FALSE,
|
LOCAL_GL_TRIANGLE_STRIP, 12,
|
||||||
0, vertices);
|
vcattr, (GLfloat *) vertices2,
|
||||||
|
tcattr, (GLfloat *) texCoords2);
|
||||||
context->fVertexAttribPointer(tcattr,
|
|
||||||
2, LOCAL_GL_FLOAT,
|
|
||||||
LOCAL_GL_FALSE,
|
|
||||||
0, texCoords);
|
|
||||||
|
|
||||||
context->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 12);
|
|
||||||
|
|
||||||
context->fVertexAttribPointer(vcattr,
|
|
||||||
2, LOCAL_GL_FLOAT,
|
|
||||||
LOCAL_GL_FALSE,
|
|
||||||
0, vertices2);
|
|
||||||
|
|
||||||
context->fVertexAttribPointer(tcattr,
|
|
||||||
2, LOCAL_GL_FLOAT,
|
|
||||||
LOCAL_GL_FALSE,
|
|
||||||
0, texCoords2);
|
|
||||||
|
|
||||||
context->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 12);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CHECK_CURRENT_PROGRAM
|
#ifdef CHECK_CURRENT_PROGRAM
|
||||||
|
@ -312,9 +337,17 @@ CompositorOGL::GetTemporaryTexture(GLenum aTextureUnit)
|
||||||
void
|
void
|
||||||
CompositorOGL::Destroy()
|
CompositorOGL::Destroy()
|
||||||
{
|
{
|
||||||
if (gl() && mTextures.Length() > 0) {
|
if (gl()) {
|
||||||
gl()->MakeCurrent();
|
gl()->MakeCurrent();
|
||||||
gl()->fDeleteTextures(mTextures.Length(), &mTextures[0]);
|
if (mTextures.Length() > 0) {
|
||||||
|
gl()->fDeleteTextures(mTextures.Length(), &mTextures[0]);
|
||||||
|
}
|
||||||
|
mVBOs.Flush(gl());
|
||||||
|
if (mFPS) {
|
||||||
|
if (mFPS->mTexture > 0)
|
||||||
|
gl()->fDeleteTextures(1, &mFPS->mTexture);
|
||||||
|
mFPS->mVBOs.Flush(gl());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mTextures.SetLength(0);
|
mTextures.SetLength(0);
|
||||||
if (!mDestroyed) {
|
if (!mDestroyed) {
|
||||||
|
@ -557,10 +590,6 @@ CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
|
||||||
aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
|
aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
|
||||||
NS_ASSERTION(texCoordAttribIndex != GLuint(-1), "no texture coords?");
|
NS_ASSERTION(texCoordAttribIndex != GLuint(-1), "no texture coords?");
|
||||||
|
|
||||||
// clear any bound VBO so that glVertexAttribPointer() goes back to
|
|
||||||
// "pointer mode"
|
|
||||||
mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
// Given what we know about these textures and coordinates, we can
|
// Given what we know about these textures and coordinates, we can
|
||||||
// compute fmod(t, 1.0f) to get the same texture coordinate out. If
|
// compute fmod(t, 1.0f) to get the same texture coordinate out. If
|
||||||
// the texCoordRect dimension is < 0 or > width/height, then we have
|
// the texCoordRect dimension is < 0 or > width/height, then we have
|
||||||
|
@ -614,25 +643,10 @@ CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
|
||||||
rects, flipped);
|
rects, flipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
mGLContext->fVertexAttribPointer(vertAttribIndex, 2,
|
DrawWithVertexBuffer2(mGLContext, mVBOs,
|
||||||
LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
|
LOCAL_GL_TRIANGLES, rects.elements(),
|
||||||
rects.vertexPointer());
|
vertAttribIndex, rects.vertexPointer(),
|
||||||
|
texCoordAttribIndex, rects.texCoordPointer());
|
||||||
mGLContext->fVertexAttribPointer(texCoordAttribIndex, 2,
|
|
||||||
LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
|
|
||||||
rects.texCoordPointer());
|
|
||||||
|
|
||||||
{
|
|
||||||
mGLContext->fEnableVertexAttribArray(texCoordAttribIndex);
|
|
||||||
{
|
|
||||||
mGLContext->fEnableVertexAttribArray(vertAttribIndex);
|
|
||||||
|
|
||||||
mGLContext->fDrawArrays(LOCAL_GL_TRIANGLES, 0, rects.elements());
|
|
||||||
|
|
||||||
mGLContext->fDisableVertexAttribArray(vertAttribIndex);
|
|
||||||
}
|
|
||||||
mGLContext->fDisableVertexAttribArray(texCoordAttribIndex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -769,6 +783,8 @@ CompositorOGL::BeginFrame(const Rect *aClipRectIn, const gfxMatrix& aTransform,
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!mFrameInProgress, "frame still in progress (should have called EndFrame or AbortFrame");
|
MOZ_ASSERT(!mFrameInProgress, "frame still in progress (should have called EndFrame or AbortFrame");
|
||||||
|
|
||||||
|
mVBOs.Reset();
|
||||||
|
|
||||||
mFrameInProgress = true;
|
mFrameInProgress = true;
|
||||||
gfxRect rect;
|
gfxRect rect;
|
||||||
if (mUseExternalSurfaceSize) {
|
if (mUseExternalSurfaceSize) {
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
|
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
|
||||||
#include "nsXULAppAPI.h" // for XRE_GetProcessType
|
#include "nsXULAppAPI.h" // for XRE_GetProcessType
|
||||||
#include "nscore.h" // for NS_IMETHOD
|
#include "nscore.h" // for NS_IMETHOD
|
||||||
|
#include "VBOArena.h" // for gl::VBOArena
|
||||||
|
|
||||||
class gfx3DMatrix;
|
class gfx3DMatrix;
|
||||||
class nsIWidget;
|
class nsIWidget;
|
||||||
struct gfxMatrix;
|
struct gfxMatrix;
|
||||||
|
@ -235,6 +237,11 @@ private:
|
||||||
* flipped and unflipped textures */
|
* flipped and unflipped textures */
|
||||||
GLuint mQuadVBO;
|
GLuint mQuadVBO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When we can't use mQuadVBO, we allocate VBOs from this arena instead.
|
||||||
|
*/
|
||||||
|
gl::VBOArena mVBOs;
|
||||||
|
|
||||||
bool mHasBGRA;
|
bool mHasBGRA;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "GLDefs.h" // for GLuint
|
#include "GLDefs.h" // for GLuint
|
||||||
#include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
|
#include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
|
||||||
#include "nsTArray.h" // for nsAutoTArray, nsTArray_Impl, etc
|
#include "nsTArray.h" // for nsAutoTArray, nsTArray_Impl, etc
|
||||||
|
#include "VBOArena.h" // for gl::VBOArena
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace gl {
|
namespace gl {
|
||||||
|
@ -70,6 +71,7 @@ struct FPSState {
|
||||||
GLuint mTexture;
|
GLuint mTexture;
|
||||||
FPSCounter mCompositionFps;
|
FPSCounter mCompositionFps;
|
||||||
FPSCounter mTransactionFps;
|
FPSCounter mTransactionFps;
|
||||||
|
gl::VBOArena mVBOs;
|
||||||
|
|
||||||
FPSState() : mTexture(0) { }
|
FPSState() : mTexture(0) { }
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче