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.
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"
19 using namespace RETRO
;
21 CRenderBufferDMA::CRenderBufferDMA(CRenderContext
& context
, int fourcc
)
22 : m_context(context
), m_fourcc(fourcc
), m_bo(CBufferObject::GetBufferObject(false))
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()
42 bool CRenderBufferDMA::Allocate(AVPixelFormat format
, unsigned int width
, unsigned int height
)
44 // Initialize IRenderBuffer
49 m_bo
->CreateBufferObject(m_fourcc
, m_width
, m_height
);
54 size_t CRenderBufferDMA::GetFrameSize() const
56 return m_bo
->GetStride() * m_height
;
59 uint8_t* CRenderBufferDMA::GetMemory()
62 return m_bo
->GetMemory();
65 void CRenderBufferDMA::ReleaseMemory()
67 m_bo
->ReleaseMemory();
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)
90 if (!glIsTexture(m_textureId
))
93 glBindTexture(m_textureTarget
, m_textureId
);
95 std::array
<CEGLImage::EglPlane
, CEGLImage::MAX_NUM_PLANES
> planes
;
97 planes
[0].fd
= m_bo
->GetFd();
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);
119 void CRenderBufferDMA::DeleteTexture()
121 if (glIsTexture(m_textureId
))
122 glDeleteTextures(1, &m_textureId
);