diff --git a/mythtv/libs/libmythtv/openglvideo.cpp b/mythtv/libs/libmythtv/openglvideo.cpp index 4cc99ca5385..c87c9769afb 100644 --- a/mythtv/libs/libmythtv/openglvideo.cpp +++ b/mythtv/libs/libmythtv/openglvideo.cpp @@ -150,14 +150,6 @@ bool OpenGLVideo::Init(MythRenderOpenGL *glcontext, VideoColourSpace *colourspac else m_extraFeatures &= ~kGLExtFBDiscard; } - else - { - if ((m_extraFeatures & kGLExtPBufObj) && !enablePBOs) - { - LOG(VB_GENERAL, LOG_INFO, LOC + "Disabling Pixel Buffer Objects"); - m_extraFeatures &= ~kGLExtPBufObj; - } - } if (viewportControl) gl_context->SetFence(); @@ -650,11 +642,10 @@ void OpenGLVideo::SetViewPort(const QSize &viewPortSize) MythGLTexture* OpenGLVideo::CreateVideoTexture(QSize size, QSize &tex_size) { MythGLTexture *texture = nullptr; - bool pbo = m_extraFeatures & kGLExtPBufObj; if (kGLYV12 == videoType) { size.setHeight((3 * size.height() + 1) / 2); - texture = gl_context->CreateTexture(size, pbo, + texture = gl_context->CreateTexture(size, QOpenGLTexture::UInt8, QOpenGLTexture::Luminance, QOpenGLTexture::Linear, QOpenGLTexture::ClampToEdge, QOpenGLTexture::LuminanceFormat); @@ -662,11 +653,11 @@ MythGLTexture* OpenGLVideo::CreateVideoTexture(QSize size, QSize &tex_size) else if (kGLUYVY == videoType) { size.setWidth(size.width() >> 1); - texture = gl_context->CreateTexture(size, pbo); + texture = gl_context->CreateTexture(size); } else if ((kGLHQUYV == videoType) || (kGLGPU == videoType) || (kGLRGBA == videoType)) { - texture = gl_context->CreateTexture(size, pbo); + texture = gl_context->CreateTexture(size); } tex_size = gl_context->GetTextureSize(size); @@ -703,43 +694,58 @@ void OpenGLVideo::UpdateInputFrame(const VideoFrame *frame) if (hardwareDeinterlacing) RotateTextures(); - // We need to convert frames here to avoid dependencies in MythRenderOpenGL + MythGLTexture *texture = inputTextures[0]; + if (!texture) + return; - // A buffer is not needed if we are transferring a YV12 frame directly without - // any conversion. If a Pixel Buffer Object is being used - that will however - // be returned and will need to be copied to. - bool usebuffer = !((kGLYV12 == videoType) && (video_dim.width() == frame->pitches[0])); - void* buf = gl_context->GetTextureBuffer(inputTextures[0], usebuffer); - if (!buf) + void* buf = nullptr; + if ((kGLYV12 == videoType) && (video_dim.width() == frame->pitches[0])) { buf = frame->buf; } - else if (kGLYV12 == videoType) - { - copybuffer((uint8_t*)buf, frame, video_dim.width()); - } - else if (kGLUYVY == videoType) - { - AVFrame img_out; - m_copyCtx.Copy(&img_out, frame, (unsigned char*)buf, AV_PIX_FMT_UYVY422); - } - else if (kGLRGBA == videoType) - { - AVFrame img_out; - m_copyCtx.Copy(&img_out, frame, (unsigned char*)buf, AV_PIX_FMT_RGBA); - } - else if (kGLHQUYV == videoType && frame->interlaced_frame) - { - pack_yv12interlaced(frame->buf, (unsigned char*)buf, frame->offsets, - frame->pitches, video_dim); - } - else if (kGLHQUYV == videoType) + else { - pack_yv12progressive(frame->buf, (unsigned char*)buf, frame->offsets, - frame->pitches, video_dim); + // create a storage buffer + if (!texture->m_data) + { + unsigned char *scratch = new unsigned char[texture->m_bufferSize]; + if (scratch) + { + memset(scratch, 0, texture->m_bufferSize); + texture->m_data = scratch; + } + } + if (!texture->m_data) + return; + buf = texture->m_data; + + if (kGLYV12 == videoType) + { + copybuffer((uint8_t*)buf, frame, video_dim.width()); + } + else if (kGLUYVY == videoType) + { + AVFrame img_out; + m_copyCtx.Copy(&img_out, frame, (unsigned char*)buf, AV_PIX_FMT_UYVY422); + } + else if (kGLRGBA == videoType) + { + AVFrame img_out; + m_copyCtx.Copy(&img_out, frame, (unsigned char*)buf, AV_PIX_FMT_RGBA); + } + else if (kGLHQUYV == videoType && frame->interlaced_frame) + { + pack_yv12interlaced(frame->buf, (unsigned char*)buf, frame->offsets, + frame->pitches, video_dim); + } + else if (kGLHQUYV == videoType) + { + pack_yv12progressive(frame->buf, (unsigned char*)buf, frame->offsets, + frame->pitches, video_dim); + } } - gl_context->UpdateTexture(inputTextures[0], buf); + texture->m_texture->setData(texture->m_pixelFormat, texture->m_pixelType, buf); if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO)) gl_context->logDebugMarker(LOC + "UPDATE_FRAME_END"); diff --git a/mythtv/libs/libmythtv/visualisations/videovisualgoom.cpp b/mythtv/libs/libmythtv/visualisations/videovisualgoom.cpp index 2bca5a5095e..6832530ae67 100644 --- a/mythtv/libs/libmythtv/visualisations/videovisualgoom.cpp +++ b/mythtv/libs/libmythtv/visualisations/videovisualgoom.cpp @@ -94,21 +94,24 @@ void VideoVisualGoom::Draw(const QRect &area, MythPainter */*painter*/, if ((m_render->Type() == kRenderOpenGL)) { MythRenderOpenGL *glrender = static_cast(m_render); - if (!m_glSurface && glrender && m_buffer) + if (glrender && m_buffer) { - m_glSurface = glrender->CreateTexture(m_area.size(), true); - } + glrender->makeCurrent(); - if (m_glSurface && glrender && m_buffer) - { - if (m_buffer != last) + if (!m_glSurface) + m_glSurface = glrender->CreateTexture(m_area.size()); + + if (m_glSurface) { - void* buf = glrender->GetTextureBuffer(m_glSurface, false); - if (buf) - memcpy(buf, m_buffer, m_area.width() * m_area.height() * 4); - glrender->UpdateTexture(m_glSurface, (void*)m_buffer); + if (m_buffer != last) + m_glSurface->m_texture->setData(m_glSurface->m_pixelFormat, m_glSurface->m_pixelType, m_buffer); + // goom doesn't render properly due to changes in video alpha blending + // so turn blend off + glrender->SetBlend(false); + glrender->DrawBitmap(&m_glSurface, 1, nullptr, m_area, area, nullptr); + glrender->SetBlend(true); } - glrender->DrawBitmap(&m_glSurface, 1, nullptr, m_area, area, nullptr); + glrender->doneCurrent(); } return; } diff --git a/mythtv/libs/libmythui/mythrender_opengl.cpp b/mythtv/libs/libmythui/mythrender_opengl.cpp index f4abc23970a..60f9c7e5473 100644 --- a/mythtv/libs/libmythui/mythrender_opengl.cpp +++ b/mythtv/libs/libmythui/mythrender_opengl.cpp @@ -51,7 +51,6 @@ MythGLTexture::MythGLTexture(QOpenGLTexture *Texture) m_texture(Texture), m_pixelFormat(QOpenGLTexture::RGBA), m_pixelType(QOpenGLTexture::UInt8), - m_pbo(nullptr), m_vbo(nullptr), m_size(0,0), m_totalSize(0,0), @@ -70,7 +69,6 @@ MythGLTexture::MythGLTexture(GLuint Texture) m_texture(nullptr), m_pixelFormat(QOpenGLTexture::RGBA), m_pixelType(QOpenGLTexture::UInt8), - m_pbo(nullptr), m_vbo(nullptr), m_size(0,0), m_totalSize(0,0), @@ -253,8 +251,6 @@ bool MythRenderOpenGL::Init(void) // Pixel buffer objects bool buffer_procs = (MYTH_GLMAPBUFFERPROC)GetProcAddress("glMapBuffer") && (MYTH_GLUNMAPBUFFERPROC)GetProcAddress("glUnmapBuffer"); - if (!isOpenGLES() && hasExtension("GL_ARB_pixel_buffer_object") && buffer_procs) - m_extraFeatures |= kGLExtPBufObj; // Buffers are available by default (GL and GLES). // Buffer mapping is available by extension @@ -321,7 +317,6 @@ void MythRenderOpenGL::DebugFeatures(void) LOG(VB_GENERAL, LOG_INFO, LOC + QString("Buffer mapping : %1").arg(GLYesNo(m_extraFeatures & kGLBufferMap))); LOG(VB_GENERAL, LOG_INFO, LOC + QString("Framebuffer objects : %1").arg(GLYesNo(m_features & Framebuffers))); LOG(VB_GENERAL, LOG_INFO, LOC + QString("Framebuffer discard : %1").arg(GLYesNo(m_extraFeatures & kGLExtFBDiscard))); - LOG(VB_GENERAL, LOG_INFO, LOC + QString("Pixelbuffer objects : %1").arg(GLYesNo(m_extraFeatures & kGLExtPBufObj))); LOG(VB_GENERAL, LOG_INFO, LOC + QString("Fence : %1") .arg(GLYesNo((m_extraFeatures & kGLAppleFence) || (m_extraFeatures & kGLNVFence)))); @@ -528,60 +523,7 @@ void MythRenderOpenGL::DeleteFence(void) } } -void* MythRenderOpenGL::GetTextureBuffer(MythGLTexture *Texture, bool create_buffer) -{ - if (!Texture || (Texture && !Texture->m_texture)) - return nullptr; - - makeCurrent(); // associated doneCurrent() in UpdateTexture - EnableTextures(); - - if (Texture->m_pbo) - { - Texture->m_pbo->bind(); - return Texture->m_pbo->map(QOpenGLBuffer::WriteOnly); - } - else if (!create_buffer) - { - return nullptr; - } - - if (Texture->m_data) - return Texture->m_data; - if (!Texture->m_bufferSize) - return nullptr; - - unsigned char *scratch = new unsigned char[Texture->m_bufferSize]; - if (scratch) - { - memset(scratch, 0, Texture->m_bufferSize); - Texture->m_data = scratch; - } - return scratch; -} - -void MythRenderOpenGL::UpdateTexture(MythGLTexture *Texture, void *buf) -{ - // N.B. GetTextureBuffer must be called first - if (!Texture) - return; - - if (Texture->m_pbo) - { - Texture->m_pbo->unmap(); - Texture->m_texture->setData(Texture->m_pixelFormat, Texture->m_pixelType, nullptr); - Texture->m_pbo->release(QOpenGLBuffer::PixelUnpackBuffer); - } - else - { - Texture->m_texture->setData(Texture->m_pixelFormat, Texture->m_pixelType, buf); - } - - doneCurrent(); -} - MythGLTexture* MythRenderOpenGL::CreateTexture(QSize Size, - bool UsePBO, QOpenGLTexture::PixelType PixelType, QOpenGLTexture::PixelFormat PixelFormat, QOpenGLTexture::Filter Filter, @@ -623,8 +565,6 @@ MythGLTexture* MythRenderOpenGL::CreateTexture(QSize Size, result->m_totalSize = GetTextureSize(Size); result->m_bufferSize = datasize; result->m_size = Size; - if (UsePBO) - result->m_pbo = CreatePBO(datasize); return result; } @@ -661,7 +601,7 @@ MythGLTexture* MythRenderOpenGL::CreateHelperTexture(void) makeCurrent(); uint width = m_max_tex_size; - MythGLTexture *texture = CreateTexture(QSize(width, 1), false, + MythGLTexture *texture = CreateTexture(QSize(width, 1), QOpenGLTexture::Float32, QOpenGLTexture::RGBA, QOpenGLTexture::Linear, @@ -812,8 +752,6 @@ void MythRenderOpenGL::DeleteTexture(MythGLTexture *Texture) delete Texture->m_texture; if (Texture->m_data) delete [] Texture->m_data; - if (Texture->m_pbo) - delete Texture->m_pbo; if (Texture->m_vbo) delete Texture->m_vbo; delete Texture; @@ -1396,36 +1334,6 @@ void MythRenderOpenGL::ResetProcs(void) m_glDiscardFramebuffer = nullptr; } -QOpenGLBuffer* MythRenderOpenGL::CreatePBO(uint BufferSize) -{ - OpenGLLocker locker(this); - if (!(m_extraFeaturesUsed & kGLExtPBufObj) || !BufferSize) - return nullptr; - - QOpenGLBuffer *buffer = new QOpenGLBuffer(QOpenGLBuffer::PixelUnpackBuffer); - if (buffer->create()) - { - buffer->setUsagePattern(QOpenGLBuffer::StreamDraw); - buffer->bind(); - buffer->allocate(BufferSize); - buffer->release(QOpenGLBuffer::PixelUnpackBuffer); - return buffer; - } - else - { - LOG(VB_GENERAL, LOG_WARNING, LOC + "Failed to create Pixel Buffer Object"); - if (glCheck()) - { - LOG(VB_GENERAL, LOG_INFO, LOC + "Pixel Buffer Objects unusable, disabling"); - m_extraFeatures &= ~kGLExtPBufObj; - m_extraFeaturesUsed &= ~kGLExtPBufObj; - } - delete buffer; - buffer = nullptr; - } - return buffer; -} - QOpenGLBuffer* MythRenderOpenGL::CreateVBO(uint Size, bool Release /*=true*/) { OpenGLLocker locker(this); diff --git a/mythtv/libs/libmythui/mythrender_opengl.h b/mythtv/libs/libmythui/mythrender_opengl.h index 56661fb26d0..dbccb5a522d 100644 --- a/mythtv/libs/libmythui/mythrender_opengl.h +++ b/mythtv/libs/libmythui/mythrender_opengl.h @@ -30,11 +30,10 @@ typedef enum { kGLFeatNone = 0x0000, kGLExtFBDiscard= 0x0001, - kGLExtPBufObj = 0x0002, - kGLNVFence = 0x0004, - kGLAppleFence = 0x0008, - kGLBufferMap = 0x0010, - kGLExtRGBA16 = 0x0020 + kGLNVFence = 0x0002, + kGLAppleFence = 0x0004, + kGLBufferMap = 0x0008, + kGLExtRGBA16 = 0x0010 } GLFeatures; #define TEX_OFFSET 8 @@ -52,7 +51,6 @@ class MUI_PUBLIC MythGLTexture QOpenGLTexture *m_texture; QOpenGLTexture::PixelFormat m_pixelFormat; QOpenGLTexture::PixelType m_pixelType; - QOpenGLBuffer *m_pbo; QOpenGLBuffer *m_vbo; QSize m_size; QSize m_totalSize; @@ -114,10 +112,8 @@ class MUI_PUBLIC MythRenderOpenGL : public QOpenGLContext, protected QOpenGLFunc void SetFence(void); void DeleteFence(void); - void* GetTextureBuffer(MythGLTexture *Texture, bool create_buffer); - void UpdateTexture(MythGLTexture *Texture, void *buf); MythGLTexture* CreateHelperTexture(void); - MythGLTexture* CreateTexture(QSize Size, bool UsePBO, + MythGLTexture* CreateTexture(QSize Size, QOpenGLTexture::PixelType PixelType = QOpenGLTexture::UInt8, QOpenGLTexture::PixelFormat PixelFormat = QOpenGLTexture::RGBA, QOpenGLTexture::Filter Filter = QOpenGLTexture::Linear, @@ -186,7 +182,6 @@ class MUI_PUBLIC MythRenderOpenGL : public QOpenGLContext, protected QOpenGLFunc void ResetProcs(void); void SetMatrixView(void); - QOpenGLBuffer* CreatePBO(uint BufferSize); QOpenGLBuffer* CreateVBO(uint Size, bool Release = true); void DeleteOpenGLResources(void); void DeleteFramebuffers(void); diff --git a/mythtv/programs/mythfrontend/globalsettings.cpp b/mythtv/programs/mythfrontend/globalsettings.cpp index de0a05c791b..2dc6eab1ca8 100644 --- a/mythtv/programs/mythfrontend/globalsettings.cpp +++ b/mythtv/programs/mythfrontend/globalsettings.cpp @@ -143,17 +143,6 @@ static HostCheckBoxSetting *OpenGLDiscardFB() gc->setValue(false); return gc; } - -static HostCheckBoxSetting *OpenGLEnablePBO() -{ - HostCheckBoxSetting *gc = new HostCheckBoxSetting("OpenGLEnablePBO"); - gc->setLabel(PlaybackSettings::tr("Enable Pixel Buffer Objects for OpenGL video")); - gc->setHelpText(PlaybackSettings::tr( - "Pixel Buffer Objects are enabled by default to improve video playback " - "but on some integrated GPUs (e.g. Intel) they are not needed and will reduce performance.")); - gc->setValue(true); - return gc; -} #endif #if CONFIG_DEBUGTYPE @@ -4288,8 +4277,6 @@ void PlaybackSettings::Load(void) advanced->addChild(OpenGLExtraStage()); if (isOpenGLES) advanced->addChild(OpenGLDiscardFB()); - else - advanced->addChild(OpenGLEnablePBO()); #endif addChild(advanced);