Renderers: Added DFBRenderer
authorMarek Pikarski <mass@directfb.org>
Tue, 1 Oct 2013 07:26:24 +0000 (09:26 +0200)
committerTimo Lotterbach <timo.lotterbach@bmw-carit.de>
Tue, 1 Oct 2013 14:19:00 +0000 (16:19 +0200)
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>
LayerManagerPlugins/Renderers/Platform/DFBRenderer/CMakeLists.txt [new file with mode: 0644]
LayerManagerPlugins/Renderers/Platform/DFBRenderer/include/DFBRenderer.h [new file with mode: 0644]
LayerManagerPlugins/Renderers/Platform/DFBRenderer/include/ShaderProgramGLES.h [new file with mode: 0644]
LayerManagerPlugins/Renderers/Platform/DFBRenderer/src/DFBRenderer.cpp [new file with mode: 0644]
LayerManagerPlugins/Renderers/Platform/DFBRenderer/src/ShaderProgramGLES.cpp [new file with mode: 0644]

diff --git a/LayerManagerPlugins/Renderers/Platform/DFBRenderer/CMakeLists.txt b/LayerManagerPlugins/Renderers/Platform/DFBRenderer/CMakeLists.txt
new file mode 100644 (file)
index 0000000..76020c7
--- /dev/null
@@ -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 (file)
index 0000000..8545b88
--- /dev/null
@@ -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 (file)
index 0000000..087235c
--- /dev/null
@@ -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 (file)
index 0000000..9f99247
--- /dev/null
@@ -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 (file)
index 0000000..96056b8
--- /dev/null
@@ -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);
+}
+