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>
39 const char * const IMAGE_URL_NAME("image-url");
40 const char * const IMAGE_FITTING_MODE("image-fitting-mode");
41 const char * const IMAGE_SAMPLING_MODE("image-sampling-mode");
42 const char * const IMAGE_DESIRED_WIDTH("image-desired-width");
43 const char * const IMAGE_DESIRED_HEIGHT("image-desired-height");
45 std::string TEXTURE_UNIFORM_NAME = "sTexture";
47 #define MAKE_SHADER(A)#A
49 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
50 attribute mediump vec2 aPosition;\n
51 varying mediump vec2 vTexCoord;\n
52 uniform mediump mat4 uMvpMatrix;\n
53 uniform mediump vec3 uSize;\n
57 mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
58 vertexPosition.xyz *= uSize;\n
59 vertexPosition = uMvpMatrix * vertexPosition;\n
61 vTexCoord = aPosition + vec2(0.5);\n
62 gl_Position = vertexPosition;\n
66 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
67 varying mediump vec2 vTexCoord;\n
68 uniform sampler2D sTexture;\n
69 uniform lowp vec4 uColor;\n
73 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
79 ImageRenderer::ImageRenderer()
82 mFittingMode( FittingMode::DEFAULT ),
83 mSamplingMode( SamplingMode::DEFAULT )
87 ImageRenderer::~ImageRenderer()
91 void ImageRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
93 Initialize(factoryCache);
95 Property::Value* imageURLValue = propertyMap.Find( IMAGE_URL_NAME );
98 imageURLValue->Get( mImageUrl );
100 Property::Value* fittingValue = propertyMap.Find( IMAGE_FITTING_MODE );
104 fittingValue->Get( fitting );
106 mFittingMode = FittingMode::DEFAULT;
107 if( fitting == "shrink-to-fit" )
109 mFittingMode = FittingMode::SHRINK_TO_FIT;
111 else if( fitting == "scale-to-fill" )
113 mFittingMode = FittingMode::SCALE_TO_FILL;
115 else if( fitting == "fit-width" )
117 mFittingMode = FittingMode::FIT_WIDTH;
119 else if( fitting == "fit-height" )
121 mFittingMode = FittingMode::FIT_HEIGHT;
123 else if( fitting == "default" )
125 mFittingMode = FittingMode::DEFAULT;
129 DALI_ASSERT_ALWAYS("Unknown fitting mode");
133 Property::Value* samplingValue = propertyMap.Find( IMAGE_SAMPLING_MODE );
136 std::string sampling;
137 samplingValue->Get( sampling );
139 mSamplingMode = SamplingMode::DEFAULT;
140 if( sampling == "box" )
142 mSamplingMode = SamplingMode::BOX;
144 else if( sampling == "nearest" )
146 mSamplingMode = SamplingMode::NEAREST;
148 else if( sampling == "linear" )
150 mSamplingMode = SamplingMode::LINEAR;
152 else if( sampling == "box-then-nearest" )
154 mSamplingMode = SamplingMode::BOX_THEN_NEAREST;
156 else if( sampling == "box-then-linear" )
158 mSamplingMode = SamplingMode::BOX_THEN_LINEAR;
160 else if( sampling == "no-filter" )
162 mSamplingMode = SamplingMode::NO_FILTER;
164 else if( sampling == "dont-care" )
166 mSamplingMode = SamplingMode::DONT_CARE;
168 else if( sampling == "default" )
170 mSamplingMode = SamplingMode::DEFAULT;
174 DALI_ASSERT_ALWAYS("Unknown sampling mode");
178 int desiredWidth = 0;
179 Property::Value* desiredWidthValue = propertyMap.Find( IMAGE_DESIRED_WIDTH );
180 if( desiredWidthValue )
182 desiredWidthValue->Get( desiredWidth );
185 int desiredHeight = 0;
186 Property::Value* desiredHeightValue = propertyMap.Find( IMAGE_DESIRED_HEIGHT );
187 if( desiredHeightValue )
189 desiredHeightValue->Get( desiredHeight );
192 mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
198 void ImageRenderer::SetSize( const Vector2& size )
200 ControlRenderer::SetSize( size );
201 // ToDo: renderer responds to the size change
204 void ImageRenderer::SetClipRect( const Rect<int>& clipRect )
206 ControlRenderer::SetClipRect( clipRect );
207 //ToDo: renderer responds to the clipRect change
210 void ImageRenderer::SetOffset( const Vector2& offset )
212 //ToDo: renderer applies the offset
215 void ImageRenderer::DoSetOnStage( Actor& actor )
217 if( !mImageUrl.empty() && !mImage )
219 mImage = Dali::ResourceImage::New( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode );
222 ApplyImageToSampler();
225 void ImageRenderer::DoSetOffStage( Actor& actor )
227 //If we own the image then make sure we release it when we go off stage
228 if( !mImageUrl.empty() )
234 void ImageRenderer::Initialize( RendererFactoryCache& factoryCache )
236 mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY );
237 if( !(mImpl->mGeometry) )
239 mImpl->mGeometry = factoryCache.CreateQuadGeometry();
240 factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry );
243 mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER );
244 if( !mImpl->mShader )
246 mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
247 factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, mImpl->mShader );
250 mDesiredSize = ImageDimensions();
251 mFittingMode = FittingMode::DEFAULT;
252 mSamplingMode = SamplingMode::DEFAULT;
256 void ImageRenderer::SetImage( const std::string& imageUrl )
258 SetImage( imageUrl, 0, 0, Dali::FittingMode::DEFAULT, Dali::SamplingMode::DEFAULT );
261 void ImageRenderer::SetImage( const std::string& imageUrl, int desiredWidth, int desiredHeight, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode )
263 if( mImageUrl != imageUrl )
265 mImageUrl = imageUrl;
266 mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
267 mFittingMode = fittingMode;
268 mSamplingMode = samplingMode;
270 if( !mImageUrl.empty() && mImpl->mIsOnStage )
272 mImage = Dali::ResourceImage::New( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode );
273 ApplyImageToSampler();
282 void ImageRenderer::SetImage( Image image )
284 if( mImage != image )
287 mDesiredSize = ImageDimensions();
288 mFittingMode = FittingMode::DEFAULT;
289 mSamplingMode = SamplingMode::DEFAULT;
292 if( mImage && mImpl->mIsOnStage )
294 ApplyImageToSampler();
299 Image ImageRenderer::GetImage() const
304 void ImageRenderer::ApplyImageToSampler()
308 Material material = mImpl->mRenderer.GetMaterial();
311 for( std::size_t i = 0; i < material.GetNumberOfSamplers(); ++i )
313 Sampler sampler = material.GetSamplerAt( i );
314 if( sampler.GetUniformName() == TEXTURE_UNIFORM_NAME )
316 sampler.SetImage( mImage );
321 Sampler sampler = Sampler::New( mImage, TEXTURE_UNIFORM_NAME );
322 material.AddSampler( sampler );
327 } // namespace Internal
329 } // namespace Toolkit