WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
WIP
blitter.patch (text/plain), 30.38 KB, created by
Kalyan
on 2013-01-29 14:08:06 PST
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Kalyan
Created:
2013-01-29 14:08:06 PST
Size:
30.38 KB
patch
obsolete
>diff --git Source/WebCore/ChangeLog Source/WebCore/ChangeLog >index 05b66f7..9c11526 100644 >--- Source/WebCore/ChangeLog >+++ Source/WebCore/ChangeLog >@@ -1,3 +1,54 @@ >+2013-01-29 Kondapally Kalyan <kalyan.kondapally@intel.com> >+ >+ [EFL] [WebGL] Add support for bliting texture contents to FBO. >+ https://bugs.webkit.org/show_bug.cgi?id=106508 >+ >+ We currently rely on EXT_framebuffer_blit to blit contents of a texture to a FBO. >+ This extension is not exposed on GLES1.1 or 2.0. This patch provides a fall back >+ mechanism by using shaders to blit texture contents to an FBO. >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Covered by existing WebGL tests. >+ >+ * PlatformEfl.cmake: >+ * PlatformNix.cmake: >+ * platform/graphics/opengl/GLPlatformSurface.cpp: >+ (WebCore::GLPlatformSurface::GLPlatformSurface): >+ (WebCore::GLPlatformSurface::updateContents): >+ (WebCore::GLPlatformSurface::destroy): >+ * platform/graphics/opengl/GLPlatformSurface.h: >+ (GLPlatformSurface): >+ * platform/graphics/surfaces/TextureBlitter.cpp: Added. >+ (WebCore): >+ (WebCore::initializeGLBindings): >+ (ScopedToggleGLState): >+ (WebCore::ScopedToggleGLState::ScopedToggleGLState): >+ (WebCore::ScopedToggleGLState::~ScopedToggleGLState): >+ (WebCore::ScopedToggleGLState::toggleState): >+ (ScopedProgramBinding): >+ (WebCore::ScopedProgramBinding::ScopedProgramBinding): >+ (WebCore::ScopedProgramBinding::~ScopedProgramBinding): >+ (WebCore::GetShaderSource): >+ (WebCore::TextureBlitter::TextureBlitter): >+ (WebCore::TextureBlitter::~TextureBlitter): >+ (WebCore::TextureBlitter::clear): >+ (WebCore::TextureBlitter::loadShader): >+ (WebCore::TextureBlitter::bindArrayBuffer): >+ (WebCore::TextureBlitter::enableVertexArray): >+ (WebCore::TextureBlitter::disableVertexArray): >+ (WebCore::TextureBlitter::linkProgram): >+ (WebCore::TextureBlitter::initializeVBO): >+ (WebCore::TextureBlitter::initializeProgram): >+ (WebCore::TextureBlitter::drawTexture): >+ (WebCore::TextureBlitter::copyTexture): >+ * platform/graphics/surfaces/TextureBlitter.h: Added. >+ (WebCore): >+ (TextureBlitter): >+ (WebCore::TextureBlitter::create): >+ (WebCore::TextureBlitter::deref): >+ Helper class to blit texture contents to an FBO. >+ > 2013-01-24 Victor Jaquez <vjaquez@igalia.com> > >diff --git Source/WebCore/PlatformEfl.cmake Source/WebCore/PlatformEfl.cmake >index f5179c6..52d337c 100644 >--- Source/WebCore/PlatformEfl.cmake >+++ Source/WebCore/PlatformEfl.cmake >@@ -314,6 +314,7 @@ if (WTF_USE_3D_GRAPHICS) > platform/graphics/opengl/GLPlatformSurface.cpp > platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp > platform/graphics/surfaces/GraphicsSurface.cpp >+ platform/graphics/surfaces/TextureBlitter.cpp > platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp > platform/graphics/surfaces/glx/X11WindowResources.cpp > platform/graphics/texmap/TextureMapperGL.cpp >diff --git Source/WebCore/platform/graphics/opengl/GLPlatformSurface.cpp Source/WebCore/platform/graphics/opengl/GLPlatformSurface.cpp >index 7f7a564..467194d 100644 >--- Source/WebCore/platform/graphics/opengl/GLPlatformSurface.cpp >+++ Source/WebCore/platform/graphics/opengl/GLPlatformSurface.cpp >@@ -70,11 +70,11 @@ PassOwnPtr<GLPlatformSurface> GLPlatformSurface::createTransportSurface() > > GLPlatformSurface::GLPlatformSurface() > : m_restoreNeeded(true) >- , m_fboId(0) > , m_sharedDisplay(0) > , m_drawable(0) > , m_bufferHandle(0) > { >+ m_blitter = TextureBlitter::create(); > } > > GLPlatformSurface::~GLPlatformSurface() >@@ -113,24 +113,11 @@ void GLPlatformSurface::swapBuffers() > > void GLPlatformSurface::updateContents(const uint32_t texture, const GLuint bindFboId, const uint32_t bindTexture) > { >- if (!m_fboId) >- glGenFramebuffers(1, &m_fboId); >- >- m_restoreNeeded = false; >- >- int x = 0; >- int y = 0; >- int width = m_rect.width(); >- int height = m_rect.height(); >- >- glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fboId); >- glBindTexture(GL_TEXTURE_2D, texture); >- glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); >- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); >- // Use NEAREST as no scale is performed during the blit. >- glBlitFramebuffer(x, y, width, height, x, y, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); >+ if (!m_blitter) >+ return; >+ >+ m_blitter->drawTexture(texture, 0, m_rect, m_rect); > swapBuffers(); >- glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); > glBindTexture(GL_TEXTURE_2D, bindTexture); > glBindFramebuffer(GL_FRAMEBUFFER, bindFboId); > } >@@ -143,11 +130,7 @@ void GLPlatformSurface::setGeometry(const IntRect& newRect) > void GLPlatformSurface::destroy() > { > m_rect = IntRect(); >- >- if (m_fboId) >- glDeleteFramebuffers(1, &m_fboId); >- >- m_fboId = 0; >+ m_blitter = nullptr; > } > > } >diff --git Source/WebCore/platform/graphics/opengl/GLPlatformSurface.h Source/WebCore/platform/graphics/opengl/GLPlatformSurface.h >index e8db425..673a2bf 100644 >--- Source/WebCore/platform/graphics/opengl/GLPlatformSurface.h >+++ Source/WebCore/platform/graphics/opengl/GLPlatformSurface.h >@@ -30,6 +30,7 @@ > > #include "GLDefs.h" > #include "IntRect.h" >+#include <surfaces/TextureBlitter.h> > #include <wtf/Noncopyable.h> > #include <wtf/PassOwnPtr.h> > >@@ -78,10 +79,10 @@ protected: > GLPlatformSurface(); > bool m_restoreNeeded; > IntRect m_rect; >- GLuint m_fboId; > PlatformDisplay m_sharedDisplay; > PlatformDrawable m_drawable; > PlatformBufferHandle m_bufferHandle; >+ RefPtr<TextureBlitter> m_blitter; > }; > > } >diff --git Source/WebCore/platform/graphics/surfaces/TextureBlitter.cpp Source/WebCore/platform/graphics/surfaces/TextureBlitter.cpp >new file mode 100644 >index 0000000..01f6d3c >--- /dev/null >+++ Source/WebCore/platform/graphics/surfaces/TextureBlitter.cpp >@@ -0,0 +1,609 @@ >+/* >+ * Copyright (C) 2012 Intel Corporation. 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. >+ * >+ * 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 "TextureBlitter.h" >+ >+#if USE(ACCELERATED_COMPOSITING) >+ >+#include "TextureMapperGL.h" >+ >+#include <opengl/GLPlatformContext.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+//#define SHADER_DEBUG >+TextureBlitter* TextureBlitter::m_staticTextureBlitter = 0; >+static const GLfloat vertices[] = { 1.0f, 1.0f, 0.0f, 1.0f, >+ -1.0f, 1.0f, 0.0f, 1.0f, >+ 1.0f, -1.0f, 0.0f, 1.0f, >+ -1.0f, -1.0f, 0.0f, 1.0f, >+ -1.0f, -1.0f, 0.0f, 1.0f, // Flip coordinates. >+ 1.0f, -1.0f, 0.0f, 1.0f, >+ -1.0f, 1.0f, 0.0f, 1.0f, >+ 1.0f, 1.0f, 0.0f, 1.0f, >+ 0.0f, 1.0f,1.0f, 1.0f, // Tex coordinates. >+ 0.0f, 0.0f,1.0f, 0.0f}; >+ >+static const GLushort indexVertices[] = { 0, 1, 2, 3}; >+static const int vertexIndexSize = sizeof(indexVertices)/sizeof(indexVertices[0]); >+static const int FLIPOFFSET = sizeof(float) * 4 * 4; >+static const int TEXCOORDOFFSET = FLIPOFFSET * 2; >+static const int VERTEXATTRIB = 0; >+static const int TEXCOORDATTRIB = 1; >+ >+#if USE(OPENGL_ES_2) >+static PFNGLBINDVERTEXARRAYOESPROC m_glBindVertexArray = 0; >+static PFNGLDELETEVERTEXARRAYSOESPROC m_glDeleteVertexArrays = 0; >+static PFNGLGENVERTEXARRAYSOESPROC m_glGenVertexArrays = 0; >+static PFNGLISVERTEXARRAYOESPROC m_glIsVertexArray = 0; >+#else >+static PFNGLBINDVERTEXARRAYPROC m_glBindVertexArray = 0; >+static PFNGLDELETEVERTEXARRAYSPROC m_glDeleteVertexArrays = 0; >+static PFNGLGENVERTEXARRAYSPROC m_glGenVertexArrays = 0; >+static PFNGLISVERTEXARRAYPROC m_glIsVertexArray = 0; >+static PFNGLSAMPLERPARAMETERIPROC m_glSamplerParameteri = 0; >+static PFNGLGENSAMPLERSPROC m_glGenSamplers = 0; >+static PFNGLBINDSAMPLERPROC m_glBindSampler = 0; >+#endif >+ >+static void initializeGLBindings() >+{ >+ static bool bindingsInitialized = false; >+ if (bindingsInitialized) >+ return; >+ >+ bindingsInitialized = true; >+ >+#if USE(OPENGL_ES_2) >+ if (GLPlatformContext::supportsGLExtension("GL_OES_vertex_array_object")) { >+ m_glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYOESPROC>(eglGetProcAddress("glBindVertexArrayOES")); >+ m_glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSOESPROC>(eglGetProcAddress("glGenVertexArraysOES")); >+ m_glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSOESPROC>(eglGetProcAddress("glDeleteVertexArraysOES")); >+ m_glIsVertexArray = reinterpret_cast<PFNGLISVERTEXARRAYOESPROC>(eglGetProcAddress("glIsVertexArrayOES")); >+ } >+ >+#else >+ bool supportsVAO = GLPlatformContext::supportsGLExtension("GL_ARB_vertex_array_object"); >+ // This ext is only available with desktop GL and is not supported by GLES2.0, support for the same has been added in GLES3.0. >+ bool supportsSamplerObjects = GLPlatformContext::supportsGLExtension("GL_ARB_sampler_objects"); >+#if USE(GLX) >+ if (supportsVAO) { >+ m_glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glBindVertexArray"))); >+ m_glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glGenVertexArrays"))); >+ m_glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glDeleteVertexArrays"))); >+ m_glIsVertexArray = reinterpret_cast<PFNGLISVERTEXARRAYPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glIsVertexArray"))); >+ } >+ >+ if (supportsSamplerObjects) { >+ m_glSamplerParameteri = reinterpret_cast<PFNGLSAMPLERPARAMETERIPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glSamplerParameteri"))); >+ m_glGenSamplers = reinterpret_cast<PFNGLGENSAMPLERSPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glGenSamplers"))); >+ m_glBindSampler = reinterpret_cast<PFNGLBINDSAMPLERPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glBindSampler"))); >+ } >+#elif USE(EGL) >+ if (supportsVAO) { >+ m_glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYPROC>(eglGetProcAddress("glBindVertexArray")); >+ m_glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSPROC>(eglGetProcAddress("glGenVertexArrays")); >+ m_glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSPROC>(eglGetProcAddress("glDeleteVertexArrays")); >+ m_glIsVertexArray = reinterpret_cast<PFNGLISVERTEXARRAYPROC>(eglGetProcAddress("glIsVertexArray")); >+ } >+ >+ if (supportsSamplerObjects) { >+ m_glSamplerParameteri = reinterpret_cast<PFNGLSAMPLERPARAMETERIPROC>(eglGetProcAddress("glSamplerParameteri")); >+ m_glGenSamplers = reinterpret_cast<PFNGLGENSAMPLERSPROC>(eglGetProcAddress("glGenSamplers")); >+ m_glBindSampler = reinterpret_cast<PFNGLBINDSAMPLERPROC>(eglGetProcAddress("glBindSampler")); >+ } >+#endif >+#endif >+} >+ >+class ScopedToggleGLState >+{ >+ WTF_MAKE_NONCOPYABLE(ScopedToggleGLState); >+ >+public: >+ ScopedToggleGLState() >+ { >+ m_enableBlend = toggleState(GL_BLEND); >+ m_enableCullFace = toggleState(GL_CULL_FACE); >+ m_enableDepthTest = toggleState(GL_DEPTH_TEST); >+ m_enableDitherTest = toggleState(GL_DITHER); >+ m_enablePolygonOffsetFill = toggleState(GL_POLYGON_OFFSET_FILL); >+ m_enableSampleAlpha = toggleState(GL_SAMPLE_ALPHA_TO_COVERAGE); >+ m_enableSampleCoverage = toggleState(GL_SAMPLE_COVERAGE); >+ m_enableStencilTest = toggleState(GL_STENCIL_TEST); >+ m_enableScissorTest = toggleState(GL_SCISSOR_TEST); >+ } >+ >+ ~ScopedToggleGLState() >+ { >+ if (m_enableBlend) >+ ::glEnable(GL_BLEND); >+ >+ if (m_enableCullFace) >+ ::glEnable(GL_CULL_FACE); >+ >+ if (m_enableDepthTest) >+ ::glEnable(GL_DEPTH_TEST); >+ >+ if (m_enableDitherTest) >+ ::glEnable(GL_DITHER); >+ >+ if (m_enablePolygonOffsetFill) >+ ::glEnable(GL_POLYGON_OFFSET_FILL); >+ >+ if (m_enableSampleAlpha) >+ ::glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); >+ >+ if (m_enableSampleCoverage) >+ ::glEnable(GL_SAMPLE_COVERAGE); >+ >+ if (m_enableStencilTest) >+ ::glEnable(GL_STENCIL_TEST); >+ >+ if (m_enableScissorTest) >+ ::glEnable(GL_SCISSOR_TEST); >+ } >+ >+private: >+ bool toggleState(const GLenum capability) >+ { >+ bool enabled = ::glIsEnabled(capability); >+ >+ if (!enabled) >+ return false; >+ >+ ::glDisable(capability); >+ >+ return true; >+ } >+ >+ bool m_enableBlend :1; >+ bool m_enableCullFace :1; >+ bool m_enableDepthTest :1; >+ bool m_enableDitherTest :1; >+ bool m_enablePolygonOffsetFill :1; >+ bool m_enableSampleAlpha :1; >+ bool m_enableSampleCoverage :1; >+ bool m_enableStencilTest :1; >+ bool m_enableScissorTest :1; >+}; >+ >+class ScopedProgramBinding >+{ >+ WTF_MAKE_NONCOPYABLE(ScopedProgramBinding); >+ >+public: >+ ScopedProgramBinding(GLuint programId, GLenum filter) >+ { >+ ::glGetIntegerv(GL_ACTIVE_TEXTURE, &m_boundTexUnit); >+ ::glGetIntegerv(GL_CURRENT_PROGRAM, &m_boundProgram); >+ ::glGetBooleanv(GL_COLOR_WRITEMASK, m_colorMask); >+ ::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); >+ ::glGetIntegerv(GL_VIEWPORT, &m_currentViewport[0]); >+ >+ if (m_glGenVertexArrays) >+#if USE(OPENGL_ES_2) >+ ::glGetIntegerv(GL_VERTEX_ARRAY_BINDING_OES, &m_currentVertexArrayBinding); >+#else >+ ::glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &m_currentVertexArrayBinding); >+#endif >+ else { >+ ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &m_attribEnabled); >+ ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_SIZE, &m_attribSize); >+ ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &m_attribStride); >+ ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_TYPE, &m_attribType); >+ ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &m_attribNormalized); >+ ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &m_attribBufferBinding); >+ ::glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &m_attribPointer); >+ ::glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &m_currentArrayBufferBinding); >+ ::glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &m_currentElementryArrayBufferBinding); >+ } >+ >+ ::glUseProgram(programId); >+ ::glActiveTexture(GL_TEXTURE0); >+ >+#if USE(OPENGL_ES_2) >+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); >+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); >+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); >+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); >+#endif >+ } >+ >+ ~ScopedProgramBinding() >+ { >+ ::glViewport(m_currentViewport[0], m_currentViewport[1], m_currentViewport[2], m_currentViewport[3]); >+ ::glColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], m_colorMask[3]); >+ >+ if (m_glGenVertexArrays) >+ m_glBindVertexArray(m_currentVertexArrayBinding); >+ else { >+ if (m_attribEnabled) >+ ::glEnableVertexAttribArray(0); >+ >+ ::glBindBuffer(GL_ARRAY_BUFFER, m_attribBufferBinding); >+ ::glVertexAttribPointer(0, m_attribSize, m_attribType, m_attribNormalized, m_attribStride, m_attribPointer); >+ ::glBindBuffer(GL_ARRAY_BUFFER, m_currentArrayBufferBinding); >+ ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentElementryArrayBufferBinding); >+ } >+ >+ ::glUseProgram(m_boundProgram); >+ ::glActiveTexture(m_boundTexUnit); >+ } >+ >+private: >+ GLint m_boundTexUnit; >+ GLint m_boundProgram; >+ GLint m_currentArrayBufferBinding; >+ GLint m_attribEnabled; >+ GLint m_attribSize; >+ GLint m_attribStride; >+ GLint m_attribType; >+ GLint m_attribNormalized; >+ GLint m_attribBufferBinding; >+ GLint m_currentViewport[4]; >+ GLint m_currentVertexArrayBinding; >+ GLint m_currentElementryArrayBufferBinding; >+ GLboolean m_colorMask[4]; >+ ScopedToggleGLState m_scopedToggleState; >+ void* m_attribPointer; >+}; >+ >+#define STRINGIFY(...) #__VA_ARGS__ >+ >+const char* GetShaderSource(GLenum type) { >+ switch (type) { >+ case GL_VERTEX_SHADER: >+ return STRINGIFY( >+ attribute vec4 m_vPosition; >+ attribute vec2 m_texCoord; >+ varying vec2 m_vTexCoord; >+ void main(void) { >+ gl_Position = m_vPosition; >+ m_vTexCoord = m_texCoord; >+ }); >+ case GL_FRAGMENT_SHADER: >+ return STRINGIFY( >+ uniform sampler2D u_texSampler; >+ varying vec2 m_vTexCoord; >+ void main(void) { >+ gl_FragColor = texture2D(u_texSampler, m_vTexCoord.st); >+ }); >+ default: >+ return 0; >+ } >+} >+ >+TextureBlitter::TextureBlitter() >+ : m_vertexHandle(0) >+ , m_flipVertexHandle(0) >+ , m_currentVertexHandle(0) >+ , m_shaderProgram(0) >+ , m_vertexBuffer(0) >+ , m_indexBuffer(0) >+ , m_fboId(0) >+ , m_flip(false) >+{ >+} >+ >+TextureBlitter::~TextureBlitter() >+{ >+ clear(); >+} >+ >+void TextureBlitter::clear() >+{ >+ if (m_shaderProgram) { >+ ::glDeleteProgram(m_shaderProgram); >+ m_shaderProgram = 0; >+ } >+ >+ if (m_fboId) { >+ ::glDeleteFramebuffers(1, &m_fboId); >+ m_fboId = 0; >+ } >+ >+ if (m_vertexHandle && m_glDeleteVertexArrays) { >+ m_glDeleteVertexArrays(1, &m_vertexHandle); >+ m_vertexHandle = 0; >+ } >+ >+ if (m_flipVertexHandle && m_glDeleteVertexArrays) { >+ m_glDeleteVertexArrays(1, &m_flipVertexHandle); >+ m_flipVertexHandle = 0; >+ } >+ >+ if (m_vertexBuffer) { >+ ::glDeleteBuffers(1, &m_vertexBuffer); >+ m_vertexBuffer = 0; >+ } >+ >+ if (m_indexBuffer) { >+ ::glDeleteBuffers(1, &m_indexBuffer); >+ m_indexBuffer = 0; >+ } >+} >+ >+GLuint TextureBlitter::loadShader(GLenum type, const GLchar *shaderSrc) >+{ >+ GLuint shader; >+ GLint compiled; >+ >+ shader = glCreateShader(type); >+ >+ if (!shader) { >+ LOG_ERROR("Failed to create shader."); >+ return 0; >+ } >+ >+ glShaderSource(shader, 1, &shaderSrc, 0); >+ glCompileShader(shader); >+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); >+ >+ if (!compiled) { >+ glDeleteShader(shader); >+ LOG_ERROR("Failed to compile shader."); >+ return 0; >+ } >+ >+ return shader; >+} >+ >+void TextureBlitter::bindArrayBuffer() >+{ >+ glEnableVertexAttribArray(VERTEXATTRIB); >+ glEnableVertexAttribArray(TEXCOORDATTRIB); >+ glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer); >+ >+ if (m_flip) >+ glVertexAttribPointer(VERTEXATTRIB, 4, GL_FLOAT, GL_FALSE, 0, (void*)FLIPOFFSET); >+ else >+ glVertexAttribPointer(VERTEXATTRIB, 4, GL_FLOAT, GL_FALSE, 0, (void*)NULL); >+ >+ glVertexAttribPointer(TEXCOORDATTRIB, 2, GL_FLOAT, GL_FALSE, 0, (void*)TEXCOORDOFFSET); >+} >+ >+void TextureBlitter::enableVertexArray() >+{ >+ if (m_currentVertexHandle) >+ m_glBindVertexArray(m_currentVertexHandle); >+ else { >+ bindArrayBuffer(); >+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer); >+ } >+} >+ >+void TextureBlitter::disableVertexArray() >+{ >+ if (m_currentVertexHandle) >+ return; >+ >+ glDisableVertexAttribArray(VERTEXATTRIB); >+ glDisableVertexAttribArray(TEXCOORDATTRIB); >+} >+ >+bool TextureBlitter::linkProgram(const GLuint programId) >+{ >+ glLinkProgram(programId); >+ GLint linkStatus = 0; >+ glGetProgramiv(programId, GL_LINK_STATUS, &linkStatus); >+ >+ if (!linkStatus) >+ return false; >+ >+ return true; >+} >+ >+void TextureBlitter::initializeVBO() >+{ >+ if (m_glGenVertexArrays) { >+ m_currentVertexHandle = m_flip ? m_flipVertexHandle : m_vertexHandle; >+ >+ if (m_currentVertexHandle) >+ return; >+ } else if (m_vertexBuffer) >+ return; >+ >+ // bind buffers. >+ GLuint temp[2]; >+ glGenBuffers(2, temp); >+ m_vertexBuffer = temp[0]; >+ m_indexBuffer = temp[1]; >+ glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer); >+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, >+ GL_STATIC_DRAW); >+ >+ // Create and set-up the vertex array object >+ if (m_glGenVertexArrays && m_glBindVertexArray) { >+ GLuint vertexHandle; >+ m_glGenVertexArrays(1, &vertexHandle); >+ m_glBindVertexArray(vertexHandle); >+ bindArrayBuffer(); >+ >+ if (m_flip) >+ m_flipVertexHandle = vertexHandle; >+ else >+ m_vertexHandle = vertexHandle; >+ >+ m_currentVertexHandle = vertexHandle; >+ } >+ >+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer); >+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexVertices), indexVertices, >+ GL_STATIC_DRAW); >+} >+ >+bool TextureBlitter::initializeProgram() >+{ >+ if (m_shaderProgram) >+ return true; >+ >+ // create shader. >+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, GetShaderSource(GL_VERTEX_SHADER)); >+ if (!vertexShader) >+ return false; >+ >+ GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, GetShaderSource(GL_FRAGMENT_SHADER)); >+ >+ if (!fragmentShader) { >+ glDeleteShader(vertexShader); >+ return false; >+ } >+ >+ m_shaderProgram = glCreateProgram(); >+ >+ if (!m_shaderProgram) { >+ LOG_ERROR("Failed to create program."); >+ glDeleteShader(vertexShader); >+ glDeleteShader(fragmentShader); >+ return false; >+ } >+ >+ glAttachShader(m_shaderProgram, vertexShader); >+ glAttachShader(m_shaderProgram, fragmentShader); >+ glBindAttribLocation(m_shaderProgram, VERTEXATTRIB, "m_vPosition"); >+ glBindAttribLocation(m_shaderProgram, TEXCOORDATTRIB, "m_texCoord"); >+ bool linked = linkProgram(m_shaderProgram); >+ glDeleteShader(vertexShader); >+ glDeleteShader(fragmentShader); >+ >+ if (!linked) { >+ clear(); >+ return false; >+ } >+ >+#if !USE(OPENGL_ES_2) >+ GLuint samplerLocation = glGetUniformLocation(m_shaderProgram, "u_texSampler"); >+ GLuint sampler = 0; >+ // Create and initialize sampler object. This would help us seperate the texture and sampler state. >+ if (m_glGenSamplers && m_glSamplerParameteri) { >+ m_glGenSamplers(1 , &sampler); >+ m_glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); >+ m_glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); >+ m_glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST); >+ m_glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); >+ } >+#endif >+ >+ GLint boundProgram; >+ ::glGetIntegerv(GL_CURRENT_PROGRAM, &boundProgram); >+ >+ glUseProgram(m_shaderProgram); >+ >+#if !USE(OPENGL_ES_2) >+ glUniform1i(samplerLocation, 0); >+ >+ if (m_glBindSampler) >+ m_glBindSampler(0 , sampler); >+ >+ glUniform1i(samplerLocation, 0); >+#endif >+ glUseProgram(boundProgram); >+ >+ return true; >+} >+ >+#if USE(OPENGL_ES_2) >+bool TextureBlitter::drawTexture(const GLuint sourceTexture, const GLuint targetFboId, const IntRect&, const IntRect& destRect, bool flip, GLenum filter) >+{ >+ initializeGLBindings(); >+ >+ if (!initializeProgram()) >+ return false; >+ >+ ScopedProgramBinding program(m_shaderProgram, filter); >+ m_flip = flip; >+ initializeVBO(); >+ ::glBindFramebuffer(GL_FRAMEBUFFER, targetFboId); >+ ::glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT); >+ ::glBindTexture(GL_TEXTURE_2D, sourceTexture); >+ ::glViewport (destRect.x(), destRect.y(), destRect.width(), destRect.height()); >+ enableVertexArray(); >+ ::glDrawElements(GL_TRIANGLE_STRIP, vertexIndexSize, GL_UNSIGNED_SHORT, 0); >+ disableVertexArray(); >+ >+ return true; >+} >+#else >+bool TextureBlitter::drawTexture(const GLuint sourceTexture, const GLuint targetFboId, const IntRect& srcRect, const IntRect& destRect, bool flip, GLenum filter) >+{ >+ bool enableScissorTest = ::glIsEnabled(GL_SCISSOR_TEST); >+ >+ if (enableScissorTest) >+ ::glDisable(GL_SCISSOR_TEST); >+ >+ if (!m_fboId) >+ glGenFramebuffers(1, &m_fboId); >+ >+ ::glBindFramebuffer(Extensions3D::READ_FRAMEBUFFER, m_fboId); >+ ::glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT); >+ ::glBindTexture(GL_TEXTURE_2D, sourceTexture); >+ ::glFramebufferTexture2D(Extensions3D::READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTexture, 0); >+ ::glBindFramebuffer(Extensions3D::DRAW_FRAMEBUFFER, targetFboId); >+ >+ if (flip) >+ ::glBlitFramebuffer(srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), destRect.x(), destRect.x() + destRect.height(), destRect.y() + destRect.width(), destRect.y(), GL_COLOR_BUFFER_BIT, filter); >+ else >+ ::glBlitFramebuffer(srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), destRect.x(), destRect.y(), destRect.width(), destRect.height(), GL_COLOR_BUFFER_BIT, filter); >+ >+ ::glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); >+ >+ if (enableScissorTest) >+ ::glEnable(GL_SCISSOR_TEST); >+ >+ return true; >+} >+#endif >+ >+bool TextureBlitter::copyTexture(const GLuint source, const GLuint destination, bool flip) >+{ >+ initializeGLBindings(); >+ >+ if (!initializeProgram()) >+ return false; >+ >+ if (!m_fboId) >+ glGenFramebuffers(1, &m_fboId); >+ >+ ScopedProgramBinding program(m_shaderProgram, GraphicsContext3D::NEAREST); >+ m_flip = flip; >+ initializeVBO(); >+ ::glBindFramebuffer(GL_FRAMEBUFFER, m_fboId); >+ ::glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT); >+ ::glBindTexture(GL_TEXTURE_2D, source); >+ ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destination, 0); >+ enableVertexArray(); >+ ::glDrawElements(GL_TRIANGLE_STRIP, vertexIndexSize, GL_UNSIGNED_SHORT, 0); >+ disableVertexArray(); >+ ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); >+ return true; >+} >+ >+} >+ >+#endif >+ >diff --git Source/WebCore/platform/graphics/surfaces/TextureBlitter.h Source/WebCore/platform/graphics/surfaces/TextureBlitter.h >new file mode 100644 >index 0000000..668cb66 >--- /dev/null >+++ Source/WebCore/platform/graphics/surfaces/TextureBlitter.h >@@ -0,0 +1,89 @@ >+/* >+ * Copyright (C) 2012 Intel Corporation. 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. >+ * >+ * 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 TextureBlitter_h >+#define TextureBlitter_h >+ >+#if USE(ACCELERATED_COMPOSITING) >+ >+#include <opengl/GLDefs.h> >+#include <wtf/Noncopyable.h> >+#include <wtf/PassRefPtr.h> >+#include <wtf/RefCounted.h> >+ >+namespace WebCore { >+ >+class TextureBlitter : public WTF::RefCountedBase { >+ WTF_MAKE_NONCOPYABLE(TextureBlitter); >+ >+public: >+ static PassRefPtr<TextureBlitter> create() >+ { >+ if (!m_staticTextureBlitter) >+ m_staticTextureBlitter = new TextureBlitter(); >+ else >+ m_staticTextureBlitter->ref(); >+ >+ return adoptRef(m_staticTextureBlitter); >+ } >+ >+ void deref() >+ { >+ if (derefBase()) { >+ m_staticTextureBlitter = 0; >+ delete this; >+ } >+ } >+ >+ TextureBlitter(); >+ ~TextureBlitter(); >+ bool copyTexture(const GLuint, const GLuint, bool = false); >+ bool drawTexture(const GLuint, const GLuint, const IntRect&, const IntRect&, bool = false, GLenum = GraphicsContext3D::NEAREST); >+ void clear(); >+ >+private: >+ static TextureBlitter* m_staticTextureBlitter; >+ bool initializeProgram(); >+ void enableVertexArray(); >+ void disableVertexArray(); >+ void bindArrayBuffer(); >+ void initializeVBO(); >+ bool linkProgram(const GLuint programId); >+ GLuint loadShader(GLenum type, const GLchar *shaderSrc); >+ GLuint m_vertexHandle; >+ GLuint m_flipVertexHandle; >+ GLuint m_currentVertexHandle; >+ GLuint m_shaderProgram; >+ GLuint m_vertexBuffer; >+ GLuint m_indexBuffer; >+ GLuint m_fboId; >+ bool m_flip :1; >+}; >+ >+} >+ >+#endif >+ >+#endif
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 106508
:
182022
|
182603
|
185304
|
187316
|
187435
|
187475
|
187480
|
187483
|
187728