| Index: Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
|
| diff --git a/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp b/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
|
| deleted file mode 100644
|
| index 15ab255bd1528d99b94453335a843308b97f6de5..0000000000000000000000000000000000000000
|
| --- a/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
|
| +++ /dev/null
|
| @@ -1,421 +0,0 @@
|
| -/*
|
| - 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 "GraphicsSurface.h"
|
| -
|
| -#if USE(GRAPHICS_SURFACE) && OS(DARWIN)
|
| -#include "TextureMapperGL.h"
|
| -#include <CFNumber.h>
|
| -#include <CGLContext.h>
|
| -#include <CGLCurrent.h>
|
| -#include <CGLIOSurface.h>
|
| -#include <IOSurface/IOSurface.h>
|
| -#include <OpenGL/OpenGL.h>
|
| -#include <OpenGL/gl.h>
|
| -#include <mach/mach.h>
|
| -
|
| -namespace WebCore {
|
| -
|
| -static uint32_t createTexture(IOSurfaceRef handle)
|
| -{
|
| - GLuint texture = 0;
|
| - GLuint format = GL_BGRA;
|
| - GLuint type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
| - GLuint internalFormat = GL_RGBA;
|
| - CGLContextObj context = CGLGetCurrentContext();
|
| - if (!context)
|
| - return 0;
|
| -
|
| - GLint prevTexture;
|
| - glGetIntegerv(GL_TEXTURE_RECTANGLE_ARB, &prevTexture);
|
| -
|
| - glGenTextures(1, &texture);
|
| - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
|
| - CGLError error = CGLTexImageIOSurface2D(context, GL_TEXTURE_RECTANGLE_ARB, internalFormat, IOSurfaceGetWidth(handle), IOSurfaceGetHeight(handle), format, type, handle, 0);
|
| - if (error) {
|
| - glDeleteTextures(1, &texture);
|
| - texture = 0;
|
| - }
|
| -
|
| - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, prevTexture);
|
| -
|
| - return texture;
|
| -}
|
| -
|
| -struct GraphicsSurfacePrivate {
|
| -public:
|
| - GraphicsSurfacePrivate(const GraphicsSurfaceToken& token, const IntSize& size)
|
| - : m_context(0)
|
| - , m_size(size)
|
| - , m_token(token)
|
| - , m_frontBufferTexture(0)
|
| - , m_frontBufferReadTexture(0)
|
| - , m_backBufferTexture(0)
|
| - , m_backBufferReadTexture(0)
|
| - , m_readFbo(0)
|
| - , m_drawFbo(0)
|
| - {
|
| - m_frontBuffer = IOSurfaceLookupFromMachPort(m_token.frontBufferHandle);
|
| - m_backBuffer = IOSurfaceLookupFromMachPort(m_token.backBufferHandle);
|
| - }
|
| -
|
| - GraphicsSurfacePrivate(const PlatformGraphicsContext3D shareContext, const IntSize& size, GraphicsSurface::Flags flags)
|
| - : m_context(0)
|
| - , m_size(size)
|
| - , m_frontBufferTexture(0)
|
| - , m_frontBufferReadTexture(0)
|
| - , m_backBufferTexture(0)
|
| - , m_backBufferReadTexture(0)
|
| - , m_readFbo(0)
|
| - , m_drawFbo(0)
|
| - {
|
| - unsigned pixelFormat = 'BGRA';
|
| - unsigned bytesPerElement = 4;
|
| - int width = m_size.width();
|
| - int height = m_size.height();
|
| -
|
| - unsigned long bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, width * bytesPerElement);
|
| - if (!bytesPerRow)
|
| - return;
|
| -
|
| - unsigned long allocSize = IOSurfaceAlignProperty(kIOSurfaceAllocSize, height * bytesPerRow);
|
| - if (!allocSize)
|
| - return;
|
| -
|
| - const void *keys[6];
|
| - const void *values[6];
|
| - keys[0] = kIOSurfaceWidth;
|
| - values[0] = CFNumberCreate(0, kCFNumberIntType, &width);
|
| - keys[1] = kIOSurfaceHeight;
|
| - values[1] = CFNumberCreate(0, kCFNumberIntType, &height);
|
| - keys[2] = kIOSurfacePixelFormat;
|
| - values[2] = CFNumberCreate(0, kCFNumberIntType, &pixelFormat);
|
| - keys[3] = kIOSurfaceBytesPerElement;
|
| - values[3] = CFNumberCreate(0, kCFNumberIntType, &bytesPerElement);
|
| - keys[4] = kIOSurfaceBytesPerRow;
|
| - values[4] = CFNumberCreate(0, kCFNumberLongType, &bytesPerRow);
|
| - keys[5] = kIOSurfaceAllocSize;
|
| - values[5] = CFNumberCreate(0, kCFNumberLongType, &allocSize);
|
| -
|
| - CFDictionaryRef dict = CFDictionaryCreate(0, keys, values, 6, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
| - for (unsigned i = 0; i < 6; i++)
|
| - CFRelease(values[i]);
|
| -
|
| - m_frontBuffer = IOSurfaceCreate(dict);
|
| - m_backBuffer = IOSurfaceCreate(dict);
|
| -
|
| - if (!(flags & GraphicsSurface::SupportsSharing))
|
| - return;
|
| -
|
| - m_token = GraphicsSurfaceToken(IOSurfaceCreateMachPort(m_frontBuffer), IOSurfaceCreateMachPort(m_backBuffer));
|
| - }
|
| -
|
| - ~GraphicsSurfacePrivate()
|
| - {
|
| - if (m_frontBufferTexture)
|
| - glDeleteTextures(1, &m_frontBufferTexture);
|
| -
|
| - if (m_frontBufferReadTexture)
|
| - glDeleteTextures(1, &m_frontBufferReadTexture);
|
| -
|
| - if (m_backBufferTexture)
|
| - glDeleteTextures(1, &m_backBufferTexture);
|
| -
|
| - if (m_backBufferReadTexture)
|
| - glDeleteTextures(1, &m_backBufferReadTexture);
|
| -
|
| - if (m_frontBuffer)
|
| - CFRelease(IOSurfaceRef(m_frontBuffer));
|
| -
|
| - if (m_backBuffer)
|
| - CFRelease(IOSurfaceRef(m_backBuffer));
|
| -
|
| - if (m_readFbo)
|
| - glDeleteFramebuffers(1, &m_readFbo);
|
| -
|
| - if (m_drawFbo)
|
| - glDeleteFramebuffers(1, &m_drawFbo);
|
| -
|
| - if (m_context)
|
| - CGLReleaseContext(m_context);
|
| -
|
| - if (m_token.frontBufferHandle)
|
| - mach_port_deallocate(mach_task_self(), m_token.frontBufferHandle);
|
| - if (m_token.backBufferHandle)
|
| - mach_port_deallocate(mach_task_self(), m_token.backBufferHandle);
|
| -
|
| - }
|
| -
|
| - uint32_t swapBuffers()
|
| - {
|
| - std::swap(m_frontBuffer, m_backBuffer);
|
| - std::swap(m_frontBufferTexture, m_backBufferTexture);
|
| - std::swap(m_frontBufferReadTexture, m_backBufferReadTexture);
|
| -
|
| - return IOSurfaceGetID(m_frontBuffer);
|
| - }
|
| -
|
| - void makeCurrent()
|
| - {
|
| - m_detachedContext = CGLGetCurrentContext();
|
| -
|
| - if (m_context)
|
| - CGLSetCurrentContext(m_context);
|
| - }
|
| -
|
| - void doneCurrent()
|
| - {
|
| - CGLSetCurrentContext(m_detachedContext);
|
| - m_detachedContext = 0;
|
| - }
|
| -
|
| - void copyFromTexture(uint32_t texture, const IntRect& sourceRect)
|
| - {
|
| - // FIXME: The following glFlush can possibly be replaced by using the GL_ARB_sync extension.
|
| - glFlush(); // Make sure the texture has actually been completely written in the original context.
|
| -
|
| - makeCurrent();
|
| -
|
| - int x = sourceRect.x();
|
| - int y = sourceRect.y();
|
| - int width = sourceRect.width();
|
| - int height = sourceRect.height();
|
| -
|
| - glPushAttrib(GL_ALL_ATTRIB_BITS);
|
| - GLint previousFBO;
|
| - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &previousFBO);
|
| -
|
| - if (!m_drawFbo)
|
| - glGenFramebuffers(1, &m_drawFbo);
|
| -
|
| - if (!m_readFbo)
|
| - glGenFramebuffers(1, &m_readFbo);
|
| -
|
| - glBindFramebuffer(GL_READ_FRAMEBUFFER, m_readFbo);
|
| - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
| -
|
| - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFbo);
|
| - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, backBufferTextureID(), 0);
|
| - glBlitFramebuffer(x, y, width, height, x, x+height, y+width, y, GL_COLOR_BUFFER_BIT, GL_LINEAR); // Flip the texture upside down.
|
| -
|
| - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
| - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
| - glBindFramebuffer(GL_FRAMEBUFFER, previousFBO);
|
| - glPopAttrib();
|
| -
|
| - // Flushing the gl command buffer is necessary to ensure the texture has correctly been bound to the IOSurface.
|
| - glFlush();
|
| -
|
| - swapBuffers();
|
| - doneCurrent();
|
| - }
|
| -
|
| - GraphicsSurfaceToken token() const
|
| - {
|
| - return m_token;
|
| - }
|
| -
|
| - uint32_t frontBufferTextureID()
|
| - {
|
| - if (!m_frontBufferReadTexture)
|
| - m_frontBufferReadTexture = createTexture(m_frontBuffer);
|
| -
|
| - return m_frontBufferReadTexture;
|
| - }
|
| -
|
| - uint32_t backBufferTextureID()
|
| - {
|
| - if (!m_backBufferTexture)
|
| - m_backBufferTexture = createTexture(m_backBuffer);
|
| -
|
| - return m_backBufferTexture;
|
| - }
|
| -
|
| - PlatformGraphicsSurface frontBuffer() const
|
| - {
|
| - return m_frontBuffer;
|
| - }
|
| -
|
| - PlatformGraphicsSurface backBuffer() const
|
| - {
|
| - return m_backBuffer;
|
| - }
|
| -
|
| - IntSize size() const
|
| - {
|
| - return m_size;
|
| - }
|
| -
|
| -private:
|
| - CGLContextObj m_context;
|
| - IntSize m_size;
|
| - CGLContextObj m_detachedContext;
|
| - PlatformGraphicsSurface m_frontBuffer;
|
| - PlatformGraphicsSurface m_backBuffer;
|
| - uint32_t m_frontBufferTexture;
|
| - uint32_t m_frontBufferReadTexture;
|
| - uint32_t m_backBufferTexture;
|
| - uint32_t m_backBufferReadTexture;
|
| - uint32_t m_readFbo;
|
| - uint32_t m_drawFbo;
|
| - GraphicsSurfaceToken m_token;
|
| -};
|
| -
|
| -GraphicsSurfaceToken GraphicsSurface::platformExport()
|
| -{
|
| - return m_private->token();
|
| -}
|
| -
|
| -uint32_t GraphicsSurface::platformGetTextureID()
|
| -{
|
| - return m_private->frontBufferTextureID();
|
| -}
|
| -
|
| -void GraphicsSurface::platformCopyToGLTexture(uint32_t target, uint32_t id, const IntRect& targetRect, const IntPoint& offset)
|
| -{
|
| - glPushAttrib(GL_ALL_ATTRIB_BITS);
|
| - if (!m_fbo)
|
| - glGenFramebuffers(1, &m_fbo);
|
| - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
| - glBindTexture(target, id);
|
| - glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo);
|
| - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, m_private->frontBufferTextureID(), 0);
|
| - glCopyTexSubImage2D(target, 0, targetRect.x(), targetRect.y(), offset.x(), offset.y(), targetRect.width(), targetRect.height());
|
| - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
| - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
| - glPopAttrib();
|
| -
|
| - // According to IOSurface's documentation, glBindFramebuffer is the one triggering an update of the surface's cache.
|
| - // If the web process starts rendering and unlocks the surface before this happens, we might copy contents
|
| - // of the currently rendering frame on our texture instead of the previously completed frame.
|
| - // Flush the command buffer to reduce the odds of this happening, this would not be necessary with double buffering.
|
| - glFlush();
|
| -}
|
| -
|
| -void GraphicsSurface::platformCopyFromTexture(uint32_t texture, const IntRect& sourceRect)
|
| -{
|
| - m_private->copyFromTexture(texture, sourceRect);
|
| -}
|
| -
|
| -void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
|
| -{
|
| - IntSize size = m_private->size();
|
| - FloatRect rectOnContents(FloatPoint::zero(), size);
|
| - TransformationMatrix adjustedTransform = transform;
|
| - adjustedTransform.multiply(TransformationMatrix::rectToRect(rectOnContents, targetRect));
|
| - static_cast<TextureMapperGL*>(textureMapper)->drawTexture(m_private->frontBufferTextureID(), TextureMapperGL::ShouldBlend | TextureMapperGL::ShouldUseARBTextureRect, size, rectOnContents, adjustedTransform, opacity);
|
| -}
|
| -
|
| -uint32_t GraphicsSurface::platformFrontBuffer() const
|
| -{
|
| - return IOSurfaceGetID(m_private->frontBuffer());
|
| -}
|
| -
|
| -uint32_t GraphicsSurface::platformSwapBuffers()
|
| -{
|
| - return m_private->swapBuffers();
|
| -}
|
| -
|
| -IntSize GraphicsSurface::platformSize() const
|
| -{
|
| - return m_private->size();
|
| -}
|
| -
|
| -PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size, Flags flags, const PlatformGraphicsContext3D shareContext)
|
| -{
|
| - // We currently disable support for CopyToTexture on Mac, because this is used for single buffered Tiles.
|
| - // The single buffered nature of this requires a call to glFlush, as described in platformCopyToTexture.
|
| - // This call blocks the GPU for about 40ms, which makes smooth animations impossible.
|
| - if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered)
|
| - return PassRefPtr<GraphicsSurface>();
|
| -
|
| - RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
|
| - surface->m_private = new GraphicsSurfacePrivate(shareContext, size, flags);
|
| -
|
| - if (!surface->m_private->frontBuffer() || !surface->m_private->backBuffer())
|
| - return PassRefPtr<GraphicsSurface>();
|
| -
|
| - return surface;
|
| -}
|
| -
|
| -PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, const GraphicsSurfaceToken& token)
|
| -{
|
| - // We currently disable support for CopyToTexture on Mac, because this is used for single buffered Tiles.
|
| - // The single buffered nature of this requires a call to glFlush, as described in platformCopyToTexture.
|
| - // This call blocks the GPU for about 40ms, which makes smooth animations impossible.
|
| - if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered)
|
| - return PassRefPtr<GraphicsSurface>();
|
| -
|
| - RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
|
| - surface->m_private = new GraphicsSurfacePrivate(token, size);
|
| -
|
| - if (!surface->m_private->frontBuffer() || !surface->m_private->backBuffer())
|
| - return PassRefPtr<GraphicsSurface>();
|
| -
|
| - return surface;
|
| -}
|
| -
|
| -static int ioSurfaceLockOptions(int lockOptions)
|
| -{
|
| - int options = 0;
|
| - if (lockOptions & GraphicsSurface::ReadOnly)
|
| - options |= kIOSurfaceLockReadOnly;
|
| - if (!(lockOptions & GraphicsSurface::RetainPixels))
|
| - options |= kIOSurfaceLockAvoidSync;
|
| -
|
| - return options;
|
| -}
|
| -
|
| -char* GraphicsSurface::platformLock(const IntRect& rect, int* outputStride, LockOptions lockOptions)
|
| -{
|
| - // Locking is only necessary for single buffered use.
|
| - // In this case we only have a front buffer, so we only lock this one.
|
| - m_lockOptions = lockOptions;
|
| - IOReturn status = IOSurfaceLock(m_private->frontBuffer(), ioSurfaceLockOptions(m_lockOptions), 0);
|
| - if (status == kIOReturnCannotLock) {
|
| - m_lockOptions |= RetainPixels;
|
| - IOSurfaceLock(m_private->frontBuffer(), ioSurfaceLockOptions(m_lockOptions), 0);
|
| - }
|
| -
|
| - int stride = IOSurfaceGetBytesPerRow(m_private->frontBuffer());
|
| - if (outputStride)
|
| - *outputStride = stride;
|
| -
|
| - char* base = static_cast<char*>(IOSurfaceGetBaseAddress(m_private->frontBuffer()));
|
| -
|
| - return base + stride * rect.y() + rect.x() * 4;
|
| -}
|
| -
|
| -void GraphicsSurface::platformUnlock()
|
| -{
|
| - IOSurfaceUnlock(m_private->frontBuffer(), ioSurfaceLockOptions(m_lockOptions), 0);
|
| -}
|
| -
|
| -void GraphicsSurface::platformDestroy()
|
| -{
|
| - if (m_fbo)
|
| - glDeleteFramebuffers(1, &m_fbo);
|
| - if (m_private)
|
| - delete m_private;
|
| - m_private = 0;
|
| -}
|
| -
|
| -}
|
| -#endif
|
|
|