15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 2591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * Copyright (c) 2008, Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 4591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 7591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * modification, are permitted provided that the following conditions are 8591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * met: 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 10591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * * Redistributions of source code must retain the above copyright 11591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * notice, this list of conditions and the following disclaimer. 12591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * * Redistributions in binary form must reproduce the above 13591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * copyright notice, this list of conditions and the following disclaimer 14591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * in the documentation and/or other materials provided with the 15591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * distribution. 16591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * * Neither the name of Google Inc. nor the names of its 17591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * contributors may be used to endorse or promote products derived from 18591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * this software without specific prior written permission. 19591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * 20591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 34a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/ImageBuffer.h" 35a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 36323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#include "GrContext.h" 3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/MIMETypeRegistry.h" 381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/IntRect.h" 39a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/BitmapImage.h" 40a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContext.h" 4109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/graphics/GraphicsTypes3D.h" 42aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch#include "platform/graphics/ImageBufferClient.h" 43a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/UnacceleratedImageBufferSurface.h" 44a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/gpu/DrawingBuffer.h" 4509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/graphics/gpu/Extensions3DUtil.h" 46a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/skia/NativeImageSkia.h" 47a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/skia/SkiaUtils.h" 48a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/image-encoders/skia/JPEGImageEncoder.h" 49a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/image-encoders/skia/PNGImageEncoder.h" 50a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/image-encoders/skia/WEBPImageEncoder.h" 51591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "public/platform/Platform.h" 5243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)#include "public/platform/WebExternalTextureMailbox.h" 5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/WebGraphicsContext3D.h" 5409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/WebGraphicsContext3DProvider.h" 55c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "third_party/skia/include/core/SkPicture.h" 56c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "third_party/skia/include/effects/SkTableColorFilter.h" 57591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/MathExtras.h" 58c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "wtf/Vector.h" 59591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/text/Base64.h" 60591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/text/WTFString.h" 61591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 62c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 64a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)PassOwnPtr<ImageBuffer> ImageBuffer::create(PassOwnPtr<ImageBufferSurface> surface) 65591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 66a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!surface->isValid()) 67591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return nullptr; 68a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return adoptPtr(new ImageBuffer(surface)); 69591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 70591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 71a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)PassOwnPtr<ImageBuffer> ImageBuffer::create(const IntSize& size, OpacityMode opacityMode) 7251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 73a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBufferSurface> surface = adoptPtr(new UnacceleratedImageBufferSurface(size, opacityMode)); 74a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!surface->isValid()) 7551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return nullptr; 76a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return adoptPtr(new ImageBuffer(surface.release())); 77591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 78591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 79a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)ImageBuffer::ImageBuffer(PassOwnPtr<ImageBufferSurface> surface) 80a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) : m_surface(surface) 81aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch , m_client(0) 82591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 83a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (m_surface->canvas()) { 84a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_context = adoptPtr(new GraphicsContext(m_surface->canvas())); 85a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_context->setCertainlyOpaque(m_surface->opacityMode() == Opaque); 86a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_context->setAccelerated(m_surface->isAccelerated()); 8751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 88c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_surface->setImageBuffer(this); 89591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 90591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 91591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochImageBuffer::~ImageBuffer() 92591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 93591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 94591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 95591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochGraphicsContext* ImageBuffer::context() const 96591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 97aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch if (!isSurfaceValid()) 98aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch return 0; 9909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT(m_context.get()); 100591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return m_context.get(); 101591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 102591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)const SkBitmap& ImageBuffer::bitmap() const 10409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return m_surface->bitmap(); 10609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 107fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch 108aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochbool ImageBuffer::isSurfaceValid() const 109fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch{ 110a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return m_surface->isValid(); 111fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch} 112fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch 113c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool ImageBuffer::isDirty() 114aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch{ 115c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return m_client ? m_client->isDirty() : false; 116aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch} 117aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch 118c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void ImageBuffer::didFinalizeFrame() 119aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch{ 120aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch if (m_client) 121c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_client->didFinalizeFrame(); 122aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch} 123aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch 1247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid ImageBuffer::finalizeFrame(const FloatRect &dirtyRect) 125c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 1267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_surface->finalizeFrame(dirtyRect); 127c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) didFinalizeFrame(); 128c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 129c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 130c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool ImageBuffer::restoreSurface() const 131c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 132c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return m_surface->isValid() || m_surface->restore(); 133c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 134c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 135c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void ImageBuffer::notifySurfaceInvalid() 136197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 137197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (m_client) 138c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_client->notifySurfaceInvalid(); 139197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 140197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 141591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic SkBitmap deepSkBitmapCopy(const SkBitmap& bitmap) 142591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 143591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SkBitmap tmp; 144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!bitmap.deepCopyTo(&tmp)) 145d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) bitmap.copyTo(&tmp, bitmap.colorType()); 146591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 147591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return tmp; 148591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 149591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 150591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochPassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBehavior) const 151591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 152aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch if (!isSurfaceValid()) 153fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch return BitmapImage::create(NativeImageSkia::create()); 154fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch 155a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) const SkBitmap& bitmap = m_surface->bitmap(); 156a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return BitmapImage::create(NativeImageSkia::create(copyBehavior == CopyBackingStore ? deepSkBitmapCopy(bitmap) : bitmap)); 157591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 158591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 159591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochBackingStoreCopy ImageBuffer::fastCopyImageMode() 160591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 161591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return DontCopyBackingStore; 162591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 163591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 164e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)WebLayer* ImageBuffer::platformLayer() const 165591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 166a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return m_surface->layer(); 167591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 168591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 169e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)bool ImageBuffer::copyToPlatformTexture(WebGraphicsContext3D* context, Platform3DObject texture, GLenum internalFormat, GLenum destType, GLint level, bool premultiplyAlpha, bool flipY) 170591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 1717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!m_surface->isAccelerated() || !getBackingTexture() || !isSurfaceValid()) 172591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return false; 173591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 17443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(internalFormat, destType, level)) 175591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return false; 176591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 177e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) OwnPtr<WebGraphicsContext3DProvider> provider = adoptPtr(Platform::current()->createSharedOffscreenGraphicsContext3DProvider()); 17843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) if (!provider) 17943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) return false; 180e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) WebGraphicsContext3D* sharedContext = provider->context3d(); 1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!sharedContext) 18243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) return false; 18343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 184e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) OwnPtr<WebExternalTextureMailbox> mailbox = adoptPtr(new WebExternalTextureMailbox); 18543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 18643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) // Contexts may be in a different share group. We must transfer the texture through a mailbox first 18743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) sharedContext->genMailboxCHROMIUM(mailbox->name); 1885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) sharedContext->produceTextureDirectCHROMIUM(getBackingTexture(), GL_TEXTURE_2D, mailbox->name); 18943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) sharedContext->flush(); 19043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 19143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) mailbox->syncPoint = sharedContext->insertSyncPoint(); 19243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 19343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) context->waitSyncPoint(mailbox->syncPoint); 1945d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) Platform3DObject sourceTexture = context->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox->name); 19543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 196591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // The canvas is stored in a premultiplied format, so unpremultiply if necessary. 19709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, !premultiplyAlpha); 198591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 199591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // The canvas is stored in an inverted position, so the flip semantics are reversed. 20009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, !flipY); 20143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) context->copyTextureCHROMIUM(GL_TEXTURE_2D, sourceTexture, texture, level, internalFormat, destType); 202591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 20309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, false); 20409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false); 20543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 20643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) context->deleteTexture(sourceTexture); 20743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 20809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) context->flush(); 20943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) sharedContext->waitSyncPoint(context->insertSyncPoint()); 21043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) 211323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // Undo grContext texture binding changes introduced in this function 212323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) provider->grContext()->resetContext(kTextureBinding_GrGLBackendState); 213323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 214591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return true; 215591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 216591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 217591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic bool drawNeedsCopy(GraphicsContext* src, GraphicsContext* dst) 218591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 219a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ASSERT(dst); 220591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return (src == dst); 221591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 222591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 22351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)Platform3DObject ImageBuffer::getBackingTexture() 22451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 225a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return m_surface->getBackingTexture(); 22651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 22751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 2287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid ImageBuffer::didModifyBackingTexture() 2297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 2307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_surface->didModifyBackingTexture(); 2317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 2327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2335d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)bool ImageBuffer::copyRenderingResultsFromDrawingBuffer(DrawingBuffer* drawingBuffer, bool fromFrontBuffer) 23451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 23551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (!drawingBuffer) 23651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return false; 237e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) OwnPtr<WebGraphicsContext3DProvider> provider = adoptPtr(Platform::current()->createSharedOffscreenGraphicsContext3DProvider()); 23809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!provider) 23909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return false; 240e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) WebGraphicsContext3D* context3D = provider->context3d(); 241a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) Platform3DObject tex = m_surface->getBackingTexture(); 24251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (!context3D || !tex) 24351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return false; 2445d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 24509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_surface->invalidateCachedBitmap(); 2467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci bool result = drawingBuffer->copyToPlatformTexture(context3D, tex, GL_RGBA, 2475d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) GL_UNSIGNED_BYTE, 0, true, false, fromFrontBuffer); 2487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (result) { 2507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_surface->didModifyBackingTexture(); 2517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 2527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return result; 25451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 25551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 256c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void ImageBuffer::draw(GraphicsContext* context, const FloatRect& destRect, const FloatRect* srcPtr, CompositeOperator op, WebBlendMode blendMode) 257591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 258aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch if (!isSurfaceValid()) 259fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch return; 260fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch 261f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu FloatRect srcRect = srcPtr ? *srcPtr : FloatRect(FloatPoint(), size()); 262c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) RefPtr<SkPicture> picture = m_surface->getPicture(); 263c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (picture) { 264c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) context->drawPicture(picture.release(), destRect, srcRect, op, blendMode); 265c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return; 266c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 267c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 26809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SkBitmap bitmap = m_surface->bitmap(); 26909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // For ImageBufferSurface that enables cachedBitmap, Use the cached Bitmap for CPU side usage 27009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // if it is available, otherwise generate and use it. 271aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch if (!context->isAccelerated() && m_surface->isAccelerated() && m_surface->cachedBitmapEnabled() && isSurfaceValid()) { 27209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_surface->updateCachedBitmapIfNeeded(); 27309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) bitmap = m_surface->cachedBitmap(); 27409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 27509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 276591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsCopy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); 27709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 278c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) context->drawImage(image.get(), destRect, srcRect, op, blendMode, DoNotRespectImageOrientation); 279591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 280591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 281a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void ImageBuffer::flush() 282a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){ 283a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (m_surface->canvas()) { 284a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_surface->canvas()->flush(); 285a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 286a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)} 287a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 288591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const FloatSize& scale, 289e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect, WebBlendMode blendMode, const IntSize& repeatSpacing) 290591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 291aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch if (!isSurfaceValid()) 292fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch return; 293fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch 294a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) const SkBitmap& bitmap = m_surface->bitmap(); 295591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsCopy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); 2961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) image->drawPattern(context, srcRect, scale, phase, op, destRect, blendMode, repeatSpacing); 297591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 298591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 299591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace) 300591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 30109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const uint8_t* lookUpTable = ColorSpaceUtilities::getConversionLUT(dstColorSpace, srcColorSpace); 30209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!lookUpTable) 303591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return; 304591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 305591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // FIXME: Disable color space conversions on accelerated canvases (for now). 306aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch if (context()->isAccelerated() || !isSurfaceValid()) 307591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return; 308591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 309a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) const SkBitmap& bitmap = m_surface->bitmap(); 310591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (bitmap.isNull()) 311591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return; 312591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 313197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(bitmap.colorType() == kN32_SkColorType); 314a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) IntSize size = m_surface->size(); 315591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SkAutoLockPixels bitmapLock(bitmap); 316a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) for (int y = 0; y < size.height(); ++y) { 317591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch uint32_t* srcRow = bitmap.getAddr32(0, y); 318a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) for (int x = 0; x < size.width(); ++x) { 319591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SkColor color = SkPMColorToColor(srcRow[x]); 320591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch srcRow[x] = SkPreMultiplyARGB( 321591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SkColorGetA(color), 322591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lookUpTable[SkColorGetR(color)], 323591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lookUpTable[SkColorGetG(color)], 324591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch lookUpTable[SkColorGetB(color)]); 325591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 326591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 327591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 328591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 329c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)PassRefPtr<SkColorFilter> ImageBuffer::createColorSpaceFilter(ColorSpace srcColorSpace, 330c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) ColorSpace dstColorSpace) 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 33209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const uint8_t* lut = ColorSpaceUtilities::getConversionLUT(dstColorSpace, srcColorSpace); 33309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!lut) 334d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 3355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 336c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return adoptRef(SkTableColorFilter::CreateARGB(0, lut, lut, lut)); 337c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)} 338591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 339197021e6b966cfb06891637935ef33fff06433d1Ben MurdochPassRefPtr<Uint8ClampedArray> ImageBuffer::getImageData(Multiply multiplied, const IntRect& rect) const 3405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){ 341197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!isSurfaceValid()) 342197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return Uint8ClampedArray::create(rect.width() * rect.height() * 4); 343197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 344591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch float area = 4.0f * rect.width() * rect.height(); 345591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (area > static_cast<float>(std::numeric_limits<int>::max())) 346d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 348591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch RefPtr<Uint8ClampedArray> result = Uint8ClampedArray::createUninitialized(rect.width() * rect.height() * 4); 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 350591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (rect.x() < 0 351591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch || rect.y() < 0 352197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch || rect.maxX() > m_surface->size().width() 353197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch || rect.maxY() > m_surface->size().height()) 354591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch result->zeroFill(); 355591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 35607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch SkAlphaType alphaType = (multiplied == Premultiplied) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType; 35707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch SkImageInfo info = SkImageInfo::Make(rect.width(), rect.height(), kRGBA_8888_SkColorType, alphaType); 358591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 359e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) m_surface->willAccessPixels(); 360197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch context()->readPixels(info, result->data(), 4 * rect.width(), rect.x(), rect.y()); 361591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return result.release(); 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 364a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint) 365591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 366aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch if (!isSurfaceValid()) 367fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch return; 368fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch 369591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(sourceRect.width() > 0); 370591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(sourceRect.height() > 0); 371591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 372591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int originX = sourceRect.x(); 373591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int destX = destPoint.x() + sourceRect.x(); 374591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(destX >= 0); 375a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ASSERT(destX < m_surface->size().width()); 376591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(originX >= 0); 377591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(originX < sourceRect.maxX()); 378591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 379591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int originY = sourceRect.y(); 380591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int destY = destPoint.y() + sourceRect.y(); 381591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(destY >= 0); 382a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ASSERT(destY < m_surface->size().height()); 383591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(originY >= 0); 384591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(originY < sourceRect.maxY()); 385591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 386d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const size_t srcBytesPerRow = 4 * sourceSize.width(); 387d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const void* srcAddr = source->data() + originY * srcBytesPerRow + originX * 4; 388197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch SkAlphaType alphaType = (multiplied == Premultiplied) ? kPremul_SkAlphaType : kUnpremul_SkAlphaType; 389d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) SkImageInfo info = SkImageInfo::Make(sourceRect.width(), sourceRect.height(), kRGBA_8888_SkColorType, alphaType); 390591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 391e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) m_surface->willAccessPixels(); 392e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) 393d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) context()->writePixels(info, srcAddr, srcBytesPerRow, destX, destY); 394591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 395591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 396591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochtemplate <typename T> 397591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic bool encodeImage(T& source, const String& mimeType, const double* quality, Vector<char>* output) 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 399591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch Vector<unsigned char>* encodedImage = reinterpret_cast<Vector<unsigned char>*>(output); 400591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 401591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (mimeType == "image/jpeg") { 402591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int compressionQuality = JPEGImageEncoder::DefaultCompressionQuality; 403591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (quality && *quality >= 0.0 && *quality <= 1.0) 404591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch compressionQuality = static_cast<int>(*quality * 100 + 0.5); 405591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!JPEGImageEncoder::encode(source, compressionQuality, encodedImage)) 406591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return false; 407591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } else if (mimeType == "image/webp") { 408591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int compressionQuality = WEBPImageEncoder::DefaultCompressionQuality; 409591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (quality && *quality >= 0.0 && *quality <= 1.0) 410591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch compressionQuality = static_cast<int>(*quality * 100 + 0.5); 411591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!WEBPImageEncoder::encode(source, compressionQuality, encodedImage)) 412591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return false; 413591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } else { 414591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!PNGImageEncoder::encode(source, encodedImage)) 415591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return false; 416591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(mimeType == "image/png"); 417591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 418591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 419591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return true; 420591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 421591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 422a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)String ImageBuffer::toDataURL(const String& mimeType, const double* quality) const 423591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 424591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); 425591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 426591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch Vector<char> encodedImage; 427aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch if (!isSurfaceValid() || !encodeImage(m_surface->bitmap(), mimeType, quality, &encodedImage)) 428591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return "data:,"; 429591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 4307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return "data:" + mimeType + ";base64," + base64Encode(encodedImage); 431591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 432591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 43351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)String ImageDataToDataURL(const ImageDataBuffer& imageData, const String& mimeType, const double* quality) 434591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 435591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); 436591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 437591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch Vector<char> encodedImage; 438591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (!encodeImage(imageData, mimeType, quality, &encodedImage)) 439591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return "data:,"; 440591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 4417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return "data:" + mimeType + ";base64," + base64Encode(encodedImage); 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 444c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 445