diff options
Diffstat (limited to 'Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp')
-rw-r--r-- | Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp | 248 |
1 files changed, 76 insertions, 172 deletions
diff --git a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp index ddff6051c..9e69ce698 100644 --- a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp +++ b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp @@ -18,7 +18,6 @@ */ #include "config.h" - #include "TextureMapperGL.h" #include "GraphicsContext.h" @@ -31,6 +30,12 @@ #include <wtf/RefCounted.h> #if PLATFORM(QT) +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#include <QPlatformPixmap> +#endif +#endif + +#if PLATFORM(QT) || USE(CAIRO) #include <cairo/OpenGLShims.h> #elif defined(TEXMAP_OPENGL_ES_2) #include <GLES2/gl2.h> @@ -51,7 +56,14 @@ #include <GL/glx.h> #endif -#if !defined(TEXMAP_OPENGL_ES_2) && !PLATFORM(QT) +#if USE(CAIRO) +#include "CairoUtilities.h" +#include "RefPtrCairo.h" +#include <cairo.h> +#include <wtf/ByteArray.h> +#endif + +#if !defined(TEXMAP_OPENGL_ES_2) && !PLATFORM(QT) && !PLATFORM(GTK) extern "C" { void glUniform1f(GLint, GLfloat); void glUniform1i(GLint, GLint); @@ -265,57 +277,6 @@ struct TextureMapperGLData { }; - struct DirectlyCompositedImageRepository { - struct Entry { - GLuint texture; - int refCount; - }; - typedef HashMap<ImageUID, Entry> ImageTextureMap; - ImageTextureMap imageToTexture; - - GLuint findOrCreate(ImageUID image, bool& found) - { - ImageTextureMap::iterator it = imageToTexture.find(image); - found = false; - if (it != imageToTexture.end()) { - it->second.refCount++; - found = true; - return it->second.texture; - } - Entry entry; - GL_CMD(glGenTextures(1, &entry.texture)); - entry.refCount = 1; - imageToTexture.add(image, entry); - return entry.texture; - } - - bool deref(ImageUID image) - { - HashMap<ImageUID, Entry>::iterator it = imageToTexture.find(image); - if (it != imageToTexture.end()) { - if (it->second.refCount < 2) { - imageToTexture.remove(it); - return false; - } - } - return true; - } - - DirectlyCompositedImageRepository() - { - } - - ~DirectlyCompositedImageRepository() - { - for (ImageTextureMap::iterator it = imageToTexture.begin(); it != imageToTexture.end(); ++it) { - GLuint texture = it->second.texture; - if (texture) - GL_CMD(glDeleteTextures(1, &texture)); - } - - } - } directlyCompositedImages; - SharedGLData& sharedGLData() const { return *(m_sharedGLData.get()); @@ -332,6 +293,7 @@ struct TextureMapperGLData { int currentProgram; GLint previousProgram; GLint previousScissorState; + GLint viewport[4]; RefPtr<SharedGLData> m_sharedGLData; }; @@ -342,56 +304,25 @@ public: virtual bool isValid() const; virtual void reset(const IntSize&, bool opaque); void bind(); - virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect); - virtual void endPaint(); - virtual void setContentsToImage(Image*); ~BitmapTextureGL() { destroy(); } virtual uint32_t id() const { return m_id; } - inline bool isOpaque() const { return m_opaque; } inline FloatSize relativeSize() const { return m_relativeSize; } void setTextureMapper(TextureMapperGL* texmap) { m_textureMapper = texmap; } - - void updateContents(PixelFormat, const IntRect&, void*); - void updateRawContents(const IntRect&, const void*); - void pack() - { - // This is currently a stub. - if (isPacked()) - return; - m_isPacked = true; - } - - void unpack() - { - // This is currently a stub. - if (!isPacked()) - return; - m_isPacked = false; - } - - bool isPacked() const - { - return m_isPacked; - } + void updateContents(Image*, const IntRect&, const IntRect&, PixelFormat); + void updateContents(const void*, const IntRect&); private: GLuint m_id; - ImageUID m_imageUID; FloatSize m_relativeSize; - bool m_opaque; IntSize m_textureSize; - OwnPtr<BGRA32PremultimpliedBuffer> m_buffer; IntRect m_dirtyRect; GLuint m_fbo; GLuint m_rbo; IntSize m_actualSize; bool m_surfaceNeedsReset; - bool m_isPacked; TextureMapperGL* m_textureMapper; BitmapTextureGL() : m_id(0) - , m_imageUID(0) - , m_opaque(false) , m_fbo(0) , m_rbo(0) , m_surfaceNeedsReset(true) @@ -544,6 +475,7 @@ void TextureMapperGL::beginPainting() #endif glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); + glGetIntegerv(GL_VIEWPORT, data().viewport); bindSurface(0); } @@ -663,7 +595,6 @@ static void texImage2DResourceSafe(size_t width, size_t height) void BitmapTextureGL::reset(const IntSize& newSize, bool opaque) { BitmapTexture::reset(newSize, opaque); - m_imageUID = 0; IntSize newTextureSize = nextPowerOfTwo(newSize); bool justCreated = false; if (!m_id) { @@ -682,28 +613,10 @@ void BitmapTextureGL::reset(const IntSize& newSize, bool opaque) } m_actualSize = newSize; m_relativeSize = FloatSize(float(newSize.width()) / m_textureSize.width(), float(newSize.height()) / m_textureSize.height()); - m_opaque = opaque; m_surfaceNeedsReset = true; } -PlatformGraphicsContext* BitmapTextureGL::beginPaint(const IntRect& dirtyRect) -{ - m_buffer = BGRA32PremultimpliedBuffer::create(); - m_dirtyRect = dirtyRect; - return m_buffer->beginPaint(dirtyRect, m_opaque); -} - -void BitmapTextureGL::endPaint() -{ - if (!m_buffer) - return; - m_buffer->endPaint(); - updateContents(BGRAFormat, m_dirtyRect, m_buffer->data()); - GL_CMD(glBindTexture(GL_TEXTURE_2D, m_id)) - m_buffer.clear(); -} - -#ifdef TEXMAP_OPENGL_ES_2 +#if PLATFORM(QT) || (USE(CAIRO) && defined(TEXMAP_OPENGL_ES_2)) static void swizzleBGRAToRGBA(uint32_t* data, const IntSize& size) { int width = size.width(); @@ -716,77 +629,62 @@ static void swizzleBGRAToRGBA(uint32_t* data, const IntSize& size) } #endif -void BitmapTextureGL::updateContents(PixelFormat pixelFormat, const IntRect& rect, void* bits) +void BitmapTextureGL::updateContents(const void* data, const IntRect& targetRect) { GL_CMD(glBindTexture(GL_TEXTURE_2D, m_id)) -#ifdef TEXMAP_OPENGL_ES_2 - bool shouldSwizzle = false; -#endif - - GLint glFormat = GL_RGBA; - switch (pixelFormat) { - case RGBAFormat: - glFormat = GL_RGBA; - break; - case RGBFormat: - glFormat = GL_RGB; - break; - case BGRAFormat: -#ifdef TEXMAP_OPENGL_ES_2 - shouldSwizzle = true; - glFormat = GL_RGBA; -#else - glFormat = GL_BGRA; -#endif - break; - case BGRFormat: -#ifdef TEXMAP_OPENGL_ES_2 - shouldSwizzle = true; - glFormat = GL_RGB; -#else - glFormat = GL_BGR; -#endif - break; - } - -#ifdef TEXMAP_OPENGL_ES_2 - if (shouldSwizzle) - swizzleBGRAToRGBA(static_cast<uint32_t*>(bits), rect.size()); -#endif - GL_CMD(glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), glFormat, GL_UNSIGNED_BYTE, bits)) + GL_CMD(glTexSubImage2D(GL_TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, data)) } -void BitmapTextureGL::updateRawContents(const IntRect& rect, const void* bits) +void BitmapTextureGL::updateContents(Image* image, const IntRect& targetRect, const IntRect& sourceRect, BitmapTexture::PixelFormat format) { + if (!image) + return; GL_CMD(glBindTexture(GL_TEXTURE_2D, m_id)) GLuint glFormat = isOpaque() ? GL_RGB : GL_RGBA; - GL_CMD(glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), glFormat, GL_UNSIGNED_BYTE, bits)) -} - -void BitmapTextureGL::setContentsToImage(Image* image) -{ - ImageUID uid = image ? uidForImage(image) : 0; - if (!image || !uid) { - if (m_imageUID) - destroy(); + NativeImagePtr frameImage = image->nativeImageForCurrentFrame(); + if (!frameImage) return; - } - if (uid == m_imageUID) - return; - bool found = false; - GLuint newTextureID = m_textureMapper->data().directlyCompositedImages.findOrCreate(uid, found); - if (newTextureID != m_id) { - m_imageUID = uid; - destroy(); - m_id = newTextureID; - reset(image->size(), false); - if (!found) { - GraphicsContext context(beginPaint(IntRect(0, 0, m_textureSize.width(), m_textureSize.height()))); - context.drawImage(image, ColorSpaceDeviceRGB, IntPoint(0, 0), CompositeCopy); - endPaint(); - } - } +#if PLATFORM(QT) + QImage qtImage; + +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + // With QPA, we can avoid a deep copy. + qtImage = *frameImage->handle()->buffer(); +#else + // This might be a deep copy, depending on other references to the pixmap. + qtImage = frameImage->toImage(); +#endif + + if (IntSize(qtImage.size()) != sourceRect.size()) + qtImage = qtImage.copy(sourceRect); + if (format == BGRAFormat || format == BGRFormat) + swizzleBGRAToRGBA(reinterpret_cast<uint32_t*>(qtImage.bits()), qtImage.size()); + GL_CMD(glTexSubImage2D(GL_TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, GL_UNSIGNED_BYTE, qtImage.constBits())) + +#elif USE(CAIRO) + +#if !CPU(BIG_ENDIAN) +#if defined(TEXMAP_OPENGL_ES_2) + swizzleBGRAToRGBA(reinterpret_cast<uint32_t*>(cairo_image_surface_get_data(frameImage)), + cairo_image_surface_get_stride(frameImage) * cairo_image_surface_get_height(frameImage)); +#else + glFormat = isOpaque() ? GL_BGR : GL_BGRA; +#endif +#endif + + glPixelStorei(GL_UNPACK_ROW_LENGTH, cairo_image_surface_get_stride(frameImage) / 4); + glPixelStorei(GL_UNPACK_SKIP_ROWS, sourceRect.y()); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, sourceRect.x()); + GL_CMD(glTexSubImage2D(GL_TEXTURE_2D, 0, + targetRect.x(), targetRect.y(), + targetRect.width(), targetRect.height(), + glFormat, GL_UNSIGNED_BYTE, + cairo_image_surface_get_data(frameImage))); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); +#endif } static inline TransformationMatrix createProjectionMatrix(const IntSize& size, bool flip) @@ -837,7 +735,7 @@ void BitmapTextureGL::bind() void BitmapTextureGL::destroy() { - if (m_id && (!m_imageUID || !m_textureMapper->data().directlyCompositedImages.deref(m_imageUID))) + if (m_id) GL_CMD(glDeleteTextures(1, &m_id)) if (m_fbo) @@ -872,12 +770,13 @@ void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer) BitmapTextureGL* surface = static_cast<BitmapTextureGL*>(surfacePointer); if (!surface) { + IntSize viewportSize(data().viewport[2], data().viewport[3]); GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, 0)) - data().projectionMatrix = createProjectionMatrix(viewportSize(), true).multiply(transform()); + data().projectionMatrix = createProjectionMatrix(viewportSize, true); GL_CMD(glStencilFunc(data().sharedGLData().stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().sharedGLData().stencilIndex - 1, data().sharedGLData().stencilIndex - 1)) GL_CMD(glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)) - GL_CMD(glViewport(0, 0, viewportSize().width(), viewportSize().height())) - data().sharedGLData().clipStack.append(IntRect(IntPoint::zero(), viewportSize())); + GL_CMD(glViewport(0, 0, viewportSize.width(), viewportSize.height())) + data().sharedGLData().clipStack.append(IntRect(data().viewport[0], data().viewport[1], data().viewport[2], data().viewport[3])); return; } @@ -985,4 +884,9 @@ PassRefPtr<BitmapTexture> TextureMapperGL::createTexture() return adoptRef(texture); } +PassOwnPtr<TextureMapper> TextureMapper::platformCreateAccelerated() +{ + return TextureMapperGL::create(); +} + }; |