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

View File

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

View File

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

View File

@ -74,24 +74,20 @@ private:
int textureRows; int textureRows;
/// The number of columns of textures /// The number of columns of textures
int textureCols; int textureCols;
/// The frame currently displayed
int lastFrame;
void DetectOpenGLCapabilities(); 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(const VideoOutGL &);
VideoOutGL& operator=(const VideoOutGL&); VideoOutGL& operator=(const VideoOutGL&);
public: public:
/// @brief Render a frame /// @brief Set the frame to be displayed when Render() is called
/// @param frame The frame to be displayed /// @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 sw The current script width
/// @param sh The current script height /// @param sh The current script height
void DisplayFrame(const AegiVideoFrame& frame, int frameNumber, int sw, int sh); void Render(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 /// @brief Constructor
VideoOutGL(); VideoOutGL();