From df5ada10067c24ce697dcb99946d5541970e2288 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 20 Oct 2009 19:07:18 +0000 Subject: [PATCH] Make the video display only upload texture data when the frame has changed rather than every time Render is called. Originally committed to SVN as r3726. --- aegisub/src/video_display.cpp | 3 ++- aegisub/src/video_out_gl.cpp | 20 +++++++++++++------- aegisub/src/video_out_gl.h | 8 +++++++- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/aegisub/src/video_display.cpp b/aegisub/src/video_display.cpp index fde75aef6..3ea91506b 100644 --- a/aegisub/src/video_display.cpp +++ b/aegisub/src/video_display.cpp @@ -193,6 +193,7 @@ void VideoDisplay::SetFrame(int frameNumber) { if (IsShownOnScreen() && visual) visual->Refresh(); // Render the new frame + videoOut->InvalidateFrame(); Render(frameNumber); currentFrame = frameNumber; @@ -274,7 +275,7 @@ void VideoDisplay::Render(int frameNumber) try { glDisable(GL_BLEND); if (glGetError()) throw _T("Error disabling blending."); - videoOut->DisplayFrame(context->GetFrame(frameNumber), sw, sh); + videoOut->DisplayFrame(context->GetFrame(frameNumber), frameNumber, sw, sh); DrawTVEffects(); diff --git a/aegisub/src/video_out_gl.cpp b/aegisub/src/video_out_gl.cpp index 3df30f3fc..26ddefd0f 100644 --- a/aegisub/src/video_out_gl.cpp +++ b/aegisub/src/video_out_gl.cpp @@ -111,7 +111,8 @@ VideoOutGL::VideoOutGL() textureList(), textureCount(0), textureRows(0), - textureCols(0) + textureCols(0), + lastFrame(-1) { } /// @brief Runtime detection of required OpenGL capabilities @@ -218,9 +219,8 @@ void VideoOutGL::InitTextures(int width, int height, GLenum format, int bpp) { ti.texTop = 1.0f / (2 * h); } - // Calculate what percent of the texture is actually used - ti.texRight = float(ti.sourceW) / w - ti.texLeft; - ti.texBottom = float(ti.sourceH) / h - ti.texTop; + ti.texRight = 1.0f - ti.texLeft; + ti.texBottom = 1.0f - ti.texTop; // destW/H is the percent of the output which this texture covers ti.destW = float(w) / width; @@ -259,9 +259,11 @@ void VideoOutGL::InitTextures(int width, int height, GLenum format, int bpp) { frameFormat = format; } -void VideoOutGL::DisplayFrame(AegiVideoFrame frame, int sw, int sh) { +void VideoOutGL::DisplayFrame(AegiVideoFrame frame, int frameNumber, int sw, int sh) { 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); @@ -283,8 +285,10 @@ void VideoOutGL::DisplayFrame(AegiVideoFrame frame, int sw, int sh) { 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); + 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); @@ -313,6 +317,8 @@ void VideoOutGL::DisplayFrame(AegiVideoFrame frame, int sw, int sh) { glDisable(GL_TEXTURE_2D); if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glDisable(GL_TEXTURE_2d)", err); + + lastFrame = frameNumber; } VideoOutGL::~VideoOutGL() { diff --git a/aegisub/src/video_out_gl.h b/aegisub/src/video_out_gl.h index 309224d1c..2d6d9c4da 100644 --- a/aegisub/src/video_out_gl.h +++ b/aegisub/src/video_out_gl.h @@ -74,6 +74,8 @@ 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); @@ -83,9 +85,13 @@ private: public: /// @brief Render a frame /// @param frame The frame to be displayed + /// @param frameNumber The frame number of the frame to be displayed /// @param sw The current script width /// @param sh The current script height - void DisplayFrame(AegiVideoFrame frame, int sw, int sh); + void DisplayFrame(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; } /// @brief Constructor VideoOutGL();