author | Chris Jones <jones.chris.g@gmail.com> |
Tue, 04 Sep 2012 22:17:13 -0700 | |
changeset 104278 | 4915f7de0b1838c6888a0af41a0b7d82fb5c1a00 |
parent 104277 | 8bde8f163d35af962fd0235b2d8aded137b0c154 |
child 104279 | 85d7349e70863ab38dee1d574108e43094cdab58 |
push id | 23417 |
push user | ryanvm@gmail.com |
push date | Thu, 06 Sep 2012 02:27:31 +0000 |
treeherder | mozilla-central@501f4e46a88c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jrmuizel |
bugs | 780074 |
milestone | 18.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
gfx/layers/opengl/LayerManagerOGL.cpp | file | annotate | diff | comparison | revisions | |
gfx/layers/opengl/LayerManagerOGL.h | file | annotate | diff | comparison | revisions |
--- a/gfx/layers/opengl/LayerManagerOGL.cpp +++ b/gfx/layers/opengl/LayerManagerOGL.cpp @@ -43,16 +43,250 @@ namespace layers { using namespace mozilla::gfx; using namespace mozilla::gl; #ifdef CHECK_CURRENT_PROGRAM int ShaderProgramOGL::sCurrentProgramKey = 0; #endif +static const double kFpsWindowMs = 250.0; +static const size_t kNumFrameTimeStamps = 16; +struct FPSCounter { + FPSCounter() : mCurrentFrameIndex(0) {} + + // We keep a circular buffer of the time points at which the last K + // frames were drawn. To estimate FPS, we count the number of + // frames we've drawn within the last kFPSWindowMs milliseconds and + // divide by the amount time since the first of those frames. + TimeStamp mFrames[kNumFrameTimeStamps]; + size_t mCurrentFrameIndex; + + void AddFrame(TimeStamp aNewFrame) { + mFrames[mCurrentFrameIndex] = aNewFrame; + mCurrentFrameIndex = (mCurrentFrameIndex + 1) % kNumFrameTimeStamps; + } + + double AddFrameAndGetFps(TimeStamp aCurrentFrame) { + AddFrame(aCurrentFrame); + return EstimateFps(aCurrentFrame); + } + + double GetFpsAt(TimeStamp aNow) { + return EstimateFps(aNow); + } + +private: + double EstimateFps(TimeStamp aNow) { + TimeStamp beginningOfWindow = + (aNow - TimeDuration::FromMilliseconds(kFpsWindowMs)); + TimeStamp earliestFrameInWindow = aNow; + size_t numFramesDrawnInWindow = 0; + for (size_t i = 0; i < kNumFrameTimeStamps; ++i) { + const TimeStamp& frame = mFrames[i]; + if (!frame.IsNull() && frame > beginningOfWindow) { + ++numFramesDrawnInWindow; + earliestFrameInWindow = PR_MIN(earliestFrameInWindow, frame); + } + } + double realWindowSecs = (aNow - earliestFrameInWindow).ToSeconds(); + if (realWindowSecs == 0.0) { + return 0.0; + } + return double(numFramesDrawnInWindow) / realWindowSecs; + } +}; + +struct FPSState { + GLuint mTexture; + FPSCounter mCompositionFps; + FPSCounter mTransactionFps; + + FPSState() : mTexture(0) { } + + void DrawFPS(TimeStamp, GLContext*, ShaderProgramOGL*); + + void NotifyShadowTreeTransaction() { + mTransactionFps.AddFrame(TimeStamp::Now()); + } +}; + + +void +FPSState::DrawFPS(TimeStamp aNow, + GLContext* context, ShaderProgramOGL* copyprog) +{ + int fps = int(mCompositionFps.AddFrameAndGetFps(aNow)); + int txnFps = int(mTransactionFps.GetFpsAt(aNow)); + + GLint viewport[4]; + context->fGetIntegerv(LOCAL_GL_VIEWPORT, viewport); + + if (!mTexture) { + // Bind the number of textures we need, in this case one. + context->fGenTextures(1, &mTexture); + context->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture); + context->fTexParameteri(LOCAL_GL_TEXTURE_2D,LOCAL_GL_TEXTURE_MIN_FILTER,LOCAL_GL_NEAREST); + context->fTexParameteri(LOCAL_GL_TEXTURE_2D,LOCAL_GL_TEXTURE_MAG_FILTER,LOCAL_GL_NEAREST); + + unsigned char text[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 255, 255, 255, 0, 255, 255, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 0, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, + 0, 255, 0, 255, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, + 0, 255, 0, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, + 0, 255, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, + 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 255, 0, 255, 255, 255, 0, 0, 0, 255, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + // convert from 8 bit to 32 bit so that don't have to write the text above out in 32 bit format + // we rely on int being 32 bits + unsigned int* buf = (unsigned int*)malloc(64 * 8 * 4); + for (int i = 0; i < 7; i++) { + for (int j = 0; j < 41; j++) { + unsigned int purple = 0xfff000ff; + unsigned int white = 0xffffffff; + buf[i * 64 + j] = (text[i * 41 + j] == 0) ? purple : white; + } + } + context->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, 64, 8, 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, buf); + free(buf); + } + + struct Vertex2D { + float x,y; + }; + const Vertex2D vertices[] = { + { -1.0f, 1.0f - 42.f / viewport[3] }, + { -1.0f, 1.0f}, + { -1.0f + 22.f / viewport[2], 1.0f - 42.f / viewport[3] }, + { -1.0f + 22.f / viewport[2], 1.0f }, + + { -1.0f + 22.f / viewport[2], 1.0f - 42.f / viewport[3] }, + { -1.0f + 22.f / viewport[2], 1.0f }, + { -1.0f + 44.f / viewport[2], 1.0f - 42.f / viewport[3] }, + { -1.0f + 44.f / viewport[2], 1.0f }, + + { -1.0f + 44.f / viewport[2], 1.0f - 42.f / viewport[3] }, + { -1.0f + 44.f / viewport[2], 1.0f }, + { -1.0f + 66.f / viewport[2], 1.0f - 42.f / viewport[3] }, + { -1.0f + 66.f / viewport[2], 1.0f } + }; + + const Vertex2D vertices2[] = { + { -1.0f + 80.f / viewport[2], 1.0f - 42.f / viewport[3] }, + { -1.0f + 80.f / viewport[2], 1.0f }, + { -1.0f + 102.f / viewport[2], 1.0f - 42.f / viewport[3] }, + { -1.0f + 102.f / viewport[2], 1.0f }, + + { -1.0f + 102.f / viewport[2], 1.0f - 42.f / viewport[3] }, + { -1.0f + 102.f / viewport[2], 1.0f }, + { -1.0f + 124.f / viewport[2], 1.0f - 42.f / viewport[3] }, + { -1.0f + 124.f / viewport[2], 1.0f }, + + { -1.0f + 124.f / viewport[2], 1.0f - 42.f / viewport[3] }, + { -1.0f + 124.f / viewport[2], 1.0f }, + { -1.0f + 146.f / viewport[2], 1.0f - 42.f / viewport[3] }, + { -1.0f + 146.f / viewport[2], 1.0f }, + }; + + int v1 = fps % 10; + int v10 = (fps % 100) / 10; + int v100 = (fps % 1000) / 100; + + int txn1 = txnFps % 10; + int txn10 = (txnFps % 100) / 10; + int txn100 = (txnFps % 1000) / 100; + + // Feel free to comment these texture coordinates out and use one + // of the ones below instead, or play around with your own values. + const GLfloat texCoords[] = { + (v100 * 4.f) / 64, 7.f / 8, + (v100 * 4.f) / 64, 0.0f, + (v100 * 4.f + 4) / 64, 7.f / 8, + (v100 * 4.f + 4) / 64, 0.0f, + + (v10 * 4.f) / 64, 7.f / 8, + (v10 * 4.f) / 64, 0.0f, + (v10 * 4.f + 4) / 64, 7.f / 8, + (v10 * 4.f + 4) / 64, 0.0f, + + (v1 * 4.f) / 64, 7.f / 8, + (v1 * 4.f) / 64, 0.0f, + (v1 * 4.f + 4) / 64, 7.f / 8, + (v1 * 4.f + 4) / 64, 0.0f, + }; + + const GLfloat texCoords2[] = { + (txn100 * 4.f) / 64, 7.f / 8, + (txn100 * 4.f) / 64, 0.0f, + (txn100 * 4.f + 4) / 64, 7.f / 8, + (txn100 * 4.f + 4) / 64, 0.0f, + + (txn10 * 4.f) / 64, 7.f / 8, + (txn10 * 4.f) / 64, 0.0f, + (txn10 * 4.f + 4) / 64, 7.f / 8, + (txn10 * 4.f + 4) / 64, 0.0f, + + (txn1 * 4.f) / 64, 7.f / 8, + (txn1 * 4.f) / 64, 0.0f, + (txn1 * 4.f + 4) / 64, 7.f / 8, + (txn1 * 4.f + 4) / 64, 0.0f, + }; + + // Turn necessary features on + context->fEnable(LOCAL_GL_BLEND); + context->fBlendFunc(LOCAL_GL_ONE, LOCAL_GL_SRC_COLOR); + + context->fActiveTexture(LOCAL_GL_TEXTURE0); + context->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture); + + copyprog->Activate(); + copyprog->SetTextureUnit(0); + + // we're going to use client-side vertex arrays for this. + context->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0); + + // "COPY" + context->fBlendFuncSeparate(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 tcattr = copyprog->AttribLocation(ShaderProgramOGL::TexCoordAttrib); + + context->fEnableVertexAttribArray(vcattr); + context->fEnableVertexAttribArray(tcattr); + + context->fVertexAttribPointer(vcattr, + 2, LOCAL_GL_FLOAT, + LOCAL_GL_FALSE, + 0, vertices); + + 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); +} + /** * LayerManagerOGL */ LayerManagerOGL::LayerManagerOGL(nsIWidget *aWidget, int aSurfaceWidth, int aSurfaceHeight, bool aIsRenderingToEGLSurface) : mWidget(aWidget) , mWidgetSize(-1, -1) , mSurfaceSize(aSurfaceWidth, aSurfaceHeight) @@ -509,212 +743,16 @@ LayerManagerOGL::RootLayer() const return nullptr; } return static_cast<LayerOGL*>(mRoot->ImplData()); } bool LayerManagerOGL::sDrawFPS = false; -void -LayerManagerOGL::FPSState::NotifyShadowTreeTransaction() -{ - contentFCount++; -} - -/* This function tries to stick to portable C89 as much as possible - * so that it can be easily copied into other applications */ -void -LayerManagerOGL::FPSState::DrawFPS(GLContext* context, ShaderProgramOGL* copyprog) -{ - fcount++; - - int rate = 30; - if (fcount >= rate) { - TimeStamp now = TimeStamp::Now(); - TimeDuration duration = now - last; - last = now; - fps = rate / duration.ToSeconds() + .5; - fcount = 0; - } - if (contentFCount >= rate) { - TimeStamp now = TimeStamp::Now(); - TimeDuration duration = now - contentLast; - contentLast = now; - contentFps = contentFCount / duration.ToSeconds() + .5; - contentFCount = 0; - } - - GLint viewport[4]; - context->fGetIntegerv(LOCAL_GL_VIEWPORT, viewport); - - static GLuint texture; - if (!initialized) { - // Bind the number of textures we need, in this case one. - context->fGenTextures(1, &texture); - context->fBindTexture(LOCAL_GL_TEXTURE_2D, texture); - context->fTexParameteri(LOCAL_GL_TEXTURE_2D,LOCAL_GL_TEXTURE_MIN_FILTER,LOCAL_GL_NEAREST); - context->fTexParameteri(LOCAL_GL_TEXTURE_2D,LOCAL_GL_TEXTURE_MAG_FILTER,LOCAL_GL_NEAREST); - - unsigned char text[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 255, 255, 0, 255, 255, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 0, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, - 0, 255, 0, 255, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, - 0, 255, 0, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, - 0, 255, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, - 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 255, 0, 255, 255, 255, 0, 0, 0, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }; - - // convert from 8 bit to 32 bit so that don't have to write the text above out in 32 bit format - // we rely on int being 32 bits - unsigned int* buf = (unsigned int*)malloc(64 * 8 * 4); - for (int i = 0; i < 7; i++) { - for (int j = 0; j < 41; j++) { - unsigned int purple = 0xfff000ff; - unsigned int white = 0xffffffff; - buf[i * 64 + j] = (text[i * 41 + j] == 0) ? purple : white; - } - } - context->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, 64, 8, 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, buf); - free(buf); - initialized = true; - } - - struct Vertex2D { - float x,y; - }; - const Vertex2D vertices[] = { - { -1.0f, 1.0f - 42.f / viewport[3] }, - { -1.0f, 1.0f}, - { -1.0f + 22.f / viewport[2], 1.0f - 42.f / viewport[3] }, - { -1.0f + 22.f / viewport[2], 1.0f }, - - { -1.0f + 22.f / viewport[2], 1.0f - 42.f / viewport[3] }, - { -1.0f + 22.f / viewport[2], 1.0f }, - { -1.0f + 44.f / viewport[2], 1.0f - 42.f / viewport[3] }, - { -1.0f + 44.f / viewport[2], 1.0f }, - - { -1.0f + 44.f / viewport[2], 1.0f - 42.f / viewport[3] }, - { -1.0f + 44.f / viewport[2], 1.0f }, - { -1.0f + 66.f / viewport[2], 1.0f - 42.f / viewport[3] }, - { -1.0f + 66.f / viewport[2], 1.0f }, - }; - - const Vertex2D vertices2[] = { - { -1.0f + 80.f / viewport[2], 1.0f - 42.f / viewport[3] }, - { -1.0f + 80.f / viewport[2], 1.0f }, - { -1.0f + 102.f / viewport[2], 1.0f - 42.f / viewport[3] }, - { -1.0f + 102.f / viewport[2], 1.0f }, - - { -1.0f + 102.f / viewport[2], 1.0f - 42.f / viewport[3] }, - { -1.0f + 102.f / viewport[2], 1.0f }, - { -1.0f + 124.f / viewport[2], 1.0f - 42.f / viewport[3] }, - { -1.0f + 124.f / viewport[2], 1.0f }, - - { -1.0f + 124.f / viewport[2], 1.0f - 42.f / viewport[3] }, - { -1.0f + 124.f / viewport[2], 1.0f }, - { -1.0f + 146.f / viewport[2], 1.0f - 42.f / viewport[3] }, - { -1.0f + 146.f / viewport[2], 1.0f }, - }; - - int v1 = fps % 10; - int v10 = (fps % 100) / 10; - int v100 = (fps % 1000) / 100; - - int content1 = contentFps % 10; - int content10 = (contentFps % 100) / 10; - int content100 = (contentFps % 1000) / 100; - - // Feel free to comment these texture coordinates out and use one - // of the ones below instead, or play around with your own values. - const GLfloat texCoords[] = { - (v100 * 4.f) / 64, 7.f / 8, - (v100 * 4.f) / 64, 0.0f, - (v100 * 4.f + 4) / 64, 7.f / 8, - (v100 * 4.f + 4) / 64, 0.0f, - - (v10 * 4.f) / 64, 7.f / 8, - (v10 * 4.f) / 64, 0.0f, - (v10 * 4.f + 4) / 64, 7.f / 8, - (v10 * 4.f + 4) / 64, 0.0f, - - (v1 * 4.f) / 64, 7.f / 8, - (v1 * 4.f) / 64, 0.0f, - (v1 * 4.f + 4) / 64, 7.f / 8, - (v1 * 4.f + 4) / 64, 0.0f, - }; - - const GLfloat texCoords2[] = { - (content100 * 4.f) / 64, 7.f / 8, - (content100 * 4.f) / 64, 0.0f, - (content100 * 4.f + 4) / 64, 7.f / 8, - (content100 * 4.f + 4) / 64, 0.0f, - - (content10 * 4.f) / 64, 7.f / 8, - (content10 * 4.f) / 64, 0.0f, - (content10 * 4.f + 4) / 64, 7.f / 8, - (content10 * 4.f + 4) / 64, 0.0f, - - (content1 * 4.f) / 64, 7.f / 8, - (content1 * 4.f) / 64, 0.0f, - (content1 * 4.f + 4) / 64, 7.f / 8, - (content1 * 4.f + 4) / 64, 0.0f, - }; - - // Turn necessary features on - context->fEnable(LOCAL_GL_BLEND); - context->fBlendFunc(LOCAL_GL_ONE, LOCAL_GL_SRC_COLOR); - - context->fActiveTexture(LOCAL_GL_TEXTURE0); - context->fBindTexture(LOCAL_GL_TEXTURE_2D, texture); - - copyprog->Activate(); - copyprog->SetTextureUnit(0); - - // we're going to use client-side vertex arrays for this. - context->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0); - - // "COPY" - context->fBlendFuncSeparate(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 tcattr = copyprog->AttribLocation(ShaderProgramOGL::TexCoordAttrib); - - context->fEnableVertexAttribArray(vcattr); - context->fEnableVertexAttribArray(tcattr); - - context->fVertexAttribPointer(vcattr, - 2, LOCAL_GL_FLOAT, - LOCAL_GL_FALSE, - 0, vertices); - - 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); -} - // |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. // // |aTexSize| is the actual size of the texture, as it can be larger // than the rectangle given by |aTexCoordRect|. void @@ -783,17 +821,19 @@ LayerManagerOGL::BindAndDrawQuadWithText } mGLContext->fDisableVertexAttribArray(texCoordAttribIndex); } } void LayerManagerOGL::NotifyShadowTreeTransaction() { - mFPS.NotifyShadowTreeTransaction(); + if (mFPS) { + mFPS->NotifyShadowTreeTransaction(); + } } void LayerManagerOGL::Render() { SAMPLE_LABEL("LayerManagerOGL", "Render"); if (mDestroyed) { NS_WARNING("Call on destroyed layer manager"); @@ -895,18 +935,24 @@ LayerManagerOGL::Render() #endif if (mTarget) { CopyToTarget(mTarget); mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0); return; } - if (sDrawFPS) { - mFPS.DrawFPS(mGLContext, GetProgram(Copy2DProgramType)); + if (sDrawFPS && !mFPS) { + mFPS = new FPSState(); + } else if (!sDrawFPS && mFPS) { + mFPS = nullptr; + } + + if (mFPS) { + mFPS->DrawFPS(TimeStamp::Now(), mGLContext, GetProgram(Copy2DProgramType)); } if (mGLContext->IsDoubleBuffered()) { mGLContext->SwapBuffers(); LayerManager::PostPresent(); mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0); return; }
--- a/gfx/layers/opengl/LayerManagerOGL.h +++ b/gfx/layers/opengl/LayerManagerOGL.h @@ -37,16 +37,17 @@ namespace mozilla { namespace layers { class LayerOGL; class ShadowThebesLayer; class ShadowContainerLayer; class ShadowImageLayer; class ShadowCanvasLayer; class ShadowColorLayer; +struct FPSState; /** * This is the LayerManager used for OpenGL 2.1 and OpenGL ES 2.0. * This can be used either on the main thread or the compositor. */ class THEBES_API LayerManagerOGL : public ShadowLayerManager { @@ -433,42 +434,17 @@ private: */ void AddPrograms(gl::ShaderProgramType aType); /* Thebes layer callbacks; valid at the end of a transaciton, * while rendering */ DrawThebesLayerCallback mThebesLayerCallback; void *mThebesLayerCallbackData; gfxMatrix mWorldMatrix; - - struct FPSState - { - GLuint texture; - int fps; - bool initialized; - int fcount; - TimeStamp last; - - int contentFps; - int contentFCount; - TimeStamp contentLast; - - FPSState() - : texture(0) - , fps(0) - , initialized(false) - , fcount(0) - , contentFps(0) - , contentFCount(0) - { - contentLast = last = TimeStamp::Now(); - } - void DrawFPS(GLContext*, ShaderProgramOGL*); - void NotifyShadowTreeTransaction(); - } mFPS; + nsAutoPtr<FPSState> mFPS; static bool sDrawFPS; }; /** * General information and tree management for OGL layers. */ class LayerOGL