/* Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "ShareableSurface.h" #include "CoordinatedGraphicsArgumentCoders.h" #include "GraphicsContext.h" #include "WebCoreArgumentCoders.h" #include #if USE(TEXTURE_MAPPER) #include "TextureMapperGL.h" #endif using namespace WebCore; namespace WebKit { ShareableSurface::Handle::Handle() { } void ShareableSurface::Handle::encode(CoreIPC::ArgumentEncoder& encoder) const { encoder.encode(m_size); encoder.encode(m_flags); #if USE(GRAPHICS_SURFACE) encoder.encode(m_graphicsSurfaceToken); if (m_graphicsSurfaceToken.isValid()) return; #endif encoder.encode(m_bitmapHandle); } bool ShareableSurface::Handle::decode(CoreIPC::ArgumentDecoder* decoder, Handle& handle) { if (!decoder->decode(handle.m_size)) return false; if (!decoder->decode(handle.m_flags)) return false; #if USE(GRAPHICS_SURFACE) if (!decoder->decode(handle.m_graphicsSurfaceToken)) return false; if (handle.m_graphicsSurfaceToken.isValid()) return true; #endif if (!decoder->decode(handle.m_bitmapHandle)) return false; return true; } PassRefPtr ShareableSurface::create(const IntSize& size, ShareableBitmap::Flags flags, Hints hints) { #if USE(GRAPHICS_SURFACE) if (hints & SupportsGraphicsSurface) { RefPtr surface = createWithSurface(size, flags); if (surface) return surface.release(); } #endif UNUSED_PARAM(hints); return create(size, flags, ShareableBitmap::createShareable(size, flags)); } #if USE(GRAPHICS_SURFACE) PassRefPtr ShareableSurface::createWithSurface(const IntSize& size, ShareableBitmap::Flags flags) { GraphicsSurface::Flags surfaceFlags = GraphicsSurface::SupportsSoftwareWrite | GraphicsSurface::SupportsCopyToTexture | GraphicsSurface::SupportsSharing; if (flags & ShareableBitmap::SupportsAlpha) surfaceFlags |= GraphicsSurface::SupportsAlpha; // This might return null, if the system is unable to provide a new graphics surface. // In that case, this function would return null and allow falling back to ShareableBitmap. RefPtr surface = GraphicsSurface::create(size, surfaceFlags); if (!surface) return 0; ASSERT(surface); return adoptRef(new ShareableSurface(size, flags, surface.release())); } #endif PassOwnPtr ShareableSurface::createGraphicsContext(const IntRect& rect) { #if USE(GRAPHICS_SURFACE) if (isBackedByGraphicsSurface()) return m_graphicsSurface->beginPaint(rect, 0 /* Write without retaining pixels*/); #endif ASSERT(m_bitmap); OwnPtr graphicsContext = m_bitmap->createGraphicsContext(); graphicsContext->clip(rect); graphicsContext->translate(rect.x(), rect.y()); return graphicsContext.release(); } PassRefPtr ShareableSurface::create(const IntSize& size, ShareableBitmap::Flags flags, PassRefPtr bitmap) { return adoptRef(new ShareableSurface(size, flags, bitmap)); } ShareableSurface::ShareableSurface(const IntSize& size, ShareableBitmap::Flags flags, PassRefPtr bitmap) : m_size(size) , m_flags(flags) , m_bitmap(bitmap) { } #if USE(GRAPHICS_SURFACE) ShareableSurface::ShareableSurface(const WebCore::IntSize& size, ShareableBitmap::Flags flags, PassRefPtr surface) : m_size(size) , m_flags(flags) , m_graphicsSurface(surface) { } PassRefPtr ShareableSurface::create(const IntSize& size, ShareableBitmap::Flags flags, PassRefPtr surface) { return adoptRef(new ShareableSurface(size, flags, surface)); } #endif ShareableSurface::~ShareableSurface() { } PassRefPtr ShareableSurface::create(const Handle& handle) { #if USE(GRAPHICS_SURFACE) if (handle.graphicsSurfaceToken().isValid()) { RefPtr surface = GraphicsSurface::create(handle.m_size, handle.m_flags, handle.m_graphicsSurfaceToken); if (surface) return adoptRef(new ShareableSurface(handle.m_size, handle.m_flags, PassRefPtr(surface))); } #endif RefPtr bitmap = ShareableBitmap::create(handle.m_bitmapHandle); if (!bitmap) return 0; return create(handle.m_size, handle.m_flags, bitmap.release()); } bool ShareableSurface::createHandle(Handle& handle) { handle.m_size = m_size; handle.m_flags = m_flags; #if USE(GRAPHICS_SURFACE) handle.m_graphicsSurfaceToken = m_graphicsSurface ? m_graphicsSurface->exportToken() : GraphicsSurfaceToken(); if (handle.m_graphicsSurfaceToken.isValid()) return true; #endif if (!m_bitmap->createHandle(handle.m_bitmapHandle)) return false; return true; } #if USE(TEXTURE_MAPPER) void ShareableSurface::copyToTexture(PassRefPtr passTexture, const IntRect& target, const IntPoint& sourceOffset) { RefPtr texture(passTexture); #if USE(GRAPHICS_SURFACE) if (isBackedByGraphicsSurface()) { RefPtr textureGL = toBitmapTextureGL(texture.get()); if (textureGL) { uint32_t textureID = textureGL->id(); uint32_t textureTarget = textureGL->textureTarget(); m_graphicsSurface->copyToGLTexture(textureTarget, textureID, target, sourceOffset); return; } RefPtr image = m_graphicsSurface->createReadOnlyImage(IntRect(sourceOffset, target.size())); texture->updateContents(image.get(), target, IntPoint::zero(), BitmapTexture::UpdateCanModifyOriginalImageData); } #endif ASSERT(m_bitmap); RefPtr image = m_bitmap->createImage(); texture->updateContents(image.get(), target, sourceOffset, BitmapTexture::UpdateCanModifyOriginalImageData); return; } #endif // USE(TEXTURE_MAPPER) } // namespace WebKit