| Differences between
and this patch
- Source/WebCore/ChangeLog +51 lines
Lines 1-3 Source/WebCore/ChangeLog_sec1
1
2013-01-29  Kondapally Kalyan  <kalyan.kondapally@intel.com>
2
3
        [EFL] [WebGL] Add support for bliting texture contents to FBO.
4
        https://bugs.webkit.org/show_bug.cgi?id=106508
5
6
        We currently rely on EXT_framebuffer_blit to blit contents of a texture to a FBO.
7
        This extension is not exposed on GLES1.1 or 2.0. This patch provides a fall back
8
        mechanism by using shaders to blit texture contents to an FBO.
9
10
        Reviewed by NOBODY (OOPS!).
11
12
        Covered by existing WebGL tests.
13
14
        * PlatformEfl.cmake:
15
        * PlatformNix.cmake:
16
        * platform/graphics/opengl/GLPlatformSurface.cpp:
17
        (WebCore::GLPlatformSurface::GLPlatformSurface):
18
        (WebCore::GLPlatformSurface::updateContents):
19
        (WebCore::GLPlatformSurface::destroy):
20
        * platform/graphics/opengl/GLPlatformSurface.h:
21
        (GLPlatformSurface):
22
        * platform/graphics/surfaces/TextureBlitter.cpp: Added.
23
        (WebCore):
24
        (WebCore::initializeGLBindings):
25
        (ScopedToggleGLState):
26
        (WebCore::ScopedToggleGLState::ScopedToggleGLState):
27
        (WebCore::ScopedToggleGLState::~ScopedToggleGLState):
28
        (WebCore::ScopedToggleGLState::toggleState):
29
        (ScopedProgramBinding):
30
        (WebCore::ScopedProgramBinding::ScopedProgramBinding):
31
        (WebCore::ScopedProgramBinding::~ScopedProgramBinding):
32
        (WebCore::GetShaderSource):
33
        (WebCore::TextureBlitter::TextureBlitter):
34
        (WebCore::TextureBlitter::~TextureBlitter):
35
        (WebCore::TextureBlitter::clear):
36
        (WebCore::TextureBlitter::loadShader):
37
        (WebCore::TextureBlitter::bindArrayBuffer):
38
        (WebCore::TextureBlitter::enableVertexArray):
39
        (WebCore::TextureBlitter::disableVertexArray):
40
        (WebCore::TextureBlitter::linkProgram):
41
        (WebCore::TextureBlitter::initializeVBO):
42
        (WebCore::TextureBlitter::initializeProgram):
43
        (WebCore::TextureBlitter::drawTexture):
44
        (WebCore::TextureBlitter::copyTexture):
45
        * platform/graphics/surfaces/TextureBlitter.h: Added.
46
        (WebCore):
47
        (TextureBlitter):
48
        (WebCore::TextureBlitter::create):
49
        (WebCore::TextureBlitter::deref):
50
        Helper class to blit texture contents to an FBO.
51
1
2013-01-24  Victor Jaquez  <vjaquez@igalia.com>
52
2013-01-24  Victor Jaquez  <vjaquez@igalia.com>
- Source/WebCore/PlatformEfl.cmake +1 lines
Lines 314-319 if (WTF_USE_3D_GRAPHICS) Source/WebCore/PlatformEfl.cmake_sec1
314
        platform/graphics/opengl/GLPlatformSurface.cpp
314
        platform/graphics/opengl/GLPlatformSurface.cpp
315
        platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
315
        platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
316
        platform/graphics/surfaces/GraphicsSurface.cpp
316
        platform/graphics/surfaces/GraphicsSurface.cpp
317
        platform/graphics/surfaces/TextureBlitter.cpp
317
        platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp
318
        platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp
318
        platform/graphics/surfaces/glx/X11WindowResources.cpp
319
        platform/graphics/surfaces/glx/X11WindowResources.cpp
319
        platform/graphics/texmap/TextureMapperGL.cpp
320
        platform/graphics/texmap/TextureMapperGL.cpp
- Source/WebCore/platform/graphics/opengl/GLPlatformSurface.cpp -23 / +6 lines
Lines 70-80 PassOwnPtr<GLPlatformSurface> GLPlatformSurface::createTransportSurface() Source/WebCore/platform/graphics/opengl/GLPlatformSurface.cpp_sec1
70
70
71
GLPlatformSurface::GLPlatformSurface()
71
GLPlatformSurface::GLPlatformSurface()
72
    : m_restoreNeeded(true)
72
    : m_restoreNeeded(true)
73
    , m_fboId(0)
74
    , m_sharedDisplay(0)
73
    , m_sharedDisplay(0)
75
    , m_drawable(0)
74
    , m_drawable(0)
76
    , m_bufferHandle(0)
75
    , m_bufferHandle(0)
77
{
76
{
77
    m_blitter = TextureBlitter::create();
78
}
78
}
79
79
80
GLPlatformSurface::~GLPlatformSurface()
80
GLPlatformSurface::~GLPlatformSurface()
Lines 113-136 void GLPlatformSurface::swapBuffers() Source/WebCore/platform/graphics/opengl/GLPlatformSurface.cpp_sec2
113
113
114
void GLPlatformSurface::updateContents(const uint32_t texture, const GLuint bindFboId, const uint32_t bindTexture)
114
void GLPlatformSurface::updateContents(const uint32_t texture, const GLuint bindFboId, const uint32_t bindTexture)
115
{
115
{
116
    if (!m_fboId)
116
    if (!m_blitter)
117
        glGenFramebuffers(1, &m_fboId);
117
        return;
118
118
119
    m_restoreNeeded = false;
119
    m_blitter->drawTexture(texture, 0, m_rect, m_rect);
120
121
    int x = 0;
122
    int y = 0;
123
    int width = m_rect.width();
124
    int height = m_rect.height();
125
126
    glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fboId);
127
    glBindTexture(GL_TEXTURE_2D, texture);
128
    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
129
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
130
    // Use NEAREST as no scale is performed during the blit.
131
    glBlitFramebuffer(x, y, width, height, x, y, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
132
    swapBuffers();
120
    swapBuffers();
133
    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
134
    glBindTexture(GL_TEXTURE_2D, bindTexture);
121
    glBindTexture(GL_TEXTURE_2D, bindTexture);
135
    glBindFramebuffer(GL_FRAMEBUFFER, bindFboId);
122
    glBindFramebuffer(GL_FRAMEBUFFER, bindFboId);
136
}
123
}
Lines 143-153 void GLPlatformSurface::setGeometry(const IntRect& newRect) Source/WebCore/platform/graphics/opengl/GLPlatformSurface.cpp_sec3
143
void GLPlatformSurface::destroy()
130
void GLPlatformSurface::destroy()
144
{
131
{
145
    m_rect = IntRect();
132
    m_rect = IntRect();
146
133
    m_blitter = nullptr;
147
    if (m_fboId)
148
        glDeleteFramebuffers(1, &m_fboId);
149
150
    m_fboId = 0;
151
}
134
}
152
135
153
}
136
}
- Source/WebCore/platform/graphics/opengl/GLPlatformSurface.h -1 / +2 lines
Lines 30-35 Source/WebCore/platform/graphics/opengl/GLPlatformSurface.h_sec1
30
30
31
#include "GLDefs.h"
31
#include "GLDefs.h"
32
#include "IntRect.h"
32
#include "IntRect.h"
33
#include <surfaces/TextureBlitter.h>
33
#include <wtf/Noncopyable.h>
34
#include <wtf/Noncopyable.h>
34
#include <wtf/PassOwnPtr.h>
35
#include <wtf/PassOwnPtr.h>
35
36
Lines 78-87 protected: Source/WebCore/platform/graphics/opengl/GLPlatformSurface.h_sec2
78
    GLPlatformSurface();
79
    GLPlatformSurface();
79
    bool m_restoreNeeded;
80
    bool m_restoreNeeded;
80
    IntRect m_rect;
81
    IntRect m_rect;
81
    GLuint m_fboId;
82
    PlatformDisplay m_sharedDisplay;
82
    PlatformDisplay m_sharedDisplay;
83
    PlatformDrawable m_drawable;
83
    PlatformDrawable m_drawable;
84
    PlatformBufferHandle m_bufferHandle;
84
    PlatformBufferHandle m_bufferHandle;
85
    RefPtr<TextureBlitter> m_blitter;
85
};
86
};
86
87
87
}
88
}
- Source/WebCore/platform/graphics/surfaces/TextureBlitter.cpp +609 lines
Line 0 Source/WebCore/platform/graphics/surfaces/TextureBlitter.cpp_sec1
1
/*
2
 * Copyright (C) 2012 Intel Corporation. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
 * THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
#include "config.h"
27
#include "TextureBlitter.h"
28
29
#if USE(ACCELERATED_COMPOSITING)
30
31
#include "TextureMapperGL.h"
32
33
#include <opengl/GLPlatformContext.h>
34
#include <wtf/text/WTFString.h>
35
36
namespace WebCore {
37
38
//#define SHADER_DEBUG
39
TextureBlitter* TextureBlitter::m_staticTextureBlitter = 0;
40
static const GLfloat vertices[] = { 1.0f, 1.0f, 0.0f, 1.0f,
41
                                    -1.0f, 1.0f, 0.0f, 1.0f,
42
                                    1.0f, -1.0f, 0.0f, 1.0f,
43
                                    -1.0f, -1.0f, 0.0f, 1.0f,
44
                                    -1.0f, -1.0f, 0.0f, 1.0f,  // Flip coordinates.
45
                                    1.0f, -1.0f, 0.0f, 1.0f,
46
                                    -1.0f, 1.0f, 0.0f, 1.0f,
47
                                    1.0f, 1.0f, 0.0f, 1.0f,
48
                                    0.0f, 1.0f,1.0f, 1.0f,   // Tex coordinates.
49
                                    0.0f, 0.0f,1.0f, 0.0f};
50
51
static const GLushort indexVertices[] = { 0, 1, 2, 3};
52
static const int vertexIndexSize = sizeof(indexVertices)/sizeof(indexVertices[0]);
53
static const int FLIPOFFSET = sizeof(float) * 4 * 4;
54
static const int TEXCOORDOFFSET = FLIPOFFSET * 2;
55
static const int VERTEXATTRIB = 0;
56
static const int TEXCOORDATTRIB = 1;
57
58
#if USE(OPENGL_ES_2)
59
static PFNGLBINDVERTEXARRAYOESPROC m_glBindVertexArray = 0;
60
static PFNGLDELETEVERTEXARRAYSOESPROC m_glDeleteVertexArrays = 0;
61
static PFNGLGENVERTEXARRAYSOESPROC m_glGenVertexArrays = 0;
62
static PFNGLISVERTEXARRAYOESPROC m_glIsVertexArray = 0;
63
#else
64
static PFNGLBINDVERTEXARRAYPROC m_glBindVertexArray = 0;
65
static PFNGLDELETEVERTEXARRAYSPROC m_glDeleteVertexArrays = 0;
66
static PFNGLGENVERTEXARRAYSPROC m_glGenVertexArrays = 0;
67
static PFNGLISVERTEXARRAYPROC m_glIsVertexArray = 0;
68
static PFNGLSAMPLERPARAMETERIPROC m_glSamplerParameteri = 0;
69
static PFNGLGENSAMPLERSPROC m_glGenSamplers = 0;
70
static PFNGLBINDSAMPLERPROC m_glBindSampler = 0;
71
#endif
72
73
static void initializeGLBindings()
74
{
75
    static bool bindingsInitialized = false;
76
    if (bindingsInitialized)
77
        return;
78
79
    bindingsInitialized = true;
80
81
#if USE(OPENGL_ES_2)
82
    if (GLPlatformContext::supportsGLExtension("GL_OES_vertex_array_object")) {
83
        m_glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYOESPROC>(eglGetProcAddress("glBindVertexArrayOES"));
84
        m_glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSOESPROC>(eglGetProcAddress("glGenVertexArraysOES"));
85
        m_glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSOESPROC>(eglGetProcAddress("glDeleteVertexArraysOES"));
86
        m_glIsVertexArray = reinterpret_cast<PFNGLISVERTEXARRAYOESPROC>(eglGetProcAddress("glIsVertexArrayOES"));
87
    }
88
89
#else
90
    bool supportsVAO = GLPlatformContext::supportsGLExtension("GL_ARB_vertex_array_object");
91
    // 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.
92
    bool supportsSamplerObjects = GLPlatformContext::supportsGLExtension("GL_ARB_sampler_objects");
93
#if USE(GLX)
94
    if (supportsVAO) {
95
        m_glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glBindVertexArray")));
96
        m_glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glGenVertexArrays")));
97
        m_glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glDeleteVertexArrays")));
98
        m_glIsVertexArray = reinterpret_cast<PFNGLISVERTEXARRAYPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glIsVertexArray")));
99
    }
100
101
    if (supportsSamplerObjects) {
102
        m_glSamplerParameteri = reinterpret_cast<PFNGLSAMPLERPARAMETERIPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glSamplerParameteri")));
103
        m_glGenSamplers = reinterpret_cast<PFNGLGENSAMPLERSPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glGenSamplers")));
104
        m_glBindSampler = reinterpret_cast<PFNGLBINDSAMPLERPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glBindSampler")));
105
    }
106
#elif USE(EGL)
107
    if (supportsVAO) {
108
        m_glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYPROC>(eglGetProcAddress("glBindVertexArray"));
109
        m_glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSPROC>(eglGetProcAddress("glGenVertexArrays"));
110
        m_glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSPROC>(eglGetProcAddress("glDeleteVertexArrays"));
111
        m_glIsVertexArray = reinterpret_cast<PFNGLISVERTEXARRAYPROC>(eglGetProcAddress("glIsVertexArray"));
112
    }
113
114
    if (supportsSamplerObjects) {
115
        m_glSamplerParameteri = reinterpret_cast<PFNGLSAMPLERPARAMETERIPROC>(eglGetProcAddress("glSamplerParameteri"));
116
        m_glGenSamplers = reinterpret_cast<PFNGLGENSAMPLERSPROC>(eglGetProcAddress("glGenSamplers"));
117
        m_glBindSampler = reinterpret_cast<PFNGLBINDSAMPLERPROC>(eglGetProcAddress("glBindSampler"));
118
    }
119
#endif
120
#endif
121
}
122
123
class ScopedToggleGLState
124
{
125
    WTF_MAKE_NONCOPYABLE(ScopedToggleGLState);
126
127
public:
128
    ScopedToggleGLState()
129
    {
130
        m_enableBlend = toggleState(GL_BLEND);
131
        m_enableCullFace = toggleState(GL_CULL_FACE);
132
        m_enableDepthTest = toggleState(GL_DEPTH_TEST);
133
        m_enableDitherTest = toggleState(GL_DITHER);
134
        m_enablePolygonOffsetFill = toggleState(GL_POLYGON_OFFSET_FILL);
135
        m_enableSampleAlpha = toggleState(GL_SAMPLE_ALPHA_TO_COVERAGE);
136
        m_enableSampleCoverage = toggleState(GL_SAMPLE_COVERAGE);
137
        m_enableStencilTest = toggleState(GL_STENCIL_TEST);
138
        m_enableScissorTest = toggleState(GL_SCISSOR_TEST);
139
    }
140
141
    ~ScopedToggleGLState()
142
    {
143
        if (m_enableBlend)
144
            ::glEnable(GL_BLEND);
145
146
        if (m_enableCullFace)
147
            ::glEnable(GL_CULL_FACE);
148
149
        if (m_enableDepthTest)
150
            ::glEnable(GL_DEPTH_TEST);
151
152
        if (m_enableDitherTest)
153
            ::glEnable(GL_DITHER);
154
155
        if (m_enablePolygonOffsetFill)
156
            ::glEnable(GL_POLYGON_OFFSET_FILL);
157
158
        if (m_enableSampleAlpha)
159
            ::glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
160
161
        if (m_enableSampleCoverage)
162
            ::glEnable(GL_SAMPLE_COVERAGE);
163
164
        if (m_enableStencilTest)
165
            ::glEnable(GL_STENCIL_TEST);
166
167
        if (m_enableScissorTest)
168
            ::glEnable(GL_SCISSOR_TEST);
169
    }
170
171
private:
172
    bool toggleState(const GLenum capability)
173
    {
174
        bool enabled = ::glIsEnabled(capability);
175
176
        if (!enabled)
177
            return false;
178
179
        ::glDisable(capability);
180
181
        return true;
182
    }
183
184
    bool m_enableBlend :1;
185
    bool m_enableCullFace :1;
186
    bool m_enableDepthTest :1;
187
    bool m_enableDitherTest :1;
188
    bool m_enablePolygonOffsetFill :1;
189
    bool m_enableSampleAlpha :1;
190
    bool m_enableSampleCoverage :1;
191
    bool m_enableStencilTest :1;
192
    bool m_enableScissorTest :1;
193
};
194
195
class ScopedProgramBinding
196
{
197
    WTF_MAKE_NONCOPYABLE(ScopedProgramBinding);
198
199
public:
200
    ScopedProgramBinding(GLuint programId, GLenum filter)
201
    {
202
        ::glGetIntegerv(GL_ACTIVE_TEXTURE, &m_boundTexUnit);
203
        ::glGetIntegerv(GL_CURRENT_PROGRAM, &m_boundProgram);
204
        ::glGetBooleanv(GL_COLOR_WRITEMASK, m_colorMask);
205
        ::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
206
        ::glGetIntegerv(GL_VIEWPORT, &m_currentViewport[0]);
207
208
        if (m_glGenVertexArrays)
209
#if USE(OPENGL_ES_2)
210
            ::glGetIntegerv(GL_VERTEX_ARRAY_BINDING_OES, &m_currentVertexArrayBinding);
211
#else
212
            ::glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &m_currentVertexArrayBinding);
213
#endif
214
        else {
215
            ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &m_attribEnabled);
216
            ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_SIZE, &m_attribSize);
217
            ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &m_attribStride);
218
            ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_TYPE, &m_attribType);
219
            ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &m_attribNormalized);
220
            ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &m_attribBufferBinding);
221
            ::glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &m_attribPointer);
222
            ::glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &m_currentArrayBufferBinding);
223
            ::glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &m_currentElementryArrayBufferBinding);
224
        }
225
226
        ::glUseProgram(programId);
227
        ::glActiveTexture(GL_TEXTURE0);
228
229
#if USE(OPENGL_ES_2)
230
        ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
231
        ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
232
        ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
233
        ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
234
#endif
235
    }
236
237
    ~ScopedProgramBinding()
238
    {
239
        ::glViewport(m_currentViewport[0], m_currentViewport[1], m_currentViewport[2], m_currentViewport[3]);
240
        ::glColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], m_colorMask[3]);
241
242
        if (m_glGenVertexArrays)
243
            m_glBindVertexArray(m_currentVertexArrayBinding);
244
        else {
245
            if (m_attribEnabled)
246
                ::glEnableVertexAttribArray(0);
247
248
            ::glBindBuffer(GL_ARRAY_BUFFER, m_attribBufferBinding);
249
            ::glVertexAttribPointer(0, m_attribSize, m_attribType, m_attribNormalized, m_attribStride, m_attribPointer);
250
            ::glBindBuffer(GL_ARRAY_BUFFER, m_currentArrayBufferBinding);
251
            ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentElementryArrayBufferBinding);
252
        }
253
254
        ::glUseProgram(m_boundProgram);
255
        ::glActiveTexture(m_boundTexUnit);
256
    }
257
258
private:
259
    GLint m_boundTexUnit;
260
    GLint m_boundProgram;
261
    GLint m_currentArrayBufferBinding;
262
    GLint m_attribEnabled;
263
    GLint m_attribSize;
264
    GLint m_attribStride;
265
    GLint m_attribType;
266
    GLint m_attribNormalized;
267
    GLint m_attribBufferBinding;
268
    GLint m_currentViewport[4];
269
    GLint m_currentVertexArrayBinding;
270
    GLint m_currentElementryArrayBufferBinding;
271
    GLboolean m_colorMask[4];
272
    ScopedToggleGLState m_scopedToggleState;
273
    void* m_attribPointer;
274
};
275
276
#define STRINGIFY(...) #__VA_ARGS__
277
278
const char* GetShaderSource(GLenum type) {
279
    switch (type) {
280
    case GL_VERTEX_SHADER:
281
        return STRINGIFY(
282
                    attribute vec4 m_vPosition;
283
                attribute vec2 m_texCoord;
284
        varying vec2 m_vTexCoord;
285
        void main(void) {
286
            gl_Position = m_vPosition;
287
            m_vTexCoord = m_texCoord;
288
        });
289
    case GL_FRAGMENT_SHADER:
290
        return STRINGIFY(
291
                    uniform sampler2D u_texSampler;
292
                varying vec2 m_vTexCoord;
293
        void main(void) {
294
            gl_FragColor = texture2D(u_texSampler, m_vTexCoord.st);
295
        });
296
    default:
297
        return 0;
298
    }
299
}
300
301
TextureBlitter::TextureBlitter()
302
    : m_vertexHandle(0)
303
    , m_flipVertexHandle(0)
304
    , m_currentVertexHandle(0)
305
    , m_shaderProgram(0)
306
    , m_vertexBuffer(0)
307
    , m_indexBuffer(0)
308
    , m_fboId(0)
309
    , m_flip(false)
310
{
311
}
312
313
TextureBlitter::~TextureBlitter()
314
{
315
    clear();
316
}
317
318
void TextureBlitter::clear()
319
{
320
    if (m_shaderProgram) {
321
        ::glDeleteProgram(m_shaderProgram);
322
        m_shaderProgram = 0;
323
    }
324
325
    if (m_fboId) {
326
        ::glDeleteFramebuffers(1, &m_fboId);
327
        m_fboId = 0;
328
    }
329
330
    if (m_vertexHandle && m_glDeleteVertexArrays) {
331
        m_glDeleteVertexArrays(1, &m_vertexHandle);
332
        m_vertexHandle = 0;
333
    }
334
335
    if (m_flipVertexHandle && m_glDeleteVertexArrays) {
336
        m_glDeleteVertexArrays(1, &m_flipVertexHandle);
337
        m_flipVertexHandle = 0;
338
    }
339
340
    if (m_vertexBuffer) {
341
        ::glDeleteBuffers(1, &m_vertexBuffer);
342
        m_vertexBuffer = 0;
343
    }
344
345
    if (m_indexBuffer) {
346
        ::glDeleteBuffers(1, &m_indexBuffer);
347
        m_indexBuffer = 0;
348
    }
349
}
350
351
GLuint TextureBlitter::loadShader(GLenum type, const GLchar *shaderSrc)
352
{
353
    GLuint shader;
354
    GLint compiled;
355
356
    shader = glCreateShader(type);
357
358
    if (!shader) {
359
        LOG_ERROR("Failed to create shader.");
360
        return 0;
361
    }
362
363
    glShaderSource(shader, 1, &shaderSrc, 0);
364
    glCompileShader(shader);
365
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
366
367
    if (!compiled) {
368
        glDeleteShader(shader);
369
        LOG_ERROR("Failed to compile shader.");
370
        return 0;
371
    }
372
373
    return shader;
374
}
375
376
void TextureBlitter::bindArrayBuffer()
377
{
378
    glEnableVertexAttribArray(VERTEXATTRIB);
379
    glEnableVertexAttribArray(TEXCOORDATTRIB);
380
    glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
381
382
    if (m_flip)
383
        glVertexAttribPointer(VERTEXATTRIB, 4, GL_FLOAT, GL_FALSE, 0, (void*)FLIPOFFSET);
384
    else
385
        glVertexAttribPointer(VERTEXATTRIB, 4, GL_FLOAT, GL_FALSE, 0, (void*)NULL);
386
387
    glVertexAttribPointer(TEXCOORDATTRIB, 2, GL_FLOAT, GL_FALSE, 0, (void*)TEXCOORDOFFSET);
388
}
389
390
void TextureBlitter::enableVertexArray()
391
{
392
    if (m_currentVertexHandle)
393
        m_glBindVertexArray(m_currentVertexHandle);
394
    else {
395
        bindArrayBuffer();
396
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
397
    }
398
}
399
400
void TextureBlitter::disableVertexArray()
401
{
402
    if (m_currentVertexHandle)
403
        return;
404
405
    glDisableVertexAttribArray(VERTEXATTRIB);
406
    glDisableVertexAttribArray(TEXCOORDATTRIB);
407
}
408
409
bool TextureBlitter::linkProgram(const GLuint programId)
410
{
411
    glLinkProgram(programId);
412
    GLint linkStatus = 0;
413
    glGetProgramiv(programId, GL_LINK_STATUS, &linkStatus);
414
415
    if (!linkStatus)
416
        return false;
417
418
    return true;
419
}
420
421
void TextureBlitter::initializeVBO()
422
{
423
    if (m_glGenVertexArrays) {
424
        m_currentVertexHandle = m_flip ? m_flipVertexHandle : m_vertexHandle;
425
426
        if (m_currentVertexHandle)
427
            return;
428
    } else if (m_vertexBuffer)
429
        return;
430
431
    // bind buffers.
432
    GLuint temp[2];
433
    glGenBuffers(2, temp);
434
    m_vertexBuffer = temp[0];
435
    m_indexBuffer = temp[1];
436
    glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
437
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,
438
                 GL_STATIC_DRAW);
439
440
    // Create and set-up the vertex array object
441
    if (m_glGenVertexArrays && m_glBindVertexArray) {
442
        GLuint vertexHandle;
443
        m_glGenVertexArrays(1, &vertexHandle);
444
        m_glBindVertexArray(vertexHandle);
445
        bindArrayBuffer();
446
447
        if (m_flip)
448
            m_flipVertexHandle = vertexHandle;
449
        else
450
            m_vertexHandle = vertexHandle;
451
452
        m_currentVertexHandle = vertexHandle;
453
    }
454
455
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
456
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexVertices), indexVertices,
457
                 GL_STATIC_DRAW);
458
}
459
460
bool TextureBlitter::initializeProgram()
461
{
462
    if (m_shaderProgram)
463
        return true;
464
465
    // create shader.
466
    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, GetShaderSource(GL_VERTEX_SHADER));
467
    if (!vertexShader)
468
        return false;
469
470
    GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, GetShaderSource(GL_FRAGMENT_SHADER));
471
472
    if (!fragmentShader) {
473
        glDeleteShader(vertexShader);
474
        return false;
475
    }
476
477
    m_shaderProgram = glCreateProgram();
478
479
    if (!m_shaderProgram) {
480
        LOG_ERROR("Failed to create program.");
481
        glDeleteShader(vertexShader);
482
        glDeleteShader(fragmentShader);
483
        return false;
484
    }
485
486
    glAttachShader(m_shaderProgram, vertexShader);
487
    glAttachShader(m_shaderProgram, fragmentShader);
488
    glBindAttribLocation(m_shaderProgram, VERTEXATTRIB, "m_vPosition");
489
    glBindAttribLocation(m_shaderProgram, TEXCOORDATTRIB, "m_texCoord");
490
    bool linked = linkProgram(m_shaderProgram);
491
    glDeleteShader(vertexShader);
492
    glDeleteShader(fragmentShader);
493
494
    if (!linked) {
495
        clear();
496
        return false;
497
    }
498
499
#if !USE(OPENGL_ES_2)
500
    GLuint samplerLocation = glGetUniformLocation(m_shaderProgram, "u_texSampler");
501
    GLuint sampler = 0;
502
    // Create and initialize sampler object. This would help us seperate the texture and sampler state.
503
    if (m_glGenSamplers && m_glSamplerParameteri) {
504
        m_glGenSamplers(1 , &sampler);
505
        m_glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
506
        m_glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
507
        m_glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
508
        m_glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
509
    }
510
#endif
511
512
    GLint boundProgram;
513
    ::glGetIntegerv(GL_CURRENT_PROGRAM, &boundProgram);
514
515
    glUseProgram(m_shaderProgram);
516
517
#if !USE(OPENGL_ES_2)
518
    glUniform1i(samplerLocation, 0);
519
520
    if (m_glBindSampler)
521
        m_glBindSampler(0 , sampler);
522
523
    glUniform1i(samplerLocation, 0);
524
#endif
525
    glUseProgram(boundProgram);
526
527
    return true;
528
}
529
530
#if USE(OPENGL_ES_2)
531
bool TextureBlitter::drawTexture(const GLuint sourceTexture, const GLuint targetFboId, const IntRect&, const IntRect& destRect, bool flip, GLenum filter)
532
{
533
    initializeGLBindings();
534
535
    if (!initializeProgram())
536
        return false;
537
538
    ScopedProgramBinding program(m_shaderProgram, filter);
539
    m_flip = flip;
540
    initializeVBO();
541
    ::glBindFramebuffer(GL_FRAMEBUFFER, targetFboId);
542
    ::glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
543
    ::glBindTexture(GL_TEXTURE_2D, sourceTexture);
544
    ::glViewport (destRect.x(), destRect.y(), destRect.width(), destRect.height());
545
    enableVertexArray();
546
    ::glDrawElements(GL_TRIANGLE_STRIP, vertexIndexSize, GL_UNSIGNED_SHORT, 0);
547
    disableVertexArray();
548
549
    return true;
550
}
551
#else
552
bool TextureBlitter::drawTexture(const GLuint sourceTexture, const GLuint targetFboId, const IntRect& srcRect, const IntRect& destRect, bool flip, GLenum filter)
553
{
554
    bool enableScissorTest = ::glIsEnabled(GL_SCISSOR_TEST);
555
556
    if (enableScissorTest)
557
        ::glDisable(GL_SCISSOR_TEST);
558
559
    if (!m_fboId)
560
        glGenFramebuffers(1, &m_fboId);
561
562
    ::glBindFramebuffer(Extensions3D::READ_FRAMEBUFFER, m_fboId);
563
    ::glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
564
    ::glBindTexture(GL_TEXTURE_2D, sourceTexture);
565
    ::glFramebufferTexture2D(Extensions3D::READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTexture, 0);
566
    ::glBindFramebuffer(Extensions3D::DRAW_FRAMEBUFFER, targetFboId);
567
568
    if (flip)
569
        ::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);
570
    else
571
        ::glBlitFramebuffer(srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), destRect.x(), destRect.y(), destRect.width(), destRect.height(), GL_COLOR_BUFFER_BIT, filter);
572
573
    ::glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
574
575
    if (enableScissorTest)
576
        ::glEnable(GL_SCISSOR_TEST);
577
578
    return true;
579
}
580
#endif
581
582
bool TextureBlitter::copyTexture(const GLuint source, const GLuint destination, bool flip)
583
{
584
    initializeGLBindings();
585
586
    if (!initializeProgram())
587
        return false;
588
589
    if (!m_fboId)
590
        glGenFramebuffers(1, &m_fboId);
591
592
    ScopedProgramBinding program(m_shaderProgram, GraphicsContext3D::NEAREST);
593
    m_flip = flip;
594
    initializeVBO();
595
    ::glBindFramebuffer(GL_FRAMEBUFFER, m_fboId);
596
    ::glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
597
    ::glBindTexture(GL_TEXTURE_2D, source);
598
    ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destination, 0);
599
    enableVertexArray();
600
    ::glDrawElements(GL_TRIANGLE_STRIP, vertexIndexSize, GL_UNSIGNED_SHORT, 0);
601
    disableVertexArray();
602
    ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
603
    return true;
604
}
605
606
}
607
608
#endif
609
- Source/WebCore/platform/graphics/surfaces/TextureBlitter.h +89 lines
Line 0 Source/WebCore/platform/graphics/surfaces/TextureBlitter.h_sec1
1
/*
2
 * Copyright (C) 2012 Intel Corporation. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
 * THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
#ifndef TextureBlitter_h
27
#define TextureBlitter_h
28
29
#if USE(ACCELERATED_COMPOSITING)
30
31
#include <opengl/GLDefs.h>
32
#include <wtf/Noncopyable.h>
33
#include <wtf/PassRefPtr.h>
34
#include <wtf/RefCounted.h>
35
36
namespace WebCore {
37
38
class TextureBlitter : public WTF::RefCountedBase {
39
    WTF_MAKE_NONCOPYABLE(TextureBlitter);
40
41
public:
42
    static PassRefPtr<TextureBlitter> create()
43
    {
44
        if (!m_staticTextureBlitter)
45
            m_staticTextureBlitter = new TextureBlitter();
46
        else
47
            m_staticTextureBlitter->ref();
48
49
        return adoptRef(m_staticTextureBlitter);
50
    }
51
52
    void deref()
53
    {
54
        if (derefBase()) {
55
            m_staticTextureBlitter = 0;
56
            delete this;
57
        }
58
    }
59
60
    TextureBlitter();
61
    ~TextureBlitter();
62
    bool copyTexture(const GLuint, const GLuint, bool = false);
63
    bool drawTexture(const GLuint, const GLuint, const IntRect&, const IntRect&, bool = false, GLenum = GraphicsContext3D::NEAREST);
64
    void clear();
65
66
private:
67
    static TextureBlitter* m_staticTextureBlitter;
68
    bool initializeProgram();
69
    void enableVertexArray();
70
    void disableVertexArray();
71
    void bindArrayBuffer();
72
    void initializeVBO();
73
    bool linkProgram(const GLuint programId);
74
    GLuint loadShader(GLenum type, const GLchar *shaderSrc);
75
    GLuint m_vertexHandle;
76
    GLuint m_flipVertexHandle;
77
    GLuint m_currentVertexHandle;
78
    GLuint m_shaderProgram;
79
    GLuint m_vertexBuffer;
80
    GLuint m_indexBuffer;
81
    GLuint m_fboId;
82
    bool m_flip :1;
83
};
84
85
}
86
87
#endif
88
89
#endif

Return to Bug 106508