Apply platform surface to source surface of Canvas.
authorByeongha Cho <byeongha.cho@samsung.com>
Fri, 29 Mar 2013 06:21:10 +0000 (15:21 +0900)
committerGerrit Code Review <gerrit2@kim11>
Wed, 17 Apr 2013 12:30:16 +0000 (21:30 +0900)
[Title] Apply platform surface to source surface of Canvas.
[Issue#] N/A
[Problem] N/A
[Cause] N/A
[Solution] N/A

Change-Id: I859f85c80bc15b2d6799b5eff475d55eb3ccb82c

22 files changed:
Source/WTF/wtf/Platform.h
Source/WebCore/platform/graphics/BitmapImage.cpp
Source/WebCore/platform/graphics/BitmapImage.h
Source/WebCore/platform/graphics/ImageBuffer.h
Source/WebCore/platform/graphics/ImageSource.cpp
Source/WebCore/platform/graphics/ImageSource.h
Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp
Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp
Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp
Source/WebCore/platform/graphics/cairo/NativeImageCairo.h
Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp
Source/WebCore/platform/image-decoders/ImageDecoder.cpp
Source/WebCore/platform/image-decoders/ImageDecoder.h
Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp
Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp
Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h
Source/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp
Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp

index 64d7288..d600e7e 100644 (file)
@@ -722,7 +722,10 @@ com) : Patch to do not adjust cover rect as fixed pixel size*/
 #endif
 #endif
 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
+#define ENABLE_TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE 1 /* Byeongha Cho(byeongha.cho@samsung.com) : Use pixmap surface to decode image and share the buffer between CPU and GPU */
+#if !ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
 #define ENABLE_TIZEN_CAIROGLES_IMAGE_CACHE 1
+#endif
 #if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
 #define ENABLE_TIZEN_CAIROGLES_IMAGE_AUTOSCALE 1
 #endif
index 6e854ad..c33dc08 100644 (file)
 #include "cairo.h"
 #endif
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+#include <cairo-gl.h>
+#endif
+
 namespace WebCore {
 
 static int frameBytes(const IntSize& frameSize)
@@ -66,6 +70,9 @@ BitmapImage::BitmapImage(ImageObserver* observer)
     , m_sizeAvailable(false)
     , m_hasUniformFrameSize(true)
     , m_haveFrameCount(false)
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    , m_isGLTargetSurface(false)
+#endif
 {
 }
 
@@ -149,7 +156,11 @@ void BitmapImage::cacheFrame(size_t index)
     if (m_frames.size() < numFrames)
         m_frames.grow(numFrames);
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    m_source.setTargetType(m_isGLTargetSurface);
+#endif
     m_frames[index].m_frame = m_source.createFrameAtIndex(index);
+
     if (numFrames == 1 && m_frames[index].m_frame)
         checkForSolidColor();
 
@@ -167,9 +178,23 @@ void BitmapImage::cacheFrame(size_t index)
 #if !ENABLE(TIZEN_JPEG_IMAGE_SCALE_DECODING)
         int deltaBytes = frameBytes(frameSize);
 #else
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        cairo_surface_t* surface;
+        if (m_isGLTargetSurface)
+            surface = m_frames[index].m_frame->glsurface();
+        else
+            surface = m_frames[index].m_frame->surface();
+
+        int deltaBytes;
+        if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_GL)
+            deltaBytes = cairo_gl_surface_get_width(surface) * cairo_gl_surface_get_height(surface) * 4;
+        else
+            deltaBytes = cairo_image_surface_get_width(surface) * cairo_image_surface_get_height(surface) * 4;
+#else
         cairo_surface_t* surface = m_frames[index].m_frame->surface();
         int deltaBytes = cairo_image_surface_get_width(surface) * cairo_image_surface_get_height(surface) * 4;
 #endif
+#endif
         m_decodedSize += deltaBytes;
         // The fully-decoded frame will subsume the partially decoded data used
         // to determine image properties.
@@ -309,7 +334,13 @@ bool BitmapImage::ensureFrameIsCached(size_t index)
     if (index >= frameCount())
         return false;
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    if (index >= m_frames.size() || !m_frames[index].m_frame
+        || (m_isGLTargetSurface && m_frames[index].m_frame->surfaceType() != NativeImageCairo::NATIVE_GL_SURFACE)
+        || (!m_isGLTargetSurface && m_frames[index].m_frame->surfaceType() != NativeImageCairo::NATIVE_IMAGE_SURFACE))
+#else
     if (index >= m_frames.size() || !m_frames[index].m_frame)
+#endif
         cacheFrame(index);
     return true;
 }
index 58bf745..49f6148 100644 (file)
@@ -321,6 +321,9 @@ protected:
     Mutex m_decodeMutex;
     Mutex m_clearMutex;
 #endif
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    bool m_isGLTargetSurface;
+#endif
 };
 
 }
index 6ac717e..8add808 100644 (file)
@@ -162,7 +162,7 @@ namespace WebCore {
 
 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
         bool setBindingTexture();
-        static cairo_device_t* m_sharedCairoDevice;
+
         unsigned m_bindingTexID;
         void* m_eglImage;
 #endif // ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
@@ -173,11 +173,6 @@ namespace WebCore {
         PassRefPtr<cairo_surface_t> querySurface() const;
         bool unlockSurface() const;
 
-        static void* m_nativeDisplay;
-        static int m_nativeWindow;
-        static void* m_egl_display;
-        static void* m_egl_config;
-
         int m_platformSurfaceID;
         void* m_eglSurface;
         bool m_isLockable;
index ab05b53..e5ac44b 100644 (file)
 #include "ImageOrientation.h"
 #include "NotImplemented.h"
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+#include "cairo-gl.h"
+#endif
+
 namespace WebCore {
 
 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
@@ -50,6 +54,9 @@ ImageSource::ImageSource(ImageSource::AlphaOption alphaOption, ImageSource::Gamm
     : m_decoder(0)
     , m_alphaOption(alphaOption)
     , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    , m_isGLTargetSurface(false)
+#endif
 {
 }
 
@@ -161,6 +168,9 @@ NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
     if (!m_decoder)
         return 0;
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    m_decoder->setTargetType(m_isGLTargetSurface);
+#endif
     ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
     if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
         return 0;
@@ -172,6 +182,10 @@ NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
 
     // Return the buffer contents as a native image.  For some ports, the data
     // is already in a native container, and this just increments its refcount.
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    if (m_isGLTargetSurface)
+        return buffer->asNewNativeImageForGL();
+#endif
     return buffer->asNewNativeImage();
 }
 
index 6b53cac..e85e608 100644 (file)
@@ -178,6 +178,10 @@ public:
 
     size_t frameCount() const;
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    void setTargetType(bool isGLTargetSurface) { m_isGLTargetSurface = isGLTargetSurface; }
+#endif
+
     // Callers should not call this after calling clear() with a higher index;
     // see comments on clear() above.
     NativeImagePtr createFrameAtIndex(size_t);
@@ -203,6 +207,9 @@ private:
 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) || ENABLE(TIZEN_JPEG_IMAGE_SCALE_DECODING)
     static unsigned s_maxPixelsPerDecodedImage;
 #endif
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    bool m_isGLTargetSurface;
+#endif
 };
 
 }
index 3ee7c1f..11f183f 100644 (file)
@@ -41,6 +41,13 @@ namespace WebCore {
 
 PassRefPtr<BitmapImage> BitmapImage::create(cairo_surface_t* surface)
 {
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_GL) {
+        NativeImageCairo* nativeImage = new NativeImageCairo();
+        nativeImage->setGLSurface(surface);
+        return BitmapImage::create(nativeImage);
+    }
+#endif
     return BitmapImage::create(new NativeImageCairo(surface));
 }
 
@@ -62,7 +69,19 @@ BitmapImage::BitmapImage(NativeImageCairo* nativeImage, ImageObserver* observer)
     , m_sizeAvailable(true)
     , m_haveFrameCount(true)
 {
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    ASSERT(nativeImage->surfaceType() != NativeImageCairo::NATIVE_NONE_SURFACE);
+    cairo_surface_t* surface;
+    if (nativeImage->surfaceType() == NativeImageCairo::NATIVE_IMAGE_SURFACE) {
+        surface = nativeImage->surface();
+        m_isGLTargetSurface = false;
+    } else if (nativeImage->surfaceType() == NativeImageCairo::NATIVE_GL_SURFACE) {
+        surface = nativeImage->glsurface();
+        m_isGLTargetSurface = true;
+    }
+#else
     cairo_surface_t* surface = nativeImage->surface();
+#endif
 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
     int width = 0, height = 0;
     if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_GL) {
@@ -93,6 +112,19 @@ static void adjustSourceRectForScaling(FloatRect& srcRect, const IntSize& origSi
     // We assume down-sampling zoom rates in X direction and in Y direction are same.
     if (origSize.width() == scaledSize.width())
         return;
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    // We assume zoom rates are not same in X,Y direction.
+    double rateWidth = static_cast<double>(scaledSize.width()) / origSize.width();
+    double rateHeight = static_cast<double>(scaledSize.height()) / origSize.height();
+    // Calculate end of srcRect in X direction and apply zoom rate.
+    double temp = (srcRect.x() + srcRect.width()) * rateWidth;
+    srcRect.setX(srcRect.x() * rateWidth);
+    srcRect.setWidth(temp - srcRect.x());
+    // Calculate end of srcRect in Y direction and apply zoom rate.
+    temp = (srcRect.y() + srcRect.height()) * rateHeight;
+    srcRect.setY(srcRect.y() * rateHeight);
+    srcRect.setHeight(temp - srcRect.y());
+#else
     // Image has been down sampled.
     double rate = static_cast<double>(scaledSize.width()) / origSize.width();
     double temp = (srcRect.x() + srcRect.width()) * rate;
@@ -101,6 +133,7 @@ static void adjustSourceRectForScaling(FloatRect& srcRect, const IntSize& origSi
     temp = (srcRect.y() + srcRect.height()) * rate;
     srcRect.setY(srcRect.y() * rate);
     srcRect.setHeight(temp - srcRect.y());
+#endif
 }
 #endif
 
@@ -114,6 +147,16 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
 
     startAnimation();
 
+#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE) || ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    cairo_surface_type_t surfaceType = cairo_surface_get_type(cairo_get_target(context->platformContext()->cr()));
+#endif
+
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    if (surfaceType == CAIRO_SURFACE_TYPE_GL)
+        m_isGLTargetSurface = true;
+    else
+        m_isGLTargetSurface = false;
+#endif
     NativeImageCairo* nativeImage = frameAtIndex(m_currentFrame);
     if (!nativeImage) // If it's too early we won't have an image yet.
         return;
@@ -125,17 +168,13 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
 
     context->save();
 
-#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
-    cairo_surface_type_t surfaceType = cairo_surface_get_type(cairo_get_target(context->platformContext()->cr()));
-#endif
-
 #if !ENABLE(TIZEN_ATLAS_IMAGE_BUG_FIX)
     // Set the compositing operation.
     if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame))
         context->setCompositeOperation(CompositeCopy);
     else
 #else
-#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
+#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE) || ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
     // Set the compositing operation.
     if (surfaceType == CAIRO_SURFACE_TYPE_GL && op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame))
         context->setCompositeOperation(CompositeCopy);
@@ -161,13 +200,26 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
         cairo_surface_unmap_image(nativeImage->surface(), imageSurface);
     }
 #else
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    IntSize imageSize = IntSize();
+    if (surfaceType == CAIRO_SURFACE_TYPE_GL) {
+        imageSize.setWidth(cairo_gl_surface_get_width(nativeImage->glsurface()));
+        imageSize.setHeight(cairo_gl_surface_get_height(nativeImage->glsurface()));
+        adjustSourceRectForScaling(srcRect, size(), imageSize);
+    } else {
+        imageSize.setWidth(cairo_image_surface_get_width(nativeImage->surface()));
+        imageSize.setHeight(cairo_image_surface_get_height(nativeImage->surface()));
+        adjustSourceRectForScaling(srcRect, size(), imageSize);
+    }
+#else
     IntSize imageSize(cairo_image_surface_get_width(nativeImage->surface()), cairo_image_surface_get_height(nativeImage->surface()));
     adjustSourceRectForScaling(srcRect, size(), imageSize);
 #endif
 #endif
+#endif
 
 #if ENABLE(TIZEN_ADD_AA_CONDITIONS_FOR_NINE_PATCH)
-#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
+#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE) || ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
     if (surfaceType != CAIRO_SURFACE_TYPE_GL) {
         cairo_t* cr = context->platformContext()->cr();
         if ((cairo_get_antialias(cr) != CAIRO_ANTIALIAS_NONE) && (context->getCTM().isIdentityOrTranslationOrFlipped() || context->getCTM().has90MultipleRotation())) {
@@ -177,8 +229,14 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
             cairo_set_antialias(cr, savedAntialiasRule);
         } else
             context->platformContext()->drawSurfaceToContext(nativeImage->surface(), dstRect, srcRect, context);
-    } else
+    } else {
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        if (surfaceType == CAIRO_SURFACE_TYPE_GL)
+            context->platformContext()->drawSurfaceToContext(nativeImage->glsurface(), dstRect, srcRect, context);
+        else
+#endif
         context->platformContext()->drawSurfaceToContext(nativeImage->surface(), dstRect, srcRect, context);
+    }
 #else
     cairo_t* cr = context->platformContext()->cr();
     if ((cairo_get_antialias(cr) != CAIRO_ANTIALIAS_NONE) && (context->getCTM().isIdentityOrTranslationOrFlipped() || context->getCTM().has90MultipleRotation())) {
@@ -190,6 +248,11 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
         context->platformContext()->drawSurfaceToContext(nativeImage->surface(), dstRect, srcRect, context);
 #endif
 #else
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    if (surfaceType == CAIRO_SURFACE_TYPE_GL)
+        context->platformContext()->drawSurfaceToContext(nativeImage->glsurface(), dstRect, srcRect, context);
+    else
+#endif
     context->platformContext()->drawSurfaceToContext(nativeImage->surface(), dstRect, srcRect, context);
 #endif
 
@@ -211,8 +274,16 @@ void BitmapImage::checkForSolidColor()
     if (!nativeImage) // If it's too early we won't have an image yet.
         return;
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    cairo_surface_t* surface;
+    if (nativeImage->surface())
+        surface = nativeImage->surface();
+    else
+        surface = nativeImage->glsurface();
+#else
     cairo_surface_t* surface = nativeImage->surface();
     ASSERT(cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE);
+#endif
 
 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
     int width = 0, height = 0;
@@ -232,8 +303,21 @@ void BitmapImage::checkForSolidColor()
     if (width != 1 || height != 1)
         return;
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    unsigned* pixelColor = 0;
+    if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_GL) {
+        cairo_surface_t* imageSurface = cairo_surface_map_to_image(surface, NULL);
+        pixelColor = reinterpret_cast<unsigned*>(cairo_image_surface_get_data(imageSurface));
+        m_solidColor = colorFromPremultipliedARGB(*pixelColor);
+        cairo_surface_unmap_image(surface, imageSurface);
+    } else {
+        pixelColor = reinterpret_cast<unsigned*>(cairo_image_surface_get_data(surface));
+        m_solidColor = colorFromPremultipliedARGB(*pixelColor);
+    }
+#else
     unsigned* pixelColor = reinterpret_cast<unsigned*>(cairo_image_surface_get_data(surface));
     m_solidColor = colorFromPremultipliedARGB(*pixelColor);
+#endif
 
     m_isSolidColor = true;
 }
index 8f211a7..d4686b7 100644 (file)
@@ -306,7 +306,7 @@ void drawPatternToCairoContext(cairo_t* cr, cairo_surface_t* image, const IntSiz
     RefPtr<cairo_surface_t> clippedImageSurface = 0;
     if (tileRect.size() != imageSize) {
         IntRect imageRect = enclosingIntRect(tileRect);
-#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
+#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE) || ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
         if (cairo_surface_get_type(image) == CAIRO_SURFACE_TYPE_GL)
             clippedImageSurface = adoptRef(cairo_surface_create_similar(image, CAIRO_CONTENT_COLOR_ALPHA, imageRect.width(), imageRect.height()));
         else
@@ -428,7 +428,7 @@ PassRefPtr<cairo_surface_t> copyCairoImageSurface(cairo_surface_t* originalSurfa
     // Once cairo provides the way, use the function instead of this.
 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
     RefPtr<cairo_surface_t> newSurface;
-#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
+#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE) || ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
     if (cairo_surface_get_type(originalSurface) == CAIRO_SURFACE_TYPE_GL) {
         int h = cairo_gl_surface_get_height(originalSurface);
         int w = cairo_gl_surface_get_width(originalSurface);
index 298c8ef..0103a96 100755 (executable)
@@ -69,14 +69,15 @@ using namespace std;
 namespace WebCore {
 
 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING) || ENABLE(TIZEN_CANVAS_SURFACE_LOCKING)
-void* ImageBuffer::m_nativeDisplay = 0;
-int ImageBuffer::m_nativeWindow = 0;
-void* ImageBuffer::m_egl_display = 0;
-void* ImageBuffer::m_egl_config = 0;
+void* g_canvasNativeDisplay = 0;
+int g_canvasNativeWindow = 0;
+void* g_egl_display = 0;
+void* g_egl_config = 0;
 #endif
 
 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
-cairo_device_t* ImageBuffer::m_sharedCairoDevice = 0;
+cairo_device_t* g_sharedCairoDevice = 0;
+void* g_egl_context = 0;
 static PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = 0;
 static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = 0;
 static PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = 0;
@@ -92,32 +93,60 @@ ImageBufferData::ImageBufferData(const IntSize& size)
 void ImageBuffer::initializeEGL()
 {
 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
-    if (m_sharedCairoDevice)
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    if (g_sharedCairoDevice) {
+        EGLint num;
+        EGLint attr[] = {
+                EGL_RED_SIZE, 8,
+                EGL_GREEN_SIZE, 8,
+                EGL_BLUE_SIZE, 8,
+                EGL_ALPHA_SIZE, 8,
+                EGL_STENCIL_SIZE, 8,
+                EGL_DEPTH_SIZE, 8,
+                EGL_SAMPLES, 4,
+#if ENABLE(TIZEN_CANVAS_SURFACE_LOCKING)
+                EGL_MATCH_FORMAT_KHR, EGL_FORMAT_RGBA_8888_EXACT_KHR,
+                EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_LOCK_SURFACE_BIT_KHR,
+#else
+                EGL_SURFACE_TYPE, EGL_PIXMAP_BIT,
+#endif
+                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                EGL_NONE
+        };
+
+        if (!eglChooseConfig(g_egl_display, attr, &g_egl_config, 1, &num))
+            return;
+
         return;
+    }
+#else
+    if (g_sharedCairoDevice)
+        return;
+#endif
 #endif // ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
 
-    if (!m_nativeDisplay) {
-        m_nativeDisplay = XOpenDisplay(0);
+    if (!g_canvasNativeDisplay) {
+        g_canvasNativeDisplay = XOpenDisplay(0);
 
-        m_nativeWindow = XCreateSimpleWindow(static_cast<Display*>(m_nativeDisplay), XDefaultRootWindow(static_cast<Display*>(m_nativeDisplay)),
+        g_canvasNativeWindow = XCreateSimpleWindow(static_cast<Display*>(g_canvasNativeDisplay), XDefaultRootWindow(static_cast<Display*>(g_canvasNativeDisplay)),
                           0, 0, 1, 1, 0,
-                          BlackPixel(static_cast<Display*>(m_nativeDisplay), 0), WhitePixel(static_cast<Display*>(m_nativeDisplay), 0));
+                          BlackPixel(static_cast<Display*>(g_canvasNativeDisplay), 0), WhitePixel(static_cast<Display*>(g_canvasNativeDisplay), 0));
 
-        XFlush(static_cast<Display*>(m_nativeDisplay));
+        XFlush(static_cast<Display*>(g_canvasNativeDisplay));
     }
 
     EGLint major, minor;
 
-    if (!m_egl_display) {
-        m_egl_display = eglGetDisplay(static_cast<NativeDisplayType>(m_nativeDisplay));
-        if (m_egl_display == EGL_NO_DISPLAY) {
+    if (!g_egl_display) {
+        g_egl_display = eglGetDisplay(static_cast<NativeDisplayType>(g_canvasNativeDisplay));
+        if (g_egl_display == EGL_NO_DISPLAY) {
 #if ENABLE(TIZEN_DLOG_SUPPORT)
             TIZEN_LOGE("eglGetDisplay failed!\n");
 #endif
             return;
         }
 
-        if (eglInitialize(m_egl_display, &major, &minor) != EGL_TRUE) {
+        if (eglInitialize(g_egl_display, &major, &minor) != EGL_TRUE) {
 #if ENABLE(TIZEN_DLOG_SUPPORT)
             TIZEN_LOGE("eglInitialize failed!\n");
 #endif
@@ -154,7 +183,7 @@ void ImageBuffer::initializeEGL()
         attr[i++] = EGL_OPENGL_ES2_BIT;
         attr[i++] = EGL_NONE;
 
-        if (!eglChooseConfig(m_egl_display, attr, &m_egl_config, 1, &num)) {
+        if (!eglChooseConfig(g_egl_display, attr, &g_egl_config, 1, &num)) {
 #if ENABLE(TIZEN_DLOG_SUPPORT)
             TIZEN_LOGE("eglChooseConfig failed!\n");
 #endif
@@ -163,27 +192,27 @@ void ImageBuffer::initializeEGL()
     }
 
 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
-    if (!m_sharedCairoDevice) {
+    if (!g_sharedCairoDevice) {
         EGLint ctxattr[] = {
             EGL_CONTEXT_CLIENT_VERSION, 2,
             EGL_NONE
         };
-        EGLContext eglContext = eglCreateContext(m_egl_display, m_egl_config, 0, ctxattr);
-        if (eglContext == EGL_NO_CONTEXT) {
+        g_egl_context = eglCreateContext(g_egl_display, g_egl_config, NULL, ctxattr);
+        if (g_egl_context == EGL_NO_CONTEXT) {
 #if ENABLE(TIZEN_DLOG_SUPPORT)
             TIZEN_LOGE("eglCreateContext failed!\n");
 #endif
             return;
         }
-        m_sharedCairoDevice = cairo_egl_device_create(m_egl_display, eglContext);
-        if (cairo_device_status(m_sharedCairoDevice) != CAIRO_STATUS_SUCCESS) {
+        g_sharedCairoDevice = cairo_egl_device_create(g_egl_display, g_egl_context);
+        if (cairo_device_status(g_sharedCairoDevice) != CAIRO_STATUS_SUCCESS) {
 #if ENABLE(TIZEN_DLOG_SUPPORT)
             TIZEN_LOGE("cairo_egl_device_create failed!\n");
 #endif
             return;
         }
 
-        cairo_gl_device_set_thread_aware(m_sharedCairoDevice, 0);
+        cairo_gl_device_set_thread_aware(g_sharedCairoDevice, 0);
     }
 #endif // ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
 }
@@ -211,13 +240,13 @@ ImageBuffer::ImageBuffer(const IntSize& size, float /* resolutionScale */, Color
     if (renderingMode == Accelerated || renderingMode == AcceleratedMemorySaving) {
         initializeEGL();
 
-        m_platformSurfaceID = XCreatePixmap(static_cast<Display*>(m_nativeDisplay), m_nativeWindow, size.width(), size.height(),
-                                            XDefaultDepth(static_cast<Display*>(m_nativeDisplay), DefaultScreen(static_cast<Display*>(m_nativeDisplay))));
+        m_platformSurfaceID = XCreatePixmap(static_cast<Display*>(g_canvasNativeDisplay), g_canvasNativeWindow, size.width(), size.height(),
+                                            XDefaultDepth(static_cast<Display*>(g_canvasNativeDisplay), DefaultScreen(static_cast<Display*>(g_canvasNativeDisplay))));
         // XCreatePixmap is asynchronous so we should make sure changes are flushed
         // before passing the pixmap handle to eglCreatePixmapSurface().
-        XFlush(static_cast<Display*>(m_nativeDisplay));
+        XFlush(static_cast<Display*>(g_canvasNativeDisplay));
 
-        m_eglSurface = eglCreatePixmapSurface(m_egl_display, m_egl_config, m_platformSurfaceID, 0);
+        m_eglSurface = eglCreatePixmapSurface(g_egl_display, g_egl_config, m_platformSurfaceID, 0);
         if (m_eglSurface == EGL_NO_SURFACE) {
 #if ENABLE(TIZEN_DLOG_SUPPORT)
             TIZEN_LOGE("eglCreatePixmapSurface() failed!\n");
@@ -225,14 +254,14 @@ ImageBuffer::ImageBuffer(const IntSize& size, float /* resolutionScale */, Color
             return;
         }
 
-        eglSwapInterval(m_egl_display, 0);
+        eglSwapInterval(g_egl_display, 0);
     }
 
 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING)
     if (m_isLockable || renderingMode == Unaccelerated)
         m_data.m_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size.width(), size.height());
     else {
-        m_data.m_surface = cairo_gl_surface_create_for_egl(static_cast<cairo_device_t*>(m_sharedCairoDevice), m_eglSurface, size.width(), size.height());
+        m_data.m_surface = cairo_gl_surface_create_for_egl(static_cast<cairo_device_t*>(g_sharedCairoDevice), m_eglSurface, size.width(), size.height());
         if (!setBindingTexture()) {
 #if ENABLE(TIZEN_DLOG_SUPPORT)
             TIZEN_LOGE("setBindingTexture() failed!\n");
@@ -288,7 +317,7 @@ ImageBuffer::~ImageBuffer()
         if (m_eglImage) {
             if (!eglDestroyImageKHR)
                 eglDestroyImageKHR = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
-            if (eglDestroyImageKHR(m_egl_display, m_eglImage) != EGL_TRUE) {
+            if (eglDestroyImageKHR(g_egl_display, m_eglImage) != EGL_TRUE) {
 #if ENABLE(TIZEN_DLOG_SUPPORT)
                 TIZEN_LOGE("eglDestroyImageKHR failed!\n");
 #endif
@@ -298,8 +327,8 @@ ImageBuffer::~ImageBuffer()
             glDeleteTextures(1, &m_bindingTexID);
 #endif
         if (m_eglSurface)
-            eglDestroySurface(m_egl_display, m_eglSurface);
-        XFreePixmap(static_cast<Display*>(m_nativeDisplay), m_platformSurfaceID);
+            eglDestroySurface(g_egl_display, m_eglSurface);
+        XFreePixmap(static_cast<Display*>(g_canvasNativeDisplay), m_platformSurfaceID);
     }
 #endif
 
@@ -337,7 +366,7 @@ bool ImageBuffer::setBindingTexture()
     }
 
     EGLint attr_pixmap[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
-    m_eglImage = eglCreateImageKHR(m_egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<EGLClientBuffer>(m_platformSurfaceID), attr_pixmap);
+    m_eglImage = eglCreateImageKHR(g_egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<EGLClientBuffer>(m_platformSurfaceID), attr_pixmap);
     if (!m_eglImage) {
 #if ENABLE(TIZEN_DLOG_SUPPORT)
         TIZEN_LOGE("cannot create egl image\n");
@@ -393,7 +422,7 @@ bool ImageBuffer::lockSurface() const
     if (!eglLockSurfaceKHR)
         eglLockSurfaceKHR = reinterpret_cast<PFNEGLLOCKSURFACEKHRPROC>(eglGetProcAddress("eglLockSurfaceKHR"));
 
-    if (eglLockSurfaceKHR(m_egl_display, m_eglSurface, lockAttrib) != EGL_TRUE) {
+    if (eglLockSurfaceKHR(g_egl_display, m_eglSurface, lockAttrib) != EGL_TRUE) {
 #if ENABLE(TIZEN_DLOG_SUPPORT)
         TIZEN_LOGE("eglLockSurfaceKHR failed!\n");
 #endif
@@ -408,7 +437,7 @@ bool ImageBuffer::unlockSurface() const
     if (!eglUnlockSurfaceKHR)
         eglUnlockSurfaceKHR = reinterpret_cast<PFNEGLUNLOCKSURFACEKHRPROC>(eglGetProcAddress("eglUnlockSurfaceKHR"));
 
-    if (eglUnlockSurfaceKHR(m_egl_display, m_eglSurface) != EGL_TRUE) {
+    if (eglUnlockSurfaceKHR(g_egl_display, m_eglSurface) != EGL_TRUE) {
 #if ENABLE(TIZEN_DLOG_SUPPORT)
         TIZEN_LOGE("eglUnlockSurfaceKHR failed!\n");
 #endif
@@ -421,7 +450,7 @@ bool ImageBuffer::unlockSurface() const
 PassRefPtr<cairo_surface_t> ImageBuffer::querySurface() const
 {
     int* bitmapPtr = 0;
-    if (eglQuerySurface(m_egl_display, m_eglSurface, EGL_BITMAP_POINTER_KHR, (EGLint*)&bitmapPtr) != EGL_TRUE) {
+    if (eglQuerySurface(g_egl_display, m_eglSurface, EGL_BITMAP_POINTER_KHR, (EGLint*)&bitmapPtr) != EGL_TRUE) {
 #if ENABLE(TIZEN_DLOG_SUPPORT)
         TIZEN_LOGE("eglQuerySurface failed!\n");
 #endif
@@ -429,7 +458,7 @@ PassRefPtr<cairo_surface_t> ImageBuffer::querySurface() const
     }
 
     int pitch = 0;
-    eglQuerySurface(m_egl_display, m_eglSurface, EGL_BITMAP_PITCH_KHR, static_cast<EGLint*>(&pitch));
+    eglQuerySurface(g_egl_display, m_eglSurface, EGL_BITMAP_PITCH_KHR, static_cast<EGLint*>(&pitch));
 
     return adoptRef(cairo_image_surface_create_for_data(reinterpret_cast<unsigned char*>(bitmapPtr), CAIRO_FORMAT_ARGB32, m_size.width(), m_size.height(), pitch));
 }
index af674d4..cd7cbf3 100644 (file)
 #include "config.h"
 #include "NativeImageCairo.h"
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+#include "ImageDecoder.h"
+#endif
+
 namespace WebCore {
 
 NativeImageCairo::NativeImageCairo()
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    : m_surface(0)
+    , m_glsurface(0)
+    , m_imageframe(0)
+    , m_surfaceType(NATIVE_NONE_SURFACE)
+#endif
 {
 }
 
 NativeImageCairo::NativeImageCairo(cairo_surface_t* surface)
     : m_surface(adoptRef(surface))
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    , m_glsurface(0)
+    , m_imageframe(0)
+    , m_surfaceType(NATIVE_IMAGE_SURFACE)
+#endif
 {
 }
 
@@ -47,4 +62,35 @@ NativeImageCairo::~NativeImageCairo()
 {
 }
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+void NativeImageCairo::setGLSurface(cairo_surface_t* surface)
+{
+    m_glsurface = adoptRef(surface);
+    m_surfaceType = NATIVE_GL_SURFACE;
+}
+
+void NativeImageCairo::setImageSurface(cairo_surface_t* surface)
+{
+    m_surface = adoptRef(surface);
+    m_surfaceType = NATIVE_IMAGE_SURFACE;
+}
+
+void NativeImageCairo::setImageFrame(void* imageframe)
+{
+    m_imageframe = imageframe;
+}
+
+void NativeImageCairo::addImageSurfaceFromData()
+{
+    ImageFrame* imageframe = static_cast<ImageFrame*>(m_imageframe);
+    imageframe->addImageSurfaceFromData(this);
+}
+
+void NativeImageCairo::addGLSurfaceFromData()
+{
+    ImageFrame* imageframe = static_cast<ImageFrame*>(m_imageframe);
+    imageframe->addGLSurfaceFromData(this);
+}
+#endif
+
 } // namespace WebCore
index 79dc1db..ac49780 100644 (file)
@@ -38,13 +38,34 @@ namespace WebCore {
 
 class NativeImageCairo {
 public:
+
+    typedef enum _native_image_type {
+        NATIVE_NONE_SURFACE,
+        NATIVE_IMAGE_SURFACE,
+        NATIVE_GL_SURFACE
+    } native_image_type;
+
     NativeImageCairo();
     ~NativeImageCairo();
     explicit NativeImageCairo(cairo_surface_t*);
     cairo_surface_t* surface () { return m_surface.get(); }
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    cairo_surface_t* glsurface() { return m_glsurface.get(); }
+    void setGLSurface(cairo_surface_t* surface);
+    void setImageSurface(cairo_surface_t* surface);
+    void setImageFrame(void* imageframe);
+    void addImageSurfaceFromData();
+    void addGLSurfaceFromData();
+    native_image_type surfaceType() { return m_surfaceType; }
+#endif
 
 private:
     RefPtr<cairo_surface_t> m_surface;
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    RefPtr<cairo_surface_t> m_glsurface;
+    void* m_imageframe;
+    native_image_type m_surfaceType;
+#endif
 };
 
 }
index 227a27b..a38e292 100644 (file)
@@ -34,7 +34,7 @@
 #include "OwnPtrCairo.h"
 #include "Pattern.h"
 #include <cairo.h>
-#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
+#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE) || ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
 #include <cairo-gl.h>
 #if ENABLE(TIZEN_CAIROGLES_IMAGE_AUTOSCALE)
 #define CAIRO_GL_SURFACE_MAX_WIDTH 4096
@@ -163,6 +163,9 @@ static void drawPatternToCairoContext(cairo_t* cr, cairo_pattern_t* pattern, con
 
 void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& srcRect, GraphicsContext* context)
 {
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    cairo_surface_type_t surfaceType = cairo_surface_get_type(cairo_get_target (cr()));
+#endif
 
 #if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
     RefPtr<cairo_surface_t> sourceImageSurface = NULL;
@@ -286,6 +289,34 @@ void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const
     float scaleX = srcRect.width() / destRect.width();
     float scaleY = srcRect.height() / destRect.height();
     cairo_surface_t* subSurface = 0;
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    float imageWidth;
+    float imageHeight;
+    if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_GL) {
+        imageWidth = cairo_gl_surface_get_width(surface);
+        imageHeight = cairo_gl_surface_get_height(surface);
+    } else {
+        imageWidth = cairo_image_surface_get_width(surface);
+        imageHeight = cairo_image_surface_get_height(surface);
+    }
+
+    if (surfaceType != CAIRO_SURFACE_TYPE_GL) {
+        if ((srcRect.width() < imageWidth || srcRect.height() < imageHeight)
+            && (srcRect.x() >= 0 && srcRect.x() < imageWidth && srcRect.y() >= 0 && srcRect.y() < imageHeight)
+            && floor(srcRect.x() + srcRect.width()) - ceil(srcRect.x()) >= 1
+            && floor(srcRect.y() + srcRect.height()) - ceil(srcRect.y()) >= 1) {
+            subSurface = cairo_surface_create_for_rectangle(surface, srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height());
+            pattern = adoptRef(cairo_pattern_create_for_surface(subSurface));
+            cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, 0, 0 };
+            cairo_pattern_set_matrix(pattern.get(), &matrix);
+        } else {
+            pattern = adoptRef(cairo_pattern_create_for_surface(surface));
+            cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, srcRect.x(), srcRect.y() };
+            cairo_pattern_set_matrix(pattern.get(), &matrix);
+        }
+    } else
+        pattern = adoptRef(cairo_pattern_create_for_surface(surface));
+#else
     float imageWidth = cairo_image_surface_get_width(surface);
     float imageHeight = cairo_image_surface_get_height(surface);
     if ((srcRect.width() < imageWidth || srcRect.height() < imageHeight)
@@ -302,6 +333,7 @@ void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const
         cairo_pattern_set_matrix(pattern.get(), &matrix);
     }
 #endif
+#endif
 #else
     RefPtr<cairo_pattern_t> pattern = adoptRef(cairo_pattern_create_for_surface(surface));
 #endif
@@ -334,7 +366,7 @@ void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const
 #endif
     cairo_pattern_set_matrix(pattern.get(), &matrix);
 #else
-#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
+#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE) ||ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
     if (surfaceType == CAIRO_SURFACE_TYPE_GL) {
         float scaleX = srcRect.width() / destRect.width();
         float scaleY = srcRect.height() / destRect.height();
@@ -361,8 +393,9 @@ void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const
     cairo_save(m_cr.get());
     drawPatternToCairoContext(m_cr.get(), pattern.get(), destRect, globalAlpha());
     cairo_restore(m_cr.get());
+
 #if ENABLE(TIZEN_ATLAS_IMAGE_BUG_FIX)
-#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE)
+#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE) || ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
     if (surfaceType != CAIRO_SURFACE_TYPE_GL) {
         if (subSurface)
             cairo_surface_destroy(subSurface);
index 520936d..7dd2e51 100644 (file)
 #include <algorithm>
 #include <cmath>
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+#include <cairo-gl.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#endif
+
 using namespace std;
 
 namespace WebCore {
@@ -138,14 +145,42 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaO
 
 #if !USE(SKIA)
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+static PFNEGLLOCKSURFACEKHRPROC eglLockSurfaceKHR = 0;
+static PFNEGLUNLOCKSURFACEKHRPROC eglUnlockSurfaceKHR = 0;
+static PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = 0;
+extern void* g_canvasNativeDisplay;
+extern int g_canvasNativeWindow;
+extern void* g_egl_display;
+extern void* g_egl_config;
+extern void* g_sharedCairoDevice;
+extern void* g_egl_context;
+#endif
+
 ImageFrame::ImageFrame()
     : m_hasAlpha(false)
     , m_status(FrameEmpty)
     , m_duration(0)
     , m_disposalMethod(DisposeNotSpecified)
     , m_premultiplyAlpha(true)
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    , m_nativeimage(0)
+    , m_eglSurface(0)
+    , m_eglImage(0)
+    , m_platformSurfaceID(0)
+    , m_tex(0)
+    , m_stride(0)
+    , m_lockstatus(false)
+#endif
 {
-} 
+}
+
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+ImageFrame::~ImageFrame()
+{
+    clearPlatformSurface();
+}
+#endif
 
 ImageFrame& ImageFrame::operator=(const ImageFrame& other)
 {
@@ -174,8 +209,21 @@ void ImageFrame::clearPixelData()
 
 void ImageFrame::zeroFillPixelData()
 {
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    bool prevLock = false;
+    if (m_lockstatus)
+        prevLock = true;
+    else
+        lockSurface();
+#endif
     memset(m_bytes, 0, m_size.width() * m_size.height() * sizeof(PixelData));
     m_hasAlpha = true;
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    if (prevLock)
+        return;
+    else
+        unlockSurface();
+#endif
 }
 
 bool ImageFrame::copyBitmapData(const ImageFrame& other)
@@ -184,12 +232,177 @@ bool ImageFrame::copyBitmapData(const ImageFrame& other)
         return true;
 
     m_backingStore = other.m_backingStore;
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    m_bytes = other.m_bytes;
+#else
     m_bytes = m_backingStore.data();
+#endif
     m_size = other.m_size;
     setHasAlpha(other.m_hasAlpha);
     return true;
 }
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+void ImageFrame::createCairoDevice()
+{
+    if (g_sharedCairoDevice)
+        return;
+
+    if (!g_canvasNativeDisplay) {
+        g_canvasNativeDisplay = XOpenDisplay(0);
+
+        g_canvasNativeWindow = XCreateSimpleWindow(static_cast<Display*>(g_canvasNativeDisplay), XDefaultRootWindow(static_cast<Display*>(g_canvasNativeDisplay)),
+                          0, 0, 1, 1, 0,
+                          BlackPixel(static_cast<Display*>(g_canvasNativeDisplay), 0), WhitePixel(static_cast<Display*>(g_canvasNativeDisplay), 0));
+
+        XFlush(static_cast<Display*>(g_canvasNativeDisplay));
+    }
+
+    EGLint major, minor;
+    EGLint ctxattr[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+        EGL_NONE
+    };
+
+    if (!g_egl_display) {
+        g_egl_display = eglGetDisplay(static_cast<NativeDisplayType>(g_canvasNativeDisplay));
+        if (g_egl_display == EGL_NO_DISPLAY)
+            return;
+
+        if (eglInitialize(g_egl_display, &major, &minor) != EGL_TRUE)
+            return;
+
+        EGLint num;
+        EGLint attr[] = {
+                EGL_RED_SIZE, 8,
+                EGL_GREEN_SIZE, 8,
+                EGL_BLUE_SIZE, 8,
+                EGL_ALPHA_SIZE, 8,
+                EGL_STENCIL_SIZE, 8,
+                EGL_DEPTH_SIZE, 8,
+                EGL_SAMPLES, 4,
+                EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                EGL_NONE
+        };
+
+        if (!eglChooseConfig(g_egl_display, attr, &g_egl_config, 1, &num))
+            return;
+    }
+
+    if (!g_sharedCairoDevice) {
+        g_egl_context = eglCreateContext(g_egl_display, g_egl_config, EGL_NO_CONTEXT, ctxattr);
+
+        if (g_egl_context == EGL_NO_CONTEXT)
+            return;
+        g_sharedCairoDevice = cairo_egl_device_create(g_egl_display, static_cast<EGLContext>(g_egl_context));
+
+        if (cairo_device_status(static_cast<cairo_device_t*>( g_sharedCairoDevice)) != CAIRO_STATUS_SUCCESS)
+            return;
+
+        cairo_gl_device_set_thread_aware(static_cast<cairo_device_t*>(g_sharedCairoDevice), 0);
+    }
+
+}
+
+bool ImageFrame::lockSurface()
+{
+    if (m_lockstatus)
+        return false;
+
+    EGLint lockAttrib[] = { EGL_LOCK_USAGE_HINT_KHR, EGL_WRITE_SURFACE_BIT_KHR|EGL_READ_SURFACE_BIT_KHR, EGL_NONE };
+    if (!eglLockSurfaceKHR)
+        eglLockSurfaceKHR = reinterpret_cast<PFNEGLLOCKSURFACEKHRPROC>(eglGetProcAddress("eglLockSurfaceKHR"));
+    if (eglLockSurfaceKHR(static_cast<EGLDisplay>(g_egl_display), static_cast<EGLSurface>(m_eglSurface), lockAttrib)!= EGL_TRUE)
+        return false;
+
+    m_lockstatus = true;
+    return true;
+}
+
+bool ImageFrame::unlockSurface()
+{
+    if (!m_lockstatus)
+        return false;
+
+    if (!eglUnlockSurfaceKHR)
+        eglUnlockSurfaceKHR = reinterpret_cast<PFNEGLUNLOCKSURFACEKHRPROC>(eglGetProcAddress("eglUnlockSurfaceKHR"));
+    if (eglUnlockSurfaceKHR(g_egl_display, m_eglSurface) != EGL_TRUE)
+        return false;
+
+    m_lockstatus = false;
+    return true;
+}
+
+void ImageFrame::setStride()
+{
+    if (!g_egl_display || !m_eglSurface)
+        return;
+
+    eglQuerySurface(g_egl_display, m_eglSurface, EGL_BITMAP_PITCH_KHR, static_cast<EGLint*>(&m_stride));
+    return;
+}
+
+bool ImageFrame::setSize(int newWidth, int newHeight, bool isGLTargetSurface)
+{
+    ASSERT(!width() && !height());
+    if (isGLTargetSurface && newWidth <= CAIRO_GL_SURFACE_MAX_WIDTH && newHeight <= CAIRO_GL_SURFACE_MAX_HEIGHT) {
+        EGLint num;
+        EGLint attr[] = {
+                EGL_RED_SIZE, 8,
+                EGL_GREEN_SIZE, 8,
+                EGL_BLUE_SIZE, 8,
+                EGL_ALPHA_SIZE, 8,
+                EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_LOCK_SURFACE_BIT_KHR,
+                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                EGL_NONE
+        };
+
+        if (!eglChooseConfig(g_egl_display, attr, &g_egl_config, 1, &num))
+            return false;
+
+        m_platformSurfaceID = XCreatePixmap(static_cast<Display*>(g_canvasNativeDisplay), g_canvasNativeWindow, newWidth, newHeight, XDefaultDepth(static_cast<Display*>(g_canvasNativeDisplay), DefaultScreen(static_cast<Display*>(g_canvasNativeDisplay))));
+
+        m_eglSurface = eglCreatePixmapSurface(g_egl_display, g_egl_config, m_platformSurfaceID, NULL);
+
+        lockSurface();
+        eglQuerySurface(g_egl_display, static_cast<EGLSurface>(m_eglSurface), EGL_BITMAP_POINTER_KHR, reinterpret_cast<EGLint*>(&m_bytes));
+        m_size = IntSize(newWidth, newHeight);
+
+        zeroFillPixelData();
+    } else {
+        size_t backingStoreSize = newWidth * newHeight;
+        if (!m_backingStore.tryReserveCapacity(backingStoreSize))
+            return false;
+        m_backingStore.resize(backingStoreSize);
+        m_bytes = m_backingStore.data();
+        m_size = IntSize(newWidth, newHeight);
+
+        zeroFillPixelData();
+    }
+
+    return true;
+}
+
+void ImageFrame::clearPlatformSurface()
+{
+    if (m_platformSurfaceID > 0) {
+        if (g_egl_display) {
+
+            eglDestroyImageKHR = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
+            eglDestroyImageKHR(g_egl_display, static_cast<EGLImageKHR>(m_eglImage));
+
+            if (m_tex)
+                glDeleteTextures(1, &m_tex);
+
+            if (m_eglSurface)
+                eglDestroySurface(g_egl_display, m_eglSurface);
+        }
+        XFreePixmap(static_cast<Display*>(g_canvasNativeDisplay), m_platformSurfaceID);
+    }
+}
+#endif
+
 bool ImageFrame::setSize(int newWidth, int newHeight)
 {
     ASSERT(!width() && !height());
index 0fb2459..f29aad0 100644 (file)
 #endif
 #endif
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+#define CAIRO_GL_SURFACE_MAX_WIDTH 4096
+#define CAIRO_GL_SURFACE_MAX_HEIGHT 4096
+#endif
+
 namespace WebCore {
 
     // ImageFrame represents the decoded image data.  This buffer is what all
@@ -81,6 +86,10 @@ namespace WebCore {
 
         ImageFrame();
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        ~ImageFrame();
+#endif
+
         ImageFrame(const ImageFrame& other) { operator=(other); }
 
         // For backends which refcount their data, this operator doesn't need to
@@ -114,12 +123,27 @@ namespace WebCore {
         // Allocates space for the pixel data.  Must be called before any pixels
         // are written.  Must only be called once.  Returns whether allocation
         // succeeded.
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        void createCairoDevice(void);
+        void clearPlatformSurface(void);
+        bool lockSurface(void);
+        bool unlockSurface(void);
+        bool setSize(int newWidth, int newHeight, bool isGLTargetSurface);
+#endif
         bool setSize(int newWidth, int newHeight);
 
         // Returns a caller-owned pointer to the underlying native image data.
         // (Actual use: This pointer will be owned by BitmapImage and freed in
         // FrameData::clear()).
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        NativeImagePtr asNewNativeImage();
+        NativeImagePtr asNewNativeImageForGL();
+        void addImageSurfaceFromData(NativeImagePtr nativeimage);
+        void addGLSurfaceFromData(NativeImagePtr nativeimage);
+        NativeImagePtr nativeImage() const { return m_nativeimage; }
+#else
         NativeImagePtr asNewNativeImage() const;
+#endif
 
         bool hasAlpha() const;
         const IntRect& originalFrameRect() const { return m_originalFrameRect; }
@@ -146,10 +170,22 @@ namespace WebCore {
 #if USE(SKIA)
             return m_bitmap.bitmap().getAddr32(x, y);
 #else
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+            if (m_stride)
+                return m_bytes + (y * (stride() / sizeof(PixelData))) + x;
+            else
+                return m_bytes + (y * width()) + x;
+#else
             return m_bytes + (y * width()) + x;
 #endif
+#endif
         }
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+       void setStride();
+       int stride() { return m_stride; }
+#endif
+
         // Use fix point multiplier instead of integer division or floating point math.
         // This multipler produces exactly the same result for all values in range 0 - 255.
         static const unsigned fixPointShift = 24;
@@ -200,6 +236,15 @@ namespace WebCore {
         // FIXME: Do we need m_colorProfile anymore?
         ColorProfile m_colorProfile;
 #endif
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        NativeImageCairo* m_nativeimage;
+        void* m_eglSurface; //EGLSurface
+        void* m_eglImage; //EGLImageKHR
+        int m_platformSurfaceID;
+        unsigned m_tex;
+        int m_stride;
+        bool m_lockstatus;
+#endif
         IntRect m_originalFrameRect; // This will always just be the entire
                                      // buffer except for GIF frames whose
                                      // original rect was smaller than the
@@ -226,6 +271,9 @@ namespace WebCore {
             , m_sizeAvailable(false)
             , m_maxNumPixels(-1)
             , m_isAllDataReceived(false)
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+            , m_isGLTargetSurface(false)
+#endif
 #if !ENABLE(TIZEN_JPEGIMAGE_DECODING_THREAD)
             , m_failed(false) { }
 #else
@@ -388,6 +436,9 @@ namespace WebCore {
 
         BinarySemaphore* imageSemaphore() { return m_imageSemaphore; }
 #endif
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        void setTargetType(bool isGLTargetSurface) { m_isGLTargetSurface = isGLTargetSurface; }
+#endif
 
     protected:
 #if ENABLE(TIZEN_IMAGE_DECODER_DOWN_SAMPLING) || ENABLE(TIZEN_JPEG_IMAGE_SCALE_DECODING)
@@ -411,6 +462,10 @@ namespace WebCore {
         bool m_premultiplyAlpha;
         bool m_ignoreGammaAndColorProfile;
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        bool m_isGLTargetSurface;
+#endif
+
     private:
         // Some code paths compute the size of the image as "width * height * 4"
         // and return it as a (signed) int.  Avoid overflow.
index 20a248c..b21caba 100644 (file)
@@ -81,8 +81,15 @@ ImageFrame* BMPImageDecoder::frameBufferAtIndex(size_t index)
     }
 
     ImageFrame* buffer = &m_frameBufferCache.first();
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    if (buffer->status() != ImageFrame::FrameComplete) {
+        decode(false);
+        buffer->unlockSurface();
+    }
+#else
     if (buffer->status() != ImageFrame::FrameComplete)
         decode(false);
+#endif
     return buffer;
 }
 
@@ -124,6 +131,9 @@ bool BMPImageDecoder::decodeHelper(bool onlySize)
     if (!m_frameBufferCache.isEmpty())
         m_reader->setBuffer(&m_frameBufferCache.first());
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    m_reader->setTargetType(m_isGLTargetSurface);
+#endif
     return m_reader->decodeBMP(onlySize);
 }
 
index 5c00553..45a10ec 100644 (file)
@@ -48,6 +48,9 @@ BMPImageReader::BMPImageReader(ImageDecoder* parent, size_t decodedAndHeaderOffs
     , m_seenNonZeroAlphaPixel(false)
     , m_seenZeroAlphaPixel(false)
     , m_andMaskState(usesAndMask ? NotYetDecoded : None)
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    , m_isGLTargetSurface(false)
+#endif
 {
     // Clue-in decodeBMP() that we need to detect the correct info header size.
     memset(&m_infoHeader, 0, sizeof(m_infoHeader));
@@ -78,7 +81,11 @@ bool BMPImageReader::decodeBMP(bool onlySize)
     // Initialize the framebuffer if needed.
     ASSERT(m_buffer);  // Parent should set this before asking us to decode!
     if (m_buffer->status() == ImageFrame::FrameEmpty) {
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        if (!m_buffer->setSize(m_parent->size().width(), m_parent->size().height(), m_isGLTargetSurface))
+#else
         if (!m_buffer->setSize(m_parent->size().width(), m_parent->size().height()))
+#endif
             return m_parent->setFailed(); // Unable to allocate.
         m_buffer->setStatus(ImageFrame::FramePartial);
         // setSize() calls eraseARGB(), which resets the alpha flag, so we force
index dfaa9ec..4a725a3 100644 (file)
@@ -76,6 +76,10 @@ namespace WebCore {
         // whether decoding succeeded.
         bool decodeBMP(bool onlySize);
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        void setTargetType(bool isGLTargetSurface) { m_isGLTargetSurface = isGLTargetSurface; }
+#endif
+
     private:
         // The various BMP compression types.  We don't currently decode all
         // these.
@@ -347,6 +351,10 @@ namespace WebCore {
         // header, thus doubling it).  This variable tracks whether we have such
         // a mask and if we've started decoding it yet.
         AndMaskState m_andMaskState;
+
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        bool m_isGLTargetSurface;
+#endif
     };
 
 } // namespace WebCore
index 417628d..10b4d84 100644 (file)
 
 #include <cairo.h>
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+#include <cairo-gl.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#endif
+
 namespace WebCore {
 
+extern void* g_egl_display;
+extern cairo_device_t* g_sharedCairoDevice;
+extern void* g_egl_context;
+
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+NativeImagePtr ImageFrame::asNewNativeImage()
+{
+    m_nativeimage = new NativeImageCairo(cairo_image_surface_create_for_data(
+        reinterpret_cast<unsigned char*>(const_cast<PixelData*>(m_bytes)),
+        CAIRO_FORMAT_ARGB32, width(), height(), m_stride ? stride() : width() * sizeof(PixelData)));
+
+    m_nativeimage->setImageFrame(this);
+
+    return m_nativeimage;
+}
+
+NativeImagePtr ImageFrame::asNewNativeImageForGL()
+{
+    if (width() > CAIRO_GL_SURFACE_MAX_WIDTH || height() > CAIRO_GL_SURFACE_MAX_HEIGHT) {
+        cairo_surface_t* imageSurface = cairo_image_surface_create_for_data(
+            reinterpret_cast<unsigned char*>(const_cast<PixelData*>(m_bytes)),
+            CAIRO_FORMAT_ARGB32, width(), height(), m_stride ? stride() : width() * sizeof(PixelData));
+
+        float scaleX = CAIRO_GL_SURFACE_MAX_WIDTH / static_cast<float>(width());
+        float scaleY = CAIRO_GL_SURFACE_MAX_HEIGHT / static_cast<float>(height());
+        RefPtr<cairo_surface_t> shrink_image = 0;
+        float scale = scaleX < scaleY ? scaleX : scaleY;
+
+        shrink_image = adoptRef(cairo_image_surface_create(cairo_image_surface_get_format(imageSurface),
+                                                  static_cast<int>(width() * scale), static_cast<int>(height() * scale)));
+        RefPtr<cairo_t> shrink_cr = adoptRef(cairo_create(shrink_image.get()));
+        cairo_scale(shrink_cr.get(), scale, scale);
+        cairo_set_source_surface(shrink_cr.get(), imageSurface, 0, 0);
+        cairo_set_operator(shrink_cr.get(), CAIRO_OPERATOR_SOURCE);
+        cairo_paint(shrink_cr.get());
+
+        cairo_content_t content = cairo_surface_get_content(shrink_image.get());
+        RefPtr<cairo_surface_t> glSurface = adoptRef(cairo_gl_surface_create(static_cast<cairo_device_t*>(g_sharedCairoDevice), content, cairo_image_surface_get_width(shrink_image.get()), cairo_image_surface_get_height(shrink_image.get())));
+
+        RefPtr<cairo_t> glSurface_cr = adoptRef(cairo_create(glSurface.get()));
+        cairo_set_source_surface(glSurface_cr.get(), shrink_image.get(), 0, 0);
+        cairo_paint(glSurface_cr.get());
+
+        m_nativeimage = new NativeImageCairo();
+        m_nativeimage->setGLSurface(cairo_surface_reference(glSurface.get()));
+        m_nativeimage->setImageFrame(this);
+
+        if (imageSurface) {
+            cairo_surface_destroy(imageSurface);
+            m_backingStore.clear();
+            m_bytes = 0;
+        }
+
+        return m_nativeimage;
+    }
+
+    if (eglGetCurrentSurface(EGL_DRAW) == 0 || eglGetCurrentContext() == 0)
+        eglMakeCurrent(g_egl_display, m_eglSurface, m_eglSurface, g_egl_context);
+
+    GLint boundTex;
+    glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTex);
+
+    if (m_stride) {
+        PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = 0;
+        PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = 0;
+
+        EGLint image_attrib[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+
+        eglCreateImageKHR = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
+        glEGLImageTargetTexture2DOES = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
+
+        m_eglImage = eglCreateImageKHR(g_egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<EGLClientBuffer>(m_platformSurfaceID), image_attrib);
+
+        glGenTextures(1, &m_tex);
+        glBindTexture(GL_TEXTURE_2D, m_tex);
+
+        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage);
+    } else {
+        glGenTextures(1, &m_tex);
+        glBindTexture(GL_TEXTURE_2D, m_tex);
+
+        glTexImage2D(GL_TEXTURE_2D, 0, 0x80E1, width(), height(), 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_bytes);
+    }
+
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+    glBindTexture(GL_TEXTURE_2D, boundTex);
+
+    cairo_surface_t* surface = cairo_gl_surface_create_for_texture(static_cast<cairo_device_t*>(g_sharedCairoDevice), CAIRO_CONTENT_COLOR_ALPHA, m_tex, width(), height());
+
+    m_nativeimage = new NativeImageCairo();
+    m_nativeimage->setGLSurface(surface);
+    m_nativeimage->setImageFrame(this);
+
+    return m_nativeimage;
+}
+
+void ImageFrame::addImageSurfaceFromData(NativeImagePtr nativeimage)
+{
+    cairo_surface_t* surface = cairo_image_surface_create_for_data(
+        reinterpret_cast<unsigned char*>(const_cast<PixelData*>(m_bytes)),
+        CAIRO_FORMAT_ARGB32, width(), height(), m_stride ? stride() : width() * sizeof(PixelData));
+
+    nativeimage->setImageSurface(surface);
+}
+
+void ImageFrame::addGLSurfaceFromData(NativeImagePtr nativeimage)
+{
+    //FIX ME : Add procedure to copy cpu memory to pixmap.
+
+    if (width() > CAIRO_GL_SURFACE_MAX_WIDTH || height() > CAIRO_GL_SURFACE_MAX_HEIGHT) {
+        cairo_surface_t* imageSurface = cairo_image_surface_create_for_data(
+            reinterpret_cast<unsigned char*>(const_cast<PixelData*>(m_bytes)),
+            CAIRO_FORMAT_ARGB32, width(), height(), m_stride ? stride() : width() * sizeof(PixelData));
+
+        float scaleX = CAIRO_GL_SURFACE_MAX_WIDTH / static_cast<float>(width());
+        float scaleY = CAIRO_GL_SURFACE_MAX_HEIGHT / static_cast<float>(height());
+        RefPtr<cairo_surface_t> shrink_image = 0;
+        float scale = scaleX < scaleY ? scaleX : scaleY;
+
+        shrink_image = adoptRef(cairo_image_surface_create(cairo_image_surface_get_format(imageSurface),
+                                                  static_cast<int>(width() * scale), static_cast<int>(height() * scale)));
+        RefPtr<cairo_t> shrink_cr = adoptRef(cairo_create(shrink_image.get()));
+        cairo_scale(shrink_cr.get(), scale, scale);
+        cairo_set_source_surface(shrink_cr.get(), imageSurface, 0, 0);
+        cairo_set_operator(shrink_cr.get(), CAIRO_OPERATOR_SOURCE);
+        cairo_paint(shrink_cr.get());
+
+        cairo_content_t content = cairo_surface_get_content(shrink_image.get());
+        RefPtr<cairo_surface_t> glSurface = adoptRef(cairo_gl_surface_create(static_cast<cairo_device_t*>(g_sharedCairoDevice), content, cairo_image_surface_get_width(shrink_image.get()), cairo_image_surface_get_height(shrink_image.get())));
+
+        RefPtr<cairo_t> glSurface_cr = adoptRef(cairo_create(glSurface.get()));
+        cairo_set_source_surface(glSurface_cr.get(), shrink_image.get(), 0, 0);
+        cairo_paint(glSurface_cr.get());
+
+        m_nativeimage->setGLSurface(cairo_surface_reference(glSurface.get()));
+        m_nativeimage->setImageFrame(this);
+
+        if (imageSurface) {
+            cairo_surface_destroy(imageSurface);
+            m_backingStore.clear();
+            m_bytes = 0;
+        }
+
+        return;
+    }
+
+    GLint boundTex;
+    glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTex);
+
+    if (m_stride) {
+        PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = 0;
+        PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = 0;
+
+        EGLint image_attrib[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+
+        eglCreateImageKHR = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
+        glEGLImageTargetTexture2DOES = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
+
+        m_eglImage = eglCreateImageKHR(g_egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<EGLClientBuffer>(m_platformSurfaceID), image_attrib);
+
+        glGenTextures(1, &m_tex);
+        glBindTexture(GL_TEXTURE_2D, m_tex);
+
+        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage);
+    } else {
+        glGenTextures(1, &m_tex);
+        glBindTexture(GL_TEXTURE_2D, m_tex);
+
+        glTexImage2D(GL_TEXTURE_2D, 0, 0x80E1, width(), height(), 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_bytes);
+    }
+
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+    glBindTexture(GL_TEXTURE_2D, boundTex);
+
+    cairo_surface_t* surface = cairo_gl_surface_create_for_texture(static_cast<cairo_device_t*>(g_sharedCairoDevice), CAIRO_CONTENT_COLOR_ALPHA, m_tex, width(), height());
+
+    m_nativeimage->setGLSurface(surface);
+}
+#else
 NativeImagePtr ImageFrame::asNewNativeImage() const
 {
     return new NativeImageCairo(cairo_image_surface_create_for_data(
         reinterpret_cast<unsigned char*>(const_cast<PixelData*>(m_bytes)),
         CAIRO_FORMAT_ARGB32, width(), height(), width() * sizeof(PixelData)));
 }
+#endif
 
 } // namespace WebCore
index 748f5bb..a989cb4 100644 (file)
@@ -130,8 +130,15 @@ ImageFrame* GIFImageDecoder::frameBufferAtIndex(size_t index)
         return 0;
 
     ImageFrame& frame = m_frameBufferCache[index];
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    if (frame.status() != ImageFrame::FrameComplete) {
+        decode(index + 1, GIFFullQuery);
+        frame.unlockSurface();
+    }
+#else
     if (frame.status() != ImageFrame::FrameComplete)
         decode(index + 1, GIFFullQuery);
+#endif
     return &frame;
 }
 
@@ -349,10 +356,14 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex)
     int top = upperBoundScaledY(frameRect.y());
     int bottom = lowerBoundScaledY(frameRect.maxY(), top);
     buffer->setOriginalFrameRect(IntRect(left, top, right - left, bottom - top));
-    
+
     if (!frameIndex) {
         // This is the first frame, so we're not relying on any previous data.
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        if (!buffer->setSize(scaledSize().width(), scaledSize().height(), m_isGLTargetSurface))
+#else
         if (!buffer->setSize(scaledSize().width(), scaledSize().height()))
+#endif
             return setFailed();
     } else {
         // The starting state for this frame depends on the previous frame's
index 3a03e54..9c7147c 100644 (file)
@@ -121,8 +121,15 @@ ImageFrame* ICOImageDecoder::frameBufferAtIndex(size_t index)
         return 0;
 
     ImageFrame* buffer = &m_frameBufferCache[index];
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    if (buffer->status() != ImageFrame::FrameComplete) {
+        decode(index, false);
+        buffer->unlockSurface();
+    }
+#else
     if (buffer->status() != ImageFrame::FrameComplete)
         decode(index, false);
+#endif
     return buffer;
 }
 
index 984c1a1..4f3e831 100644 (file)
@@ -550,8 +550,15 @@ ImageFrame* JPEGImageDecoder::frameBufferAtIndex(size_t index)
     }
 
     ImageFrame& frame = m_frameBufferCache[0];
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    if (frame.status() != ImageFrame::FrameComplete) {
+        decode(false);
+        frame.unlockSurface();
+    }
+#else
     if (frame.status() != ImageFrame::FrameComplete)
         decode(false);
+#endif
     return &frame;
 }
 
@@ -594,6 +601,19 @@ bool JPEGImageDecoder::outputScanlines(ImageFrame& buffer)
 
     int width = isScaled ? m_scaledColumns.size() : info->output_width;
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    // Set stride value to buffer. Now this image will be decoded
+    // properly on Xpixmap even if it has odd width.
+    buffer.setStride();
+
+    bool jumpLast = false;
+    int bufferStride = buffer.stride();
+    if (bufferStride && width != bufferStride / sizeof(unsigned)) {
+        jumpLast = true;
+        width = bufferStride / sizeof(unsigned);
+    }
+#endif
+
     while (info->output_scanline < info->output_height) {
         // jpeg_read_scanlines will increase the scanline counter, so we
         // save the scanline before calling it.
@@ -614,6 +634,10 @@ bool JPEGImageDecoder::outputScanlines(ImageFrame& buffer)
         ImageFrame::PixelData* currentAddress = buffer.getAddr(0, destY);
 
         for (int x = 0; x < width; ++x) {
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+            if (x == width - 1 && jumpLast)
+                continue;
+#endif
             setPixel<colorSpace>(buffer, currentAddress, samples, isScaled ? m_scaledColumns[x] : x);
             ++currentAddress;
         }
@@ -640,10 +664,18 @@ bool JPEGImageDecoder::outputScanlines()
     ImageFrame& buffer = m_frameBufferCache[0];
     if (buffer.status() == ImageFrame::FrameEmpty) {
 #if !ENABLE(TIZEN_JPEG_IMAGE_SCALE_DECODING)
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        if (!buffer.setSize(scaledSize().width(), scaledSize().height(), m_isGLTargetSurface))
+#else
         if (!buffer.setSize(scaledSize().width(), scaledSize().height()))
+#endif
+#else
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        if (!buffer.setSize(info->output_width, info->output_height, m_isGLTargetSurface))
 #else
         if (!buffer.setSize(info->output_width, info->output_height))
 #endif
+#endif
             return setFailed();
         buffer.setStatus(ImageFrame::FramePartial);
         // The buffer is transparent outside the decoded area while the image is
@@ -655,6 +687,12 @@ bool JPEGImageDecoder::outputScanlines()
         buffer.setOriginalFrameRect(IntRect(IntPoint(), size()));
     }
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    // Set stride value to buffer. Now this image will be decoded
+    // properly on Xpixmap even if it has odd width.
+    buffer.setStride();
+#endif
+
 #if !ENABLE(TIZEN_JPEG_IMAGE_SCALE_DECODING)
     jpeg_decompress_struct* info = m_reader->info();
 #endif
index 50b0a6d..a37077a 100644 (file)
@@ -261,8 +261,15 @@ ImageFrame* PNGImageDecoder::frameBufferAtIndex(size_t index)
     }
 
     ImageFrame& frame = m_frameBufferCache[0];
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    if (frame.status() != ImageFrame::FrameComplete) {
+        decode(false);
+        frame.unlockSurface();
+    }
+#else
     if (frame.status() != ImageFrame::FrameComplete)
         decode(false);
+#endif
     return &frame;
 }
 
@@ -410,11 +417,17 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
     ImageFrame& buffer = m_frameBufferCache[0];
     if (buffer.status() == ImageFrame::FrameEmpty) {
         png_structp png = m_reader->pngPtr();
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        if (!buffer.setSize(scaledSize().width(), scaledSize().height(), m_isGLTargetSurface)) {
+            longjmp(JMPBUF(png), 1);
+            return;
+        }
+#else
         if (!buffer.setSize(scaledSize().width(), scaledSize().height())) {
             longjmp(JMPBUF(png), 1);
             return;
         }
-
+#endif
         unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3;
         if (PNG_INTERLACE_ADAM7 == png_get_interlace_type(png, m_reader->infoPtr())) {
             m_reader->createInterlaceBuffer(colorChannels * size().width() * size().height());
@@ -497,13 +510,32 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
     }
 #endif
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    // Set stride value to buffer. Now this image will be decoded
+    // properly on Xpixmap even if it has odd width.
+    if (!buffer.stride())
+        buffer.setStride();
+#endif
+
     // Write the decoded row pixels to the frame buffer.
     int width = scaledSize().width();
     bool nonTrivialAlpha = false;
     ImageFrame::PixelData* currentAddress = buffer.getAddr(0, y);
 
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+    bool jumpLast = false;
+    int bufferStride = buffer.stride();
+    if (bufferStride && width != bufferStride / sizeof(unsigned)) {
+        jumpLast = true;
+        width = bufferStride / sizeof(unsigned);
+    }
+#endif
 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
     for (int x = 0; x < width; ++x) {
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        if (x == width - 1 && jumpLast)
+            continue;
+#endif
         png_bytep pixel = row + (m_scaled ? m_scaledColumns[x] : x) * colorChannels;
         unsigned alpha = hasAlpha ? pixel[3] : 255;
         buffer.setRGBA(currentAddress, pixel[0], pixel[1], pixel[2], alpha);
@@ -514,6 +546,10 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
     ASSERT(!m_scaled);
     png_bytep pixel = row;
     for (int x = 0; x < width; ++x, pixel += colorChannels) {
+#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE)
+        if (x == width - 1 && jumpLast)
+            continue;
+#endif
         unsigned alpha = hasAlpha ? pixel[3] : 255;
         buffer.setRGBA(currentAddress, pixel[0], pixel[1], pixel[2], alpha);
         nonTrivialAlpha |= alpha < 255;