Merge pull request #26273 from 78andyp/blurayfixes2
[xbmc.git] / xbmc / cores / RetroPlayer / buffers / RenderBufferDMA.cpp
blob6277d629d834192eb3fc48c5f5dcbc4568aeb55a
1 /*
2 * Copyright (C) 2017-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "RenderBufferDMA.h"
11 #include "ServiceBroker.h"
12 #include "utils/BufferObject.h"
13 #include "utils/EGLImage.h"
14 #include "utils/log.h"
15 #include "windowing/WinSystem.h"
16 #include "windowing/linux/WinSystemEGL.h"
18 using namespace KODI;
19 using namespace RETRO;
21 CRenderBufferDMA::CRenderBufferDMA(CRenderContext& context, int fourcc)
22 : m_context(context), m_fourcc(fourcc), m_bo(CBufferObject::GetBufferObject(false))
24 auto winSystemEGL =
25 dynamic_cast<KODI::WINDOWING::LINUX::CWinSystemEGL*>(CServiceBroker::GetWinSystem());
27 if (winSystemEGL == nullptr)
28 throw std::runtime_error("dynamic_cast failed to cast to CWinSystemEGL. This is likely due to "
29 "a build misconfiguration as DMA can only be used with EGL and "
30 "specifically platforms that implement CWinSystemEGL");
32 m_egl = std::make_unique<CEGLImage>(winSystemEGL->GetEGLDisplay());
34 CLog::Log(LOGDEBUG, "CRenderBufferDMA: using BufferObject type: {}", m_bo->GetName());
37 CRenderBufferDMA::~CRenderBufferDMA()
39 DeleteTexture();
42 bool CRenderBufferDMA::Allocate(AVPixelFormat format, unsigned int width, unsigned int height)
44 // Initialize IRenderBuffer
45 m_format = format;
46 m_width = width;
47 m_height = height;
49 m_bo->CreateBufferObject(m_fourcc, m_width, m_height);
51 return true;
54 size_t CRenderBufferDMA::GetFrameSize() const
56 return m_bo->GetStride() * m_height;
59 uint8_t* CRenderBufferDMA::GetMemory()
61 m_bo->SyncStart();
62 return m_bo->GetMemory();
65 void CRenderBufferDMA::ReleaseMemory()
67 m_bo->ReleaseMemory();
68 m_bo->SyncEnd();
71 void CRenderBufferDMA::CreateTexture()
73 glGenTextures(1, &m_textureId);
75 glBindTexture(m_textureTarget, m_textureId);
77 glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
78 glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
79 glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
80 glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
82 glBindTexture(m_textureTarget, 0);
85 bool CRenderBufferDMA::UploadTexture()
87 if (m_bo->GetFd() < 0)
88 return false;
90 if (!glIsTexture(m_textureId))
91 CreateTexture();
93 glBindTexture(m_textureTarget, m_textureId);
95 std::array<CEGLImage::EglPlane, CEGLImage::MAX_NUM_PLANES> planes;
97 planes[0].fd = m_bo->GetFd();
98 planes[0].offset = 0;
99 planes[0].pitch = m_bo->GetStride();
100 planes[0].modifier = m_bo->GetModifier();
102 CEGLImage::EglAttrs attribs;
104 attribs.width = m_width;
105 attribs.height = m_height;
106 attribs.format = m_fourcc;
107 attribs.planes = planes;
109 if (m_egl->CreateImage(attribs))
110 m_egl->UploadImage(m_textureTarget);
112 m_egl->DestroyImage();
114 glBindTexture(m_textureTarget, 0);
116 return true;
119 void CRenderBufferDMA::DeleteTexture()
121 if (glIsTexture(m_textureId))
122 glDeleteTextures(1, &m_textureId);
124 m_textureId = 0;