Skip to content

Commit

Permalink
add amlogic to windowing
Browse files Browse the repository at this point in the history
  • Loading branch information
lrusak authored and popcornmix committed May 10, 2017
1 parent d10ca67 commit 38b1fd9
Show file tree
Hide file tree
Showing 9 changed files with 822 additions and 8 deletions.
14 changes: 14 additions & 0 deletions xbmc/windowing/amlogic/CMakeLists.txt
@@ -0,0 +1,14 @@
set(SOURCES GLContextEGL.cpp
WinSystemAmlogic.cpp
VideoSyncAML.cpp)

set(HEADERS GLContextEGL.h
WinSystemAmlogic.h
VideoSyncAML.h)

if(OPENGLES_FOUND)
list(APPEND SOURCES WinSystemAmlogicGLESContext.cpp)
list(APPEND HEADERS WinSystemAmlogicGLESContext.h)
endif()

core_add_library(windowing_Amlogic)
229 changes: 229 additions & 0 deletions xbmc/windowing/amlogic/GLContextEGL.cpp
@@ -0,0 +1,229 @@
/*
* Copyright (C) 2005-2013 Team XBMC
* http://xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*
*/

#include "GLContextEGL.h"

#include "guilib/IDirtyRegionSolver.h"
#include "settings/AdvancedSettings.h"
#include "utils/log.h"

CGLContextEGL::CGLContextEGL() :
m_eglDisplay(EGL_NO_DISPLAY),
m_eglSurface(EGL_NO_SURFACE),
m_eglContext(EGL_NO_CONTEXT),
m_eglConfig(0)
{
}

CGLContextEGL::~CGLContextEGL()
{
Destroy();
}

bool CGLContextEGL::CreateDisplay(EGLDisplay display,
EGLint renderable_type,
EGLint rendering_api)
{
EGLint neglconfigs = 0;
int major, minor;

EGLint surface_type = EGL_WINDOW_BIT;
// for the non-trivial dirty region modes, we need the EGL buffer to be preserved across updates
if (g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_COST_REDUCTION ||
g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_UNION)
surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;

EGLint attribs[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, 0,
EGL_SAMPLE_BUFFERS, 0,
EGL_SAMPLES, 0,
EGL_SURFACE_TYPE, surface_type,
EGL_RENDERABLE_TYPE, renderable_type,
EGL_NONE
};

if (m_eglDisplay == EGL_NO_DISPLAY)
{
m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)display);
}

if (m_eglDisplay == EGL_NO_DISPLAY)
{
CLog::Log(LOGERROR, "failed to get EGL display");
return false;
}

if (!eglInitialize(m_eglDisplay, &major, &minor))
{
CLog::Log(LOGERROR, "failed to initialize EGL display");
return false;
}

eglBindAPI(rendering_api);

if (!eglChooseConfig(m_eglDisplay, attribs,
&m_eglConfig, 1, &neglconfigs))
{
CLog::Log(LOGERROR, "Failed to query number of EGL configs");
return false;
}

if (neglconfigs <= 0)
{
CLog::Log(LOGERROR, "No suitable EGL configs found");
return false;
}

return true;
}

bool CGLContextEGL::CreateContext()
{
int client_version = 2;

const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, client_version, EGL_NONE
};

if (m_eglContext == EGL_NO_CONTEXT)
{
m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig,
EGL_NO_CONTEXT, context_attribs);
}

if (m_eglContext == EGL_NO_CONTEXT)
{
CLog::Log(LOGERROR, "failed to create EGL context");
return false;
}

return true;
}

bool CGLContextEGL::BindContext()
{
if (!eglMakeCurrent(m_eglDisplay, m_eglSurface,
m_eglSurface, m_eglContext))
{
CLog::Log(LOGERROR, "Failed to make context current %p %p %p",
m_eglDisplay, m_eglSurface, m_eglContext);
return false;
}

return true;
}

bool CGLContextEGL::SurfaceAttrib()
{
// for the non-trivial dirty region modes, we need the EGL buffer to be preserved across updates
if (g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_COST_REDUCTION ||
g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_UNION)
{
if ((m_eglDisplay == EGL_NO_DISPLAY) || (m_eglSurface == EGL_NO_SURFACE))
{
return false;
}

if (!eglSurfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED))
{
CLog::Log(LOGDEBUG, "%s: Could not set EGL_SWAP_BEHAVIOR",__FUNCTION__);
}
}

return true;
}

bool CGLContextEGL::CreateSurface(EGLNativeWindowType surface)
{
m_eglSurface = eglCreateWindowSurface(m_eglDisplay,
m_eglConfig,
surface,
nullptr);

if (m_eglSurface == EGL_NO_SURFACE)
{
CLog::Log(LOGERROR, "failed to create EGL window surface %d", eglGetError());
return false;
}

return true;
}

void CGLContextEGL::Destroy()
{
if (m_eglContext != EGL_NO_CONTEXT)
{
eglDestroyContext(m_eglDisplay, m_eglContext);
eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
m_eglContext = EGL_NO_CONTEXT;
}

if (m_eglSurface != EGL_NO_SURFACE)
{
eglDestroySurface(m_eglDisplay, m_eglSurface);
m_eglSurface = EGL_NO_SURFACE;
}

if (m_eglDisplay != EGL_NO_DISPLAY)
{
eglTerminate(m_eglDisplay);
m_eglDisplay = EGL_NO_DISPLAY;
}
}

void CGLContextEGL::Detach()
{
if (m_eglContext != EGL_NO_CONTEXT)
{
eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}

if (m_eglSurface != EGL_NO_SURFACE)
{
eglDestroySurface(m_eglDisplay, m_eglSurface);
m_eglSurface = EGL_NO_SURFACE;
}
}

bool CGLContextEGL::SetVSync(bool enable)
{
if (!eglSwapInterval(m_eglDisplay, enable))
{
return false;
}

return true;
}

void CGLContextEGL::SwapBuffers()
{
if (m_eglDisplay == EGL_NO_DISPLAY || m_eglSurface == EGL_NO_SURFACE)
{
return;
}

eglSwapBuffers(m_eglDisplay, m_eglSurface);
}
48 changes: 48 additions & 0 deletions xbmc/windowing/amlogic/GLContextEGL.h
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2005-2013 Team XBMC
* http://xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*
*/

#pragma once

#include "EGL/egl.h"

class CGLContextEGL
{
public:
CGLContextEGL();
virtual ~CGLContextEGL();

bool CreateDisplay(EGLDisplay display,
EGLint renderable_type,
EGLint rendering_api);

bool CreateSurface(EGLNativeWindowType surface);
bool CreateContext();
bool BindContext();
bool SurfaceAttrib();
void Destroy();
void Detach();
bool SetVSync(bool enable);
void SwapBuffers();

EGLDisplay m_eglDisplay;
EGLSurface m_eglSurface;
EGLContext m_eglContext;
EGLConfig m_eglConfig;
};
Expand Up @@ -20,8 +20,6 @@

#include "system.h"

#if defined(HAS_LIBAMCODEC)

#include "VideoSyncAML.h"
#include "guilib/GraphicContext.h"
#include "windowing/WindowingFactory.h"
Expand Down Expand Up @@ -106,5 +104,3 @@ void CVideoSyncAML::OnResetDisplay()
{
m_abort = true;
}

#endif
Expand Up @@ -19,8 +19,6 @@
*
*/

#if defined(HAS_LIBAMCODEC)

#include "windowing/VideoSync.h"
#include "guilib/DispResource.h"

Expand All @@ -37,5 +35,3 @@ class CVideoSyncAML : public CVideoSync, IDispResource
private:
volatile bool m_abort;
};

#endif

0 comments on commit 38b1fd9

Please sign in to comment.