2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "image-renderer.h"
21 #include <dali-toolkit/internal/controls/renderers/renderer-factory-impl.h>
22 #include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
23 #include <dali-toolkit/internal/controls/renderers/control-renderer-impl.h>
24 #include <dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h>
25 #include <dali/public-api/images/resource-image.h>
40 const char * const IMAGE_URL_NAME("image-url");
41 const char * const IMAGE_FITTING_MODE("image-fitting-mode");
42 const char * const IMAGE_SAMPLING_MODE("image-sampling-mode");
43 const char * const IMAGE_DESIRED_WIDTH("image-desired-width");
44 const char * const IMAGE_DESIRED_HEIGHT("image-desired-height");
46 std::string TEXTURE_UNIFORM_NAME = "sTexture";
48 #define MAKE_SHADER(A)#A
50 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
51 attribute mediump vec2 aPosition;\n
52 varying mediump vec2 vTexCoord;\n
53 uniform mediump mat4 uMvpMatrix;\n
54 uniform mediump vec3 uSize;\n
58 mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
59 vertexPosition.xyz *= uSize;\n
60 vertexPosition = uMvpMatrix * vertexPosition;\n
62 vTexCoord = aPosition + vec2(0.5);\n
63 gl_Position = vertexPosition;\n
67 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
68 varying mediump vec2 vTexCoord;\n
69 uniform sampler2D sTexture;\n
70 uniform lowp vec4 uColor;\n
74 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
80 ImageRenderer::ImageRenderer()
83 mFittingMode( FittingMode::DEFAULT ),
84 mSamplingMode( SamplingMode::DEFAULT )
88 ImageRenderer::~ImageRenderer()
92 void ImageRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
94 mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY );
95 if( !(mImpl->mGeometry) )
97 mImpl->mGeometry = factoryCache.CreateQuadGeometry();
98 factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry );
101 mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER );
102 if( !mImpl->mShader )
104 mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
105 factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, mImpl->mShader );
108 mDesiredSize = ImageDimensions();
109 mFittingMode = FittingMode::DEFAULT;
110 mSamplingMode = SamplingMode::DEFAULT;
113 Property::Value* imageURLValue = propertyMap.Find( IMAGE_URL_NAME );
116 imageURLValue->Get( mImageUrl );
118 Property::Value* fittingValue = propertyMap.Find( IMAGE_FITTING_MODE );
122 fittingValue->Get( fitting );
124 mFittingMode = FittingMode::DEFAULT;
125 if( fitting == "shrink-to-fit" )
127 mFittingMode = FittingMode::SHRINK_TO_FIT;
129 else if( fitting == "scale-to-fill" )
131 mFittingMode = FittingMode::SCALE_TO_FILL;
133 else if( fitting == "fit-width" )
135 mFittingMode = FittingMode::FIT_WIDTH;
137 else if( fitting == "fit-height" )
139 mFittingMode = FittingMode::FIT_HEIGHT;
141 else if( fitting == "default" )
143 mFittingMode = FittingMode::DEFAULT;
147 DALI_ASSERT_ALWAYS("Unknown fitting mode");
151 Property::Value* samplingValue = propertyMap.Find( IMAGE_SAMPLING_MODE );
154 std::string sampling;
155 samplingValue->Get( sampling );
157 mSamplingMode = SamplingMode::DEFAULT;
158 if( sampling == "box" )
160 mSamplingMode = SamplingMode::BOX;
162 else if( sampling == "nearest" )
164 mSamplingMode = SamplingMode::NEAREST;
166 else if( sampling == "linear" )
168 mSamplingMode = SamplingMode::LINEAR;
170 else if( sampling == "box-then-nearest" )
172 mSamplingMode = SamplingMode::BOX_THEN_NEAREST;
174 else if( sampling == "box-then-linear" )
176 mSamplingMode = SamplingMode::BOX_THEN_LINEAR;
178 else if( sampling == "no-filter" )
180 mSamplingMode = SamplingMode::NO_FILTER;
182 else if( sampling == "dont-care" )
184 mSamplingMode = SamplingMode::DONT_CARE;
186 else if( sampling == "default" )
188 mSamplingMode = SamplingMode::DEFAULT;
192 DALI_ASSERT_ALWAYS("Unknown sampling mode");
196 int desiredWidth = 0;
197 Property::Value* desiredWidthValue = propertyMap.Find( IMAGE_DESIRED_WIDTH );
198 if( desiredWidthValue )
200 desiredWidthValue->Get( desiredWidth );
203 int desiredHeight = 0;
204 Property::Value* desiredHeightValue = propertyMap.Find( IMAGE_DESIRED_HEIGHT );
205 if( desiredHeightValue )
207 desiredHeightValue->Get( desiredHeight );
210 mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
216 void ImageRenderer::SetSize( const Vector2& size )
218 ControlRenderer::SetSize( size );
219 // ToDo: renderer responds to the size change
222 void ImageRenderer::SetClipRect( const Rect<int>& clipRect )
224 ControlRenderer::SetClipRect( clipRect );
225 //ToDo: renderer responds to the clipRect change
228 void ImageRenderer::SetOffset( const Vector2& offset )
230 //ToDo: renderer applies the offset
233 void ImageRenderer::DoSetOnStage( Actor& actor )
235 if( !mImageUrl.empty() && !mImage )
237 mImage = Dali::ResourceImage::New( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode );
240 ApplyImageToSampler();
243 void ImageRenderer::DoSetOffStage( Actor& actor )
245 //If we own the image then make sure we release it when we go off stage
246 if( !mImageUrl.empty() )
251 ControlRenderer::SetOffStage( actor );
254 void ImageRenderer::SetImage( const std::string& imageUrl )
256 SetImage( imageUrl, 0, 0, Dali::FittingMode::DEFAULT, Dali::SamplingMode::DEFAULT );
259 void ImageRenderer::SetImage( const std::string& imageUrl, int desiredWidth, int desiredHeight, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode )
261 if( mImageUrl != imageUrl )
263 mImageUrl = imageUrl;
264 mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
265 mFittingMode = fittingMode;
266 mSamplingMode = samplingMode;
268 if( !mImageUrl.empty() && mImpl->mIsOnStage )
270 mImage = Dali::ResourceImage::New( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode );
271 ApplyImageToSampler();
280 void ImageRenderer::SetImage( Image image )
282 if( mImage != image )
285 mDesiredSize = ImageDimensions();
286 mFittingMode = FittingMode::DEFAULT;
287 mSamplingMode = SamplingMode::DEFAULT;
290 if( mImage && mImpl->mIsOnStage )
292 ApplyImageToSampler();
297 void ImageRenderer::ApplyImageToSampler()
301 Material material = mImpl->mRenderer.GetMaterial();
304 for( std::size_t i = 0; i < material.GetNumberOfSamplers(); ++i )
306 Sampler sampler = material.GetSamplerAt( i );
307 if( sampler.GetUniformName() == TEXTURE_UNIFORM_NAME )
309 sampler.SetImage( mImage );
314 Sampler sampler = Sampler::New( mImage, TEXTURE_UNIFORM_NAME );
315 material.AddSampler( sampler );
320 } // namespace Internal
322 } // namespace Toolkit