From 4632663a6e31df9e1b76abe09d6c73c70f7d26ae Mon Sep 17 00:00:00 2001 From: Byeongha Cho Date: Fri, 29 Mar 2013 15:21:10 +0900 Subject: [PATCH] Apply platform surface to source surface of Canvas. [Title] Apply platform surface to source surface of Canvas. [Issue#] N/A [Problem] N/A [Cause] N/A [Solution] N/A Change-Id: I859f85c80bc15b2d6799b5eff475d55eb3ccb82c --- Source/WTF/wtf/Platform.h | 3 + Source/WebCore/platform/graphics/BitmapImage.cpp | 31 +++ Source/WebCore/platform/graphics/BitmapImage.h | 3 + Source/WebCore/platform/graphics/ImageBuffer.h | 7 +- Source/WebCore/platform/graphics/ImageSource.cpp | 14 ++ Source/WebCore/platform/graphics/ImageSource.h | 7 + .../platform/graphics/cairo/BitmapImageCairo.cpp | 98 +++++++++- .../platform/graphics/cairo/CairoUtilities.cpp | 4 +- .../platform/graphics/cairo/ImageBufferCairo.cpp | 101 ++++++---- .../platform/graphics/cairo/NativeImageCairo.cpp | 46 +++++ .../platform/graphics/cairo/NativeImageCairo.h | 21 ++ .../graphics/cairo/PlatformContextCairo.cpp | 39 +++- .../platform/image-decoders/ImageDecoder.cpp | 215 ++++++++++++++++++++- .../WebCore/platform/image-decoders/ImageDecoder.h | 55 ++++++ .../image-decoders/bmp/BMPImageDecoder.cpp | 10 + .../platform/image-decoders/bmp/BMPImageReader.cpp | 7 + .../platform/image-decoders/bmp/BMPImageReader.h | 8 + .../image-decoders/cairo/ImageDecoderCairo.cpp | 192 ++++++++++++++++++ .../image-decoders/gif/GIFImageDecoder.cpp | 13 +- .../image-decoders/ico/ICOImageDecoder.cpp | 7 + .../image-decoders/jpeg/JPEGImageDecoder.cpp | 38 ++++ .../image-decoders/png/PNGImageDecoder.cpp | 38 +++- 22 files changed, 900 insertions(+), 57 deletions(-) diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h index 64d7288..d600e7e 100644 --- a/Source/WTF/wtf/Platform.h +++ b/Source/WTF/wtf/Platform.h @@ -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 diff --git a/Source/WebCore/platform/graphics/BitmapImage.cpp b/Source/WebCore/platform/graphics/BitmapImage.cpp index 6e854ad..c33dc08 100644 --- a/Source/WebCore/platform/graphics/BitmapImage.cpp +++ b/Source/WebCore/platform/graphics/BitmapImage.cpp @@ -39,6 +39,10 @@ #include "cairo.h" #endif +#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE) +#include +#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; } diff --git a/Source/WebCore/platform/graphics/BitmapImage.h b/Source/WebCore/platform/graphics/BitmapImage.h index 58bf745..49f6148 100644 --- a/Source/WebCore/platform/graphics/BitmapImage.h +++ b/Source/WebCore/platform/graphics/BitmapImage.h @@ -321,6 +321,9 @@ protected: Mutex m_decodeMutex; Mutex m_clearMutex; #endif +#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE) + bool m_isGLTargetSurface; +#endif }; } diff --git a/Source/WebCore/platform/graphics/ImageBuffer.h b/Source/WebCore/platform/graphics/ImageBuffer.h index 6ac717e..8add808 100644 --- a/Source/WebCore/platform/graphics/ImageBuffer.h +++ b/Source/WebCore/platform/graphics/ImageBuffer.h @@ -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 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; diff --git a/Source/WebCore/platform/graphics/ImageSource.cpp b/Source/WebCore/platform/graphics/ImageSource.cpp index ab05b53..e5ac44b 100644 --- a/Source/WebCore/platform/graphics/ImageSource.cpp +++ b/Source/WebCore/platform/graphics/ImageSource.cpp @@ -34,6 +34,10 @@ #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(); } diff --git a/Source/WebCore/platform/graphics/ImageSource.h b/Source/WebCore/platform/graphics/ImageSource.h index 6b53cac..e85e608 100644 --- a/Source/WebCore/platform/graphics/ImageSource.h +++ b/Source/WebCore/platform/graphics/ImageSource.h @@ -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 }; } diff --git a/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp b/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp index 3ee7c1f..11f183f 100644 --- a/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp @@ -41,6 +41,13 @@ namespace WebCore { PassRefPtr 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(scaledSize.width()) / origSize.width(); + double rateHeight = static_cast(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(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(cairo_image_surface_get_data(imageSurface)); + m_solidColor = colorFromPremultipliedARGB(*pixelColor); + cairo_surface_unmap_image(surface, imageSurface); + } else { + pixelColor = reinterpret_cast(cairo_image_surface_get_data(surface)); + m_solidColor = colorFromPremultipliedARGB(*pixelColor); + } +#else unsigned* pixelColor = reinterpret_cast(cairo_image_surface_get_data(surface)); m_solidColor = colorFromPremultipliedARGB(*pixelColor); +#endif m_isSolidColor = true; } diff --git a/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp b/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp index 8f211a7..d4686b7 100644 --- a/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp +++ b/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp @@ -306,7 +306,7 @@ void drawPatternToCairoContext(cairo_t* cr, cairo_surface_t* image, const IntSiz RefPtr 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 copyCairoImageSurface(cairo_surface_t* originalSurfa // Once cairo provides the way, use the function instead of this. #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING) RefPtr 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); diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp index 298c8ef..0103a96 100755 --- a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp @@ -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(m_nativeDisplay), XDefaultRootWindow(static_cast(m_nativeDisplay)), + g_canvasNativeWindow = XCreateSimpleWindow(static_cast(g_canvasNativeDisplay), XDefaultRootWindow(static_cast(g_canvasNativeDisplay)), 0, 0, 1, 1, 0, - BlackPixel(static_cast(m_nativeDisplay), 0), WhitePixel(static_cast(m_nativeDisplay), 0)); + BlackPixel(static_cast(g_canvasNativeDisplay), 0), WhitePixel(static_cast(g_canvasNativeDisplay), 0)); - XFlush(static_cast(m_nativeDisplay)); + XFlush(static_cast(g_canvasNativeDisplay)); } EGLint major, minor; - if (!m_egl_display) { - m_egl_display = eglGetDisplay(static_cast(m_nativeDisplay)); - if (m_egl_display == EGL_NO_DISPLAY) { + if (!g_egl_display) { + g_egl_display = eglGetDisplay(static_cast(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(m_nativeDisplay), m_nativeWindow, size.width(), size.height(), - XDefaultDepth(static_cast(m_nativeDisplay), DefaultScreen(static_cast(m_nativeDisplay)))); + m_platformSurfaceID = XCreatePixmap(static_cast(g_canvasNativeDisplay), g_canvasNativeWindow, size.width(), size.height(), + XDefaultDepth(static_cast(g_canvasNativeDisplay), DefaultScreen(static_cast(g_canvasNativeDisplay)))); // XCreatePixmap is asynchronous so we should make sure changes are flushed // before passing the pixmap handle to eglCreatePixmapSurface(). - XFlush(static_cast(m_nativeDisplay)); + XFlush(static_cast(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(m_sharedCairoDevice), m_eglSurface, size.width(), size.height()); + m_data.m_surface = cairo_gl_surface_create_for_egl(static_cast(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(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(m_nativeDisplay), m_platformSurfaceID); + eglDestroySurface(g_egl_display, m_eglSurface); + XFreePixmap(static_cast(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(m_platformSurfaceID), attr_pixmap); + m_eglImage = eglCreateImageKHR(g_egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, reinterpret_cast(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(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(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 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 ImageBuffer::querySurface() const } int pitch = 0; - eglQuerySurface(m_egl_display, m_eglSurface, EGL_BITMAP_PITCH_KHR, static_cast(&pitch)); + eglQuerySurface(g_egl_display, m_eglSurface, EGL_BITMAP_PITCH_KHR, static_cast(&pitch)); return adoptRef(cairo_image_surface_create_for_data(reinterpret_cast(bitmapPtr), CAIRO_FORMAT_ARGB32, m_size.width(), m_size.height(), pitch)); } diff --git a/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp b/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp index af674d4..cd7cbf3 100644 --- a/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp @@ -32,14 +32,29 @@ #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(m_imageframe); + imageframe->addImageSurfaceFromData(this); +} + +void NativeImageCairo::addGLSurfaceFromData() +{ + ImageFrame* imageframe = static_cast(m_imageframe); + imageframe->addGLSurfaceFromData(this); +} +#endif + } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/cairo/NativeImageCairo.h b/Source/WebCore/platform/graphics/cairo/NativeImageCairo.h index 79dc1db..ac49780 100644 --- a/Source/WebCore/platform/graphics/cairo/NativeImageCairo.h +++ b/Source/WebCore/platform/graphics/cairo/NativeImageCairo.h @@ -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 m_surface; +#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE) + RefPtr m_glsurface; + void* m_imageframe; + native_image_type m_surfaceType; +#endif }; } diff --git a/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp b/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp index 227a27b..a38e292 100644 --- a/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp @@ -34,7 +34,7 @@ #include "OwnPtrCairo.h" #include "Pattern.h" #include -#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE) +#if ENABLE(TIZEN_CAIROGLES_IMAGE_CACHE) || ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE) #include #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 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 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); diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp index 520936d..7dd2e51 100644 --- a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp @@ -38,6 +38,13 @@ #include #include +#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE) +#include +#include +#include +#include +#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(g_canvasNativeDisplay), XDefaultRootWindow(static_cast(g_canvasNativeDisplay)), + 0, 0, 1, 1, 0, + BlackPixel(static_cast(g_canvasNativeDisplay), 0), WhitePixel(static_cast(g_canvasNativeDisplay), 0)); + + XFlush(static_cast(g_canvasNativeDisplay)); + } + + EGLint major, minor; + EGLint ctxattr[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + + if (!g_egl_display) { + g_egl_display = eglGetDisplay(static_cast(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(g_egl_context)); + + if (cairo_device_status(static_cast( g_sharedCairoDevice)) != CAIRO_STATUS_SUCCESS) + return; + + cairo_gl_device_set_thread_aware(static_cast(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(eglGetProcAddress("eglLockSurfaceKHR")); + if (eglLockSurfaceKHR(static_cast(g_egl_display), static_cast(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(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(&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(g_canvasNativeDisplay), g_canvasNativeWindow, newWidth, newHeight, XDefaultDepth(static_cast(g_canvasNativeDisplay), DefaultScreen(static_cast(g_canvasNativeDisplay)))); + + m_eglSurface = eglCreatePixmapSurface(g_egl_display, g_egl_config, m_platformSurfaceID, NULL); + + lockSurface(); + eglQuerySurface(g_egl_display, static_cast(m_eglSurface), EGL_BITMAP_POINTER_KHR, reinterpret_cast(&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(eglGetProcAddress("eglDestroyImageKHR")); + eglDestroyImageKHR(g_egl_display, static_cast(m_eglImage)); + + if (m_tex) + glDeleteTextures(1, &m_tex); + + if (m_eglSurface) + eglDestroySurface(g_egl_display, m_eglSurface); + } + XFreePixmap(static_cast(g_canvasNativeDisplay), m_platformSurfaceID); + } +} +#endif + bool ImageFrame::setSize(int newWidth, int newHeight) { ASSERT(!width() && !height()); diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.h b/Source/WebCore/platform/image-decoders/ImageDecoder.h index 0fb2459..f29aad0 100644 --- a/Source/WebCore/platform/image-decoders/ImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/ImageDecoder.h @@ -56,6 +56,11 @@ #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. diff --git a/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp b/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp index 20a248c..b21caba 100644 --- a/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp @@ -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); } diff --git a/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp b/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp index 5c00553..45a10ec 100644 --- a/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp +++ b/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp @@ -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 diff --git a/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h b/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h index dfaa9ec..4a725a3 100644 --- a/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h +++ b/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h @@ -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 diff --git a/Source/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp b/Source/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp index 417628d..10b4d84 100644 --- a/Source/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp +++ b/Source/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp @@ -28,13 +28,205 @@ #include +#if ENABLE(TIZEN_USE_XPIXMAP_DECODED_IMAGESOURCE) +#include +#include +#include +#include +#include +#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(const_cast(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(const_cast(m_bytes)), + CAIRO_FORMAT_ARGB32, width(), height(), m_stride ? stride() : width() * sizeof(PixelData)); + + float scaleX = CAIRO_GL_SURFACE_MAX_WIDTH / static_cast(width()); + float scaleY = CAIRO_GL_SURFACE_MAX_HEIGHT / static_cast(height()); + RefPtr shrink_image = 0; + float scale = scaleX < scaleY ? scaleX : scaleY; + + shrink_image = adoptRef(cairo_image_surface_create(cairo_image_surface_get_format(imageSurface), + static_cast(width() * scale), static_cast(height() * scale))); + RefPtr 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 glSurface = adoptRef(cairo_gl_surface_create(static_cast(g_sharedCairoDevice), content, cairo_image_surface_get_width(shrink_image.get()), cairo_image_surface_get_height(shrink_image.get()))); + + RefPtr 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(eglGetProcAddress("eglCreateImageKHR")); + glEGLImageTargetTexture2DOES = reinterpret_cast(eglGetProcAddress("glEGLImageTargetTexture2DOES")); + + m_eglImage = eglCreateImageKHR(g_egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, reinterpret_cast(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(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(const_cast(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(const_cast(m_bytes)), + CAIRO_FORMAT_ARGB32, width(), height(), m_stride ? stride() : width() * sizeof(PixelData)); + + float scaleX = CAIRO_GL_SURFACE_MAX_WIDTH / static_cast(width()); + float scaleY = CAIRO_GL_SURFACE_MAX_HEIGHT / static_cast(height()); + RefPtr shrink_image = 0; + float scale = scaleX < scaleY ? scaleX : scaleY; + + shrink_image = adoptRef(cairo_image_surface_create(cairo_image_surface_get_format(imageSurface), + static_cast(width() * scale), static_cast(height() * scale))); + RefPtr 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 glSurface = adoptRef(cairo_gl_surface_create(static_cast(g_sharedCairoDevice), content, cairo_image_surface_get_width(shrink_image.get()), cairo_image_surface_get_height(shrink_image.get()))); + + RefPtr 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(eglGetProcAddress("eglCreateImageKHR")); + glEGLImageTargetTexture2DOES = reinterpret_cast(eglGetProcAddress("glEGLImageTargetTexture2DOES")); + + m_eglImage = eglCreateImageKHR(g_egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, reinterpret_cast(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(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(const_cast(m_bytes)), CAIRO_FORMAT_ARGB32, width(), height(), width() * sizeof(PixelData))); } +#endif } // namespace WebCore diff --git a/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp index 748f5bb..a989cb4 100644 --- a/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp @@ -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 diff --git a/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp b/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp index 3a03e54..9c7147c 100644 --- a/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp @@ -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; } diff --git a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp index 984c1a1..4f3e831 100644 --- a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp @@ -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(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 diff --git a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp index 50b0a6d..a37077a 100644 --- a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp @@ -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; -- 2.7.4