From: Marek Pikarski Date: Tue, 1 Oct 2013 07:26:24 +0000 (+0200) Subject: Renderers: Added DFBRenderer X-Git-Tag: 1_2~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=56a68d816bf6d20ff9652d1d2ca492fdb48aaef5;p=profile%2Fivi%2Flayer-management.git 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 --- 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 +#include + +/// 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 +#include + +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 *)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*)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*)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 +#include +#include + +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); +} +