mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 780074: Change the fps counter to provide better estimates of instantaneous fps. r=jrmuizel
This commit is contained in:
parent
a4736dd52a
commit
d0c5ba562a
@ -48,6 +48,240 @@ using namespace mozilla::gl;
|
||||
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
|
||||
*/
|
||||
@ -514,202 +748,6 @@ LayerManagerOGL::RootLayer() const
|
||||
|
||||
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
|
||||
@ -788,7 +826,9 @@ LayerManagerOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
|
||||
void
|
||||
LayerManagerOGL::NotifyShadowTreeTransaction()
|
||||
{
|
||||
mFPS.NotifyShadowTreeTransaction();
|
||||
if (mFPS) {
|
||||
mFPS->NotifyShadowTreeTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -900,8 +940,14 @@ LayerManagerOGL::Render()
|
||||
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()) {
|
||||
|
@ -42,6 +42,7 @@ class ShadowContainerLayer;
|
||||
class ShadowImageLayer;
|
||||
class ShadowCanvasLayer;
|
||||
class ShadowColorLayer;
|
||||
struct FPSState;
|
||||
|
||||
/**
|
||||
* This is the LayerManager used for OpenGL 2.1 and OpenGL ES 2.0.
|
||||
@ -438,32 +439,7 @@ private:
|
||||
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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user