summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Pikarski <mass@directfb.org>2013-10-01 09:26:24 +0200
committerTimo Lotterbach <timo.lotterbach@bmw-carit.de>2013-10-01 16:19:00 +0200
commit56a68d816bf6d20ff9652d1d2ca492fdb48aaef5 (patch)
tree502f159e7155f24b18a00d98ba03725a23411c23
parent7ba7a30df6bea7bcac1fc3a8d623af0cf743b08f (diff)
downloadlayer_management-56a68d816bf6d20ff9652d1d2ca492fdb48aaef5.tar.gz
Renderers: Added DFBRenderer
Added a new renderer plugin which implements compositing on DirectFB backend. It runs with either DFBGraphicSystem or GLESGraphicSystem. Signed-off-by: Marek Pikarski <mass@directfb.org>
-rw-r--r--LayerManagerPlugins/Renderers/Platform/DFBRenderer/CMakeLists.txt74
-rw-r--r--LayerManagerPlugins/Renderers/Platform/DFBRenderer/include/DFBRenderer.h94
-rw-r--r--LayerManagerPlugins/Renderers/Platform/DFBRenderer/include/ShaderProgramGLES.h115
-rw-r--r--LayerManagerPlugins/Renderers/Platform/DFBRenderer/src/DFBRenderer.cpp473
-rw-r--r--LayerManagerPlugins/Renderers/Platform/DFBRenderer/src/ShaderProgramGLES.cpp212
5 files changed, 968 insertions, 0 deletions
diff --git a/LayerManagerPlugins/Renderers/Platform/DFBRenderer/CMakeLists.txt b/LayerManagerPlugins/Renderers/Platform/DFBRenderer/CMakeLists.txt
new file mode 100644
index 0000000..76020c7
--- /dev/null
+++ b/LayerManagerPlugins/Renderers/Platform/DFBRenderer/CMakeLists.txt
@@ -0,0 +1,74 @@
+############################################################################
+#
+# Copyright (c) 2013 DirectFB integrated media GmbH
+# Copyright (c) 2013 Renesas Solutions Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+############################################################################
+
+cmake_minimum_required (VERSION 2.6)
+
+#===========================================================================
+# plugin configuration
+#===========================================================================
+project(DFBRenderer)
+project_type(PLUGIN)
+
+find_package(DirectFB REQUIRED)
+find_package(EGL REQUIRED)
+find_package(GLESv2 REQUIRED)
+#find_package(Threads REQUIRED)
+
+include_directories(
+ include
+ ../../Base/include
+ ../../Graphic/include
+ ${CMAKE_SOURCE_DIR}/config
+ ${CMAKE_SOURCE_DIR}/LayerManagerBase/include
+ ${CMAKE_SOURCE_DIR}/LayerManagerUtils/include
+ ${DIRECTFB_INTERNAL_INCLUDE_DIRS} ${DIRECTFB_EGL_INCLUDE_DIRS}
+ ${EGL_INCLUDE_DIR}
+ ${GLESv2_INCLUDE_DIR}
+)
+
+set(LIBS
+ ${CMAKE_THREAD_LIBS_INIT}
+ ${EGL_LIBRARY}
+ ${GLESv2_LIBRARIES}
+ ${DIRECTFB_LDFLAGS} ${DIRECTFB_LIBRARIES} ${DIRECTFB_EGL_LDFLAGS} ${DIRECTFB_EGL_LIBRARIES}
+ LayerManagerGraphicDFB
+ LayerManagerUtils
+)
+
+set(SRC_FILES
+ src/DFBRenderer.cpp
+ src/ShaderProgramGLES.cpp
+)
+
+#===========================================================================
+# create plugin
+#===========================================================================
+add_library(${PROJECT_NAME} ${LIBRARY_BUILDMODE} ${SRC_FILES})
+
+install(TARGETS ${PROJECT_NAME}
+ LIBRARY DESTINATION lib/layermanager/renderer
+ ARCHIVE DESTINATION lib/layermanager/static)
+
+#===========================================================================
+# external libraries
+#===========================================================================
+target_link_libraries(${PROJECT_NAME} ${LIBS})
+
+add_dependencies(${PROJECT_NAME} ${LIBS})
diff --git a/LayerManagerPlugins/Renderers/Platform/DFBRenderer/include/DFBRenderer.h b/LayerManagerPlugins/Renderers/Platform/DFBRenderer/include/DFBRenderer.h
new file mode 100644
index 0000000..8545b88
--- /dev/null
+++ b/LayerManagerPlugins/Renderers/Platform/DFBRenderer/include/DFBRenderer.h
@@ -0,0 +1,94 @@
+/***************************************************************************
+ *
+ * Copyright (c) 2013 DirectFB integrated media GmbH
+ * Copyright (c) 2013 Renesas Solutions Corp.
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#ifndef _DFBRENDERER_H_
+#define _DFBRENDERER_H_
+
+#include "BaseRenderer.h"
+#include "LayerList.h"
+#include "WindowSystems/DFBWindowSystem.h"
+
+typedef struct
+{
+ int index;
+ int layer_id;
+ IDirectFBDisplayLayer *layer;
+ IDirectFBSurface *surface;
+ LmScreen *lm_screen;
+ Layer *lm_layer;
+ int width;
+ int height;
+ int mixer;
+ int encoder;
+ DFBScreenMixerDescription mdesc;
+ DFBScreenEncoderDescription edesc;
+ DFBScreenOutputDescription odesc;
+ DFBScreenMixerConfig mconf;
+ DFBScreenEncoderConfig econf;
+ DFBScreenOutputConfig oconf;
+ bool single;
+ bool muted;
+ int num_surfaces;
+ double layer_opacity;
+} DFBRendererOutput;
+
+#define DFB_RENDERER_MAX_OUTPUTS 0xFF
+
+class DFBRenderer : public BaseRenderer {
+public:
+ DFBRenderer(ICommandExecutor& executor, Configuration& config);
+ bool addLayer(int index, const DFBScreenDescription *sdesc, int layer_id);
+ bool addOutput(int index, const DFBScreenDescription *sdesc, const DFBScreenMixerDescription *mdescs, const DFBScreenEncoderDescription *edescs, const DFBScreenOutputDescription *odescs);
+ bool init(int width, int height);
+ bool start(int, int, const char*, int);
+ void stop();
+ void doScreenShot(std::string fileToSave, uint screen_id);
+ void doScreenShotOfLayer(std::string fileToSave, uint id);
+ void doScreenShotOfSurface(std::string fileToSave, uint id, uint layer_id);
+ uint getNumberOfHardwareLayers(uint screenID);
+ uint* getScreenResolution(uint screenID);
+ uint* getScreenIDs(uint* length);
+ void signalWindowSystemRedraw();
+ void forceCompositionWindowSystem();
+ Shader* createShader(const string* vertexName, const string* fragmentName);
+ virtual bool setOptimizationMode(OptimizationType id, OptimizationModeType mode);
+ virtual bool getOptimizationMode(OptimizationType id, OptimizationModeType *mode);
+ virtual int getIterationCounter();
+ virtual t_ilm_const_string pluginGetName() const;
+public:
+ int m_num_outputs;
+ DFBRendererOutput m_outputs[DFB_RENDERER_MAX_OUTPUTS];
+private:
+ bool m_dfb_mode_hw;
+ IDirectFB *m_dfb;
+ IDirectFBScreen *m_screen;
+ IDirectFBDisplayLayer *m_layer_windows;
+ DFBWindowSystem *m_pWindowSystem;
+ DFBGraphicSystem *m_pDFBGraphicSystem;
+ GLESGraphicsystem *m_pGLESGraphicSystem;
+ uint m_width;
+ uint m_height;
+ ITextureBinder *m_binder;
+
+ friend DFBEnumerationResult DisplayLayerCallback(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc, void *callbackdata);
+};
+
+#endif
+
diff --git a/LayerManagerPlugins/Renderers/Platform/DFBRenderer/include/ShaderProgramGLES.h b/LayerManagerPlugins/Renderers/Platform/DFBRenderer/include/ShaderProgramGLES.h
new file mode 100644
index 0000000..087235c
--- /dev/null
+++ b/LayerManagerPlugins/Renderers/Platform/DFBRenderer/include/ShaderProgramGLES.h
@@ -0,0 +1,115 @@
+/***************************************************************************
+ *
+ * Copyright 2010 BMW Car IT GmbH
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#ifndef _SHADERPROGRAMGLES_H_
+#define _SHADERPROGRAMGLES_H_
+
+#include <ShaderProgram.h>
+#include <GLES2/gl2.h>
+
+/// pointer to shader program creator function
+//typedef ShaderProgram* (*PfnShaderProgramCreator)(const std::string&, const std::string&);
+
+/**
+ * Factory for creating platform specific shader programs.
+ */
+class ShaderProgramGLES : public ShaderProgram
+{
+public:
+ /**
+ * Create a new shader program.
+ *
+ * @param vertName File name of vertex shader.
+ * @param fragName File name of fragment shader.
+ * @return new Program instance, NULL if program could not be created.
+ */
+ static ShaderProgram* createProgram(const std::string& vertName, const std::string& fragName);
+
+ /**
+ * Destructor
+ */
+ virtual ~ShaderProgramGLES(void);
+
+ /**
+ * Start using the shader program for rendering.
+ */
+ virtual void use(void) const;
+
+ virtual int getUniformLocation(const char* name)
+ {
+ return glGetUniformLocation(m_progHandle, name);
+ }
+
+ virtual void uniform1iv(int location, int count, const int* v) const
+ {
+ glUniform1iv(location, count, v);
+ }
+
+ virtual void uniform1fv(int location, int count, const float* v) const
+ {
+ glUniform1fv(location, count, v);
+ }
+
+ virtual void uniform2fv(int location, int count, const float* v) const
+ {
+ glUniform2fv(location, count, v);
+ }
+
+ virtual void uniform3fv(int location, int count, const float* v) const
+ {
+ glUniform3fv(location, count, v);
+ }
+
+ virtual void uniform4fv(int location, int count, const float* v) const
+ {
+ glUniform4fv(location, count, v);
+ }
+
+ virtual void uniformMatrix2fv(int location, int count, bool transpose, const float* v) const
+ {
+ glUniformMatrix2fv(location, count, transpose, v);
+ }
+
+ virtual void uniformMatrix3fv(int location, int count, bool transpose, const float* v) const
+ {
+ glUniformMatrix3fv(location, count, transpose, v);
+ }
+
+ virtual void uniformMatrix4fv(int location, int count, bool transpose, const float* v) const
+ {
+ glUniformMatrix4fv(location, count, transpose, v);
+ }
+
+protected:
+ /**
+ * Protected constructor.
+ * New instances of this class are supposed to be created by ShaderProgramGLES::createProgram.
+ *
+ * @param vertName File name of vertex shader.
+ * @param fragName File name of fragment shader.
+ */
+ ShaderProgramGLES(const std::string& vertName, const std::string& fragName, GLuint handle);
+
+private:
+ /// OpenGL ES program handle
+ GLuint m_progHandle;
+};
+
+#endif /* _SHADERPROGRAMFACTORY_H */
+
diff --git a/LayerManagerPlugins/Renderers/Platform/DFBRenderer/src/DFBRenderer.cpp b/LayerManagerPlugins/Renderers/Platform/DFBRenderer/src/DFBRenderer.cpp
new file mode 100644
index 0000000..9f99247
--- /dev/null
+++ b/LayerManagerPlugins/Renderers/Platform/DFBRenderer/src/DFBRenderer.cpp
@@ -0,0 +1,473 @@
+/***************************************************************************
+ *
+ * Copyright (c) 2013 DirectFB integrated media GmbH
+ * Copyright (c) 2013 Renesas Solutions Corp.
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#include "DFBRenderer.h"
+#include "Configuration.h"
+#include "Shader.h"
+#include "ShaderProgramGLES.h"
+#include "TextureBinders/DFBEglImage.h"
+#include "TextureBinders/DFBImage.h"
+#include <pthread.h>
+#include <signal.h>
+
+DFBRenderer::DFBRenderer(ICommandExecutor& executor, Configuration& config)
+: BaseRenderer(executor, config)
+, m_num_outputs(0)
+, m_dfb_mode_hw(true)
+, m_dfb(NULL)
+, m_screen(NULL)
+, m_layer_windows(NULL)
+, m_pWindowSystem(NULL)
+, m_pDFBGraphicSystem(NULL)
+, m_pGLESGraphicSystem(NULL)
+, m_width(0)
+, m_height(0)
+, m_binder(NULL)
+{
+ memset( m_outputs, 0, sizeof(m_outputs) );
+
+ if (getenv("IVI_DFBEGL"))
+ m_dfb_mode_hw = false;
+}
+
+bool
+DFBRenderer::addLayer(int index, const DFBScreenDescription *sdesc, int layer_id)
+{
+ DFBDisplayLayerConfig config;
+ DFBResult ret;
+ char screen_name[0xfff];
+ int width;
+ int height;
+
+ if (m_pScene->isLayerInCurrentRenderOrder( layer_id )) {
+ LOG_WARNING( "DFBRenderer", __FUNCTION__ << ": layer(" << layer_id << ") is already in scene" );
+ return false;
+ }
+
+ IDirectFBDisplayLayer *dfb_l;
+ ret = m_dfb->GetDisplayLayer( m_dfb, layer_id, &dfb_l );
+ if (ret) {
+ LOG_ERROR( "DFBRenderer", __FUNCTION__ << ": IDirectFB::GetDisplayLayer(" << layer_id << ") failed! (ret=" << ret << ")" );
+ return false;
+ }
+
+ ret = dfb_l->SetCooperativeLevel( dfb_l, DLSCL_EXCLUSIVE );
+ if (ret) {
+ LOG_ERROR( "DFBRenderer", __FUNCTION__ << ": IDirectFBDisplayLayer::SetCooperativeLevel(DLSCL_EXCLUSIVE) failed! (ret=" << ret << ")" );
+ dfb_l->Release( dfb_l );
+ return false;
+ }
+
+ if (!dfb_l->GetConfiguration( dfb_l, &config )) {
+ config.flags = DLCONF_BUFFERMODE;
+ config.buffermode = DLBM_TRIPLE;
+ if (dfb_l->SetConfiguration( dfb_l, &config ))
+ LOG_WARNING( "DFBRenderer", __FUNCTION__ << ": failed to set layer configuration on layer " << dfb_l );
+ }
+
+ IDirectFBSurface *dfb_s;
+ ret = dfb_l->GetSurface( dfb_l, &dfb_s );
+ if (ret) {
+ LOG_ERROR( "DFBRenderer", __FUNCTION__ << ": IDirectFBDisplayLayer::GetSurface() failed! (ret=" << ret << ")" );
+ dfb_l->Release( dfb_l );
+ return false;
+ }
+
+ ret = dfb_s->GetSize( dfb_s, &width, &height );
+ if (ret) {
+ LOG_ERROR( "DFBRenderer", __FUNCTION__ << ": IDirectFBSurface::GetSize() failed! (ret=" << ret << ")" );
+ dfb_s->Release( dfb_s );
+ dfb_l->Release( dfb_l );
+ return false;
+ }
+
+ if (sdesc)
+ sprintf( screen_name, "DirectFB Screen %d (%s %d:%d:%d:%d)", m_num_outputs, strlen(sdesc[index].name) > 0 ? sdesc[index].name : "Output", index, layer_id, m_outputs[m_num_outputs].encoder, m_outputs[m_num_outputs].mixer );
+ else
+ sprintf( screen_name, "DirectFB Screen %d (Layer %d:%d)", m_num_outputs, index, layer_id );
+
+ LmScreen *lm_s = new LmScreen( m_num_outputs, screen_name );
+
+ LmScreenList& sceneScreens = m_pScene->getScreenList();
+ sceneScreens.push_back( lm_s );
+
+ Layer *lm_l = m_pScene->createLayer( layer_id, getpid() );
+ lm_l->setLayerType( m_dfb_mode_hw ? LayerType::Hardware : LayerType::Software_2D);
+ lm_l->setVisibility( true );
+ lm_l->setPosition( 0, 0 );
+ lm_l->setDimension( width, height );
+
+ if (m_dfb_mode_hw && !getenv("IVI_LAYER_SW"))
+ lm_l->setLayerType( LayerType::Hardware );
+ else
+ lm_l->setLayerType( LayerType::Software_2D );
+
+ const Rectangle r( 0, 0, width, height );
+ lm_l->setSourceRegion( r );
+ lm_l->setDestinationRegion( r );
+ lm_l->OriginalSourceWidth = width;
+ lm_l->OriginalSourceHeight = height;
+
+ LayerList& screenLayers = lm_s->getCurrentRenderOrder();
+ screenLayers.push_back( lm_l );
+
+ LOG_INFO( "DFBRenderer", __FUNCTION__ << ": successfully added Screen " << m_num_outputs << " '" << screen_name << "'" );
+
+ m_outputs[m_num_outputs].layer_id = layer_id;
+ m_outputs[m_num_outputs].layer = dfb_l;
+ m_outputs[m_num_outputs].surface = dfb_s;
+ m_outputs[m_num_outputs].lm_screen = lm_s;
+ m_outputs[m_num_outputs].lm_layer = lm_l;
+ m_outputs[m_num_outputs].width = width;
+ m_outputs[m_num_outputs].height = height;
+ m_outputs[m_num_outputs].single = false;
+ m_outputs[m_num_outputs].muted = false;
+ m_outputs[m_num_outputs].num_surfaces = 0;
+ m_outputs[m_num_outputs].layer_opacity = 1;
+
+ m_num_outputs++;
+
+ //m_outputs[m_num_outputs].mconf.layers = (1 << layer_id);
+ //m_screen->SetMixerConfiguration( m_screen, m_outputs[m_num_outputs].mixer, &m_outputs[m_num_outputs].mconf );
+
+ return true;
+}
+
+DFBEnumerationResult
+DisplayLayerCallback( DFBDisplayLayerID layer_id,
+ DFBDisplayLayerDescription desc,
+ void *callbackdata )
+{
+ (void)desc;
+ DFBRenderer *renderer = static_cast<DFBRenderer *>((DFBRenderer *)callbackdata);
+
+ if (!renderer->addLayer( renderer->m_num_outputs, NULL, layer_id ))
+ LOG_WARNING( "DFBRenderer", __FUNCTION__ << ": failed to add layer with id " << layer_id << " to outputs" );
+
+ return DFENUM_OK;
+}
+
+bool
+DFBRenderer::addOutput(int index, const DFBScreenDescription *sdesc, const DFBScreenMixerDescription *mdescs, const DFBScreenEncoderDescription *edescs, const DFBScreenOutputDescription *odescs)
+{
+ int layer_index;
+
+ m_outputs[m_num_outputs].index = index;
+ m_outputs[m_num_outputs].odesc = odescs[index];
+
+ if (m_screen->GetOutputConfiguration( m_screen, index, &m_outputs[m_num_outputs].oconf )) {
+ LOG_WARNING( "DFBRenderer", __FUNCTION__ << ": failed to GetOutputConfiguration()" );
+ m_outputs[m_num_outputs].encoder = 0;
+ }
+
+ if (m_outputs[m_num_outputs].oconf.flags & DSOCONF_ENCODER) {
+ m_outputs[m_num_outputs].encoder = m_outputs[m_num_outputs].oconf.encoder;
+ m_outputs[m_num_outputs].edesc = edescs[m_outputs[m_num_outputs].encoder];
+
+ if (m_screen->GetEncoderConfiguration( m_screen, m_outputs[m_num_outputs].encoder, &m_outputs[m_num_outputs].econf ))
+ LOG_WARNING( "DFBRenderer", __FUNCTION__ << ": failed to GetEncoderConfiguration()" );
+
+ if (m_outputs[m_num_outputs].econf.flags & DSECONF_MIXER) {
+ m_outputs[m_num_outputs].mixer = m_outputs[m_num_outputs].econf.mixer;
+ m_outputs[m_num_outputs].mdesc = mdescs[m_outputs[m_num_outputs].mixer];
+
+ if (m_screen->GetMixerConfiguration( m_screen, m_outputs[m_num_outputs].mixer, &m_outputs[m_num_outputs].mconf )) {
+ LOG_WARNING( "DFBRenderer", __FUNCTION__ << ": failed to GetMixerConfiguration()" );
+ m_outputs[m_num_outputs].mconf.layers = (1 << DLID_PRIMARY);
+ }
+
+ int num_outputs = m_num_outputs;
+ for (layer_index = 0; layer_index < 16; layer_index++) {
+ if (m_outputs[num_outputs].mconf.layers & (1 << layer_index)) {
+ if (!addLayer( index, sdesc, layer_index ))
+ LOG_WARNING( "DFBRenderer", __FUNCTION__ << ": failed to add layer for output " << index );
+ }
+ }
+ }
+ }
+ else {
+ LOG_WARNING( "DFBRenderer", __FUNCTION__ << ": no encoder found, fallback to enumerated layers" );
+
+ m_dfb->EnumDisplayLayers( m_dfb, DisplayLayerCallback, this );
+ }
+
+ return true;
+}
+
+bool DFBRenderer::init(int width, int height)
+{
+ DFBScreenDescription sdesc;
+ DFBResult ret;
+ int i;
+
+ LOG_DEBUG( "DFBRenderer", __FUNCTION__ << "(width=" << width << ", height" << height << ")" );
+
+ ret = DirectFBInit( 0, NULL );
+ if (ret) {
+ LOG_ERROR( "DFBRenderer", __FUNCTION__ << ": DirectFBInit() failed! (ret=" << ret << ")" );
+ return false;
+ }
+
+ ret = DirectFBCreate( &m_dfb );
+ if (ret) {
+ LOG_ERROR( "DFBRenderer", __FUNCTION__ << ": DirectFBCreate() failed! (ret=" << ret << ")" );
+ return false;
+ }
+
+ ret = m_dfb->GetScreen( m_dfb, DSCID_PRIMARY, &m_screen );
+ if (ret) {
+ LOG_ERROR( "DFBRenderer", __FUNCTION__ << ": IDirectFBScreen::GetScreen(DSCID_PRIMARY) failed! (ret=" << ret << ")" );
+ return false;
+ }
+
+ ret = m_screen->GetDescription( m_screen, &sdesc );
+ if (ret) {
+ LOG_ERROR( "DFBRenderer", __FUNCTION__ << ": IDirectFBScreen::GetDescription() failed! (ret=" << ret << ")" );
+ return false;
+ }
+
+ if (sdesc.outputs < 1) {
+ LOG_ERROR( "DFBRenderer", __FUNCTION__ << ": no screens available" );
+ return false;
+ }
+
+ ret = m_dfb->GetDisplayLayer( m_dfb, DLID_PRIMARY, &m_layer_windows );
+ if (ret) {
+ LOG_ERROR( "DFBRenderer", __FUNCTION__ << ": GetDisplayLayer() failed! (ret=" << ret << ")" );
+ return ret;
+ }
+
+ DFBScreenMixerDescription mdescs[sdesc.mixers];
+ DFBScreenEncoderDescription edescs[sdesc.encoders];
+ DFBScreenOutputDescription odescs[sdesc.outputs];
+
+ m_screen->GetMixerDescriptions( m_screen, mdescs );
+ m_screen->GetEncoderDescriptions( m_screen, edescs );
+ m_screen->GetOutputDescriptions( m_screen, odescs );
+
+ for (i = 0; i < sdesc.outputs && m_num_outputs < DFB_RENDERER_MAX_OUTPUTS - 1; i++) {
+ if (!addOutput( i, &sdesc, mdescs, edescs, odescs ))
+ LOG_WARNING( "DFBRenderer", __FUNCTION__ << ": failed to add screen for output " << i );
+ }
+
+ return m_num_outputs > 0;
+}
+
+bool DFBRenderer::start(int width, int height, const char *name, int maxIterationDurationInMS)
+{
+ (void)name;
+ m_binder = NULL;
+ m_width = width;
+ m_height = height;
+
+ LOG_INFO( "DFBRenderer", __FUNCTION__ << "(width=" << width << ", height" << height << ")" );
+
+ if (!init( width, height ))
+ return false;
+
+ m_pWindowSystem = new DFBWindowSystem( width, height, m_pScene, m_pInputManager, m_dfb, m_outputs[0].layer );
+
+ if (m_dfb_mode_hw) {
+ m_pDFBGraphicSystem = new DFBGraphicSystem( this, m_pWindowSystem, m_dfb, width, height );
+
+ if (!m_pWindowSystem->init( (BaseGraphicSystem<DFBDisplay, DFBWindow>*)m_pDFBGraphicSystem, m_dfb_mode_hw ))
+ return false;
+
+ m_pDFBGraphicSystem->setBaseWindowSystem( m_pWindowSystem );
+
+ m_binder = new DFBImage( m_pWindowSystem->getNativeDisplayHandle(), m_layer_windows );
+ if (m_binder) {
+ m_pDFBGraphicSystem->setTextureBinder( m_binder );
+
+ if (!m_pWindowSystem->start( maxIterationDurationInMS ))
+ return false;
+ }
+ else
+ return false;
+ }
+ else {
+ m_pGLESGraphicSystem = new GLESGraphicsystem( width, height, ShaderProgramGLES::createProgram );
+
+ if (!m_pWindowSystem->init( (BaseGraphicSystem<DFBDisplay, DFBWindow>*)m_pGLESGraphicSystem, m_dfb_mode_hw ))
+ return false;
+
+ m_pGLESGraphicSystem->setBaseWindowSystem( m_pWindowSystem );
+
+ m_binder = new DFBEglImage( m_pGLESGraphicSystem->getEGLDisplay(), m_layer_windows );
+ if (m_binder) {
+ m_pGLESGraphicSystem->setTextureBinder( m_binder );
+
+ if (!m_pWindowSystem->start( maxIterationDurationInMS ))
+ return false;
+ }
+ else
+ return false;
+ }
+
+ return true;
+}
+
+void DFBRenderer::stop()
+{
+ LOG_INFO( "DFBRenderer", __FUNCTION__ );
+
+ if (m_pWindowSystem) {
+ m_pWindowSystem->stop();
+ delete m_pWindowSystem;
+ m_pWindowSystem = NULL;
+ }
+
+ if (m_pDFBGraphicSystem) {
+ delete m_pDFBGraphicSystem;
+ m_pDFBGraphicSystem = NULL;
+ }
+
+ if (m_pGLESGraphicSystem) {
+ delete m_pGLESGraphicSystem;
+ m_pGLESGraphicSystem = NULL;
+ }
+
+ if (m_binder) {
+ delete m_binder;
+ m_binder = NULL;
+ }
+
+ for (int i = 0; i < m_num_outputs; i++) {
+ m_outputs[i].layer->Release( m_outputs[i].layer );
+ m_outputs[i].surface->Release( m_outputs[i].surface );
+ }
+
+ m_num_outputs = 0;
+
+ if (m_layer_windows) {
+ m_layer_windows->Release( m_layer_windows );
+ m_layer_windows = NULL;
+ }
+
+ if (m_screen) {
+ m_screen->Release( m_screen );
+ m_screen = NULL;
+ }
+
+ if (m_dfb) {
+ m_dfb->Release( m_dfb );
+ m_dfb = NULL;
+ }
+}
+
+void DFBRenderer::doScreenShot(std::string fileToSave, uint screen_id)
+{
+ m_pWindowSystem->doScreenShot( fileToSave, screen_id );
+}
+
+void DFBRenderer::doScreenShotOfLayer(std::string fileToSave, uint id)
+{
+ m_pWindowSystem->doScreenShotOfLayer( fileToSave, id );
+}
+
+void DFBRenderer::doScreenShotOfSurface(std::string fileToSave, uint id, uint layer_id)
+{
+ m_pWindowSystem->doScreenShotOfSurface( fileToSave, id, layer_id );
+}
+
+uint DFBRenderer::getNumberOfHardwareLayers(uint screenID)
+{
+ for (int i = 0; i < m_num_outputs; i++) {
+ if (m_outputs[i].lm_screen->getID() == screenID)
+ return 1;
+ }
+
+ return 0;
+}
+
+uint* DFBRenderer::getScreenResolution(uint screenID)
+{
+ for (int i = 0; i < m_num_outputs; i++) {
+ if (m_outputs[i].lm_screen->getID() == screenID) {
+ uint *resolution = new uint[2];
+ resolution[0] = m_outputs[i].width;
+ resolution[1] = m_outputs[i].height;
+ return resolution;
+ }
+ }
+
+ return NULL;
+}
+
+uint* DFBRenderer::getScreenIDs(uint* length)
+{
+ uint *screenIDS = NULL;
+
+ if (m_num_outputs > 0) {
+ screenIDS = new uint[m_num_outputs];
+ for (int i = 0; i < m_num_outputs; i++)
+ screenIDS[i] = m_outputs[i].lm_screen->getID();
+ }
+
+ *length = m_num_outputs;
+
+ return screenIDS;
+}
+
+void DFBRenderer::signalWindowSystemRedraw()
+{
+ m_pWindowSystem->signalRedrawEvent();
+}
+
+void DFBRenderer::forceCompositionWindowSystem()
+{
+ m_pWindowSystem->m_forceComposition = true;
+}
+
+bool DFBRenderer::setOptimizationMode(OptimizationType id, OptimizationModeType mode)
+{
+ if (m_pDFBGraphicSystem)
+ return false;
+
+ return m_pGLESGraphicSystem->setOptimizationMode( id, mode );
+}
+
+bool DFBRenderer::getOptimizationMode(OptimizationType id, OptimizationModeType *mode)
+{
+ if (m_pDFBGraphicSystem)
+ return false;
+
+ return m_pGLESGraphicSystem->getOptimizationMode( id, mode );
+}
+
+int DFBRenderer::getIterationCounter()
+{
+ return m_pWindowSystem->getIterationCounter();
+}
+
+t_ilm_const_string DFBRenderer::pluginGetName() const
+{
+ return "DFBRenderer";
+}
+
+Shader* DFBRenderer::createShader(const string* vertexName, const string* fragmentName)
+{
+ if (m_pDFBGraphicSystem)
+ return NULL;
+
+ return Shader::createShader( *vertexName, *fragmentName );
+}
+
+DECLARE_LAYERMANAGEMENT_PLUGIN(DFBRenderer)
diff --git a/LayerManagerPlugins/Renderers/Platform/DFBRenderer/src/ShaderProgramGLES.cpp b/LayerManagerPlugins/Renderers/Platform/DFBRenderer/src/ShaderProgramGLES.cpp
new file mode 100644
index 0000000..96056b8
--- /dev/null
+++ b/LayerManagerPlugins/Renderers/Platform/DFBRenderer/src/ShaderProgramGLES.cpp
@@ -0,0 +1,212 @@
+/***************************************************************************
+ *
+ * Copyright 2010 BMW Car IT GmbH
+ * Copyright (C) 2012 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#include "ShaderProgramGLES.h"
+#include "config.h"
+#include <GLES2/gl2ext.h>
+#include <RenderUtil.h>
+#include <Log.h>
+
+ShaderProgram* ShaderProgramGLES::createProgram(const std::string& vertName, const std::string& fragName)
+{
+ GLuint progHandle;
+ ShaderProgramGLES* program = 0;
+ char defaultShaderDir[1024];
+ char fragmentShaderLocation[1024];
+ char vertexShaderLocation[1024];
+ int multitex = 1;
+
+ const char* pluginLookupPath = getenv("LM_PLUGIN_PATH");
+ if (pluginLookupPath != NULL )
+ {
+ strncpy(defaultShaderDir, pluginLookupPath, sizeof(defaultShaderDir) - 1);
+ }
+ else
+ {
+ strncpy(defaultShaderDir, CMAKE_INSTALL_PREFIX"/lib/layermanager", sizeof(defaultShaderDir));
+ }
+ strcat(defaultShaderDir,"/renderer");
+
+ if (vertName=="default")
+ {
+ multitex = 1;
+ strcpy(vertexShaderLocation,defaultShaderDir);
+ strcat(vertexShaderLocation,"/renderer_vert.glslv");
+ }
+ else if (vertName=="default_2surf")
+ {
+ multitex = 2;
+ strcpy(vertexShaderLocation,defaultShaderDir);
+ strcat(vertexShaderLocation,"/renderer_vert_2surf.glslv");
+ }
+ else if (vertName=="default_3surf")
+ {
+ multitex = 3;
+ strcpy(vertexShaderLocation,defaultShaderDir);
+ strcat(vertexShaderLocation,"/renderer_vert_3surf.glslv");
+ }
+ else if (vertName=="default_4surf")
+ {
+ multitex = 4;
+ strcpy(vertexShaderLocation,defaultShaderDir);
+ strcat(vertexShaderLocation,"/renderer_vert_4surf.glslv");
+ }
+ else
+ {
+ strcpy(vertexShaderLocation, vertName.c_str());
+ }
+
+ if (fragName=="default_clear")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag_clear.glslf");
+ }
+ else if (fragName=="default")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag.glslf");
+ }
+ else if (fragName=="default_no_blend")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag_no_blend.glslf");
+ }
+ else if (fragName=="default_no_uniform_alpha")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag_no_ualpha.glslf");
+ progHandle = RenderUtilLoadShaderSources(vertexShaderLocation,fragmentShaderLocation, GL_TRUE);
+ }
+ else if (vertName=="default" && fragName=="default_add_uniform_chromakey")
+ {
+ strcpy(vertexShaderLocation,defaultShaderDir);
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(vertexShaderLocation,"/renderer_vert.glslv");
+ strcat(fragmentShaderLocation,"/renderer_frag_add_uchromakey.glslf");
+ }
+ else if (fragName=="default_no_blend_no_uniform_alpha")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag_no_blend_no_ualpha.glslf");
+ }
+ else if (fragName=="default_2surf")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag_2surf.glslf");
+ }
+ else if (fragName=="default_2surf_no_blend")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag_2surf_no_blend.glslf");
+ }
+ else if (fragName=="default_2surf_no_uniform_alpha")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag_2surf_no_ualpha.glslf");
+ }
+ else if (fragName=="default_2surf_no_blend_no_uniform_alpha")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag_2surf_no_blend_no_ualpha.glslf");
+ }
+ else if (fragName=="default_2surf_no_uniform_alpha_0")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag_2surf_no_ualpha_0.glslf");
+ }
+ else if (fragName=="default_2surf_no_blend_no_uniform_alpha_0")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag_2surf_no_blend_no_ualpha_0.glslf");
+ }
+ else if (fragName=="default_2surf_no_uniform_alpha_1")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag_2surf_no_ualpha_1.glslf");
+ }
+ else if (fragName=="default_2surf_no_blend_no_uniform_alpha_1")
+ {
+ strcpy(fragmentShaderLocation,defaultShaderDir);
+ strcat(fragmentShaderLocation,"/renderer_frag_2surf_no_blend_no_ualpha_1.glslf");
+ }
+ else
+ {
+ strcpy(fragmentShaderLocation, fragName.c_str());
+ }
+
+ progHandle = RenderUtilLoadShaderSources(vertexShaderLocation,fragmentShaderLocation, GL_TRUE);
+
+ if (progHandle != 0)
+ {
+ // bind attrib locations for vertex positions and texture coordinates
+ glBindAttribLocation(progHandle, 0, "aPosition");
+
+ // each texture has its own texCoord attribute
+ for (int i = 1; i <= multitex; i++)
+ {
+ char attribName[15];
+ if (i == 1)
+ {
+ sprintf(attribName, "aTexCoords");
+ }
+ else
+ {
+ sprintf(attribName, "aTexCoords%d", i);
+ }
+ glBindAttribLocation(progHandle, i, attribName);
+ }
+
+ // re-link the program as we have changed the attrib bindings
+ glLinkProgram(progHandle);
+
+ program = new ShaderProgramGLES(vertName, fragName, progHandle);
+ }
+ else
+ {
+ LOG_ERROR("ShaderProgramGLES", "Failed to create and link shader program");
+ }
+
+ return program;
+}
+
+ShaderProgramGLES::ShaderProgramGLES(const std::string& vertName, const std::string& fragName, GLuint handle)
+: ShaderProgram(vertName, fragName)
+, m_progHandle(handle)
+{
+ // Update the uniform locations.
+ // Don't move this call to the base class constructor as we need
+ // to set the OpenGL program handle first.
+ updateCommonUniformLocations();
+}
+
+ShaderProgramGLES::~ShaderProgramGLES(void)
+{
+ if (m_progHandle)
+ {
+ glDeleteProgram(m_progHandle);
+ }
+}
+
+void ShaderProgramGLES::use(void) const
+{
+ glUseProgram(m_progHandle);
+}
+