Significantly reduce the number of unnecessary calls to VideoContext::GetFrame.

Originally committed to SVN as r3739.
This commit is contained in:
Thomas Goyne 2009-10-27 14:27:39 +00:00
parent 7de7dba807
commit dcfdb02e6c
4 changed files with 48 additions and 52 deletions

View file

@ -152,6 +152,7 @@ void VideoDisplay::ShowCursor(bool show) {
}
void VideoDisplay::SetFrame(int frameNumber) {
VideoContext *context = VideoContext::Get();
ControlSlider->SetValue(frameNumber);
// Get time for frame
@ -163,7 +164,7 @@ void VideoDisplay::SetFrame(int frameNumber) {
// Set the text box for frame number and time
PositionDisplay->SetValue(wxString::Format(_T("%01i:%02i:%02i.%03i - %i"), h, m, s, ms, frameNumber));
if (VideoContext::Get()->GetKeyFrames().Index(frameNumber) != wxNOT_FOUND) {
if (context->GetKeyFrames().Index(frameNumber) != wxNOT_FOUND) {
// Set the background color to indicate this is a keyframe
PositionDisplay->SetBackgroundColour(Options.AsColour(_T("Grid selection background")));
PositionDisplay->SetForegroundColour(Options.AsColour(_T("Grid selection foreground")));
@ -178,7 +179,7 @@ void VideoDisplay::SetFrame(int frameNumber) {
int startOff = 0;
int endOff = 0;
if (AssDialogue *curLine = VideoContext::Get()->curLine) {
if (AssDialogue *curLine = context->curLine) {
startOff = time - curLine->Start.GetMS();
endOff = time - curLine->End.GetMS();
}
@ -193,8 +194,11 @@ void VideoDisplay::SetFrame(int frameNumber) {
if (IsShownOnScreen() && visual) visual->Refresh();
// Render the new frame
videoOut->InvalidateFrame();
Render(frameNumber);
if (context->IsLoaded()) {
AegiVideoFrame frame = context->GetFrame(frameNumber);
videoOut->UploadFrameData(frame);
}
Render();
currentFrame = frameNumber;
}
@ -205,7 +209,7 @@ void VideoDisplay::SetFrameRange(int from, int to) {
/// @brief Render the currently visible frame
void VideoDisplay::Render(int frameNumber) try {
void VideoDisplay::Render() try {
if (!IsShownOnScreen()) return;
if (!wxIsMainThread()) throw _T("Error: trying to render from non-primary thread");
@ -275,7 +279,7 @@ void VideoDisplay::Render(int frameNumber) try {
glDisable(GL_BLEND);
if (glGetError()) throw _T("Error disabling blending.");
videoOut->DisplayFrame(context->GetFrame(frameNumber), frameNumber, sw, sh);
videoOut->Render(sw, sh);
DrawTVEffects();

View file

@ -145,7 +145,7 @@ public:
int GetFrame() const { return currentFrame; }
void SetFrameRange(int from, int to);
void Render(int frameNumber = -1);
void Render();
void ShowCursor(bool show);
void ConvertMouseCoords(int &x,int &y);

View file

@ -111,8 +111,7 @@ VideoOutGL::VideoOutGL()
textureList(),
textureCount(0),
textureRows(0),
textureCols(0),
lastFrame(-1)
textureCols(0)
{ }
/// @brief Runtime detection of required OpenGL capabilities
@ -152,7 +151,7 @@ void VideoOutGL::DetectOpenGLCapabilities() {
/// @param height The frame's height
/// @param format The frame's format
/// @param bpp The frame's bytes per pixel
void VideoOutGL::InitTextures(int width, int height, GLenum format, int bpp) {
void VideoOutGL::InitTextures(int width, int height, GLenum format, int bpp, bool flipped) {
// Do nothing if the frame size and format are unchanged
if (width == frameWidth && height == frameHeight && format == frameFormat) return;
wxLogDebug("VideoOutGL::InitTextures: Video size: %dx%d\n", width, height);
@ -222,6 +221,12 @@ void VideoOutGL::InitTextures(int width, int height, GLenum format, int bpp) {
ti.texRight = 1.0f - ti.texLeft;
ti.texBottom = 1.0f - ti.texTop;
if (flipped) {
float t = ti.texTop;
ti.texTop = ti.texBottom;
ti.texBottom = ti.texTop;
}
// destW/H is the percent of the output which this texture covers
ti.destW = float(w) / width;
ti.destH = float(h) / height;
@ -258,22 +263,34 @@ void VideoOutGL::InitTextures(int width, int height, GLenum format, int bpp) {
frameHeight = height;
frameFormat = format;
}
void VideoOutGL::DisplayFrame(const AegiVideoFrame& frame, int frameNumber, int sw, int sh) {
void VideoOutGL::UploadFrameData(const AegiVideoFrame& frame) {
if (frame.h == 0 || frame.w == 0) return;
if (frameNumber == -1) frameNumber = lastFrame;
glEnable(GL_TEXTURE_2D);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glEnable(GL_TEXTURE_2d)", err);
GLuint format = frame.invertChannels ? GL_BGRA_EXT : GL_RGBA;
InitTextures(frame.w, frame.h, format, frame.GetBpp(0));
InitTextures(frame.w, frame.h, format, frame.GetBpp(0), frame.flipped);
// Set the row length, needed to be able to upload partial rows
glPixelStorei(GL_UNPACK_ROW_LENGTH, frame.w);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glPixelStorei(GL_UNPACK_ROW_LENGTH, FrameWidth)", err);
for (unsigned i = 0; i < textureList.size(); i++) {
TextureInfo& ti = textureList[i];
glBindTexture(GL_TEXTURE_2D, ti.textureID);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glBindTexture", err);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ti.sourceW, ti.sourceH, format, GL_UNSIGNED_BYTE, frame.data[0] + ti.dataOffset);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glTexSubImage2D", err);
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glPixelStorei(GL_UNPACK_ROW_LENGTH, default)", err);
}
void VideoOutGL::Render(int sw, int sh) {
glEnable(GL_TEXTURE_2D);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glEnable(GL_TEXTURE_2d)", err);
for (unsigned i = 0; i < textureList.size(); i++) {
TextureInfo& ti = textureList[i];
@ -285,40 +302,19 @@ void VideoOutGL::DisplayFrame(const AegiVideoFrame& frame, int frameNumber, int
glBindTexture(GL_TEXTURE_2D, ti.textureID);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glBindTexture", err);
if (lastFrame != frameNumber) {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ti.sourceW, ti.sourceH, format, GL_UNSIGNED_BYTE, frame.data[0] + ti.dataOffset);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glTexSubImage2D", err);
}
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glColor4f", err);
float top, bottom;
if (frame.flipped) {
top = ti.texBottom;
bottom = ti.texTop;
}
else {
top = ti.texTop;
bottom = ti.texBottom;
}
glBegin(GL_QUADS);
glTexCoord2f(ti.texLeft, top); glVertex2f(destX, destY);
glTexCoord2f(ti.texRight, top); glVertex2f(destX + destW, destY);
glTexCoord2f(ti.texRight, bottom); glVertex2f(destX + destW, destY + destH);
glTexCoord2f(ti.texLeft, bottom); glVertex2f(destX, destY + destH);
glTexCoord2f(ti.texLeft, ti.texTop); glVertex2f(destX, destY);
glTexCoord2f(ti.texRight, ti.texTop); glVertex2f(destX + destW, destY);
glTexCoord2f(ti.texRight, ti.texBottom); glVertex2f(destX + destW, destY + destH);
glTexCoord2f(ti.texLeft, ti.texBottom); glVertex2f(destX, destY + destH);
glEnd();
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"GL_QUADS", err);
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glPixelStorei(GL_UNPACK_ROW_LENGTH, default)", err);
glDisable(GL_TEXTURE_2D);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glDisable(GL_TEXTURE_2d)", err);
lastFrame = frameNumber;
}
VideoOutGL::~VideoOutGL() {

View file

@ -74,24 +74,20 @@ private:
int textureRows;
/// The number of columns of textures
int textureCols;
/// The frame currently displayed
int lastFrame;
void DetectOpenGLCapabilities();
void InitTextures(int width, int height, GLenum format, int bpp);
void InitTextures(int width, int height, GLenum format, int bpp, bool flipped);
VideoOutGL(const VideoOutGL &);
VideoOutGL& operator=(const VideoOutGL&);
public:
/// @brief Render a frame
/// @brief Set the frame to be displayed when Render() is called
/// @param frame The frame to be displayed
/// @param frameNumber The frame number of the frame to be displayed
void UploadFrameData(const AegiVideoFrame& frame);
/// @brief Render a frame
/// @param sw The current script width
/// @param sh The current script height
void DisplayFrame(const AegiVideoFrame& frame, int frameNumber, int sw, int sh);
/// @brief Force the redisplay of the frame the next time DisplayFrame is called even if the frame number has not changed
void InvalidateFrame() { lastFrame = -1; }
void Render(int sw, int sh);
/// @brief Constructor
VideoOutGL();