forked from mia/Aegisub
Significantly reduce the number of unnecessary calls to VideoContext::GetFrame.
Originally committed to SVN as r3739.
This commit is contained in:
parent
7de7dba807
commit
dcfdb02e6c
4 changed files with 48 additions and 52 deletions
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue