2 * Copyright (c) 2016 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.
18 #include "emscripten-platform-abstraction.h"
24 #include <SDL_surface.h>
25 #include <SDL_image.h>
26 #include "emscripten/emscripten.h"
27 #include "emscripten-callbacks.h"
29 #define EM_LOG(x); // EM_ASM( console.log( x ) );
33 #include <dali/integration-api/platform-abstraction.h>
34 #include <dali/devel-api/common/ref-counted-dali-vector.h>
39 Dali::Integration::BitmapPtr LoadResourceEncodedImage( Dali::RefCountedVector<uint8_t>* encodedBlob )
41 Dali::Integration::BitmapPtr bitmapPtr = NULL;
43 if( encodedBlob != 0 )
45 const size_t blobSize = encodedBlob->GetVector().Size();
46 uint8_t * const blobBytes = &(encodedBlob->GetVector()[0]);
47 DALI_ASSERT_DEBUG( blobSize > 0U );
48 DALI_ASSERT_DEBUG( blobBytes != 0U );
50 if( blobBytes != 0 && blobSize > 0U )
53 SDL_RWops *memory = SDL_RWFromMem(blobBytes, blobSize);
57 printf(" Error Null pointer from SDL RW memory?\n");
60 SDL_Surface *surface = IMG_Load_RW(memory, 0);
64 bitmapPtr = Dali::Integration::Bitmap::New( Dali::Integration::Bitmap::BITMAP_2D_PACKED_PIXELS,
65 Dali::ResourcePolicy::OWNED_DISCARD ); // DISCARD; Dali manages
67 Dali::Integration::Bitmap::PackedPixelsProfile* packedProfile = bitmapPtr->GetPackedPixelsProfile();
68 DALI_ASSERT_ALWAYS(packedProfile);
70 unsigned char bytesPerPixel = surface->format->BytesPerPixel;
72 Dali::Integration::PixelBuffer* pixels = NULL;
74 unsigned char targetBytesPerPixel = 3; // bytesPerPixel;
76 // SDL in emscripten returns us a 4byteperpixel image regardless of rgb/png etc
77 // Theres no apparent way to differentiate an image with an alpha channel
78 // In Dali if an image has an alpha channel it gets sorted. This introduces odd artifacts on rotation
79 // as the sorting algorithm presumes front on view.
80 // So here well just support pngs with an alpha channel.
81 // We're poking around in the format as emscripten currently lacks a file memory api where we could use
82 // Dali's machinery to read the format.
83 unsigned char *pBytes = blobBytes;
85 if( 0x89 == *(pBytes+0) && 0x50 == *(pBytes+1) ) // magic bytes for png_all_filters
87 pBytes+=8; // 8 bytes for header
88 pBytes+=4; // 4 bytes for chunk length
89 pBytes+=4; // 4 bytes for chunk type
90 // ihdr data (must be first chunk)
91 pBytes+=4; // 4 for width,height
93 pBytes+=1; // 1 for bit depth
94 unsigned char ihdr_colorType= *pBytes; // 1 for bit colorType
95 if( (4 == ihdr_colorType || // 4 is 8,16 bit depth with alpha LA
96 6 == ihdr_colorType) ) // 6 is 8,16 bit depth with alpha RGBA
98 targetBytesPerPixel = 4;
102 if(3 == targetBytesPerPixel)
104 pixels = packedProfile->ReserveBuffer(Dali::Pixel::RGB888,
105 surface->w, surface->h,
106 surface->w, surface->h);
108 else if(4 == targetBytesPerPixel)
110 pixels = packedProfile->ReserveBuffer(Dali::Pixel::RGBA8888,
111 surface->w, surface->h,
112 surface->w, surface->h);
116 DALI_ASSERT_ALWAYS(0 && "bad bytes per pixel");
119 unsigned char* fromPtr = static_cast<unsigned char*>(surface->pixels);
121 int stride = surface->pitch;
123 for(int h = 0; h < surface->h; ++h)
125 for(int w = 0; w < (surface->w*bytesPerPixel); w+=bytesPerPixel)
127 for(int j = 0; j < targetBytesPerPixel; ++j)
129 pixels[ index++ ] = *( (fromPtr + (h * stride) ) + w + j );
136 printf(" Error empty surface when decoding image? (SDL RW Memory ptr=%llx) %s. %d\n", (long long)(memory), SDL_GetError(), blobSize);
142 printf(" Error No bytes in image?\n");
148 printf(" Error Null pointer given for decoding image?\n");
154 EM_ASM( console.log( "LoadResourceEncodedImage: Image:-" ) );
156 console.log( $0 ) }, bitmapPtr->GetImageWidth() );
158 console.log( $0 ) }, bitmapPtr->GetImageHeight() );
160 console.log( $0 ) }, bitmapPtr->GetBufferSize() );
165 EM_ASM( console.log( "LoadResourceEncodedImage: no bitmap data?" ) );
176 EmscriptenPlatformAbstraction::EmscriptenPlatformAbstraction()
183 EmscriptenPlatformAbstraction::~EmscriptenPlatformAbstraction()
187 void EmscriptenPlatformAbstraction::GetTimeMicroseconds(unsigned int &seconds, unsigned int µSeconds)
189 double current = EM_ASM_DOUBLE_V({ return new Date().getTime(); }); // getTime() in ms
191 seconds = static_cast<unsigned int>(current/1000.0);
192 microSeconds = (static_cast<unsigned int>(current) - seconds*1000.0) * 1000;
195 ImageDimensions EmscriptenPlatformAbstraction::GetClosestImageSize( const std::string& filename,
196 ImageDimensions size,
197 FittingMode::Type fittingMode,
198 SamplingMode::Type samplingMode,
199 bool orientationCorrection )
201 return Dali::Internal::Emscripten::LoadImageMetadata(filename, size, fittingMode, samplingMode, orientationCorrection);
204 ImageDimensions EmscriptenPlatformAbstraction::GetClosestImageSize( Integration::ResourcePointer resourceBuffer,
205 ImageDimensions size,
206 FittingMode::Type fittingMode,
207 SamplingMode::Type samplingMode,
208 bool orientationCorrection )
211 return Dali::ImageDimensions(); // Dali::Internal::Emscripten::LoadImageMetadata(filename, size, fittingMode, samplingMode, orientationCorrection);
214 Integration::ResourcePointer EmscriptenPlatformAbstraction::LoadResourceSynchronously( const Integration::ResourceType& resourceType, const std::string& resourcePath )
216 Integration::ResourcePointer ret;
218 switch(resourceType.id)
220 case Integration::ResourceBitmap:
222 const Integration::BitmapResourceType& bitmapResource( static_cast<const Integration::BitmapResourceType&>(resourceType) );
224 Integration::BitmapPtr bitmapPtr = Dali::Internal::Emscripten::GetImage( bitmapResource.size,
225 bitmapResource.scalingMode,
226 bitmapResource.samplingMode,
227 bitmapResource.orientationCorrection,
233 } // switch(resourceType->id)
238 Integration::BitmapPtr EmscriptenPlatformAbstraction::DecodeBuffer( const Integration::ResourceType& resourceType, uint8_t * buffer, size_t bufferSize )
240 return Integration::BitmapPtr();
244 bool EmscriptenPlatformAbstraction::LoadShaderBinaryFile( const std::string& filename, Dali::Vector< unsigned char >& buffer ) const
246 EM_LOG("EmscriptenPlatformAbstraction::LoadShaderBinaryFile");
250 void EmscriptenPlatformAbstraction::UpdateDefaultsFromDevice()
252 DALI_ASSERT_ALWAYS("!Unimplemented");
253 mGetDefaultFontFamilyResult+=1.0f;
256 void EmscriptenPlatformAbstraction::IncrementGetTimeResult(size_t milliseconds)