1/* 2 * Copyright (C) 2013 Intel Corporation. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "GraphicsSurface.h" 28 29#if USE(GRAPHICS_SURFACE) 30 31#include "GLPlatformContext.h" 32#include "GLTransportSurface.h" 33#include "NotImplemented.h" 34#include "TextureMapperGL.h" 35 36namespace WebCore { 37 38struct GraphicsSurfacePrivate { 39 40 GraphicsSurfacePrivate() 41 { 42 } 43 44 GraphicsSurfacePrivate(PlatformBufferHandle winId, const IntSize& size, GraphicsSurface::Flags flags) 45 : m_flags(0) 46 , m_rect(FloatPoint::zero(), size) 47 , m_size(size) 48 , m_sharedHandle(winId) 49 { 50 if (flags & GraphicsSurface::SupportsAlpha) 51 m_flags |= TextureMapperGL::ShouldBlend; 52 } 53 54 ~GraphicsSurfacePrivate() 55 { 56 } 57 58 void destroy() 59 { 60 if (m_client) 61 m_client->destroy(); 62 63 if (m_sharedContext && m_sharedContext->handle() && m_sharedSurface) 64 makeContextCurrent(); 65 66 if (m_sharedSurface) 67 m_sharedSurface->destroy(); 68 69 if (m_sharedContext) { 70 m_sharedContext->destroy(); 71 m_sharedContext->releaseCurrent(); 72 } 73 } 74 75 bool initializeTransportSurface(const IntSize& size, GraphicsSurface::Flags flags, const PlatformGraphicsContext3D shareContext) 76 { 77 GLPlatformSurface::SurfaceAttributes sharedSurfaceAttributes = GLPlatformSurface::Default; 78 m_size = size; 79 80 if (flags & GraphicsSurface::SupportsAlpha) 81 sharedSurfaceAttributes = GLPlatformSurface::SupportAlpha; 82 83 m_sharedSurface = GLTransportSurface::createTransportSurface(size, sharedSurfaceAttributes); 84 if (!m_sharedSurface) 85 return false; 86 87 m_sharedContext = GLPlatformContext::createContext(GraphicsContext3D::RenderOffscreen); 88 if (!m_sharedContext) 89 return false; 90 91 if (!m_sharedContext->initialize(m_sharedSurface.get(), static_cast<PlatformContext>(shareContext))) 92 return false; 93 94 if (!makeContextCurrent()) 95 return false; 96 97 return true; 98 } 99 100 bool makeContextCurrent() const 101 { 102 return m_sharedContext->makeCurrent(m_sharedSurface.get()); 103 } 104 105 void copyFromTexture(GLuint textureId) 106 { 107 if (!makeContextCurrent()) 108 return; 109 110 m_sharedSurface->updateContents(textureId); 111 } 112 113 PlatformBufferHandle handle() const 114 { 115 return m_sharedSurface->handle(); 116 } 117 118 // Client 119 void updateClientBuffer() 120 { 121 if (!m_client) 122 return; 123 124 m_client->prepareTexture(); 125 } 126 127 TextureMapperGL::Flags flags() const { return m_flags; } 128 129 const FloatRect& rect() const { return m_rect; } 130 const IntSize& size() const { return m_size; } 131 132 GLuint textureId() const 133 { 134 if (!m_client) 135 const_cast<GraphicsSurfacePrivate*>(this)->initializeClient(); 136 137 return m_client ? m_client->texture() : 0; 138 } 139 140private: 141 void initializeClient() 142 { 143 m_client = GLTransportSurfaceClient::createTransportSurfaceClient(m_sharedHandle, m_size, m_flags & TextureMapperGL::ShouldBlend); 144 145 if (!m_client) 146 return; 147 } 148 149 TextureMapperGL::Flags m_flags; 150 FloatRect m_rect; 151 IntSize m_size; 152 PlatformBufferHandle m_sharedHandle; 153 OwnPtr<GLTransportSurfaceClient> m_client; 154 std::unique_ptr<GLPlatformContext> m_sharedContext; 155 OwnPtr<GLTransportSurface> m_sharedSurface; 156}; 157 158GraphicsSurfaceToken GraphicsSurface::platformExport() 159{ 160 return m_private->handle(); 161} 162 163uint32_t GraphicsSurface::platformGetTextureID() 164{ 165 return m_private->textureId(); 166} 167 168void GraphicsSurface::platformCopyToGLTexture(uint32_t /*target*/, uint32_t /*id*/, const IntRect& /*targetRect*/, const IntPoint& /*offset*/) 169{ 170 notImplemented(); 171} 172 173void GraphicsSurface::platformCopyFromTexture(uint32_t textureId, const IntRect&) 174{ 175 if (!m_private) 176 return; 177 178 m_private->copyFromTexture(textureId); 179} 180 181void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity) 182{ 183 uint32_t texture = platformGetTextureID(); 184 if (!texture) 185 return; 186 187 TransformationMatrix adjustedTransform = transform; 188 adjustedTransform.multiply(TransformationMatrix::rectToRect(m_private->rect(), targetRect)); 189 static_cast<TextureMapperGL*>(textureMapper)->drawTexture(texture, m_private->flags(), m_private->size(), m_private->rect(), adjustedTransform, opacity); 190} 191 192uint32_t GraphicsSurface::platformFrontBuffer() const 193{ 194 return 0; 195} 196 197uint32_t GraphicsSurface::platformSwapBuffers() 198{ 199 m_private->updateClientBuffer(); 200 return 0; 201} 202 203IntSize GraphicsSurface::platformSize() const 204{ 205 return m_private->size(); 206} 207 208PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size, Flags flags, const PlatformGraphicsContext3D shareContext) 209{ 210 // GraphicsSurface doesn't yet support copyToTexture or singlebuffered surface. 211 if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered) 212 return PassRefPtr<GraphicsSurface>(); 213 214 RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags)); 215 surface->m_private = new GraphicsSurfacePrivate(); 216 217 if (surface->m_private->initializeTransportSurface(size, flags, shareContext)) 218 return surface; 219 220 return PassRefPtr<GraphicsSurface>(); 221} 222 223PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, const GraphicsSurfaceToken& token) 224{ 225 // GraphicsSurface doesn't yet support copyToTexture or singlebuffered surface. 226 if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered) 227 return PassRefPtr<GraphicsSurface>(); 228 229 RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags)); 230 surface->m_private = new GraphicsSurfacePrivate(token.frontBufferHandle, size, flags); 231 return surface; 232} 233 234char* GraphicsSurface::platformLock(const IntRect&, int* /*outputStride*/, LockOptions) 235{ 236 // GraphicsSurface is currently only being used for WebGL, which does not require this locking mechanism. 237 return 0; 238} 239 240void GraphicsSurface::platformUnlock() 241{ 242 // GraphicsSurface is currently only being used for WebGL, which does not require this locking mechanism. 243} 244 245void GraphicsSurface::platformDestroy() 246{ 247 if (!m_private) 248 return; 249 250 m_private->destroy(); 251 252 delete m_private; 253 m_private = 0; 254} 255 256std::unique_ptr<GraphicsContext> GraphicsSurface::platformBeginPaint(const IntSize&, char*, int) 257{ 258 notImplemented(); 259 return nullptr; 260} 261 262PassRefPtr<Image> GraphicsSurface::createReadOnlyImage(const IntRect&) 263{ 264 notImplemented(); 265 return 0; 266} 267 268} 269 270#endif 271