1/* 2 Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) 3 Copyright (C) 2012 Company 100, Inc. 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public 7 License as published by the Free Software Foundation; either 8 version 2 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public License 16 along with this library; see the file COPYING.LIB. If not, write to 17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 21#include "config.h" 22#include "WebCoordinatedSurface.h" 23 24#if USE(COORDINATED_GRAPHICS) 25#include "CoordinatedGraphicsArgumentCoders.h" 26#include "GraphicsContext.h" 27#include "WebCoreArgumentCoders.h" 28#include <WebCore/GraphicsSurfaceToken.h> 29 30#if USE(TEXTURE_MAPPER) 31#include "TextureMapperGL.h" 32#endif 33 34using namespace WebCore; 35 36namespace WebKit { 37 38WebCoordinatedSurface::Handle::Handle() 39{ 40} 41 42void WebCoordinatedSurface::Handle::encode(IPC::ArgumentEncoder& encoder) const 43{ 44 encoder << m_size << m_flags; 45#if USE(GRAPHICS_SURFACE) 46 encoder << m_graphicsSurfaceToken; 47 if (m_graphicsSurfaceToken.isValid()) 48 return; 49#endif 50 encoder << m_bitmapHandle; 51} 52 53bool WebCoordinatedSurface::Handle::decode(IPC::ArgumentDecoder& decoder, Handle& handle) 54{ 55 if (!decoder.decode(handle.m_size)) 56 return false; 57 if (!decoder.decode(handle.m_flags)) 58 return false; 59#if USE(GRAPHICS_SURFACE) 60 if (!decoder.decode(handle.m_graphicsSurfaceToken)) 61 return false; 62 if (handle.m_graphicsSurfaceToken.isValid()) 63 return true; 64#endif 65 if (!decoder.decode(handle.m_bitmapHandle)) 66 return false; 67 68 return true; 69} 70 71PassRefPtr<WebCoordinatedSurface> WebCoordinatedSurface::create(const IntSize& size, CoordinatedSurface::Flags flags) 72{ 73 RefPtr<WebCoordinatedSurface> surface; 74#if USE(GRAPHICS_SURFACE) 75 surface = createWithSurface(size, flags); 76#endif 77 78 if (!surface) 79 surface = create(size, flags, ShareableBitmap::createShareable(size, (flags & SupportsAlpha) ? ShareableBitmap::SupportsAlpha : ShareableBitmap::NoFlags)); 80 81 return surface.release(); 82} 83 84#if USE(GRAPHICS_SURFACE) 85PassRefPtr<WebCoordinatedSurface> WebCoordinatedSurface::createWithSurface(const IntSize& size, CoordinatedSurface::Flags flags) 86{ 87 GraphicsSurface::Flags surfaceFlags = 88 GraphicsSurface::SupportsSoftwareWrite 89 | GraphicsSurface::SupportsCopyToTexture 90 | GraphicsSurface::SupportsSharing; 91 92 if (flags & SupportsAlpha) 93 surfaceFlags |= GraphicsSurface::SupportsAlpha; 94 95 // This might return null, if the system is unable to provide a new graphics surface. 96 // In that case, this function would return null and allow falling back to ShareableBitmap. 97 RefPtr<GraphicsSurface> surface = GraphicsSurface::create(size, surfaceFlags); 98 if (!surface) 99 return 0; 100 101 ASSERT(surface); 102 return adoptRef(new WebCoordinatedSurface(size, flags, surface.release())); 103} 104#endif 105 106std::unique_ptr<GraphicsContext> WebCoordinatedSurface::createGraphicsContext(const IntRect& rect) 107{ 108#if USE(GRAPHICS_SURFACE) 109 if (isBackedByGraphicsSurface()) 110 return m_graphicsSurface->beginPaint(rect, 0 /* Write without retaining pixels*/); 111#endif 112 113 ASSERT(m_bitmap); 114 auto graphicsContext = m_bitmap->createGraphicsContext(); 115 graphicsContext->clip(rect); 116 graphicsContext->translate(rect.x(), rect.y()); 117 return graphicsContext; 118} 119 120PassRefPtr<WebCoordinatedSurface> WebCoordinatedSurface::create(const IntSize& size, CoordinatedSurface::Flags flags, PassRefPtr<ShareableBitmap> bitmap) 121{ 122 return adoptRef(new WebCoordinatedSurface(size, flags, bitmap)); 123} 124 125WebCoordinatedSurface::WebCoordinatedSurface(const IntSize& size, CoordinatedSurface::Flags flags, PassRefPtr<ShareableBitmap> bitmap) 126 : CoordinatedSurface(size, flags) 127 , m_bitmap(bitmap) 128{ 129} 130 131#if USE(GRAPHICS_SURFACE) 132WebCoordinatedSurface::WebCoordinatedSurface(const WebCore::IntSize& size, CoordinatedSurface::Flags flags, PassRefPtr<WebCore::GraphicsSurface> surface) 133 : CoordinatedSurface(size, flags) 134 , m_graphicsSurface(surface) 135{ 136} 137 138PassRefPtr<WebCoordinatedSurface> WebCoordinatedSurface::create(const IntSize& size, CoordinatedSurface::Flags flags, PassRefPtr<GraphicsSurface> surface) 139{ 140 return adoptRef(new WebCoordinatedSurface(size, flags, surface)); 141} 142#endif 143 144WebCoordinatedSurface::~WebCoordinatedSurface() 145{ 146} 147 148PassRefPtr<WebCoordinatedSurface> WebCoordinatedSurface::create(const Handle& handle) 149{ 150#if USE(GRAPHICS_SURFACE) 151 if (handle.graphicsSurfaceToken().isValid()) { 152 GraphicsSurface::Flags surfaceFlags = 0; 153 if (handle.m_flags & SupportsAlpha) 154 surfaceFlags |= GraphicsSurface::SupportsAlpha; 155 RefPtr<GraphicsSurface> surface = GraphicsSurface::create(handle.m_size, surfaceFlags, handle.m_graphicsSurfaceToken); 156 if (surface) 157 return adoptRef(new WebCoordinatedSurface(handle.m_size, handle.m_flags, surface.release())); 158 } 159#endif 160 161 RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle.m_bitmapHandle); 162 if (!bitmap) 163 return 0; 164 165 return create(handle.m_size, handle.m_flags, bitmap.release()); 166} 167 168bool WebCoordinatedSurface::createHandle(Handle& handle) 169{ 170 handle.m_size = m_size; 171 handle.m_flags = m_flags; 172 173#if USE(GRAPHICS_SURFACE) 174 handle.m_graphicsSurfaceToken = m_graphicsSurface ? m_graphicsSurface->exportToken() : GraphicsSurfaceToken(); 175 if (handle.m_graphicsSurfaceToken.isValid()) 176 return true; 177#endif 178 if (!m_bitmap->createHandle(handle.m_bitmapHandle)) 179 return false; 180 181 return true; 182} 183 184void WebCoordinatedSurface::paintToSurface(const IntRect& rect, CoordinatedSurface::Client* client) 185{ 186 ASSERT(client); 187 188 auto context = createGraphicsContext(rect); 189 client->paintToSurfaceContext(context.get()); 190} 191 192#if USE(TEXTURE_MAPPER) 193void WebCoordinatedSurface::copyToTexture(PassRefPtr<WebCore::BitmapTexture> passTexture, const IntRect& target, const IntPoint& sourceOffset) 194{ 195 RefPtr<BitmapTexture> texture(passTexture); 196 197#if USE(GRAPHICS_SURFACE) 198 if (isBackedByGraphicsSurface()) { 199 RefPtr<BitmapTextureGL> textureGL = toBitmapTextureGL(texture.get()); 200 if (textureGL) { 201 uint32_t textureID = textureGL->id(); 202 uint32_t textureTarget = textureGL->textureTarget(); 203 m_graphicsSurface->copyToGLTexture(textureTarget, textureID, target, sourceOffset); 204 return; 205 } 206 207 RefPtr<Image> image = m_graphicsSurface->createReadOnlyImage(IntRect(sourceOffset, target.size())); 208 texture->updateContents(image.get(), target, IntPoint::zero(), BitmapTexture::UpdateCanModifyOriginalImageData); 209 return; 210 } 211#endif 212 213 ASSERT(m_bitmap); 214 RefPtr<Image> image = m_bitmap->createImage(); 215 texture->updateContents(image.get(), target, sourceOffset, BitmapTexture::UpdateCanModifyOriginalImageData); 216} 217#endif // USE(TEXTURE_MAPPER) 218 219} // namespace WebKit 220#endif // USE(COORDINATED_GRAPHICS) 221