summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2017-01-27 08:36:56 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2017-02-02 12:31:42 +0000
commit6b406688a4020916ba2966e6e5252d9c1385970f (patch)
tree65af619b76adb44fee03f2e496a2e4dc5c455dd8 /Source/WebCore/platform
parent46167faa61861b01a0e4e8e774da9febc3c2956e (diff)
downloadqtwebkit-6b406688a4020916ba2966e6e5252d9c1385970f.tar.gz
Imported WebKit commit bdab88b903fe1a254c80af20161183976670cd3b
Change-Id: Idc1156f4a64df4e7d89e90d4e03451f004c8ae6d Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/WebCore/platform')
-rw-r--r--Source/WebCore/platform/FileSystem.h1
-rw-r--r--Source/WebCore/platform/cf/SharedBufferCF.cpp202
-rw-r--r--Source/WebCore/platform/graphics/ANGLEWebKitBridge.h5
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext.cpp2
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3D.h31
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3DPrivate.cpp39
-rw-r--r--Source/WebCore/platform/graphics/ImageBuffer.cpp2
-rw-r--r--Source/WebCore/platform/graphics/ImageBuffer.h12
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp3
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp80
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h10
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp7
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp4
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp162
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp21
-rw-r--r--Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp13
-rw-r--r--Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.h14
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp282
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp16
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp538
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h47
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp130
-rw-r--r--Source/WebCore/platform/graphics/qt/OpenGLShimsQt.h206
-rw-r--r--Source/WebCore/platform/graphics/qt/OpenGLShimsQtVAO.h (renamed from Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp)41
-rw-r--r--Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp69
-rw-r--r--Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.h56
-rw-r--r--Source/WebCore/platform/graphics/qt/StillImageQt.h6
-rw-r--r--Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp16
-rw-r--r--Source/WebCore/platform/graphics/texmap/BitmapTextureImageBuffer.cpp88
-rw-r--r--Source/WebCore/platform/graphics/texmap/BitmapTextureImageBuffer.h60
-rw-r--r--Source/WebCore/platform/graphics/texmap/BitmapTexturePool.cpp18
-rw-r--r--Source/WebCore/platform/graphics/texmap/BitmapTexturePool.h3
-rw-r--r--Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp3
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapper.cpp8
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapper.h7
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp3
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp125
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h59
-rw-r--r--Source/WebCore/platform/graphics/texmap/coordinated/CompositingCoordinator.cpp3
-rw-r--r--Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp9
-rw-r--r--Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h1
-rw-r--r--Source/WebCore/platform/qt/FileSystemQt.cpp6
-rw-r--r--Source/WebCore/platform/qt/QWebPageClient.h2
-rw-r--r--Source/WebCore/platform/text/hyphen/HyphenationLibHyphen.cpp14
44 files changed, 2105 insertions, 319 deletions
diff --git a/Source/WebCore/platform/FileSystem.h b/Source/WebCore/platform/FileSystem.h
index f3844b8df..2c46e4da0 100644
--- a/Source/WebCore/platform/FileSystem.h
+++ b/Source/WebCore/platform/FileSystem.h
@@ -178,6 +178,7 @@ bool excludeFromBackup(const String&); // Returns true if successful.
WEBCORE_EXPORT Vector<String> listDirectory(const String& path, const String& filter = String());
WEBCORE_EXPORT CString fileSystemRepresentation(const String&);
+String stringFromFileSystemRepresentation(const char*);
inline bool isHandleValid(const PlatformFileHandle& handle) { return handle != invalidPlatformFileHandle; }
diff --git a/Source/WebCore/platform/cf/SharedBufferCF.cpp b/Source/WebCore/platform/cf/SharedBufferCF.cpp
new file mode 100644
index 000000000..21af320d9
--- /dev/null
+++ b/Source/WebCore/platform/cf/SharedBufferCF.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2008, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+#include "SharedBuffer.h"
+
+#include <wtf/OSAllocator.h>
+#include <wtf/cf/TypeCastsCF.h>
+
+namespace WebCore {
+
+SharedBuffer::SharedBuffer(CFDataRef cfData)
+ : m_buffer(adoptRef(new DataBuffer))
+ , m_cfData(cfData)
+ , m_vnodeToken(VNodeTracker::singleton().token())
+{
+}
+
+// Using Foundation allows for an even more efficient implementation of this function,
+// so only use this version for non-Foundation.
+#if !USE(FOUNDATION)
+RetainPtr<CFDataRef> SharedBuffer::createCFData()
+{
+ if (m_cfData)
+ return m_cfData;
+
+ // Internal data in SharedBuffer can be segmented. We need to get the contiguous buffer.
+ const Vector<char>& contiguousBuffer = buffer();
+ return adoptCF(CFDataCreate(0, reinterpret_cast<const UInt8*>(contiguousBuffer.data()), contiguousBuffer.size()));
+}
+#endif
+
+PassRefPtr<SharedBuffer> SharedBuffer::wrapCFData(CFDataRef data)
+{
+ return adoptRef(new SharedBuffer(data));
+}
+
+bool SharedBuffer::hasPlatformData() const
+{
+ return m_cfData;
+}
+
+const char* SharedBuffer::platformData() const
+{
+ return reinterpret_cast<const char*>(CFDataGetBytePtr(m_cfData.get()));
+}
+
+unsigned SharedBuffer::platformDataSize() const
+{
+ return CFDataGetLength(m_cfData.get());
+}
+
+void SharedBuffer::hintMemoryNotNeededSoon()
+{
+ if (!hasPlatformData())
+ return;
+ OSAllocator::hintMemoryNotNeededSoon(const_cast<char*>(platformData()), platformDataSize());
+}
+
+void SharedBuffer::maybeTransferPlatformData()
+{
+ if (!m_cfData)
+ return;
+
+ ASSERT(!m_size);
+
+ // Hang on to the m_cfData pointer in a local pointer as append() will re-enter maybeTransferPlatformData()
+ // and we need to make sure to early return when it does.
+ RetainPtr<CFDataRef> cfData = adoptCF(m_cfData.leakRef());
+
+ append(reinterpret_cast<const char*>(CFDataGetBytePtr(cfData.get())), CFDataGetLength(cfData.get()));
+}
+
+void SharedBuffer::clearPlatformData()
+{
+ m_cfData = 0;
+}
+
+bool SharedBuffer::tryReplaceContentsWithPlatformBuffer(SharedBuffer& newContents)
+{
+ if (!newContents.m_cfData)
+ return false;
+
+ clear();
+ m_cfData = newContents.m_cfData;
+ return true;
+}
+
+bool SharedBuffer::maybeAppendPlatformData(SharedBuffer* newContents)
+{
+ if (size() || !newContents->m_cfData)
+ return false;
+ m_cfData = newContents->m_cfData;
+ return true;
+}
+
+#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+PassRefPtr<SharedBuffer> SharedBuffer::wrapCFDataArray(CFArrayRef cfDataArray)
+{
+ return adoptRef(new SharedBuffer(cfDataArray));
+}
+
+SharedBuffer::SharedBuffer(CFArrayRef cfDataArray)
+ : m_buffer(adoptRef(new DataBuffer))
+ , m_cfData(nullptr)
+{
+ CFIndex dataArrayCount = CFArrayGetCount(cfDataArray);
+ for (CFIndex index = 0; index < dataArrayCount; ++index)
+ append(checked_cf_cast<CFDataRef>(CFArrayGetValueAtIndex(cfDataArray, index)));
+}
+
+void SharedBuffer::append(CFDataRef data)
+{
+ ASSERT(data);
+ m_dataArray.append(data);
+ m_size += CFDataGetLength(data);
+}
+
+void SharedBuffer::copyBufferAndClear(char* destination, unsigned bytesToCopy) const
+{
+ if (m_dataArray.isEmpty())
+ return;
+
+ CFIndex bytesLeft = bytesToCopy;
+ for (auto& cfData : m_dataArray) {
+ CFIndex dataLen = CFDataGetLength(cfData.get());
+ ASSERT(bytesLeft >= dataLen);
+ memcpy(destination, CFDataGetBytePtr(cfData.get()), dataLen);
+ destination += dataLen;
+ bytesLeft -= dataLen;
+ }
+ m_dataArray.clear();
+}
+
+unsigned SharedBuffer::copySomeDataFromDataArray(const char*& someData, unsigned position) const
+{
+ unsigned totalOffset = 0;
+ for (auto& cfData : m_dataArray) {
+ unsigned dataLen = static_cast<unsigned>(CFDataGetLength(cfData.get()));
+ ASSERT(totalOffset <= position);
+ unsigned localOffset = position - totalOffset;
+ if (localOffset < dataLen) {
+ someData = reinterpret_cast<const char *>(CFDataGetBytePtr(cfData.get())) + localOffset;
+ return dataLen - localOffset;
+ }
+ totalOffset += dataLen;
+ }
+ return 0;
+}
+
+const char *SharedBuffer::singleDataArrayBuffer() const
+{
+ // If we had previously copied data into m_buffer in copyDataArrayAndClear() or some other
+ // function, then we can't return a pointer to the CFDataRef buffer.
+ if (m_buffer->data.size())
+ return 0;
+
+ if (m_dataArray.size() != 1)
+ return 0;
+
+ return reinterpret_cast<const char*>(CFDataGetBytePtr(m_dataArray.at(0).get()));
+}
+
+bool SharedBuffer::maybeAppendDataArray(SharedBuffer* data)
+{
+ if (m_buffer->data.size() || m_cfData || !data->m_dataArray.size())
+ return false;
+#if !ASSERT_DISABLED
+ unsigned originalSize = size();
+#endif
+ for (auto& cfData : data->m_dataArray)
+ append(cfData.get());
+ ASSERT(size() == originalSize + data->size());
+ return true;
+}
+#endif
+
+}
diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
index 50684426a..dc5082a45 100644
--- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
+++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
@@ -38,6 +38,11 @@
#include "OpenGLESShims.h"
#elif PLATFORM(QT)
#include <qopengl.h>
+
+#ifndef GL_SAMPLER_2D_RECT_ARB
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#endif
+
#elif PLATFORM(GTK) || PLATFORM(EFL)
#if USE(OPENGL_ES_2)
#include <GLES2/gl2.h>
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.cpp b/Source/WebCore/platform/graphics/GraphicsContext.cpp
index 4dfef933f..b4c6f46c4 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp
@@ -993,7 +993,7 @@ void GraphicsContext::setPlatformShouldSmoothFonts(bool)
}
#endif
-#if !USE(CG) && !USE(CAIRO)
+#if !USE(CG) && !USE(CAIRO) && !PLATFORM(QT)
bool GraphicsContext::isAcceleratedContext() const
{
return false;
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h
index 940394e3b..e7d7f9a7f 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h
@@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE
class QPainter;
class QRect;
class QOpenGLContext;
+class QOpenGLExtensions;
class QSurface;
QT_END_NAMESPACE
#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN_CAIRO)
@@ -95,14 +96,9 @@ const Platform3DObject NullPlatform3DObject = 0;
namespace WebCore {
class Extensions3D;
-#if USE(OPENGL_ES_2)
+class Extensions3DOpenGLCommon;
class Extensions3DOpenGLES;
-#else
class Extensions3DOpenGL;
-#endif
-#if PLATFORM(QT)
-class Extensions3DQt;
-#endif
class HostWindow;
class Image;
class ImageBuffer;
@@ -690,7 +686,7 @@ public:
ALREADY_SIGNALED = 0x911A,
TIMEOUT_EXPIRED = 0x911B,
CONDITION_SATISFIED = 0x911C,
-#if PLATFORM(WIN)
+#if OS(WINDOWS)
WAIT_FAILED_WIN = 0x911D,
#else
WAIT_FAILED = 0x911D,
@@ -1417,17 +1413,15 @@ private:
String mappedSymbolName(Platform3DObject shaders[2], size_t count, const String& name);
String originalSymbolName(Platform3DObject program, ANGLEShaderSymbolType, const String& name);
+#if !PLATFORM(QT)
ANGLEWebKitBridge m_compiler;
+#endif
std::unique_ptr<ShaderNameHash> nameHashMapForShaders;
-#if (PLATFORM(QT) && defined(QT_OPENGL_ES_2)) || ((PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)) && USE(OPENGL_ES_2))
- friend class Extensions3DOpenGLES;
- std::unique_ptr<Extensions3DOpenGLES> m_extensions;
-#else
+ std::unique_ptr<Extensions3DOpenGLCommon> m_extensions;
friend class Extensions3DOpenGL;
- std::unique_ptr<Extensions3DOpenGL> m_extensions;
-#endif
+ friend class Extensions3DOpenGLES;
friend class Extensions3DOpenGLCommon;
Attributes m_attrs;
@@ -1470,9 +1464,18 @@ private:
// Errors raised by synthesizeGLError().
ListHashSet<GC3Denum> m_syntheticErrors;
+#if PLATFORM(QT)
+ QOpenGLExtensions* m_functions;
+#endif
+
friend class GraphicsContext3DPrivate;
std::unique_ptr<GraphicsContext3DPrivate> m_private;
-
+
+#if PLATFORM(QT)
+ // Must be initialized after m_private so that isGLES2Compliant works
+ ANGLEWebKitBridge m_compiler;
+#endif
+
WebGLRenderingContextBase* m_webglContext;
};
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3DPrivate.cpp b/Source/WebCore/platform/graphics/GraphicsContext3DPrivate.cpp
index 15cd4df00..aeaefbca0 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3DPrivate.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext3DPrivate.cpp
@@ -121,6 +121,45 @@ void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper& textureMapper
m_context->markLayerComposited();
+ // FIXME: We do not support mask for the moment with TextureMapperImageBuffer.
+ if (textureMapper->accelerationMode() != TextureMapper::OpenGLMode) {
+ GraphicsContext* context = textureMapper->graphicsContext();
+ context->save();
+ context->platformContext()->setGlobalAlpha(opacity);
+
+ const int height = m_context->m_currentHeight;
+ const int width = m_context->m_currentWidth;
+ int totalBytes = width * height * 4;
+
+ auto pixels = std::make_unique<unsigned char[]>(totalBytes);
+ if (!pixels)
+ return;
+
+ // OpenGL keeps the pixels stored bottom up, so we need to flip the image here.
+ context->translate(0, height);
+ context->scale(FloatSize(1, -1));
+
+ context->concatCTM(matrix.toAffineTransform());
+
+ m_context->readRenderingResults(pixels.get(), totalBytes);
+
+ // Premultiply alpha.
+ for (int i = 0; i < totalBytes; i += 4)
+ if (pixels[i + 3] != 255) {
+ pixels[i + 0] = min(255, pixels[i + 0] * pixels[i + 3] / 255);
+ pixels[i + 1] = min(255, pixels[i + 1] * pixels[i + 3] / 255);
+ pixels[i + 2] = min(255, pixels[i + 2] * pixels[i + 3] / 255);
+ }
+
+ RefPtr<cairo_surface_t> imageSurface = adoptRef(cairo_image_surface_create_for_data(
+ const_cast<unsigned char*>(pixels.get()), CAIRO_FORMAT_ARGB32, width, height, width * 4));
+
+ context->platformContext()->drawSurfaceToContext(imageSurface.get(), targetRect, IntRect(0, 0, width, height), context);
+
+ context->restore();
+ return;
+ }
+
#if USE(TEXTURE_MAPPER_GL)
if (m_context->m_attrs.antialias && m_context->m_state.boundFBO == m_context->m_multisampleFBO) {
GLContext* previousActiveContext = GLContext::getCurrent();
diff --git a/Source/WebCore/platform/graphics/ImageBuffer.cpp b/Source/WebCore/platform/graphics/ImageBuffer.cpp
index 2ace73c28..d3c3ae644 100644
--- a/Source/WebCore/platform/graphics/ImageBuffer.cpp
+++ b/Source/WebCore/platform/graphics/ImageBuffer.cpp
@@ -153,10 +153,12 @@ void ImageBuffer::convertToLuminanceMask()
}
#if !USE(CAIRO)
+#if !PLATFORM(QT)
PlatformLayer* ImageBuffer::platformLayer() const
{
return 0;
}
+#endif
bool ImageBuffer::copyToPlatformTexture(GraphicsContext3D&, GC3Denum, Platform3DObject, GC3Denum, bool, bool)
{
diff --git a/Source/WebCore/platform/graphics/ImageBuffer.h b/Source/WebCore/platform/graphics/ImageBuffer.h
index 04f9ef93a..6f48d3db9 100644
--- a/Source/WebCore/platform/graphics/ImageBuffer.h
+++ b/Source/WebCore/platform/graphics/ImageBuffer.h
@@ -40,6 +40,12 @@
#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
+#if PLATFORM(QT)
+QT_BEGIN_NAMESPACE
+class QOpenGLContext;
+QT_END_NAMESPACE
+#endif
+
namespace WebCore {
class FloatRect;
@@ -80,6 +86,9 @@ public:
}
static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, float resolutionScale, ColorSpace, const GraphicsContext&, bool hasAlpha);
+#if PLATFORM(QT) && ENABLE(ACCELERATED_2D_CANVAS)
+ static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const IntSize&, float resolutionScale, ColorSpace, QOpenGLContext*);
+#endif
WEBCORE_EXPORT ~ImageBuffer();
@@ -164,6 +173,9 @@ private:
// This constructor will place its success into the given out-variable
// so that create() knows when it should return failure.
WEBCORE_EXPORT ImageBuffer(const FloatSize&, float resolutionScale, ColorSpace, RenderingMode, bool& success);
+#if PLATFORM(QT) && ENABLE(ACCELERATED_2D_CANVAS)
+ ImageBuffer(const IntSize&, float resolutionScale, ColorSpace, QOpenGLContext*, bool& success);
+#endif
};
#if USE(CG)
diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp
index 310a02247..428f432e6 100644
--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp
@@ -625,6 +625,9 @@ void MediaPlayerPrivateGStreamerBase::paint(GraphicsContext& context, const Floa
#if USE(TEXTURE_MAPPER_GL) && !USE(COORDINATED_GRAPHICS)
void MediaPlayerPrivateGStreamerBase::paintToTextureMapper(TextureMapper& textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity)
{
+ if (textureMapper.accelerationMode() != TextureMapper::OpenGLMode)
+ return;
+
if (!m_player->visible())
return;
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
index a0bc40357..51d5db650 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
@@ -36,7 +36,14 @@
#include <OpenGLES/ES2/glext.h>
#elif PLATFORM(MAC)
#include <OpenGL/gl.h>
-#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(QT) || PLATFORM(WIN)
+#elif PLATFORM(QT)
+#define FUNCTIONS m_context->m_functions
+#include "OpenGLShimsQt.h"
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+#define VAO_FUNCTIONS m_vaoFunctions
+#include "OpenGLShimsQtVAO.h"
+#endif
+#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
#include "OpenGLShims.h"
#endif
@@ -44,15 +51,25 @@
#include "GraphicsContext3DIOS.h"
#endif
+// Note this implementation serves a double role for Qt where it also handles OpenGLES.
+
namespace WebCore {
Extensions3DOpenGL::Extensions3DOpenGL(GraphicsContext3D* context)
: Extensions3DOpenGLCommon(context)
{
+#if PLATFORM(QT) && QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+ context->makeContextCurrent();
+ m_vaoFunctions = new QOpenGLVertexArrayObjectHelper(context->platformGraphicsContext3D());
+#endif
}
Extensions3DOpenGL::~Extensions3DOpenGL()
{
+#if PLATFORM(QT) && QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+ delete m_vaoFunctions;
+ m_vaoFunctions = 0;
+#endif
}
@@ -119,6 +136,8 @@ GC3Dboolean Extensions3DOpenGL::isVertexArrayOES(Platform3DObject array)
#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
return glIsVertexArrayAPPLE(array);
#endif
+
+ m_context->synthesizeGLError(GL_INVALID_OPERATION);
return GL_FALSE;
}
@@ -157,6 +176,23 @@ bool Extensions3DOpenGL::supportsExtension(const String& name)
{
// GL_ANGLE_framebuffer_blit and GL_ANGLE_framebuffer_multisample are "fake". They are implemented using other
// extensions. In particular GL_EXT_framebuffer_blit and GL_EXT_framebuffer_multisample/GL_APPLE_framebuffer_multisample.
+#if PLATFORM(QT)
+ m_context->makeContextCurrent();
+
+ if (name == "GL_ANGLE_framebuffer_blit" || name == "GL_EXT_framebuffer_blit")
+ return m_context->m_functions->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit);
+ if (name == "GL_ANGLE_framebuffer_multisample" || name == "GL_EXT_framebuffer_multisample")
+ return m_context->m_functions->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample);
+
+ if (name == "GL_OES_texture_npot" || name == "GL_ARB_texture_non_power_of_two")
+ return m_context->m_functions->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures);
+ if (name == "GL_OES_packed_depth_stencil" || name == "GL_EXT_packed_depth_stencil")
+ return m_context->m_functions->hasOpenGLExtension(QOpenGLExtensions::PackedDepthStencil);
+
+ // FIXME: We don't have the robustness methods from Extensions3DOpenGLES.
+ if (name == "GL_EXT_robustness")
+ return false;
+#else
if (name == "GL_ANGLE_framebuffer_blit")
return m_availableExtensions.contains("GL_EXT_framebuffer_blit");
if (name == "GL_ANGLE_framebuffer_multisample")
@@ -165,6 +201,7 @@ bool Extensions3DOpenGL::supportsExtension(const String& name)
#else
return m_availableExtensions.contains("GL_EXT_framebuffer_multisample");
#endif
+#endif // !PLATFORM(QT)
if (name == "GL_ANGLE_instanced_arrays") {
return (m_availableExtensions.contains("GL_ARB_instanced_arrays") || m_availableExtensions.contains("GL_EXT_instanced_arrays"))
@@ -185,6 +222,10 @@ bool Extensions3DOpenGL::supportsExtension(const String& name)
return m_availableExtensions.contains("GL_EXT_frag_depth");
#endif
+#if PLATFORM(QT)
+ if (!m_context->isGLES2Compliant()) {
+#endif
+
// Desktop GL always supports GL_OES_rgb8_rgba8.
if (name == "GL_OES_rgb8_rgba8")
return true;
@@ -194,17 +235,27 @@ bool Extensions3DOpenGL::supportsExtension(const String& name)
if (name == "GL_OES_texture_float" || name == "GL_OES_texture_half_float" || name == "GL_OES_texture_float_linear" || name == "GL_OES_texture_half_float_linear")
return m_availableExtensions.contains("GL_ARB_texture_float") || m_availableExtensions.contains("GL_OES_texture_float");
+#if PLATFORM(QT)
+ }
+#endif
+
// GL_OES_vertex_array_object
if (name == "GL_OES_vertex_array_object") {
-#if (PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL))
+#if (PLATFORM(GTK) || PLATFORM(EFL))
return m_availableExtensions.contains("GL_ARB_vertex_array_object");
#elif PLATFORM(IOS)
return m_availableExtensions.contains("GL_OES_vertex_array_object");
+#elif PLATFORM(QT)
+ return isVertexArrayObjectSupported();
#else
return m_availableExtensions.contains("GL_APPLE_vertex_array_object");
#endif
}
+#if PLATFORM(QT)
+ if (!m_context->isGLES2Compliant()) {
+#endif
+
// Desktop GL always supports the standard derivative functions
if (name == "GL_OES_standard_derivatives")
return true;
@@ -212,6 +263,10 @@ bool Extensions3DOpenGL::supportsExtension(const String& name)
// Desktop GL always supports UNSIGNED_INT indices
if (name == "GL_OES_element_index_uint")
return true;
+
+#if PLATFORM(QT)
+ }
+#endif
if (name == "GL_EXT_shader_texture_lod")
return m_availableExtensions.contains("GL_EXT_shader_texture_lod");
@@ -222,7 +277,7 @@ bool Extensions3DOpenGL::supportsExtension(const String& name)
if (name == "GL_EXT_draw_buffers") {
#if PLATFORM(IOS)
return m_availableExtensions.contains(name);
-#elif PLATFORM(MAC) || PLATFORM(GTK)
+#elif PLATFORM(MAC) || PLATFORM(GTK) || (PLATFORM(QT) && QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
return m_availableExtensions.contains("GL_ARB_draw_buffers");
#else
// FIXME: implement support for other platforms.
@@ -243,7 +298,7 @@ void Extensions3DOpenGL::drawBuffersEXT(GC3Dsizei n, const GC3Denum* bufs)
// FIXME: implement support for other platforms.
#if PLATFORM(MAC)
::glDrawBuffersARB(n, bufs);
-#elif PLATFORM(GTK)
+#elif PLATFORM(GTK) || (PLATFORM(QT) && QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
::glDrawBuffers(n, bufs);
#else
UNUSED_PARAM(n);
@@ -254,7 +309,7 @@ void Extensions3DOpenGL::drawBuffersEXT(GC3Dsizei n, const GC3Denum* bufs)
void Extensions3DOpenGL::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
{
m_context->makeContextCurrent();
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || (PLATFORM(QT) && QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
::glDrawArraysInstanced(mode, first, count, primcount);
#elif PLATFORM(COCOA)
::glDrawArraysInstancedARB(mode, first, count, primcount);
@@ -269,7 +324,7 @@ void Extensions3DOpenGL::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Ds
void Extensions3DOpenGL::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount)
{
m_context->makeContextCurrent();
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || (PLATFORM(QT) && QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
::glDrawElementsInstanced(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)), primcount);
#elif PLATFORM(COCOA)
::glDrawElementsInstancedARB(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)), primcount);
@@ -285,7 +340,7 @@ void Extensions3DOpenGL::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, G
void Extensions3DOpenGL::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
{
m_context->makeContextCurrent();
-#if PLATFORM(GTK)
+#if PLATFORM(GTK) || (PLATFORM(QT) && QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
::glVertexAttribDivisor(index, divisor);
#elif PLATFORM(COCOA)
::glVertexAttribDivisorARB(index, divisor);
@@ -300,12 +355,21 @@ String Extensions3DOpenGL::getExtensions()
return String(reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS)));
}
-#if (PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(WIN) || PLATFORM(IOS))
+#if (PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN) || PLATFORM(IOS))
bool Extensions3DOpenGL::isVertexArrayObjectSupported()
{
static const bool supportsVertexArrayObject = supports("GL_OES_vertex_array_object");
return supportsVertexArrayObject;
}
+#elif PLATFORM(QT)
+bool Extensions3DOpenGL::isVertexArrayObjectSupported()
+{
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+ return m_vaoFunctions && m_vaoFunctions->isValid();
+#else
+ return false;
+#endif
+}
#endif
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
index 2938110c5..fd3512fa2 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
@@ -32,6 +32,12 @@
#include <wtf/HashSet.h>
#include <wtf/text/StringHash.h>
+#if PLATFORM(QT)
+QT_BEGIN_NAMESPACE
+class QOpenGLVertexArrayObjectHelper;
+QT_END_NAMESPACE
+#endif
+
namespace WebCore {
class Extensions3DOpenGL : public Extensions3DOpenGLCommon {
@@ -65,6 +71,10 @@ protected:
private:
bool isVertexArrayObjectSupported();
#endif
+
+#if PLATFORM(QT) && QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+ QOpenGLVertexArrayObjectHelper *m_vaoFunctions;
+#endif
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
index 93e8cfd8f..62430006b 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
@@ -35,13 +35,16 @@
#if PLATFORM(IOS)
#include <OpenGLES/ES2/glext.h>
#else
-#if USE(OPENGL_ES_2)
+#if PLATFORM(QT)
+#define FUNCTIONS m_context->m_functions
+#include "OpenGLShimsQt.h"
+#elif USE(OPENGL_ES_2)
#include "OpenGLESShims.h"
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#elif PLATFORM(MAC)
#include <OpenGL/gl.h>
-#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(QT) || PLATFORM(WIN)
+#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
#include "OpenGLShims.h"
#endif
#endif
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp
index 9199cb84e..27dc6bd5f 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp
@@ -195,10 +195,14 @@ void Extensions3DOpenGLES::setEXTContextLostCallback(std::unique_ptr<GraphicsCon
void Extensions3DOpenGLES::readnPixelsEXT(int x, int y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, GC3Dsizei bufSize, void *data)
{
if (m_glReadnPixelsEXT) {
+#if PLATFORM(QT)
+ m_context->flush();
+#else
m_context->makeContextCurrent();
// FIXME: remove the two glFlush calls when the driver bug is fixed, i.e.,
// all previous rendering calls should be done before reading pixels.
::glFlush();
+#endif
// FIXME: If non-BlackBerry platforms use this, they will need to implement
// their anti-aliasing code here.
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
index e1e244985..85da831cc 100644
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
@@ -1,6 +1,9 @@
/*
* Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2012 ChangSeok Oh <shivamidow@gmail.com>
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ * Copyright (C) 2014 Digia Plc. and/or its subsidiary(-ies).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -21,11 +24,13 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
+// Note this implementation serves a double role for Qt where it also handles OpenGLES.
+
#if ENABLE(GRAPHICS_CONTEXT_3D)
#include "GraphicsContext3D.h"
@@ -55,16 +60,66 @@
#define GL_RGB32F_ARB 0x8815
#elif PLATFORM(MAC)
#include <OpenGL/gl.h>
-#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(QT) || PLATFORM(WIN)
+#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
#include "OpenGLShims.h"
#endif
+#if PLATFORM(QT)
+
+#define FUNCTIONS m_functions
+#include "OpenGLShimsQt.h"
+#include <QOpenGLContext>
+
+#define scopedScissor(c, s) scopedScissor(m_functions, c, s)
+#define scopedDither(c, s) scopedDither(m_functions, c, s)
+#define scopedDepth(c, s) scopedDepth(m_functions, c, s)
+#define scopedStencil(c, s) scopedStencil(m_functions, c, s)
+
+#ifndef GL_BGRA
+#define GL_BGRA 0x80E1
+#endif
+
+#ifndef GL_READ_FRAMEBUFFER
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#endif
+
+#ifndef GL_DRAW_FRAMEBUFFER
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#endif
+
+#ifndef GL_MAX_VARYING_FLOATS
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#endif
+
+#ifndef GL_ALPHA16F_ARB
+#define GL_ALPHA16F_ARB 0x881C
+#endif
+
+#ifndef GL_LUMINANCE16F_ARB
+#define GL_LUMINANCE16F_ARB 0x881E
+#endif
+
+#ifndef GL_LUMINANCE_ALPHA16F_ARB
+#define GL_LUMINANCE_ALPHA16F_ARB 0x881F
+#endif
+
+#ifndef GL_HALF_FLOAT_OES
+#define GL_HALF_FLOAT_OES 0x8D61
+#endif
+
+#endif
+
namespace WebCore {
void GraphicsContext3D::releaseShaderCompiler()
{
makeContextCurrent();
+#if PLATFORM(QT)
+ ASSERT(m_private);
+ m_functions->glReleaseShaderCompiler();
+#else
notImplemented();
+#endif
}
void GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary(int x, int y, int width, int height, unsigned char* pixels)
@@ -93,13 +148,41 @@ void GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary(int x, int y, int
for (int i = 0; i < totalBytes; i += 4)
std::swap(pixels[i], pixels[i + 2]);
#endif
- } else
+ } else {
+#if PLATFORM(QT)
+ ASSERT(m_private);
+ bool readBGRA = !isGLES2Compliant() || platformGraphicsContext3D()->hasExtension("GL_EXT_read_format_bgra");
+
+ if (readBGRA)
+ glReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
+ else
+ glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ int totalBytes = width * height * 4;
+ if (!readBGRA) {
+ for (int i = 0; i < totalBytes; i += 4)
+ std::swap(pixels[i], pixels[i + 2]); // Convert to BGRA.
+ }
+#else
::glReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
+#endif
+ }
}
void GraphicsContext3D::validateAttributes()
{
+#if PLATFORM(QT)
+ if (isGLES2Compliant())
+ validateDepthStencil("GL_OES_packed_depth_stencil");
+ else
+ validateDepthStencil("GL_EXT_packed_depth_stencil");
+
+ if (m_attrs.antialias && isGLES2Compliant()) {
+ if (!m_functions->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample) || !m_functions->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit))
+ m_attrs.antialias = false;
+ }
+#else
validateDepthStencil("GL_EXT_packed_depth_stencil");
+#endif
}
bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
@@ -107,13 +190,17 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
const int width = size.width();
const int height = size.height();
GLuint colorFormat, internalDepthStencilFormat = 0;
+ GLuint pixelDataType = 0;
if (m_attrs.alpha) {
- m_internalColorFormat = GL_RGBA8;
+ m_internalColorFormat = isGLES2Compliant() ? GL_RGBA : GL_RGBA8;
colorFormat = GL_RGBA;
+ pixelDataType = GL_UNSIGNED_BYTE;
} else {
- m_internalColorFormat = GL_RGB8;
+ m_internalColorFormat = isGLES2Compliant() ? GL_RGB : GL_RGB8;
colorFormat = GL_RGB;
+ pixelDataType = isGLES2Compliant() ? GL_UNSIGNED_SHORT_5_6_5 : GL_UNSIGNED_BYTE;
}
+
if (m_attrs.stencil || m_attrs.depth) {
// We don't allow the logic where stencil is required and depth is not.
// See GraphicsContext3D::validateAttributes.
@@ -131,7 +218,7 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
}
// Resize multisample FBO.
- if (m_attrs.antialias) {
+ if (m_attrs.antialias && !isGLES2Compliant()) {
GLint maxSampleCount;
::glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount);
GLint sampleCount = std::min(8, maxSampleCount);
@@ -169,12 +256,12 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
setRenderbufferStorageFromDrawable(m_currentWidth, m_currentHeight);
#else
::glBindTexture(GL_TEXTURE_2D, m_texture);
- ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
+ ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, pixelDataType, 0);
::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
if (m_compositorTexture) {
::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
- ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
+ ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, pixelDataType, 0);
::glBindTexture(GL_TEXTURE_2D, 0);
#if USE(COORDINATED_GRAPHICS_THREADED)
::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_compositorFBO);
@@ -188,7 +275,7 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
attachDepthAndStencilBufferIfNeeded(internalDepthStencilFormat, width, height);
bool mustRestoreFBO = true;
- if (m_attrs.antialias) {
+ if (m_attrs.antialias && !isGLES2Compliant()) {
::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
if (m_state.boundFBO == m_multisampleFBO)
mustRestoreFBO = false;
@@ -203,6 +290,10 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
void GraphicsContext3D::attachDepthAndStencilBufferIfNeeded(GLuint internalDepthStencilFormat, int width, int height)
{
if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) {
+#if PLATFORM(QT)
+ bool supportPackedDepthStencilBuffer = internalDepthStencilFormat == GL_DEPTH24_STENCIL8_EXT;
+ if (supportPackedDepthStencilBuffer || !isGLES2Compliant()) {
+#endif
::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
if (m_attrs.stencil)
@@ -210,6 +301,21 @@ void GraphicsContext3D::attachDepthAndStencilBufferIfNeeded(GLuint internalDepth
if (m_attrs.depth)
::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+#if PLATFORM(QT)
+ } else {
+ if (m_attrs.stencil) {
+ ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_stencilBuffer);
+ ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8, width, height);
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencilBuffer);
+ }
+ if (m_attrs.depth) {
+ ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
+ ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, width, height);
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
+ }
+ ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+ }
+#endif
}
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
@@ -220,6 +326,18 @@ void GraphicsContext3D::attachDepthAndStencilBufferIfNeeded(GLuint internalDepth
void GraphicsContext3D::resolveMultisamplingIfNecessary(const IntRect& rect)
{
+#if PLATFORM(QT)
+ Q_ASSERT(m_private);
+ if (!m_attrs.antialias)
+ return;
+
+ // QTFIXME: Probably not needed, iOS uses following code successfully
+ if (isGLES2Compliant()) {
+ notImplemented();
+ return;
+ }
+#endif
+
TemporaryOpenGLSetting scopedScissor(GL_SCISSOR_TEST, GL_FALSE);
TemporaryOpenGLSetting scopedDither(GL_DITHER, GL_FALSE);
TemporaryOpenGLSetting scopedDepth(GL_DEPTH_TEST, GL_FALSE);
@@ -249,6 +367,9 @@ void GraphicsContext3D::renderbufferStorage(GC3Denum target, GC3Denum internalfo
{
makeContextCurrent();
#if !PLATFORM(IOS)
+#if PLATFORM(QT)
+ if (!isGLES2Compliant()) {
+#endif
switch (internalformat) {
case DEPTH_STENCIL:
internalformat = GL_DEPTH24_STENCIL8_EXT;
@@ -264,6 +385,9 @@ void GraphicsContext3D::renderbufferStorage(GC3Denum target, GC3Denum internalfo
internalformat = GL_RGB;
break;
}
+#if PLATFORM(QT)
+ }
+#endif
#endif
::glRenderbufferStorageEXT(target, internalformat, width, height);
}
@@ -275,6 +399,12 @@ void GraphicsContext3D::getIntegerv(GC3Denum pname, GC3Dint* value)
// whereas GLES2 return the number of vectors (each vector has 4 components).
// Therefore, the value returned by desktop GL needs to be divided by 4.
makeContextCurrent();
+#if PLATFORM(QT)
+ if (isGLES2Compliant()) {
+ ::glGetIntegerv(pname, value);
+ return;
+ }
+#endif
switch (pname) {
#if !PLATFORM(IOS)
case MAX_FRAGMENT_UNIFORM_VECTORS:
@@ -307,12 +437,19 @@ void GraphicsContext3D::getIntegerv(GC3Denum pname, GC3Dint* value)
void GraphicsContext3D::getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType, GC3Dint* range, GC3Dint* precision)
{
+#if !PLATFORM(QT)
UNUSED_PARAM(shaderType);
+#endif
ASSERT(range);
ASSERT(precision);
makeContextCurrent();
+#if PLATFORM(QT)
+ m_functions->glGetShaderPrecisionFormat(shaderType, precisionType, range, precision);
+ return;
+#endif
+
switch (precisionType) {
case GraphicsContext3D::LOW_INT:
case GraphicsContext3D::MEDIUM_INT:
@@ -346,6 +483,9 @@ bool GraphicsContext3D::texImage2D(GC3Denum target, GC3Dint level, GC3Denum inte
GC3Denum openGLFormat = format;
GC3Denum openGLInternalFormat = internalformat;
#if !PLATFORM(IOS)
+#if PLATFORM(QT)
+ if (!isGLES2Compliant()) {
+#endif
if (type == GL_FLOAT) {
if (format == GL_RGBA)
openGLInternalFormat = GL_RGBA32F_ARB;
@@ -370,6 +510,9 @@ bool GraphicsContext3D::texImage2D(GC3Denum target, GC3Dint level, GC3Denum inte
openGLFormat = GL_RGBA;
else if (format == Extensions3D::SRGB_EXT)
openGLFormat = GL_RGB;
+#if PLATFORM(QT)
+ }
+#endif
#endif
texImage2DDirect(target, level, openGLInternalFormat, width, height, border, openGLFormat, type, pixels);
return true;
@@ -404,6 +547,7 @@ Extensions3D* GraphicsContext3D::getExtensions()
void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
{
+ ASSERT(m_private);
// FIXME: remove the two glFlush calls when the driver bug is fixed, i.e.,
// all previous rendering calls should be done before reading pixels.
makeContextCurrent();
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
index f1509fb5f..03460cf2c 100644
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
@@ -67,11 +67,20 @@
#define GL_RGBA32F_ARB 0x8814
#define GL_RGB32F_ARB 0x8815
#else
-#if USE(OPENGL_ES_2)
+#if PLATFORM(QT)
+#define FUNCTIONS m_functions
+#include "OpenGLShimsQt.h"
+
+#define glGetError(...) m_functions->glGetError(__VA_ARGS__)
+#define glIsEnabled(...) m_functions->glIsEnabled(__VA_ARGS__)
+
+#define scopedScissor(c, s) scopedScissor(m_functions, c, s)
+#define scopedDither(c, s) scopedDither(m_functions, c, s)
+#elif USE(OPENGL_ES_2)
#include "OpenGLESShims.h"
#elif PLATFORM(MAC)
#include <OpenGL/gl.h>
-#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(QT) || PLATFORM(WIN)
+#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
#include "OpenGLShims.h"
#endif
#endif
@@ -403,7 +412,7 @@ bool GraphicsContext3D::checkVaryingsPacking(Platform3DObject vertexShader, Plat
}
GC3Dint maxVaryingVectors = 0;
-#if !PLATFORM(IOS) && !((PLATFORM(WIN) || PLATFORM(GTK)) && USE(OPENGL_ES_2))
+#if !PLATFORM(IOS) && !((PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(QT)) && USE(OPENGL_ES_2))
GC3Dint maxVaryingFloats = 0;
::glGetIntegerv(GL_MAX_VARYING_FLOATS, &maxVaryingFloats);
maxVaryingVectors = maxVaryingFloats / 4;
@@ -1012,7 +1021,7 @@ GC3Denum GraphicsContext3D::getError()
}
makeContextCurrent();
- return ::glGetError();
+ return glGetError();
}
String GraphicsContext3D::getString(GC3Denum name)
@@ -1039,7 +1048,7 @@ GC3Dboolean GraphicsContext3D::isBuffer(Platform3DObject buffer)
GC3Dboolean GraphicsContext3D::isEnabled(GC3Denum cap)
{
makeContextCurrent();
- return ::glIsEnabled(cap);
+ return glIsEnabled(cap);
}
GC3Dboolean GraphicsContext3D::isFramebuffer(Platform3DObject framebuffer)
@@ -1382,6 +1391,7 @@ void GraphicsContext3D::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsize
::glViewport(x, y, width, height);
}
+#if !PLATFORM(QT) || ENABLE(WEBGL2)
Platform3DObject GraphicsContext3D::createVertexArray()
{
makeContextCurrent();
@@ -1432,6 +1442,7 @@ void GraphicsContext3D::bindVertexArray(Platform3DObject array)
UNUSED_PARAM(array);
#endif
}
+#endif
void GraphicsContext3D::getBooleanv(GC3Denum pname, GC3Dboolean* value)
{
diff --git a/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp b/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp
index b948c3a15..c502a0c3b 100644
--- a/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp
+++ b/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp
@@ -39,16 +39,25 @@
#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
#include "OpenGLShims.h"
#elif PLATFORM(QT)
-#include <qopengl.h>
+#define FUNCTIONS m_functions
+#include "OpenGLShimsQt.h"
+#define glIsEnabled(...) m_functions->glIsEnabled(__VA_ARGS__)
#endif
namespace WebCore {
+#if PLATFORM(QT)
+TemporaryOpenGLSetting::TemporaryOpenGLSetting(QOpenGLExtensions* functions, GC3Denum capability, GC3Denum scopedState)
+#else
TemporaryOpenGLSetting::TemporaryOpenGLSetting(GLenum capability, GLenum scopedState)
+#endif
: m_capability(capability)
, m_scopedState(scopedState)
+#if PLATFORM(QT)
+ , m_functions(functions)
+#endif
{
- m_originalState = ::glIsEnabled(m_capability);
+ m_originalState = glIsEnabled(m_capability);
if (m_originalState == m_scopedState)
return;
diff --git a/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.h b/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.h
index 833f8b6be..736b57fa1 100644
--- a/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.h
+++ b/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.h
@@ -31,6 +31,12 @@
#include <wtf/Noncopyable.h>
+#if PLATFORM(QT)
+QT_BEGIN_NAMESPACE
+class QOpenGLExtensions;
+QT_END_NAMESPACE
+#endif
+
namespace WebCore {
// TemporaryOpenGLSetting<> is useful for temporarily disabling (or enabling) a particular OpenGL
@@ -43,13 +49,21 @@ namespace WebCore {
class TemporaryOpenGLSetting {
WTF_MAKE_NONCOPYABLE(TemporaryOpenGLSetting);
public:
+#if PLATFORM(QT)
+ TemporaryOpenGLSetting(QOpenGLExtensions*, GC3Denum capability, GC3Denum scopedState);
+#else
TemporaryOpenGLSetting(GC3Denum capability, GC3Denum scopedState);
+#endif
~TemporaryOpenGLSetting();
private:
const GC3Denum m_capability;
const GC3Denum m_scopedState;
GC3Denum m_originalState;
+
+#if PLATFORM(QT)
+ QOpenGLExtensions* m_functions { nullptr };
+#endif
};
}
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index a0b76cc88..7f2f07b60 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -19,13 +19,7 @@
#include "config.h"
#include "GraphicsContext3D.h"
-#if ENABLE(GRAPHICS_CONTEXT_3D)
-
-#if USE(OPENGL_ES_2)
-#include "Extensions3DOpenGLES.h"
-#else
-#include "Extensions3DOpenGL.h"
-#endif
+#include "Extensions3DOpenGLCommon.h"
#include "GraphicsContext.h"
#include "GraphicsSurface.h"
#include "HostWindow.h"
@@ -33,32 +27,51 @@
#include "ImageData.h"
#include "NativeImageQt.h"
#include "NotImplemented.h"
-#include "OpenGLShims.h"
#include "QWebPageClient.h"
#include "SharedBuffer.h"
#include "TextureMapperPlatformLayer.h"
+#include <QOffscreenSurface>
+#include <private/qopenglextensions_p.h>
#include <qpa/qplatformpixmap.h>
#include <wtf/text/CString.h>
-#include <QOffscreenSurface>
-
#if USE(TEXTURE_MAPPER_GL)
#include <texmap/TextureMapperGL.h>
#endif
+#if ENABLE(GRAPHICS_CONTEXT_3D)
+
+QT_BEGIN_NAMESPACE
+extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize&, bool alpha_format, bool include_alpha);
+QT_END_NAMESPACE
+
namespace WebCore {
#if !defined(GLchar)
typedef char GLchar;
#endif
-#if !defined(GL_DEPTH24_STENCIL8)
-#define GL_DEPTH24_STENCIL8 0x88F0
+#ifndef GL_VERTEX_PROGRAM_POINT_SIZE
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
#endif
-class GraphicsContext3DPrivate final
- : public TextureMapperPlatformLayer
-{
+#ifndef GL_POINT_SPRITE
+#define GL_POINT_SPRITE 0x8861
+#endif
+
+#ifndef GL_DEPTH24_STENCIL8
+#define GL_DEPTH24_STENCIL8 0x88F0
+#endif
+
+#ifndef GL_READ_FRAMEBUFFER
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#endif
+
+#ifndef GL_DRAW_FRAMEBUFFER
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#endif
+
+class GraphicsContext3DPrivate final : public TextureMapperPlatformLayer, public QOpenGLExtensions {
public:
GraphicsContext3DPrivate(GraphicsContext3D*, HostWindow*, GraphicsContext3D::RenderStyle);
~GraphicsContext3DPrivate();
@@ -71,13 +84,16 @@ public:
#endif
QRectF boundingRect() const;
- void blitMultisampleFramebuffer() const;
- void blitMultisampleFramebufferAndRestoreContext() const;
+ void blitMultisampleFramebuffer();
+ void blitMultisampleFramebufferAndRestoreContext();
bool makeCurrentIfNeeded() const;
void createOffscreenBuffers();
void initializeANGLE();
void createGraphicsSurfaces(const IntSize&);
+ bool isOpenGLES() const;
+ bool isValid() const;
+
GraphicsContext3D* m_context;
HostWindow* m_hostWindow;
PlatformGraphicsSurface3D m_surface;
@@ -87,10 +103,43 @@ public:
GraphicsSurface::Flags m_surfaceFlags;
RefPtr<GraphicsSurface> m_graphicsSurface;
#endif
+
+ // Register as a child of a Qt context to make the necessary when it may be destroyed before the GraphicsContext3D instance
+ class QtContextWatcher : public QObject {
+ public:
+ QtContextWatcher(QObject* ctx, GraphicsContext3DPrivate* watcher)
+ : QObject(ctx), m_watcher(watcher) { }
+ ~QtContextWatcher() { m_watcher->m_platformContext = 0; m_watcher->m_platformContextWatcher = 0; }
+
+ private:
+ GraphicsContext3DPrivate* m_watcher;
+ };
+ QtContextWatcher* m_platformContextWatcher;
};
+bool GraphicsContext3DPrivate::isOpenGLES() const
+{
+ if (m_platformContext)
+ return m_platformContext->isOpenGLES();
+#if USE(OPENGL_ES_2)
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool GraphicsContext3DPrivate::isValid() const
+{
+ if (!m_platformContext || !m_platformContext->isValid())
+ return false;
+ return m_platformContext->isOpenGLES() || m_platformContext->format().majorVersion() >= 2;
+}
+
bool GraphicsContext3D::isGLES2Compliant() const
{
+ if (m_private)
+ return m_private->isOpenGLES();
+ ASSERT_NOT_REACHED();
#if USE(OPENGL_ES_2)
return true;
#else
@@ -104,17 +153,23 @@ GraphicsContext3DPrivate::GraphicsContext3DPrivate(GraphicsContext3D* context, H
, m_surface(0)
, m_platformContext(0)
, m_surfaceOwner(0)
+ , m_platformContextWatcher(0)
{
if (renderStyle == GraphicsContext3D::RenderToCurrentGLContext) {
m_platformContext = QOpenGLContext::currentContext();
if (m_platformContext)
m_surface = m_platformContext->surface();
+
+ // Watcher needed to invalidate the GL context if destroyed before this instance
+ m_platformContextWatcher = new QtContextWatcher(m_platformContext, this);
+
+ initializeOpenGLFunctions();
return;
}
QOpenGLContext* shareContext = 0;
- if (hostWindow && hostWindow->platformPageClient() && hostWindow->platformPageClient()->makeOpenGLContextCurrentIfAvailable())
- shareContext = QOpenGLContext::currentContext();
+ if (hostWindow && hostWindow->platformPageClient())
+ shareContext = hostWindow->platformPageClient()->openGLContextIfAvailable();
QOffscreenSurface* surface = new QOffscreenSurface;
surface->create();
@@ -125,15 +180,18 @@ GraphicsContext3DPrivate::GraphicsContext3DPrivate(GraphicsContext3D* context, H
if (shareContext)
m_platformContext->setShareContext(shareContext);
- if (!m_platformContext->create())
+ if (!m_platformContext->create()) {
+ delete m_platformContext;
+ m_platformContext = 0;
return;
+ }
makeCurrentIfNeeded();
+ initializeOpenGLFunctions();
#if USE(GRAPHICS_SURFACE)
IntSize surfaceSize(m_context->m_currentWidth, m_context->m_currentHeight);
- m_surfaceFlags = GraphicsSurface::SupportsTextureTarget
- | GraphicsSurface::SupportsSharing;
+ m_surfaceFlags = GraphicsSurface::SupportsTextureTarget | GraphicsSurface::SupportsSharing;
if (!surfaceSize.isEmpty())
m_graphicsSurface = GraphicsSurface::create(surfaceSize, m_surfaceFlags, m_platformContext);
@@ -145,31 +203,31 @@ void GraphicsContext3DPrivate::createOffscreenBuffers()
glGenFramebuffers(/* count */ 1, &m_context->m_fbo);
glGenTextures(1, &m_context->m_texture);
- glBindTexture(GraphicsContext3D::TEXTURE_2D, m_context->m_texture);
- glTexParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
- glTexParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
- glTexParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
- glTexParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
- glBindTexture(GraphicsContext3D::TEXTURE_2D, 0);
+ glBindTexture(GL_TEXTURE_2D, m_context->m_texture);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glBindTexture(GL_TEXTURE_2D, 0);
// Create a multisample FBO.
if (m_context->m_attrs.antialias) {
glGenFramebuffers(1, &m_context->m_multisampleFBO);
- glBindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_context->m_multisampleFBO);
+ glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_multisampleFBO);
m_context->m_state.boundFBO = m_context->m_multisampleFBO;
glGenRenderbuffers(1, &m_context->m_multisampleColorBuffer);
if (m_context->m_attrs.stencil || m_context->m_attrs.depth)
glGenRenderbuffers(1, &m_context->m_multisampleDepthStencilBuffer);
} else {
// Bind canvas FBO.
- glBindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_context->m_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_fbo);
m_context->m_state.boundFBO = m_context->m_fbo;
-#if USE(OPENGL_ES_2)
- if (m_context->m_attrs.depth)
- glGenRenderbuffers(1, &m_context->m_depthBuffer);
- if (m_context->m_attrs.stencil)
- glGenRenderbuffers(1, &m_context->m_stencilBuffer);
-#endif
+ if (isOpenGLES()) {
+ if (m_context->m_attrs.depth)
+ glGenRenderbuffers(1, &m_context->m_depthBuffer);
+ if (m_context->m_attrs.stencil)
+ glGenRenderbuffers(1, &m_context->m_stencilBuffer);
+ }
if (m_context->m_attrs.stencil || m_context->m_attrs.depth)
glGenRenderbuffers(1, &m_context->m_depthStencilBuffer);
}
@@ -206,11 +264,9 @@ GraphicsContext3DPrivate::~GraphicsContext3DPrivate()
{
delete m_surfaceOwner;
m_surfaceOwner = 0;
-}
-static inline quint32 swapBgrToRgb(quint32 pixel)
-{
- return (((pixel << 16) | (pixel >> 16)) & 0x00ff00ff) | (pixel & 0xff00ff00);
+ delete m_platformContextWatcher;
+ m_platformContextWatcher = 0;
}
void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper& textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity)
@@ -218,34 +274,15 @@ void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper& textureMapper
m_context->markLayerComposited();
blitMultisampleFramebufferAndRestoreContext();
- // FIXME: For now we have OpenGLMode only
-// if (textureMapper->accelerationMode() == TextureMapper::OpenGLMode) {
+ if (textureMapper.accelerationMode() == TextureMapper::OpenGLMode) {
TextureMapperGL& texmapGL = static_cast<TextureMapperGL&>(textureMapper);
-#if USE(GRAPHICS_SURFACE)
- ASSERT(m_graphicsSurface);
- // CGL only provides us the context, but not the view the context is currently bound to.
- // To make sure the context is bound the the right surface we have to do a makeCurrent through QOpenGL again.
- // FIXME: Remove this code as soon as GraphicsSurfaceMac makes use of NSOpenGL.
- QOpenGLContext* currentContext = QOpenGLContext::currentContext();
- QSurface* currentSurface = currentContext->surface();
- makeCurrentIfNeeded();
-
- m_graphicsSurface->copyFromTexture(m_context->m_texture, IntRect(0, 0, m_context->m_currentWidth, m_context->m_currentHeight));
-
- // CGL only provides us the context, but not the view the context is currently bound to.
- // To make sure the context is bound the the right surface we have to do a makeCurrent through QOpenGL again.
- // FIXME: Remove this code as soon as GraphicsSurfaceMac makes use of NSOpenGL.
- currentContext->makeCurrent(currentSurface);
-
- m_graphicsSurface->paintToTextureMapper(texmapGL, targetRect, matrix, opacity);
-#else
TextureMapperGL::Flags flags = TextureMapperGL::ShouldFlipTexture | (m_context->m_attrs.alpha ? TextureMapperGL::ShouldBlend : 0);
IntSize textureSize(m_context->m_currentWidth, m_context->m_currentHeight);
texmapGL.drawTexture(m_context->m_texture, flags, textureSize, targetRect, matrix, opacity);
-#endif
return;
-// }
+ }
+ // Alternatively read pixels to a memory buffer.
GraphicsContext* context = textureMapper.graphicsContext();
QPainter* painter = context->platformContext();
painter->save();
@@ -255,36 +292,13 @@ void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper& textureMapper
const int height = m_context->m_currentHeight;
const int width = m_context->m_currentWidth;
- // Alternatively read pixels to a memory buffer.
- QImage offscreenImage(width, height, QImage::Format_ARGB32);
- quint32* imagePixels = reinterpret_cast<quint32*>(offscreenImage.bits());
-
+ painter->beginNativePainting();
makeCurrentIfNeeded();
- glBindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_context->m_fbo);
- glReadPixels(/* x */ 0, /* y */ 0, width, height, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, imagePixels);
- glBindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_context->m_state.boundFBO);
-
- // OpenGL gives us ABGR on 32 bits, and with the origin at the bottom left
- // We need RGB32 or ARGB32_PM, with the origin at the top left.
- quint32* pixelsSrc = imagePixels;
- const int halfHeight = height / 2;
- for (int row = 0; row < halfHeight; ++row) {
- const int targetIdx = (height - 1 - row) * width;
- quint32* pixelsDst = imagePixels + targetIdx;
- for (int column = 0; column < width; ++column) {
- quint32 tempPixel = *pixelsSrc;
- *pixelsSrc = swapBgrToRgb(*pixelsDst);
- *pixelsDst = swapBgrToRgb(tempPixel);
- ++pixelsSrc;
- ++pixelsDst;
- }
- }
- if (static_cast<int>(height) % 2) {
- for (int column = 0; column < width; ++column) {
- *pixelsSrc = swapBgrToRgb(*pixelsSrc);
- ++pixelsSrc;
- }
- }
+ glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_fbo);
+ QImage offscreenImage = qt_gl_read_framebuffer(QSize(width, height), true, true);
+ glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_state.boundFBO);
+
+ painter->endNativePainting();
painter->drawImage(targetRect, offscreenImage);
painter->restore();
@@ -318,19 +332,21 @@ QRectF GraphicsContext3DPrivate::boundingRect() const
return QRectF(QPointF(0, 0), QSizeF(m_context->m_currentWidth, m_context->m_currentHeight));
}
-void GraphicsContext3DPrivate::blitMultisampleFramebuffer() const
+void GraphicsContext3DPrivate::blitMultisampleFramebuffer()
{
if (!m_context->m_attrs.antialias)
return;
-#if !USE(OPENGL_ES_2)
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_context->m_multisampleFBO);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, m_context->m_fbo);
- glBlitFramebuffer(0, 0, m_context->m_currentWidth, m_context->m_currentHeight, 0, 0, m_context->m_currentWidth, m_context->m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
-#endif
- glBindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_context->m_state.boundFBO);
+
+ if (!isOpenGLES()) {
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, m_context->m_multisampleFBO);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_context->m_fbo);
+ glBlitFramebuffer(0, 0, m_context->m_currentWidth, m_context->m_currentHeight, 0, 0, m_context->m_currentWidth, m_context->m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_state.boundFBO);
}
-void GraphicsContext3DPrivate::blitMultisampleFramebufferAndRestoreContext() const
+void GraphicsContext3DPrivate::blitMultisampleFramebufferAndRestoreContext()
{
const QOpenGLContext* currentContext = QOpenGLContext::currentContext();
QSurface* currentSurface = 0;
@@ -352,6 +368,8 @@ void GraphicsContext3DPrivate::blitMultisampleFramebufferAndRestoreContext() con
bool GraphicsContext3DPrivate::makeCurrentIfNeeded() const
{
+ if (!m_platformContext)
+ return false;
const QOpenGLContext* currentContext = QOpenGLContext::currentContext();
if (currentContext == m_platformContext)
return true;
@@ -382,39 +400,34 @@ PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attri
GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
: m_currentWidth(0)
, m_currentHeight(0)
- , m_compiler(isGLES2Compliant() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT)
, m_attrs(attrs)
, m_renderStyle(renderStyle)
, m_texture(0)
, m_compositorTexture(0)
, m_fbo(0)
-#if USE(OPENGL_ES_2)
, m_depthBuffer(0)
, m_stencilBuffer(0)
-#endif
, m_depthStencilBuffer(0)
, m_layerComposited(false)
, m_internalColorFormat(0)
, m_multisampleFBO(0)
, m_multisampleDepthStencilBuffer(0)
, m_multisampleColorBuffer(0)
+ , m_functions(0)
, m_private(std::make_unique<GraphicsContext3DPrivate>(this, hostWindow, renderStyle))
+ , m_compiler(isGLES2Compliant() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT)
+ , m_webglContext(nullptr)
{
- validateAttributes();
-
if (!m_private->m_surface || !m_private->m_platformContext) {
LOG_ERROR("GraphicsContext3D: GL context creation failed.");
m_private = nullptr;
return;
}
- static bool initialized = false;
- static bool success = true;
- if (!initialized) {
- success = initializeOpenGLShims();
- initialized = true;
- }
- if (!success) {
+ m_functions = m_private.get();
+ validateAttributes();
+
+ if (!m_private->isValid()) {
m_private = nullptr;
return;
}
@@ -424,13 +437,13 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi
m_private->initializeANGLE();
-#if !USE(OPENGL_ES_2)
- glEnable(GL_POINT_SPRITE);
- glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
-#endif
+ if (!isGLES2Compliant()) {
+ m_functions->glEnable(GL_POINT_SPRITE);
+ m_functions->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
+ }
if (renderStyle != RenderToCurrentGLContext)
- glClearColor(0.0, 0.0, 0.0, 0.0);
+ m_functions->glClearColor(0.0, 0.0, 0.0, 0.0);
}
GraphicsContext3D::~GraphicsContext3D()
@@ -439,23 +452,26 @@ GraphicsContext3D::~GraphicsContext3D()
if (!m_private)
return;
- makeContextCurrent();
- glDeleteTextures(1, &m_texture);
- glDeleteFramebuffers(1, &m_fbo);
- if (m_attrs.antialias) {
- glDeleteRenderbuffers(1, &m_multisampleColorBuffer);
- glDeleteFramebuffers(1, &m_multisampleFBO);
- if (m_attrs.stencil || m_attrs.depth)
- glDeleteRenderbuffers(1, &m_multisampleDepthStencilBuffer);
- } else if (m_attrs.stencil || m_attrs.depth) {
-#if USE(OPENGL_ES_2)
- if (m_attrs.depth)
- glDeleteRenderbuffers(1, &m_depthBuffer);
- if (m_attrs.stencil)
- glDeleteRenderbuffers(1, &m_stencilBuffer);
-#endif
- glDeleteRenderbuffers(1, &m_depthStencilBuffer);
+ if (makeContextCurrent()) {
+ m_functions->glDeleteTextures(1, &m_texture);
+ m_functions->glDeleteFramebuffers(1, &m_fbo);
+ if (m_attrs.antialias) {
+ m_functions->glDeleteRenderbuffers(1, &m_multisampleColorBuffer);
+ m_functions->glDeleteFramebuffers(1, &m_multisampleFBO);
+ if (m_attrs.stencil || m_attrs.depth)
+ m_functions->glDeleteRenderbuffers(1, &m_multisampleDepthStencilBuffer);
+ } else if (m_attrs.stencil || m_attrs.depth) {
+ if (isGLES2Compliant()) {
+ if (m_attrs.depth)
+ m_functions->glDeleteRenderbuffers(1, &m_depthBuffer);
+ if (m_attrs.stencil)
+ m_functions->glDeleteRenderbuffers(1, &m_stencilBuffer);
+ }
+ m_functions->glDeleteRenderbuffers(1, &m_depthStencilBuffer);
+ }
}
+
+ m_functions = 0;
}
PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D()
@@ -475,7 +491,7 @@ PlatformLayer* GraphicsContext3D::platformLayer() const
bool GraphicsContext3D::makeContextCurrent()
{
- if (!m_private || m_renderStyle == RenderToCurrentGLContext)
+ if (!m_private)
return false;
return m_private->makeCurrentIfNeeded();
}
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index d1ab885d9..00bcb8532 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -49,6 +49,7 @@
#include "FloatConversion.h"
#include "Font.h"
#include "ImageBuffer.h"
+#include "ImageBufferDataQt.h"
#include "NotImplemented.h"
#include "Path.h"
#include "Pattern.h"
@@ -959,15 +960,8 @@ void GraphicsContext::clipToImageBuffer(ImageBuffer& buffer, const FloatRect& de
if (paintingDisabled())
return;
- RefPtr<Image> image = buffer.copyImage(DontCopyBackingStore);
- QPixmap* nativeImage = image->nativeImageForCurrentFrame();
- if (!nativeImage)
- return;
-
IntRect rect = enclosingIntRect(destRect);
- QPixmap alphaMask = *nativeImage;
-
- pushTransparencyLayerInternal(rect, 1.0, alphaMask);
+ buffer.m_data.m_impl->clip(*this, rect);
}
void drawFocusRingForPath(QPainter* p, const QPainterPath& path, const Color& color, bool antiAliasing)
@@ -1553,7 +1547,7 @@ void GraphicsContext::setCTM(const AffineTransform& transform)
m_data->p()->setWorldTransform(transform);
}
-#if ENABLE(3D_RENDERING)
+#if ENABLE(3D_TRANSFORMS)
TransformationMatrix GraphicsContext::get3DTransform() const
{
if (paintingDisabled())
@@ -1757,6 +1751,10 @@ void GraphicsContext::takeOwnershipOfPlatformContext()
m_data->takeOwnershipOfPlatformContext();
}
+bool GraphicsContext::isAcceleratedContext() const
+{
+ return (platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2);
}
+}
// vim: ts=4 sw=4 et
diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp
new file mode 100644
index 000000000..b277fd421
--- /dev/null
+++ b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.cpp
@@ -0,0 +1,538 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2008 Holger Hans Peter Freyther
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
+ * Copyright (C) 2014 Digia Plc. and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ImageBuffer.h"
+
+#include "GraphicsContext.h"
+#include "GraphicsSurface.h"
+#include "ImageData.h"
+#include "IntRect.h"
+#include "StillImageQt.h"
+
+#include <QImage>
+#include <QPaintEngine>
+#include <QPainter>
+#include <QPixmap>
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+#include "QFramebufferPaintDevice.h"
+#include "TextureMapper.h"
+#include "TextureMapperGL.h"
+#include "TextureMapperPlatformLayer.h"
+#include <QOffscreenSurface>
+#include <QOpenGLContext>
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLPaintDevice>
+#include <QThreadStorage>
+#include <private/qopenglpaintengine_p.h>
+#endif
+
+namespace WebCore {
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+
+class QOpenGLContextThreadStorage {
+public:
+ QOpenGLContext* context()
+ {
+ QOpenGLContext*& context = storage.localData();
+ if (!context) {
+ context = new QOpenGLContext;
+ context->create();
+ }
+ return context;
+ }
+
+private:
+ QThreadStorage<QOpenGLContext*> storage;
+};
+
+Q_GLOBAL_STATIC(QOpenGLContextThreadStorage, imagebuffer_opengl_context)
+
+// The owner of the surface needs to be separate from QFramebufferPaintDevice, since the surface
+// must already be current with the QFramebufferObject constructor is called.
+class ImageBufferContext {
+public:
+ ImageBufferContext(QOpenGLContext* sharedContext)
+ : m_ownSurface(0)
+ {
+ if (sharedContext)
+ m_format = sharedContext->format();
+
+ m_context = sharedContext ? sharedContext : imagebuffer_opengl_context->context();
+
+ m_surface = m_context->surface();
+ }
+ ~ImageBufferContext()
+ {
+ if (QOpenGLContext::currentContext() == m_context && m_context->surface() == m_ownSurface)
+ m_context->doneCurrent();
+ delete m_ownSurface;
+ }
+ void createSurfaceIfNeeded()
+ {
+ if (m_surface)
+ return;
+
+ m_ownSurface = new QOffscreenSurface;
+ m_ownSurface->setFormat(m_format);
+ m_ownSurface->create();
+
+ m_surface = m_ownSurface;
+ }
+ void makeCurrentIfNeeded()
+ {
+ if (QOpenGLContext::currentContext() != m_context) {
+ createSurfaceIfNeeded();
+
+ m_context->makeCurrent(m_surface);
+ }
+ }
+ QOpenGLContext* context() { return m_context; }
+
+private:
+ QSurface* m_surface;
+ QOffscreenSurface* m_ownSurface;
+ QOpenGLContext* m_context;
+ QSurfaceFormat m_format;
+};
+
+// ---------------------- ImageBufferDataPrivateAccelerated
+
+struct ImageBufferDataPrivateAccelerated final : public TextureMapperPlatformLayer, public ImageBufferDataPrivate {
+ ImageBufferDataPrivateAccelerated(const IntSize&, QOpenGLContext* sharedContext);
+ virtual ~ImageBufferDataPrivateAccelerated();
+
+ QPaintDevice* paintDevice() final { return m_paintDevice; }
+ QImage toQImage() const final;
+ RefPtr<Image> image() const final;
+ RefPtr<Image> copyImage() const final;
+ RefPtr<Image> takeImage() final;
+ bool isAccelerated() const final { return true; }
+ PlatformLayer* platformLayer() final { return this; }
+
+ void invalidateState() const;
+ void draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect,
+ CompositeOperator, BlendMode, bool ownContext) final;
+ void drawPattern(GraphicsContext& destContext, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, const FloatSize& spacing, CompositeOperator,
+ const FloatRect& destRect, BlendMode, bool ownContext) final;
+ void clip(GraphicsContext&, const IntRect& floatRect) const final;
+ void platformTransformColorSpace(const Vector<int>& lookUpTable) final;
+
+ // TextureMapperPlatformLayer:
+ void paintToTextureMapper(TextureMapper&, const FloatRect&, const TransformationMatrix& modelViewMatrix = TransformationMatrix(), float opacity = 1.0) final;
+#if USE(GRAPHICS_SURFACE)
+ IntSize platformLayerSize() const final;
+ uint32_t copyToGraphicsSurface() final;
+ GraphicsSurfaceToken graphicsSurfaceToken() const final;
+ RefPtr<GraphicsSurface> m_graphicsSurface;
+#endif
+private:
+ QFramebufferPaintDevice* m_paintDevice;
+ ImageBufferContext* m_context;
+};
+
+ImageBufferDataPrivateAccelerated::ImageBufferDataPrivateAccelerated(const IntSize& size, QOpenGLContext* sharedContext)
+{
+ m_context = new ImageBufferContext(sharedContext);
+ m_context->makeCurrentIfNeeded();
+
+ m_paintDevice = new QFramebufferPaintDevice(size);
+}
+
+ImageBufferDataPrivateAccelerated::~ImageBufferDataPrivateAccelerated()
+{
+ if (client())
+ client()->platformLayerWillBeDestroyed();
+ delete m_paintDevice;
+ delete m_context;
+}
+
+QImage ImageBufferDataPrivateAccelerated::toQImage() const
+{
+ invalidateState();
+ return m_paintDevice->toImage();
+}
+
+RefPtr<Image> ImageBufferDataPrivateAccelerated::image() const
+{
+ return copyImage();
+}
+
+RefPtr<Image> ImageBufferDataPrivateAccelerated::copyImage() const
+{
+ return StillImage::create(QPixmap::fromImage(toQImage()));
+}
+
+RefPtr<Image> ImageBufferDataPrivateAccelerated::takeImage()
+{
+ return StillImage::create(QPixmap::fromImage(toQImage()));
+}
+
+void ImageBufferDataPrivateAccelerated::invalidateState() const
+{
+ // This will flush pending QPainter operations and force ensureActiveTarget() to be called on the next paint.
+ QOpenGL2PaintEngineEx* acceleratedPaintEngine = static_cast<QOpenGL2PaintEngineEx*>(m_paintDevice->paintEngine());
+ acceleratedPaintEngine->invalidateState();
+}
+
+void ImageBufferDataPrivateAccelerated::draw(GraphicsContext& destContext, const FloatRect& destRect,
+ const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, bool /*ownContext*/)
+{
+ if (destContext.isAcceleratedContext()) {
+ invalidateState();
+
+ // If accelerated compositing is disabled, this may be the painter of the QGLWidget, which is a QGL2PaintEngineEx.
+ QOpenGL2PaintEngineEx* acceleratedPaintEngine = dynamic_cast<QOpenGL2PaintEngineEx*>(destContext.platformContext()->paintEngine()); // toQOpenGL2PaintEngineEx(destContext.platformContext()->paintEngine());
+ if (acceleratedPaintEngine) {
+ QPaintDevice* targetPaintDevice = acceleratedPaintEngine->paintDevice();
+
+ QRect rect(QPoint(), m_paintDevice->size());
+
+ // drawTexture's rendering is flipped relative to QtWebKit's convention, so we need to compensate
+ FloatRect srcRectFlipped = m_paintDevice->paintFlipped()
+ ? FloatRect(srcRect.x(), srcRect.maxY(), srcRect.width(), -srcRect.height())
+ : FloatRect(srcRect.x(), rect.height() - srcRect.maxY(), srcRect.width(), srcRect.height());
+
+ // Using the same texture as source and target of a rendering operation is undefined in OpenGL,
+ // so if that's the case we need to use a temporary intermediate buffer.
+ if (m_paintDevice == targetPaintDevice) {
+ m_context->makeCurrentIfNeeded();
+
+ QFramebufferPaintDevice device(rect.size(), QOpenGLFramebufferObject::NoAttachment, false);
+
+ // We disable flipping in order to do a pure blit into the intermediate buffer
+ device.setPaintFlipped(false);
+
+ QPainter painter(&device);
+ QOpenGL2PaintEngineEx* pe = static_cast<QOpenGL2PaintEngineEx*>(painter.paintEngine());
+ pe->drawTexture(rect, m_paintDevice->texture(), rect.size(), rect);
+ painter.end();
+
+ acceleratedPaintEngine->drawTexture(destRect, device.texture(), rect.size(), srcRectFlipped);
+ } else {
+ acceleratedPaintEngine->drawTexture(destRect, m_paintDevice->texture(), rect.size(), srcRectFlipped);
+ }
+
+ return;
+ }
+ }
+ RefPtr<Image> image = StillImage::create(QPixmap::fromImage(toQImage()));
+ destContext.drawImage(*image, destRect, srcRect, ImagePaintingOptions(op, blendMode, DoNotRespectImageOrientation));
+}
+
+
+void ImageBufferDataPrivateAccelerated::drawPattern(GraphicsContext& destContext, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode, bool /*ownContext*/)
+{
+ RefPtr<Image> image = StillImage::create(QPixmap::fromImage(toQImage()));
+ image->drawPattern(destContext, srcRect, patternTransform, phase, spacing, op, destRect, blendMode);
+}
+
+void ImageBufferDataPrivateAccelerated::clip(GraphicsContext& context, const IntRect& rect) const
+{
+ QPixmap alphaMask = QPixmap::fromImage(toQImage());
+ context.pushTransparencyLayerInternal(rect, 1.0, alphaMask);
+}
+
+void ImageBufferDataPrivateAccelerated::platformTransformColorSpace(const Vector<int>& lookUpTable)
+{
+ QPainter* painter = paintDevice()->paintEngine()->painter();
+
+ QImage image = toQImage().convertToFormat(QImage::Format_ARGB32);
+ ASSERT(!image.isNull());
+
+ uchar* bits = image.bits();
+ const int bytesPerLine = image.bytesPerLine();
+
+ for (int y = 0; y < image.height(); ++y) {
+ quint32* scanLine = reinterpret_cast_ptr<quint32*>(bits + y * bytesPerLine);
+ for (int x = 0; x < image.width(); ++x) {
+ QRgb& pixel = scanLine[x];
+ pixel = qRgba(lookUpTable[qRed(pixel)],
+ lookUpTable[qGreen(pixel)],
+ lookUpTable[qBlue(pixel)],
+ qAlpha(pixel));
+ }
+ }
+
+ painter->save();
+ painter->resetTransform();
+ painter->setOpacity(1.0);
+ painter->setClipping(false);
+ painter->setCompositionMode(QPainter::CompositionMode_Source);
+ painter->drawImage(QPoint(0, 0), image);
+ painter->restore();
+}
+
+void ImageBufferDataPrivateAccelerated::paintToTextureMapper(TextureMapper& textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity)
+{
+ bool canRenderDirectly = false;
+ if (textureMapper.accelerationMode() == TextureMapper::OpenGLMode) {
+ if (QOpenGLContext::areSharing(m_context->context(),
+ static_cast<TextureMapperGL&>(textureMapper).graphicsContext3D()->platformGraphicsContext3D()))
+ {
+ canRenderDirectly = true;
+ }
+ }
+
+ if (!canRenderDirectly) {
+ QImage image = toQImage();
+ TransformationMatrix oldTransform = textureMapper.graphicsContext()->get3DTransform();
+ textureMapper.graphicsContext()->concat3DTransform(matrix);
+ textureMapper.graphicsContext()->platformContext()->drawImage(targetRect, image);
+ textureMapper.graphicsContext()->set3DTransform(oldTransform);
+ return;
+ }
+
+ invalidateState();
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+ static_cast<TextureMapperGL&>(textureMapper).drawTexture(m_paintDevice->texture(), TextureMapperGL::ShouldBlend, m_paintDevice->size(), targetRect, matrix, opacity);
+#else
+ static_cast<TextureMapperGL&>(textureMapper).drawTexture(m_paintDevice->texture(), TextureMapperGL::ShouldBlend | TextureMapperGL::ShouldFlipTexture, m_paintDevice->size(), targetRect, matrix, opacity);
+#endif
+}
+
+#if USE(GRAPHICS_SURFACE)
+IntSize ImageBufferDataPrivateAccelerated::platformLayerSize() const
+{
+ return m_paintDevice->size();
+}
+
+uint32_t ImageBufferDataPrivateAccelerated::copyToGraphicsSurface()
+{
+ if (!m_graphicsSurface) {
+ GraphicsSurface::Flags flags = GraphicsSurface::SupportsAlpha | GraphicsSurface::SupportsTextureTarget | GraphicsSurface::SupportsSharing;
+ m_graphicsSurface = GraphicsSurface::create(m_paintDevice->size(), flags);
+ }
+
+ invalidateState();
+
+ m_graphicsSurface->copyFromTexture(m_paintDevice->texture(), IntRect(IntPoint(), m_paintDevice->size()));
+ return m_graphicsSurface->swapBuffers();
+}
+
+GraphicsSurfaceToken ImageBufferDataPrivateAccelerated::graphicsSurfaceToken() const
+{
+ return m_graphicsSurface->exportToken();
+}
+#endif // USE(GRAPHICS_SURFACE)
+
+#endif // ENABLE(ACCELERATED_2D_CANVAS)
+
+// ---------------------- ImageBufferDataPrivateUnaccelerated
+
+struct ImageBufferDataPrivateUnaccelerated final : public ImageBufferDataPrivate {
+ ImageBufferDataPrivateUnaccelerated(const IntSize&);
+ QPaintDevice* paintDevice() final { return m_pixmap.isNull() ? 0 : &m_pixmap; }
+ QImage toQImage() const final;
+ RefPtr<Image> image() const final;
+ RefPtr<Image> copyImage() const final;
+ RefPtr<Image> takeImage() final;
+ bool isAccelerated() const final { return false; }
+ PlatformLayer* platformLayer() final { return 0; }
+ void draw(GraphicsContext& destContext, const FloatRect& destRect,
+ const FloatRect& srcRect, CompositeOperator, BlendMode, bool ownContext) final;
+ void drawPattern(GraphicsContext& destContext, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, const FloatSize& spacing, CompositeOperator,
+ const FloatRect& destRect, BlendMode, bool ownContext) final;
+ void clip(GraphicsContext&, const IntRect& floatRect) const final;
+ void platformTransformColorSpace(const Vector<int>& lookUpTable) final;
+
+ QPixmap m_pixmap;
+ RefPtr<Image> m_image;
+};
+
+ImageBufferDataPrivateUnaccelerated::ImageBufferDataPrivateUnaccelerated(const IntSize& size)
+ : m_pixmap(size)
+ , m_image(StillImage::createForRendering(&m_pixmap))
+{
+ m_pixmap.fill(QColor(Qt::transparent));
+}
+
+QImage ImageBufferDataPrivateUnaccelerated::toQImage() const
+{
+ QPaintEngine* paintEngine = m_pixmap.paintEngine();
+ if (!paintEngine || paintEngine->type() != QPaintEngine::Raster)
+ return m_pixmap.toImage();
+
+ // QRasterPixmapData::toImage() will deep-copy the backing QImage if there's an active QPainter on it.
+ // For performance reasons, we don't want that here, so we temporarily redirect the paint engine.
+ QPaintDevice* currentPaintDevice = paintEngine->paintDevice();
+ paintEngine->setPaintDevice(0);
+ QImage image = m_pixmap.toImage();
+ paintEngine->setPaintDevice(currentPaintDevice);
+ return image;
+}
+
+RefPtr<Image> ImageBufferDataPrivateUnaccelerated::image() const
+{
+ return StillImage::createForRendering(&m_pixmap);
+}
+
+RefPtr<Image> ImageBufferDataPrivateUnaccelerated::copyImage() const
+{
+ return StillImage::create(m_pixmap);
+}
+
+RefPtr<Image> ImageBufferDataPrivateUnaccelerated::takeImage()
+{
+ return StillImage::create(WTFMove(m_pixmap));
+}
+
+void ImageBufferDataPrivateUnaccelerated::draw(GraphicsContext& destContext, const FloatRect& destRect,
+ const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, bool ownContext)
+{
+ if (ownContext) {
+ // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first.
+ RefPtr<Image> copy = copyImage();
+ destContext.drawImage(*copy, destRect, srcRect, ImagePaintingOptions(op, blendMode, ImageOrientationDescription()));
+ } else
+ destContext.drawImage(*m_image, destRect, srcRect, ImagePaintingOptions(op, blendMode, ImageOrientationDescription()));
+}
+
+void ImageBufferDataPrivateUnaccelerated::drawPattern(GraphicsContext& destContext, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op,
+ const FloatRect& destRect, BlendMode blendMode, bool ownContext)
+{
+ if (ownContext) {
+ // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first.
+ RefPtr<Image> copy = copyImage();
+ copy->drawPattern(destContext, srcRect, patternTransform, phase, spacing, op, destRect, blendMode);
+ } else
+ m_image->drawPattern(destContext, srcRect, patternTransform, phase, spacing, op, destRect, blendMode);
+}
+
+void ImageBufferDataPrivateUnaccelerated::clip(GraphicsContext& context, const IntRect& rect) const
+{
+ QPixmap* nativeImage = m_image->nativeImageForCurrentFrame();
+ if (!nativeImage)
+ return;
+
+ QPixmap alphaMask = *nativeImage;
+ context.pushTransparencyLayerInternal(rect, 1.0, alphaMask);
+}
+
+void ImageBufferDataPrivateUnaccelerated::platformTransformColorSpace(const Vector<int>& lookUpTable)
+{
+ QPainter* painter = paintDevice()->paintEngine()->painter();
+
+ bool isPainting = painter->isActive();
+ if (isPainting)
+ painter->end();
+
+ QImage image = toQImage().convertToFormat(QImage::Format_ARGB32);
+ ASSERT(!image.isNull());
+
+ uchar* bits = image.bits();
+ const int bytesPerLine = image.bytesPerLine();
+
+ for (int y = 0; y < m_pixmap.height(); ++y) {
+ quint32* scanLine = reinterpret_cast_ptr<quint32*>(bits + y * bytesPerLine);
+ for (int x = 0; x < m_pixmap.width(); ++x) {
+ QRgb& pixel = scanLine[x];
+ pixel = qRgba(lookUpTable[qRed(pixel)],
+ lookUpTable[qGreen(pixel)],
+ lookUpTable[qBlue(pixel)],
+ qAlpha(pixel));
+ }
+ }
+
+ m_pixmap = QPixmap::fromImage(image);
+
+ if (isPainting)
+ painter->begin(&m_pixmap);
+}
+
+// ---------------------- ImageBufferData
+
+ImageBufferData::ImageBufferData(const IntSize& size)
+{
+ m_painter = new QPainter;
+
+ m_impl = new ImageBufferDataPrivateUnaccelerated(size);
+
+ if (!m_impl->paintDevice())
+ return;
+ if (!m_painter->begin(m_impl->paintDevice()))
+ return;
+
+ initPainter();
+}
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ImageBufferData::ImageBufferData(const IntSize& size, QOpenGLContext* compatibleContext)
+{
+ m_painter = new QPainter;
+
+ m_impl = new ImageBufferDataPrivateAccelerated(size, compatibleContext);
+
+ if (!m_impl->paintDevice())
+ return;
+ if (!m_painter->begin(m_impl->paintDevice()))
+ return;
+
+ initPainter();
+}
+#endif
+
+ImageBufferData::~ImageBufferData()
+{
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ if (m_impl->isAccelerated())
+ static_cast<QFramebufferPaintDevice*>(m_impl->paintDevice())->ensureActiveTarget();
+#endif
+ m_painter->end();
+ delete m_painter;
+ delete m_impl;
+}
+
+void ImageBufferData::initPainter()
+{
+ m_painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
+
+ // Since ImageBuffer is used mainly for Canvas, explicitly initialize
+ // its painter's pen and brush with the corresponding canvas defaults
+ // NOTE: keep in sync with CanvasRenderingContext2D::State
+ QPen pen = m_painter->pen();
+ pen.setColor(Qt::black);
+ pen.setWidth(1);
+ pen.setCapStyle(Qt::FlatCap);
+ pen.setJoinStyle(Qt::SvgMiterJoin);
+ pen.setMiterLimit(10);
+ m_painter->setPen(pen);
+ QBrush brush = m_painter->brush();
+ brush.setColor(Qt::black);
+ m_painter->setBrush(brush);
+ m_painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h
index abd51a584..2ead943ca 100644
--- a/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h
+++ b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h
@@ -23,10 +23,20 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef ImageBufferDataQt_h
+#define ImageBufferDataQt_h
+
#include "Image.h"
+#include "PlatformLayer.h"
+
+#include <QImage>
+#include <QPaintDevice>
#include <QPainter>
-#include <QPixmap>
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+#include <QOpenGLContext>
+#endif
#include <wtf/RefPtr.h>
@@ -34,16 +44,39 @@ namespace WebCore {
class IntSize;
+struct ImageBufferDataPrivate {
+ virtual ~ImageBufferDataPrivate() { }
+ virtual QPaintDevice* paintDevice() = 0;
+ virtual QImage toQImage() const = 0;
+ virtual RefPtr<Image> image() const = 0;
+ virtual RefPtr<Image> copyImage() const = 0;
+ virtual RefPtr<Image> takeImage() = 0;
+ virtual bool isAccelerated() const = 0;
+ virtual PlatformLayer* platformLayer() = 0;
+ virtual void draw(GraphicsContext& destContext, const FloatRect& destRect,
+ const FloatRect& srcRect, CompositeOperator, BlendMode,
+ bool ownContext) = 0;
+ virtual void drawPattern(GraphicsContext& destContext, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, const FloatSize& spacing, CompositeOperator,
+ const FloatRect& destRect, BlendMode, bool ownContext) = 0;
+ virtual void clip(GraphicsContext&, const IntRect& floatRect) const = 0;
+ virtual void platformTransformColorSpace(const Vector<int>& lookUpTable) = 0;
+};
+
class ImageBufferData {
public:
ImageBufferData(const IntSize&);
-
- QImage toQImage() const;
-
- QPixmap m_pixmap;
- std::unique_ptr<QPainter> m_painter;
- RefPtr<Image> m_image;
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ ImageBufferData(const IntSize&, QOpenGLContext*);
+#endif
+ ~ImageBufferData();
+ QPainter* m_painter;
std::unique_ptr<GraphicsContext> m_context;
+ ImageBufferDataPrivate* m_impl;
+protected:
+ void initPainter();
};
} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index b0990b3ee..885c43f92 100644
--- a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -3,6 +3,7 @@
* Copyright (C) 2008 Holger Hans Peter Freyther
* Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
* Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
+ * Copyright (C) 2014 Digia Plc. and/or its subsidiary(-ies)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -41,7 +42,6 @@
#include <wtf/text/WTFString.h>
#include <QBuffer>
-#include <QColor>
#include <QImage>
#include <QImageWriter>
#include <QPainter>
@@ -50,53 +50,21 @@
namespace WebCore {
-ImageBufferData::ImageBufferData(const IntSize& size)
- : m_pixmap(size)
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ImageBuffer::ImageBuffer(const IntSize& size, float /* resolutionScale */, ColorSpace, QOpenGLContext* compatibleContext, bool& success)
+ : m_data(size, compatibleContext)
+ , m_size(size)
+ , m_logicalSize(size)
{
- if (m_pixmap.isNull())
- return;
-
- m_pixmap.fill(QColor(Qt::transparent));
-
- m_painter = std::make_unique<QPainter>();
-
- if (!m_painter->begin(&m_pixmap))
+ success = m_data.m_painter && m_data.m_painter->isActive();
+ if (!success)
return;
- // Since ImageBuffer is used mainly for Canvas, explicitly initialize
- // its painter's pen and brush with the corresponding canvas defaults
- // NOTE: keep in sync with CanvasRenderingContext2D::State
- QPen pen = m_painter->pen();
- pen.setColor(Qt::black);
- pen.setWidth(1);
- pen.setCapStyle(Qt::FlatCap);
- pen.setJoinStyle(Qt::SvgMiterJoin);
- pen.setMiterLimit(10);
- m_painter->setPen(pen);
- QBrush brush = m_painter->brush();
- brush.setColor(Qt::black);
- m_painter->setBrush(brush);
- m_painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
-
- m_image = StillImage::createForRendering(&m_pixmap);
-}
-
-QImage ImageBufferData::toQImage() const
-{
- QPaintEngine* paintEngine = m_pixmap.paintEngine();
- if (!paintEngine || paintEngine->type() != QPaintEngine::Raster)
- return m_pixmap.toImage();
-
- // QRasterPixmapData::toImage() will deep-copy the backing QImage if there's an active QPainter on it.
- // For performance reasons, we don't want that here, so we temporarily redirect the paint engine.
- QPaintDevice* currentPaintDevice = paintEngine->paintDevice();
- paintEngine->setPaintDevice(0);
- QImage image = m_pixmap.toImage();
- paintEngine->setPaintDevice(currentPaintDevice);
- return image;
+ m_data.m_context = std::make_unique<GraphicsContext>(m_data.m_painter);
}
+#endif
-ImageBuffer::ImageBuffer(const FloatSize& size, float /* resolutionScale */, ColorSpace, RenderingMode, bool& success)
+ImageBuffer::ImageBuffer(const FloatSize& size, float /* resolutionScale */, ColorSpace, RenderingMode /*renderingMode*/, bool& success)
: m_data(IntSize(size))
, m_size(size)
, m_logicalSize(size)
@@ -105,13 +73,24 @@ ImageBuffer::ImageBuffer(const FloatSize& size, float /* resolutionScale */, Col
if (!success)
return;
- m_data.m_context = std::make_unique<GraphicsContext>(m_data.m_painter.get());
+ m_data.m_context = std::make_unique<GraphicsContext>(m_data.m_painter);
}
ImageBuffer::~ImageBuffer()
{
}
+#if ENABLE(ACCELERATED_2D_CANVAS)
+std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const IntSize& size, float resolutionScale, ColorSpace colorSpace, QOpenGLContext* context)
+{
+ bool success = false;
+ std::unique_ptr<ImageBuffer> buf(new ImageBuffer(size, resolutionScale, colorSpace, context, success));
+ if (!success)
+ return nullptr;
+ return buf;
+}
+#endif
+
GraphicsContext& ImageBuffer::context() const
{
ASSERT(m_data.m_painter->isActive());
@@ -122,14 +101,14 @@ GraphicsContext& ImageBuffer::context() const
RefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBehavior) const
{
if (copyBehavior == CopyBackingStore)
- return StillImage::create(m_data.m_pixmap);
+ return m_data.m_impl->copyImage();
- return StillImage::createForRendering(&m_data.m_pixmap);
+ return m_data.m_impl->image();
}
-RefPtr<Image> ImageBuffer::sinkIntoImage(std::unique_ptr<ImageBuffer> imageBuffer, ScaleBehavior scaleBehavior)
+RefPtr<Image> ImageBuffer::sinkIntoImage(std::unique_ptr<ImageBuffer> imageBuffer, ScaleBehavior)
{
- return StillImage::create(WTFMove(imageBuffer->m_data.m_pixmap));
+ return imageBuffer->m_data.m_impl->takeImage();
}
BackingStoreCopy ImageBuffer::fastCopyImageMode()
@@ -145,52 +124,18 @@ void ImageBuffer::drawConsuming(std::unique_ptr<ImageBuffer> imageBuffer, Graphi
void ImageBuffer::draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect,
CompositeOperator op, BlendMode blendMode)
{
- if (&destContext == &context()) {
- // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first.
- RefPtr<Image> copy = copyImage(CopyBackingStore);
- destContext.drawImage(*copy, destRect, srcRect, ImagePaintingOptions(op, blendMode, ImageOrientationDescription()));
- } else
- destContext.drawImage(*m_data.m_image, destRect, srcRect, ImagePaintingOptions(op, blendMode, ImageOrientationDescription()));
+ m_data.m_impl->draw(destContext, destRect, srcRect, op, blendMode, &destContext == &context());
}
void ImageBuffer::drawPattern(GraphicsContext& destContext, const FloatRect& srcRect, const AffineTransform& patternTransform,
const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode)
{
- if (&destContext == &context()) {
- // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first.
- RefPtr<Image> copy = copyImage(CopyBackingStore);
- copy->drawPattern(destContext, srcRect, patternTransform, phase, spacing, op, destRect, blendMode);
- } else
- m_data.m_image->drawPattern(destContext, srcRect, patternTransform, phase, spacing, op, destRect, blendMode);
+ m_data.m_impl->drawPattern(destContext, srcRect, patternTransform, phase, spacing, op, destRect, blendMode, &destContext == &context());
}
void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
{
- bool isPainting = m_data.m_painter->isActive();
- if (isPainting)
- m_data.m_painter->end();
-
- QImage image = m_data.toQImage().convertToFormat(QImage::Format_ARGB32);
- ASSERT(!image.isNull());
-
- uchar* bits = image.bits();
- const int bytesPerLine = image.bytesPerLine();
-
- for (int y = 0; y < m_size.height(); ++y) {
- quint32* scanLine = reinterpret_cast_ptr<quint32*>(bits + y * bytesPerLine);
- for (int x = 0; x < m_size.width(); ++x) {
- QRgb& pixel = scanLine[x];
- pixel = qRgba(lookUpTable[qRed(pixel)],
- lookUpTable[qGreen(pixel)],
- lookUpTable[qBlue(pixel)],
- qAlpha(pixel));
- }
- }
-
- m_data.m_pixmap = QPixmap::fromImage(image);
-
- if (isPainting)
- m_data.m_painter->begin(&m_data.m_pixmap);
+ m_data.m_impl->platformTransformColorSpace(lookUpTable);
}
template <Multiply multiplied>
@@ -207,10 +152,11 @@ PassRefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, const ImageBuffe
if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > size.width() || rect.maxY() > size.height())
image.fill(0);
- // Let drawPixmap deal with the conversion.
+ // Let drawImage deal with the conversion.
+ // FIXME: This is inefficient for accelerated ImageBuffers when only part of the imageData is read.
QPainter painter(&image);
painter.setCompositionMode(QPainter::CompositionMode_Source);
- painter.drawPixmap(QPoint(0, 0), imageData.m_pixmap, rect);
+ painter.drawImage(QPoint(0, 0), imageData.m_impl->toQImage(), rect);
painter.end();
return result.release();
@@ -233,7 +179,7 @@ void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, c
bool isPainting = m_data.m_painter->isActive();
if (!isPainting)
- m_data.m_painter->begin(&m_data.m_pixmap);
+ m_data.m_painter->begin(m_data.m_impl->paintDevice());
else {
m_data.m_painter->save();
@@ -281,11 +227,17 @@ String ImageBuffer::toDataURL(const String& mimeType, const double* quality, Coo
// gif, jpeg..., xpm) so skip the image/ to get the Qt image format used to encode
// the m_pixmap image.
+ RefPtr<Image> image = copyImage(DontCopyBackingStore);
QByteArray data;
- if (!encodeImage(m_data.m_pixmap, mimeType.substring(sizeof "image"), quality, data))
+ if (!encodeImage(*image->nativeImageForCurrentFrame(), mimeType.substring(sizeof "image"), quality, data))
return "data:,";
return "data:" + mimeType + ";base64," + data.toBase64().data();
}
+PlatformLayer* ImageBuffer::platformLayer() const
+{
+ return m_data.m_impl->platformLayer();
+}
+
}
diff --git a/Source/WebCore/platform/graphics/qt/OpenGLShimsQt.h b/Source/WebCore/platform/graphics/qt/OpenGLShimsQt.h
new file mode 100644
index 000000000..827d8f6b2
--- /dev/null
+++ b/Source/WebCore/platform/graphics/qt/OpenGLShimsQt.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2017 Konstantin Tokarev <annulen@yandex.ru>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <private/qopenglextensions_p.h>
+
+#ifndef FUNCTIONS
+#error You must define FUNCTIONS macro before including this header
+#endif
+
+namespace OpenGLShimsQt {
+ALWAYS_INLINE static void doNothing() { }
+}
+
+#define LOOKUP_GL_FUNCTION(f, ...) OpenGLShimsQt::doNothing(), FUNCTIONS->f(__VA_ARGS__)
+
+// Extra items
+#define glBindTexture(...) LOOKUP_GL_FUNCTION(glBindTexture, __VA_ARGS__)
+#define glBlendFunc(...) LOOKUP_GL_FUNCTION(glBlendFunc, __VA_ARGS__)
+#define glClear(...) LOOKUP_GL_FUNCTION(glClear, __VA_ARGS__)
+#define glClearColor(...) LOOKUP_GL_FUNCTION(glClearColor, __VA_ARGS__)
+#define glClearDepth(...) LOOKUP_GL_FUNCTION(glClearDepthf, __VA_ARGS__)
+#define glClearStencil(...) LOOKUP_GL_FUNCTION(glClearStencil, __VA_ARGS__)
+#define glColorMask(...) LOOKUP_GL_FUNCTION(glColorMask, __VA_ARGS__)
+#define glCopyTexImage2D(...) LOOKUP_GL_FUNCTION(glCopyTexImage2D, __VA_ARGS__)
+#define glCopyTexSubImage2D(...) LOOKUP_GL_FUNCTION(glCopyTexSubImage2D, __VA_ARGS__)
+#define glCullFace(...) LOOKUP_GL_FUNCTION(glCullFace, __VA_ARGS__)
+#define glDeleteTextures(...) LOOKUP_GL_FUNCTION(glDeleteTextures, __VA_ARGS__)
+#define glDepthFunc(...) LOOKUP_GL_FUNCTION(glDepthFunc, __VA_ARGS__)
+#define glDepthMask(...) LOOKUP_GL_FUNCTION(glDepthMask, __VA_ARGS__)
+#define glDepthRange(...) LOOKUP_GL_FUNCTION(glDepthRangef, __VA_ARGS__)
+#define glDisable(...) LOOKUP_GL_FUNCTION(glDisable, __VA_ARGS__)
+#define glDrawArrays(...) LOOKUP_GL_FUNCTION(glDrawArrays, __VA_ARGS__)
+#define glDrawElements(...) LOOKUP_GL_FUNCTION(glDrawElements, __VA_ARGS__)
+#define glEnable(...) LOOKUP_GL_FUNCTION(glEnable, __VA_ARGS__)
+#define glFinish(...) LOOKUP_GL_FUNCTION(glFinish, __VA_ARGS__)
+#define glFlush(...) LOOKUP_GL_FUNCTION(glFlush, __VA_ARGS__)
+#define glFrontFace(...) LOOKUP_GL_FUNCTION(glFrontFace, __VA_ARGS__)
+#define glGenTextures(...) LOOKUP_GL_FUNCTION(glGenTextures, __VA_ARGS__)
+#define glGetBooleanv(...) LOOKUP_GL_FUNCTION(glGetBooleanv, __VA_ARGS__)
+#define glGetFloatv(...) LOOKUP_GL_FUNCTION(glGetFloatv, __VA_ARGS__)
+#define glGetIntegerv(...) LOOKUP_GL_FUNCTION(glGetIntegerv, __VA_ARGS__)
+#define glGetString(...) LOOKUP_GL_FUNCTION(glGetString, __VA_ARGS__)
+#define glGetTexParameterfv(...) LOOKUP_GL_FUNCTION(glGetTexParameterfv, __VA_ARGS__)
+#define glGetTexParameteriv(...) LOOKUP_GL_FUNCTION(glGetTexParameteriv, __VA_ARGS__)
+#define glHint(...) LOOKUP_GL_FUNCTION(glHint, __VA_ARGS__)
+#define glIsTexture(...) LOOKUP_GL_FUNCTION(glIsTexture, __VA_ARGS__)
+#define glLineWidth(...) LOOKUP_GL_FUNCTION(glLineWidth, __VA_ARGS__)
+#define glPixelStorei(...) LOOKUP_GL_FUNCTION(glPixelStorei, __VA_ARGS__)
+#define glPolygonOffset(...) LOOKUP_GL_FUNCTION(glPolygonOffset, __VA_ARGS__)
+#define glReadPixels(...) LOOKUP_GL_FUNCTION(glReadPixels, __VA_ARGS__)
+#define glScissor(...) LOOKUP_GL_FUNCTION(glScissor, __VA_ARGS__)
+#define glStencilFunc(...) LOOKUP_GL_FUNCTION(glStencilFunc, __VA_ARGS__)
+#define glStencilMask(...) LOOKUP_GL_FUNCTION(glStencilMask, __VA_ARGS__)
+#define glStencilOp(...) LOOKUP_GL_FUNCTION(glStencilOp, __VA_ARGS__)
+#define glTexImage2D(...) LOOKUP_GL_FUNCTION(glTexImage2D, __VA_ARGS__)
+#define glTexParameterf(...) LOOKUP_GL_FUNCTION(glTexParameterf, __VA_ARGS__)
+#define glTexParameteri(...) LOOKUP_GL_FUNCTION(glTexParameteri, __VA_ARGS__)
+#define glTexSubImage2D(...) LOOKUP_GL_FUNCTION(glTexSubImage2D, __VA_ARGS__)
+#define glViewport(...) LOOKUP_GL_FUNCTION(glViewport, __VA_ARGS__)
+
+// Keep in sync with OpenGLShims.h
+
+#define glActiveTexture(...) LOOKUP_GL_FUNCTION(glActiveTexture, __VA_ARGS__)
+#define glAttachShader(...) LOOKUP_GL_FUNCTION(glAttachShader, __VA_ARGS__)
+#define glBindAttribLocation(...) LOOKUP_GL_FUNCTION(glBindAttribLocation, __VA_ARGS__)
+#define glBindBuffer(...) LOOKUP_GL_FUNCTION(glBindBuffer, __VA_ARGS__)
+#define glBindFramebufferEXT glBindFramebuffer
+#define glBindFramebuffer(...) LOOKUP_GL_FUNCTION(glBindFramebuffer, __VA_ARGS__)
+#define glBindRenderbufferEXT glBindRenderbuffer
+#define glBindRenderbuffer(...) LOOKUP_GL_FUNCTION(glBindRenderbuffer, __VA_ARGS__)
+#define glBlendColor(...) LOOKUP_GL_FUNCTION(glBlendColor, __VA_ARGS__)
+#define glBlendEquation(...) LOOKUP_GL_FUNCTION(glBlendEquation, __VA_ARGS__)
+#define glBlendEquationSeparate(...) LOOKUP_GL_FUNCTION(glBlendEquationSeparate, __VA_ARGS__)
+#define glBlendFuncSeparate(...) LOOKUP_GL_FUNCTION(glBlendFuncSeparate, __VA_ARGS__)
+#define glBlitFramebufferEXT glBlitFramebuffer
+#define glBlitFramebuffer(...) LOOKUP_GL_FUNCTION(glBlitFramebuffer, __VA_ARGS__)
+#define glBufferData(...) LOOKUP_GL_FUNCTION(glBufferData, __VA_ARGS__)
+#define glBufferSubData(...) LOOKUP_GL_FUNCTION(glBufferSubData, __VA_ARGS__)
+#define glCheckFramebufferStatusEXT glCheckFramebufferStatus
+#define glCheckFramebufferStatus(...) LOOKUP_GL_FUNCTION(glCheckFramebufferStatus, __VA_ARGS__)
+#define glCompileShader(...) LOOKUP_GL_FUNCTION(glCompileShader, __VA_ARGS__)
+#define glCompressedTexImage2D(...) LOOKUP_GL_FUNCTION(glCompressedTexImage2D, __VA_ARGS__)
+#define glCompressedTexSubImage2D(...) LOOKUP_GL_FUNCTION(glCompressedTexSubImage2D, __VA_ARGS__)
+#define glCreateProgram(...) LOOKUP_GL_FUNCTION(glCreateProgram, __VA_ARGS__)
+#define glCreateShader(...) LOOKUP_GL_FUNCTION(glCreateShader, __VA_ARGS__)
+#define glDeleteBuffers(...) LOOKUP_GL_FUNCTION(glDeleteBuffers, __VA_ARGS__)
+#define glDeleteFramebuffersEXT glDeleteFramebuffers
+#define glDeleteFramebuffers(...) LOOKUP_GL_FUNCTION(glDeleteFramebuffers, __VA_ARGS__)
+#define glDeleteProgram(...) LOOKUP_GL_FUNCTION(glDeleteProgram, __VA_ARGS__)
+#define glDeleteRenderbuffersEXT glDeleteRenderbuffers
+#define glDeleteRenderbuffers(...) LOOKUP_GL_FUNCTION(glDeleteRenderbuffers, __VA_ARGS__)
+#define glDeleteShader(...) LOOKUP_GL_FUNCTION(glDeleteShader, __VA_ARGS__)
+#define glDetachShader(...) LOOKUP_GL_FUNCTION(glDetachShader, __VA_ARGS__)
+#define glDisableVertexAttribArray(...) LOOKUP_GL_FUNCTION(glDisableVertexAttribArray, __VA_ARGS__)
+#define glDrawArraysInstancedEXT glDrawArraysInstanced
+#define glDrawArraysInstanced(...) LOOKUP_GL_FUNCTION(glDrawArraysInstanced, __VA_ARGS__)
+#define glDrawBuffersEXT glDrawBuffers
+#define glDrawBuffers(...) LOOKUP_GL_FUNCTION(glDrawBuffers, __VA_ARGS__)
+#define glDrawElementsInstancedEXT glDrawElementsInstanced
+#define glDrawElementsInstanced(...) LOOKUP_GL_FUNCTION(glDrawElementsInstanced, __VA_ARGS__)
+#define glEnableVertexAttribArray(...) LOOKUP_GL_FUNCTION(glEnableVertexAttribArray, __VA_ARGS__)
+#define glFramebufferRenderbufferEXT glFramebufferRenderbuffer
+#define glFramebufferRenderbuffer(...) LOOKUP_GL_FUNCTION(glFramebufferRenderbuffer, __VA_ARGS__)
+#define glFramebufferTexture2DEXT glFramebufferTexture2D
+#define glFramebufferTexture2D(...) LOOKUP_GL_FUNCTION(glFramebufferTexture2D, __VA_ARGS__)
+#define glGenBuffers(...) LOOKUP_GL_FUNCTION(glGenBuffers, __VA_ARGS__)
+#define glGenerateMipmapEXT glGenerateMipmap
+#define glGenerateMipmap(...) LOOKUP_GL_FUNCTION(glGenerateMipmap, __VA_ARGS__)
+#define glGenFramebuffersEXT glGenFramebuffers
+#define glGenFramebuffers(...) LOOKUP_GL_FUNCTION(glGenFramebuffers, __VA_ARGS__)
+#define glGenRenderbuffersEXT glGenRenderbuffers
+#define glGenRenderbuffers(...) LOOKUP_GL_FUNCTION(glGenRenderbuffers, __VA_ARGS__)
+#define glGetActiveAttrib(...) LOOKUP_GL_FUNCTION(glGetActiveAttrib, __VA_ARGS__)
+#define glGetActiveUniform(...) LOOKUP_GL_FUNCTION(glGetActiveUniform, __VA_ARGS__)
+#define glGetAttachedShaders(...) LOOKUP_GL_FUNCTION(glGetAttachedShaders, __VA_ARGS__)
+#define glGetAttribLocation(...) LOOKUP_GL_FUNCTION(glGetAttribLocation, __VA_ARGS__)
+#define glGetBufferParameterivEXT glGetBufferParameteriv
+#define glGetBufferParameteriv(...) LOOKUP_GL_FUNCTION(glGetBufferParameteriv, __VA_ARGS__)
+#define glGetFramebufferAttachmentParameterivEXT glGetFramebufferAttachmentParameteriv
+#define glGetFramebufferAttachmentParameteriv(...) LOOKUP_GL_FUNCTION(glGetFramebufferAttachmentParameteriv, __VA_ARGS__)
+#define glGetProgramInfoLog(...) LOOKUP_GL_FUNCTION(glGetProgramInfoLog, __VA_ARGS__)
+#define glGetProgramiv(...) LOOKUP_GL_FUNCTION(glGetProgramiv, __VA_ARGS__)
+#define glGetRenderbufferParameterivEXT glGetRenderbufferParameteriv
+#define glGetRenderbufferParameteriv(...) LOOKUP_GL_FUNCTION(glGetRenderbufferParameteriv, __VA_ARGS__)
+#define glGetShaderInfoLog(...) LOOKUP_GL_FUNCTION(glGetShaderInfoLog, __VA_ARGS__)
+#define glGetShaderiv(...) LOOKUP_GL_FUNCTION(glGetShaderiv, __VA_ARGS__)
+#define glGetShaderSource(...) LOOKUP_GL_FUNCTION(glGetShaderSource, __VA_ARGS__)
+#define glGetUniformfv(...) LOOKUP_GL_FUNCTION(glGetUniformfv, __VA_ARGS__)
+#define glGetUniformiv(...) LOOKUP_GL_FUNCTION(glGetUniformiv, __VA_ARGS__)
+#define glGetUniformLocation(...) LOOKUP_GL_FUNCTION(glGetUniformLocation, __VA_ARGS__)
+#define glGetVertexAttribfv(...) LOOKUP_GL_FUNCTION(glGetVertexAttribfv, __VA_ARGS__)
+#define glGetVertexAttribiv(...) LOOKUP_GL_FUNCTION(glGetVertexAttribiv, __VA_ARGS__)
+#define glGetVertexAttribPointerv(...) LOOKUP_GL_FUNCTION(glGetVertexAttribPointerv, __VA_ARGS__)
+#define glIsBuffer(...) LOOKUP_GL_FUNCTION(glIsBuffer, __VA_ARGS__)
+#define glIsFramebufferEXT glIsFramebuffer
+#define glIsFramebuffer(...) LOOKUP_GL_FUNCTION(glIsFramebuffer, __VA_ARGS__)
+#define glIsProgram(...) LOOKUP_GL_FUNCTION(glIsProgram, __VA_ARGS__)
+#define glIsRenderbufferEXT glIsRenderbuffer
+#define glIsRenderbuffer(...) LOOKUP_GL_FUNCTION(glIsRenderbuffer, __VA_ARGS__)
+#define glIsShader(...) LOOKUP_GL_FUNCTION(glIsShader, __VA_ARGS__)
+#define glLinkProgram(...) LOOKUP_GL_FUNCTION(glLinkProgram, __VA_ARGS__)
+#define glRenderbufferStorageEXT glRenderbufferStorage
+#define glRenderbufferStorage(...) LOOKUP_GL_FUNCTION(glRenderbufferStorage, __VA_ARGS__)
+#define glRenderbufferStorageMultisampleEXT glRenderbufferStorageMultisample
+#define glRenderbufferStorageMultisample(...) LOOKUP_GL_FUNCTION(glRenderbufferStorageMultisample, __VA_ARGS__)
+#define glSampleCoverage(...) LOOKUP_GL_FUNCTION(glSampleCoverage, __VA_ARGS__)
+#define glShaderSource(...) LOOKUP_GL_FUNCTION(glShaderSource, __VA_ARGS__)
+#define glStencilFuncSeparate(...) LOOKUP_GL_FUNCTION(glStencilFuncSeparate, __VA_ARGS__)
+#define glStencilMaskSeparate(...) LOOKUP_GL_FUNCTION(glStencilMaskSeparate, __VA_ARGS__)
+#define glStencilOpSeparate(...) LOOKUP_GL_FUNCTION(glStencilOpSeparate, __VA_ARGS__)
+#define glUniform1f(...) LOOKUP_GL_FUNCTION(glUniform1f, __VA_ARGS__)
+#define glUniform1fv(...) LOOKUP_GL_FUNCTION(glUniform1fv, __VA_ARGS__)
+#define glUniform1i(...) LOOKUP_GL_FUNCTION(glUniform1i, __VA_ARGS__)
+#define glUniform1iv(...) LOOKUP_GL_FUNCTION(glUniform1iv, __VA_ARGS__)
+#define glUniform2f(...) LOOKUP_GL_FUNCTION(glUniform2f, __VA_ARGS__)
+#define glUniform2fv(...) LOOKUP_GL_FUNCTION(glUniform2fv, __VA_ARGS__)
+#define glUniform2i(...) LOOKUP_GL_FUNCTION(glUniform2i, __VA_ARGS__)
+#define glUniform2iv(...) LOOKUP_GL_FUNCTION(glUniform2iv, __VA_ARGS__)
+#define glUniform3f(...) LOOKUP_GL_FUNCTION(glUniform3f, __VA_ARGS__)
+#define glUniform3fv(...) LOOKUP_GL_FUNCTION(glUniform3fv, __VA_ARGS__)
+#define glUniform3i(...) LOOKUP_GL_FUNCTION(glUniform3i, __VA_ARGS__)
+#define glUniform3iv(...) LOOKUP_GL_FUNCTION(glUniform3iv, __VA_ARGS__)
+#define glUniform4f(...) LOOKUP_GL_FUNCTION(glUniform4f, __VA_ARGS__)
+#define glUniform4fv(...) LOOKUP_GL_FUNCTION(glUniform4fv, __VA_ARGS__)
+#define glUniform4i(...) LOOKUP_GL_FUNCTION(glUniform4i, __VA_ARGS__)
+#define glUniform4iv(...) LOOKUP_GL_FUNCTION(glUniform4iv, __VA_ARGS__)
+#define glUniformMatrix2fv(...) LOOKUP_GL_FUNCTION(glUniformMatrix2fv, __VA_ARGS__)
+#define glUniformMatrix3fv(...) LOOKUP_GL_FUNCTION(glUniformMatrix3fv, __VA_ARGS__)
+#define glUniformMatrix4fv(...) LOOKUP_GL_FUNCTION(glUniformMatrix4fv, __VA_ARGS__)
+#define glUseProgram(...) LOOKUP_GL_FUNCTION(glUseProgram, __VA_ARGS__)
+#define glValidateProgram(...) LOOKUP_GL_FUNCTION(glValidateProgram, __VA_ARGS__)
+#define glVertexAttrib1f(...) LOOKUP_GL_FUNCTION(glVertexAttrib1f, __VA_ARGS__)
+#define glVertexAttrib1fv(...) LOOKUP_GL_FUNCTION(glVertexAttrib1fv, __VA_ARGS__)
+#define glVertexAttrib2f(...) LOOKUP_GL_FUNCTION(glVertexAttrib2f, __VA_ARGS__)
+#define glVertexAttrib2fv(...) LOOKUP_GL_FUNCTION(glVertexAttrib2fv, __VA_ARGS__)
+#define glVertexAttrib3f(...) LOOKUP_GL_FUNCTION(glVertexAttrib3f, __VA_ARGS__)
+#define glVertexAttrib3fv(...) LOOKUP_GL_FUNCTION(glVertexAttrib3fv, __VA_ARGS__)
+#define glVertexAttrib4f(...) LOOKUP_GL_FUNCTION(glVertexAttrib4f, __VA_ARGS__)
+#define glVertexAttrib4fv(...) LOOKUP_GL_FUNCTION(glVertexAttrib4fv, __VA_ARGS__)
+#define glVertexAttribDivisorEXT glVertexAttribDivisor
+#define glVertexAttribDivisor(...) LOOKUP_GL_FUNCTION(glVertexAttribDivisor, __VA_ARGS__)
+#define glVertexAttribPointer(...) LOOKUP_GL_FUNCTION(glVertexAttribPointer, __VA_ARGS__)
diff --git a/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp b/Source/WebCore/platform/graphics/qt/OpenGLShimsQtVAO.h
index 47cb4b95b..36b3aec69 100644
--- a/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/OpenGLShimsQtVAO.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Andrew Wason (rectalogic@rectalogic.com)
+ * Copyright (C) 2017 Konstantin Tokarev <annulen@yandex.ru>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -13,40 +13,31 @@
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
+#pragma once
-#if USE(3D_GRAPHICS)
+#include <private/qopenglvertexarrayobject_p.h>
-#include "DrawingBuffer.h"
-
-namespace WebCore {
-
-#if USE(ACCELERATED_COMPOSITING)
-PlatformLayer* DrawingBuffer::platformLayer()
-{
- return 0;
-}
-
-unsigned DrawingBuffer::frontColorBuffer() const
-{
- return colorBuffer();
-}
-
-void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer*)
-{
-}
+#ifndef VAO_FUNCTIONS
+#error You must define VAO_FUNCTIONS macro before including this header
#endif
-}
-
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+#define LOOKUP_VAO_FUNCTION(f, ...) VAO_FUNCTIONS->f(__VA_ARGS__)
+#else
+#define LOOKUP_VAO_FUNCTION(f, ...)
#endif
+
+#define glGenVertexArrays(...) LOOKUP_VAO_FUNCTION(glGenVertexArrays, __VA_ARGS__)
+#define glDeleteVertexArrays(...) LOOKUP_VAO_FUNCTION(glDeleteVertexArrays, __VA_ARGS__)
+#define glIsVertexArray(...) LOOKUP_VAO_FUNCTION(glIsVertexArray, __VA_ARGS__)
+#define glBindVertexArray(...) LOOKUP_VAO_FUNCTION(glBindVertexArray, __VA_ARGS__)
diff --git a/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp b/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp
new file mode 100644
index 000000000..7c29d95e6
--- /dev/null
+++ b/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.cpp
@@ -0,0 +1,69 @@
+/*
+ Copyright (C) 2014 Digia Plc. 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 "QFramebufferPaintDevice.h"
+
+#include <QOpenGLFunctions>
+
+QFramebufferPaintDevice::QFramebufferPaintDevice(const QSize& size,
+ QOpenGLFramebufferObject::Attachment attachment, bool clearOnInit)
+ : QOpenGLPaintDevice(size)
+ , m_framebufferObject(size, attachment)
+{
+ m_surface = QOpenGLContext::currentContext()->surface();
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+ setPaintFlipped(true);
+#endif
+ if (clearOnInit) {
+ m_framebufferObject.bind();
+
+ context()->functions()->glClearColor(0, 0, 0, 0);
+ context()->functions()->glClear(GL_COLOR_BUFFER_BIT);
+ }
+}
+
+void QFramebufferPaintDevice::ensureActiveTarget()
+{
+ if (QOpenGLContext::currentContext() != context())
+ context()->makeCurrent(m_surface);
+
+ m_framebufferObject.bind();
+}
+
+QImage QFramebufferPaintDevice::toImage() const
+{
+ QOpenGLContext* currentContext = QOpenGLContext::currentContext();
+ QSurface* currentSurface = currentContext ? currentContext->surface() : 0;
+
+ context()->makeCurrent(m_surface);
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+ QImage image = m_framebufferObject.toImage(false);
+#else
+ QImage image = m_framebufferObject.toImage();
+#endif
+
+ if (currentContext)
+ currentContext->makeCurrent(currentSurface);
+ else
+ context()->doneCurrent();
+
+ return image;
+}
diff --git a/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.h b/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.h
new file mode 100644
index 000000000..14562acb2
--- /dev/null
+++ b/Source/WebCore/platform/graphics/qt/QFramebufferPaintDevice.h
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2014 Digia Plc. 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.
+*/
+
+#ifndef QFramebufferPaintDevice_h
+#define QFramebufferPaintDevice_h
+
+#include <QImage>
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLPaintDevice>
+#include <QSurface>
+
+class QFramebufferPaintDevice : public QOpenGLPaintDevice {
+public:
+ QFramebufferPaintDevice(const QSize&,
+ QOpenGLFramebufferObject::Attachment = QOpenGLFramebufferObject::CombinedDepthStencil,
+ bool clearOnInit = true);
+
+ // QOpenGLPaintDevice:
+ virtual void ensureActiveTarget() Q_DECL_OVERRIDE;
+
+ bool isValid() const { return m_framebufferObject.isValid(); }
+ GLuint handle() const { return m_framebufferObject.handle(); }
+ GLuint texture() const { return m_framebufferObject.texture(); }
+ QImage toImage() const;
+
+ bool bind() { return m_framebufferObject.bind(); }
+ bool release() { return m_framebufferObject.release(); }
+ QSize size() const { return m_framebufferObject.size(); }
+
+ QOpenGLFramebufferObject* framebufferObject() { return &m_framebufferObject; }
+ const QOpenGLFramebufferObject* framebufferObject() const { return &m_framebufferObject; }
+
+ static bool isSupported() { return QOpenGLFramebufferObject::hasOpenGLFramebufferObjects(); }
+
+private:
+ QOpenGLFramebufferObject m_framebufferObject;
+ QSurface* m_surface;
+};
+
+#endif
diff --git a/Source/WebCore/platform/graphics/qt/StillImageQt.h b/Source/WebCore/platform/graphics/qt/StillImageQt.h
index e35e56609..b9079727e 100644
--- a/Source/WebCore/platform/graphics/qt/StillImageQt.h
+++ b/Source/WebCore/platform/graphics/qt/StillImageQt.h
@@ -34,17 +34,17 @@ namespace WebCore {
class StillImage final : public Image {
public:
- static PassRefPtr<StillImage> create(const QPixmap& pixmap)
+ static RefPtr<StillImage> create(const QPixmap& pixmap)
{
return adoptRef(new StillImage(pixmap));
}
- static PassRefPtr<StillImage> createForRendering(const QPixmap* pixmap)
+ static RefPtr<StillImage> createForRendering(const QPixmap* pixmap)
{
return adoptRef(new StillImage(pixmap));
}
- static PassRefPtr<StillImage> create(QPixmap&& pixmap)
+ static RefPtr<StillImage> create(QPixmap&& pixmap)
{
return adoptRef(new StillImage(WTFMove(pixmap)));
}
diff --git a/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp b/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp
index 3d7037c2f..59c763b51 100644
--- a/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp
+++ b/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp
@@ -37,6 +37,10 @@
#include <wtf/RefCounted.h>
#include <wtf/TemporaryChange.h>
+#if PLATFORM(QT)
+#include <QPaintEngine>
+#endif
+
#if USE(CAIRO)
#include "CairoUtilities.h"
#include "RefPtrCairo.h"
@@ -200,7 +204,17 @@ void BitmapTextureGL::updateContents(Image* image, const IntRect& targetRect, co
imageData = reinterpret_cast<const char*>(cairo_image_surface_get_data(surface));
bytesPerLine = cairo_image_surface_get_stride(surface);
#elif PLATFORM(QT)
- QImage qImage = frameImage->toImage();
+ QImage qImage;
+ QPaintEngine* paintEngine = frameImage->paintEngine();
+ if (paintEngine && paintEngine->type() == QPaintEngine::Raster) {
+ // QRasterPixmapData::toImage() will deep-copy the backing QImage if there's an active QPainter on it.
+ // For performance reasons, we don't want that here, so we temporarily redirect the paint engine.
+ QPaintDevice* currentPaintDevice = paintEngine->paintDevice();
+ paintEngine->setPaintDevice(0);
+ qImage = frameImage->toImage();
+ paintEngine->setPaintDevice(currentPaintDevice);
+ } else
+ qImage = frameImage->toImage();
imageData = reinterpret_cast<const char*>(qImage.constBits());
bytesPerLine = qImage.bytesPerLine();
#endif
diff --git a/Source/WebCore/platform/graphics/texmap/BitmapTextureImageBuffer.cpp b/Source/WebCore/platform/graphics/texmap/BitmapTextureImageBuffer.cpp
new file mode 100644
index 000000000..ee677c2a2
--- /dev/null
+++ b/Source/WebCore/platform/graphics/texmap/BitmapTextureImageBuffer.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BitmapTextureImageBuffer.h"
+
+#include "GraphicsLayer.h"
+
+#if PLATFORM(QT)
+#include "GraphicsContext.h"
+#include "NativeImageQt.h"
+#endif
+
+namespace WebCore {
+
+void BitmapTextureImageBuffer::updateContents(const void* data, const IntRect& targetRect, const IntPoint& sourceOffset, int bytesPerLine, UpdateContentsFlag)
+{
+#if PLATFORM(QT)
+ QImage image(reinterpret_cast<const uchar*>(data), targetRect.width(), targetRect.height(), bytesPerLine, NativeImageQt::defaultFormatForAlphaEnabledImages());
+
+ QPainter* painter = m_image->context().platformContext();
+ painter->save();
+ painter->setCompositionMode(QPainter::CompositionMode_Source);
+ painter->drawImage(targetRect, image, IntRect(sourceOffset, targetRect.size()));
+ painter->restore();
+#elif PLATFORM(CAIRO)
+ RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data(static_cast<unsigned char*>(data()),
+ CAIRO_FORMAT_ARGB32, targetRect.width(), targetRect.height(), bytesPerLine));
+ m_image->context()->platformContext()->drawSurfaceToContext(surface.get(), targetRect,
+ IntRect(sourceOffset, targetRect.size()), m_image->context());
+#else
+ UNUSED_PARAM(data);
+ UNUSED_PARAM(targetRect);
+ UNUSED_PARAM(sourceOffset);
+ UNUSED_PARAM(bytesPerLine);
+#endif
+}
+
+void BitmapTextureImageBuffer::updateContents(TextureMapper&, GraphicsLayer* sourceLayer, const IntRect& targetRect, const IntPoint& sourceOffset, UpdateContentsFlag, float scale)
+{
+ // QTFIXME: Handle scale, like BitmapTexture::updateContents
+ GraphicsContext& context = m_image->context();
+
+ context.clearRect(targetRect);
+
+ IntRect sourceRect(targetRect);
+ sourceRect.setLocation(sourceOffset);
+ context.save();
+ context.clip(targetRect);
+ context.translate(targetRect.x() - sourceOffset.x(), targetRect.y() - sourceOffset.y());
+ sourceLayer->paintGraphicsLayerContents(context, sourceRect);
+ context.restore();
+}
+
+void BitmapTextureImageBuffer::didReset()
+{
+ m_image = ImageBuffer::create(contentSize(), Unaccelerated);
+}
+
+void BitmapTextureImageBuffer::updateContents(Image* image, const IntRect& targetRect, const IntPoint& offset, UpdateContentsFlag)
+{
+ m_image->context().drawImage(*image, targetRect, IntRect(offset, targetRect.size()), CompositeCopy);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/texmap/BitmapTextureImageBuffer.h b/Source/WebCore/platform/graphics/texmap/BitmapTextureImageBuffer.h
new file mode 100644
index 000000000..6443ba737
--- /dev/null
+++ b/Source/WebCore/platform/graphics/texmap/BitmapTextureImageBuffer.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BitmapTextureImageBuffer_h
+#define BitmapTextureImageBuffer_h
+
+#include "BitmapTexture.h"
+#include "ImageBuffer.h"
+#include "IntRect.h"
+#include "IntSize.h"
+
+namespace WebCore {
+
+class GraphicsContext;
+
+class BitmapTextureImageBuffer final : public BitmapTexture {
+public:
+ static PassRefPtr<BitmapTexture> create() { return adoptRef(new BitmapTextureImageBuffer); }
+ IntSize size() const final { return m_image->internalSize(); }
+ void didReset() final;
+ bool isValid() const final { return m_image.get(); }
+ void updateContents(Image*, const IntRect&, const IntPoint&, UpdateContentsFlag) final;
+ void updateContents(TextureMapper&, GraphicsLayer*, const IntRect& target, const IntPoint& offset, UpdateContentsFlag, float scale) final;
+ void updateContents(const void*, const IntRect& target, const IntPoint& sourceOffset, int bytesPerLine, UpdateContentsFlag) final;
+ PassRefPtr<BitmapTexture> applyFilters(TextureMapper&, const FilterOperations&) final;
+
+ inline GraphicsContext* graphicsContext() { return m_image ? &m_image->context() : nullptr; }
+ ImageBuffer* image() const { return m_image.get(); }
+
+private:
+ BitmapTextureImageBuffer() { }
+ std::unique_ptr<ImageBuffer> m_image;
+};
+
+}
+
+#endif // BitmapTextureImageBuffer_h
diff --git a/Source/WebCore/platform/graphics/texmap/BitmapTexturePool.cpp b/Source/WebCore/platform/graphics/texmap/BitmapTexturePool.cpp
index 1b46f3752..f0e7f23e7 100644
--- a/Source/WebCore/platform/graphics/texmap/BitmapTexturePool.cpp
+++ b/Source/WebCore/platform/graphics/texmap/BitmapTexturePool.cpp
@@ -31,11 +31,23 @@
#include "BitmapTextureGL.h"
#endif
+#if PLATFORM(QT)
+#include "BitmapTextureImageBuffer.h"
+#endif
+
namespace WebCore {
static const double s_releaseUnusedSecondsTolerance = 3;
static const double s_releaseUnusedTexturesTimerInterval = 0.5;
+
+#if PLATFORM(QT)
+BitmapTexturePool::BitmapTexturePool()
+ : m_releaseUnusedTexturesTimer(*this, &BitmapTexturePool::releaseUnusedTexturesTimerFired)
+{
+}
+#endif
+
#if USE(TEXTURE_MAPPER_GL)
BitmapTexturePool::BitmapTexturePool(RefPtr<GraphicsContext3D>&& context3D)
: m_context3D(WTFMove(context3D))
@@ -104,10 +116,14 @@ void BitmapTexturePool::releaseUnusedTexturesTimerFired()
RefPtr<BitmapTexture> BitmapTexturePool::createTexture(const BitmapTexture::Flags flags)
{
+#if PLATFORM(QT)
+ if (!m_context3D)
+ return BitmapTextureImageBuffer::create();
+#endif
#if USE(TEXTURE_MAPPER_GL)
return adoptRef(new BitmapTextureGL(m_context3D, flags));
#else
- return nullptr;
+ return BitmapTextureImageBuffer::create();
#endif
}
diff --git a/Source/WebCore/platform/graphics/texmap/BitmapTexturePool.h b/Source/WebCore/platform/graphics/texmap/BitmapTexturePool.h
index 95ba249aa..bf577344b 100644
--- a/Source/WebCore/platform/graphics/texmap/BitmapTexturePool.h
+++ b/Source/WebCore/platform/graphics/texmap/BitmapTexturePool.h
@@ -44,6 +44,9 @@ class BitmapTexturePool {
WTF_MAKE_NONCOPYABLE(BitmapTexturePool);
WTF_MAKE_FAST_ALLOCATED;
public:
+#if PLATFORM(QT)
+ BitmapTexturePool();
+#endif
#if USE(TEXTURE_MAPPER_GL)
explicit BitmapTexturePool(RefPtr<GraphicsContext3D>&&);
#endif
diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
index 636be8751..812980a28 100644
--- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
+++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
@@ -608,7 +608,8 @@ void GraphicsLayerTextureMapper::removeAnimation(const String& animationName)
bool GraphicsLayerTextureMapper::setFilters(const FilterOperations& filters)
{
TextureMapper* textureMapper = m_layer.textureMapper();
- if (!textureMapper)
+ // TextureMapperImageBuffer does not support CSS filters.
+ if (!textureMapper || textureMapper->accelerationMode() == TextureMapper::SoftwareMode)
return false;
notifyChange(FilterChange);
return GraphicsLayer::setFilters(filters);
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp
index b985c7b90..a458f8177 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp
@@ -23,6 +23,7 @@
#include "BitmapTexturePool.h"
#include "FilterOperations.h"
#include "GraphicsLayer.h"
+#include "TextureMapperImageBuffer.h"
#include "Timer.h"
#include <wtf/CurrentTime.h>
@@ -35,15 +36,18 @@ PassRefPtr<BitmapTexture> TextureMapper::acquireTextureFromPool(const IntSize& s
return selectedTexture.release();
}
-std::unique_ptr<TextureMapper> TextureMapper::create()
+std::unique_ptr<TextureMapper> TextureMapper::create(AccelerationMode mode)
{
+ if (mode == SoftwareMode)
+ return std::make_unique<TextureMapperImageBuffer>();
return platformCreateAccelerated();
}
-TextureMapper::TextureMapper()
+TextureMapper::TextureMapper(AccelerationMode accelerationMode)
: m_context(0)
, m_interpolationQuality(InterpolationDefault)
, m_textDrawingMode(TextModeFill)
+ , m_accelerationMode(accelerationMode)
, m_isMaskMode(false)
, m_wrapMode(StretchWrap)
{ }
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.h b/Source/WebCore/platform/graphics/texmap/TextureMapper.h
index bfe718e28..43d1db7a1 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapper.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.h
@@ -48,6 +48,7 @@ class FilterOperations;
class TextureMapper {
WTF_MAKE_FAST_ALLOCATED;
public:
+ enum AccelerationMode { SoftwareMode, OpenGLMode };
enum PaintFlag {
PaintingMirrored = 1 << 0,
};
@@ -59,9 +60,9 @@ public:
typedef unsigned PaintFlags;
- static std::unique_ptr<TextureMapper> create();
+ static std::unique_ptr<TextureMapper> create(AccelerationMode newMode = SoftwareMode);
- explicit TextureMapper();
+ explicit TextureMapper(AccelerationMode);
virtual ~TextureMapper();
enum ExposedEdges {
@@ -93,6 +94,7 @@ public:
InterpolationQuality imageInterpolationQuality() const { return m_interpolationQuality; }
TextDrawingModeFlags textDrawingMode() const { return m_textDrawingMode; }
+ AccelerationMode accelerationMode() const { return m_accelerationMode; }
virtual void beginPainting(PaintFlags = 0) { }
virtual void endPainting() { }
@@ -125,6 +127,7 @@ private:
#endif
InterpolationQuality m_interpolationQuality;
TextDrawingModeFlags m_textDrawingMode;
+ AccelerationMode m_accelerationMode;
bool m_isMaskMode;
TransformationMatrix m_patternTransform;
WrapMode m_wrapMode;
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
index 86f100262..25ed9dd7f 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
@@ -176,7 +176,8 @@ void TextureMapperGLData::initializeStencil()
}
TextureMapperGL::TextureMapperGL()
- : m_enableEdgeDistanceAntialiasing(false)
+ : TextureMapper(OpenGLMode)
+ , m_enableEdgeDistanceAntialiasing(false)
{
m_context3D = GraphicsContext3D::createForCurrentGLContext();
m_data = new TextureMapperGLData(m_context3D.get());
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp
new file mode 100644
index 000000000..0812b585d
--- /dev/null
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp
@@ -0,0 +1,125 @@
+/*
+ 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 "TextureMapperImageBuffer.h"
+
+#include "BitmapTexturePool.h"
+#include "GraphicsLayer.h"
+#include "NotImplemented.h"
+
+#if USE(TEXTURE_MAPPER)
+namespace WebCore {
+
+static const int s_maximumAllowedImageBufferDimension = 4096;
+
+TextureMapperImageBuffer::TextureMapperImageBuffer()
+ : TextureMapper(SoftwareMode)
+{
+ m_texturePool = std::make_unique<BitmapTexturePool>();
+}
+
+IntSize TextureMapperImageBuffer::maxTextureSize() const
+{
+ return IntSize(s_maximumAllowedImageBufferDimension, s_maximumAllowedImageBufferDimension);
+}
+
+void TextureMapperImageBuffer::beginClip(const TransformationMatrix& matrix, const FloatRect& rect)
+{
+ GraphicsContext* context = currentContext();
+ if (!context)
+ return;
+#if ENABLE(3D_TRANSFORMS)
+ TransformationMatrix previousTransform = context->get3DTransform();
+#else
+ AffineTransform previousTransform = context->getCTM();
+#endif
+ context->save();
+
+#if ENABLE(3D_TRANSFORMS)
+ context->concat3DTransform(matrix);
+#else
+ context->concatCTM(matrix.toAffineTransform());
+#endif
+
+ context->clip(rect);
+
+#if ENABLE(3D_TRANSFORMS)
+ context->set3DTransform(previousTransform);
+#else
+ context->setCTM(previousTransform);
+#endif
+}
+
+void TextureMapperImageBuffer::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, unsigned /* exposedEdges */)
+{
+ GraphicsContext* context = currentContext();
+ if (!context)
+ return;
+
+ const BitmapTextureImageBuffer& textureImageBuffer = static_cast<const BitmapTextureImageBuffer&>(texture);
+ ImageBuffer* image = textureImageBuffer.image();
+ context->save();
+ context->setCompositeOperation(isInMaskMode() ? CompositeDestinationIn : CompositeSourceOver);
+ context->setAlpha(opacity);
+#if ENABLE(3D_TRANSFORMS)
+ context->concat3DTransform(matrix);
+#else
+ context->concatCTM(matrix.toAffineTransform());
+#endif
+ context->drawImageBuffer(*image, targetRect);
+ context->restore();
+}
+
+void TextureMapperImageBuffer::drawSolidColor(const FloatRect& rect, const TransformationMatrix& matrix, const Color& color)
+{
+ GraphicsContext* context = currentContext();
+ if (!context)
+ return;
+
+ context->save();
+ context->setCompositeOperation(isInMaskMode() ? CompositeDestinationIn : CompositeSourceOver);
+#if ENABLE(3D_TRANSFORMS)
+ context->concat3DTransform(matrix);
+#else
+ context->concatCTM(matrix.toAffineTransform());
+#endif
+
+ context->fillRect(rect, color);
+ context->restore();
+}
+
+void TextureMapperImageBuffer::drawBorder(const Color&, float /* borderWidth */, const FloatRect&, const TransformationMatrix&)
+{
+ notImplemented();
+}
+
+void TextureMapperImageBuffer::drawNumber(int /* number */, const Color&, const FloatPoint&, const TransformationMatrix&)
+{
+ notImplemented();
+}
+
+PassRefPtr<BitmapTexture> BitmapTextureImageBuffer::applyFilters(TextureMapper&, const FilterOperations&)
+{
+ ASSERT_NOT_REACHED();
+ return this;
+}
+
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h
new file mode 100644
index 000000000..234b8eeec
--- /dev/null
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h
@@ -0,0 +1,59 @@
+/*
+ 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.
+ */
+
+#ifndef TextureMapperImageBuffer_h
+#define TextureMapperImageBuffer_h
+
+#include "BitmapTextureImageBuffer.h"
+#include "ImageBuffer.h"
+#include "TextureMapper.h"
+
+#if USE(TEXTURE_MAPPER)
+namespace WebCore {
+
+class TextureMapperImageBuffer final : public TextureMapper {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ TextureMapperImageBuffer();
+
+ // TextureMapper implementation
+ void drawBorder(const Color&, float borderWidth, const FloatRect&, const TransformationMatrix&) final;
+ void drawNumber(int number, const Color&, const FloatPoint&, const TransformationMatrix&) final;
+ void drawTexture(const BitmapTexture&, const FloatRect& targetRect, const TransformationMatrix&, float opacity, unsigned exposedEdges) final;
+ void drawSolidColor(const FloatRect&, const TransformationMatrix&, const Color&) final;
+ void beginClip(const TransformationMatrix&, const FloatRect&) final;
+ void bindSurface(BitmapTexture* surface) final { m_currentSurface = surface;}
+ void endClip() final { graphicsContext()->restore(); }
+ IntRect clipBounds() final { return currentContext()->clipBounds(); }
+ IntSize maxTextureSize() const final;
+ PassRefPtr<BitmapTexture> createTexture() final { return BitmapTextureImageBuffer::create(); }
+
+ inline GraphicsContext* currentContext()
+ {
+ return m_currentSurface ? static_cast<BitmapTextureImageBuffer*>(m_currentSurface.get())->graphicsContext() : graphicsContext();
+ }
+
+private:
+ RefPtr<BitmapTexture> m_currentSurface;
+};
+
+}
+#endif // USE(TEXTURE_MAPPER)
+
+#endif // TextureMapperImageBuffer_h
diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CompositingCoordinator.cpp b/Source/WebCore/platform/graphics/texmap/coordinated/CompositingCoordinator.cpp
index 4bfddfd6c..e2f15b3b8 100644
--- a/Source/WebCore/platform/graphics/texmap/coordinated/CompositingCoordinator.cpp
+++ b/Source/WebCore/platform/graphics/texmap/coordinated/CompositingCoordinator.cpp
@@ -58,6 +58,9 @@ CompositingCoordinator::CompositingCoordinator(Page* page, CompositingCoordinato
, m_lastAnimationServiceTime(0)
#endif
{
+ // This is a temporary way to enable this only in the GL case, until TextureMapperImageBuffer is removed.
+ // See https://bugs.webkit.org/show_bug.cgi?id=114869
+ CoordinatedGraphicsLayer::setShouldSupportContentsTiling(true);
}
CompositingCoordinator::~CompositingCoordinator()
diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp
index cb94a9652..7de531692 100644
--- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp
+++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp
@@ -376,9 +376,16 @@ void CoordinatedGraphicsLayer::setContentsTilePhase(const FloatSize& p)
didChangeLayerState();
}
+static bool s_shouldSupportContentsTiling = false;
+
+void CoordinatedGraphicsLayer::setShouldSupportContentsTiling(bool s)
+{
+ s_shouldSupportContentsTiling = s;
+}
+
bool GraphicsLayer::supportsContentsTiling()
{
- return true;
+ return s_shouldSupportContentsTiling;
}
void CoordinatedGraphicsLayer::setContentsNeedsDisplay()
diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h
index 8a45c3565..1664cffe7 100644
--- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h
+++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h
@@ -146,6 +146,7 @@ public:
void setNeedsVisibleRectAdjustment();
void purgeBackingStores();
+ static void setShouldSupportContentsTiling(bool);
CoordinatedGraphicsLayer* findFirstDescendantWithContentsRecursively();
private:
diff --git a/Source/WebCore/platform/qt/FileSystemQt.cpp b/Source/WebCore/platform/qt/FileSystemQt.cpp
index 363029406..167ff8354 100644
--- a/Source/WebCore/platform/qt/FileSystemQt.cpp
+++ b/Source/WebCore/platform/qt/FileSystemQt.cpp
@@ -147,6 +147,12 @@ CString fileSystemRepresentation(const String& path)
return path.utf8();
}
+String stringFromFileSystemRepresentation(const char* fileSystemRepresentation)
+{
+ // This needs to do the opposite of fileSystemRepresentation.
+ return String::fromUTF8(fileSystemRepresentation);
+}
+
String openTemporaryFile(const String& prefix, PlatformFileHandle& handle)
{
#ifndef QT_NO_TEMPORARYFILE
diff --git a/Source/WebCore/platform/qt/QWebPageClient.h b/Source/WebCore/platform/qt/QWebPageClient.h
index c9211044c..c37abff62 100644
--- a/Source/WebCore/platform/qt/QWebPageClient.h
+++ b/Source/WebCore/platform/qt/QWebPageClient.h
@@ -34,6 +34,7 @@
#include <QRect>
QT_BEGIN_NAMESPACE
+class QOpenGLContext;
class QStyle;
class QWindow;
QT_END_NAMESPACE
@@ -54,6 +55,7 @@ public:
virtual void setInputMethodEnabled(bool) = 0;
virtual bool inputMethodEnabled() const = 0;
virtual bool makeOpenGLContextCurrentIfAvailable() { return false; }
+ virtual QOpenGLContext* openGLContextIfAvailable() { return 0; }
virtual void setInputMethodHints(Qt::InputMethodHints) = 0;
virtual bool isViewVisible() = 0;
diff --git a/Source/WebCore/platform/text/hyphen/HyphenationLibHyphen.cpp b/Source/WebCore/platform/text/hyphen/HyphenationLibHyphen.cpp
index 16a540c91..92ce4685a 100644
--- a/Source/WebCore/platform/text/hyphen/HyphenationLibHyphen.cpp
+++ b/Source/WebCore/platform/text/hyphen/HyphenationLibHyphen.cpp
@@ -31,6 +31,8 @@
#include "FileSystem.h"
#include <hyphen.h>
+#include <limits>
+#include <stdlib.h>
#include <wtf/HashMap.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/TinyLRUCache.h>
@@ -62,8 +64,14 @@ static String extractLocaleFromDictionaryFilePath(const String& filePath)
static void scanDirectoryForDicionaries(const char* directoryPath, HashMap<AtomicString, Vector<String>>& availableLocales)
{
- for (const auto& filePath : listDirectory(directoryPath, "hyph_*.dic")) {
+ for (auto& filePath : listDirectory(directoryPath, "hyph_*.dic")) {
String locale = extractLocaleFromDictionaryFilePath(filePath).convertToASCIILowercase();
+
+ char normalizedPath[PATH_MAX];
+ if (!realpath(fileSystemRepresentation(filePath).data(), normalizedPath))
+ continue;
+
+ filePath = stringFromFileSystemRepresentation(normalizedPath);
availableLocales.add(locale, Vector<String>()).iterator->value.append(filePath);
String localeReplacingUnderscores = String(locale);
@@ -170,9 +178,9 @@ template<>
class TinyLRUCachePolicy<AtomicString, RefPtr<HyphenationDictionary>>
{
public:
- static TinyLRUCache<AtomicString, RefPtr<HyphenationDictionary>>& cache()
+ static TinyLRUCache<AtomicString, RefPtr<WebCore::HyphenationDictionary>, 32>& cache()
{
- static NeverDestroyed<TinyLRUCache<AtomicString, RefPtr<HyphenationDictionary>>> cache;
+ static NeverDestroyed<TinyLRUCache<AtomicString, RefPtr<WebCore::HyphenationDictionary>, 32>> cache;
return cache;
}