| Differences between
and this patch
- Source/WebCore/platform/graphics/opengl/GLPlatformSurface.cpp -21 / +5 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_restoreNeeded = false;
120
120
    m_blitter->drawTexture(texture, 0, m_rect, m_rect);
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();
121
    swapBuffers();
133
    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
134
    glBindTexture(GL_TEXTURE_2D, bindTexture);
122
    glBindTexture(GL_TEXTURE_2D, bindTexture);
135
    glBindFramebuffer(GL_FRAMEBUFFER, bindFboId);
123
    glBindFramebuffer(GL_FRAMEBUFFER, bindFboId);
136
}
124
}
Lines 143-153 void GLPlatformSurface::setGeometry(const IntRect& newRect) Source/WebCore/platform/graphics/opengl/GLPlatformSurface.cpp_sec3
143
void GLPlatformSurface::destroy()
131
void GLPlatformSurface::destroy()
144
{
132
{
145
    m_rect = IntRect();
133
    m_rect = IntRect();
146
134
    m_blitter = nullptr;
147
    if (m_fboId)
148
        glDeleteFramebuffers(1, &m_fboId);
149
150
    m_fboId = 0;
151
}
135
}
152
136
153
}
137
}
- 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 <texmap/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/egl/EGLSurface.cpp +1 lines
Lines 108-113 void EGLWindowTransportSurface::swapBuffers() Source/WebCore/platform/graphics/surfaces/egl/EGLSurface.cpp_sec1
108
108
109
void EGLWindowTransportSurface::destroy()
109
void EGLWindowTransportSurface::destroy()
110
{
110
{
111
    GLPlatformSurface::destroy();
111
    m_nativeResource->destroyWindow(m_bufferHandle);
112
    m_nativeResource->destroyWindow(m_bufferHandle);
112
    freeEGLResources();
113
    freeEGLResources();
113
    m_nativeResource = nullptr;
114
    m_nativeResource = nullptr;
- Source/WebCore/platform/graphics/surfaces/glx/GLXSurface.cpp +3 lines
Lines 75-80 void GLXTransportSurface::setGeometry(const IntRect& newRect) Source/WebCore/platform/graphics/surfaces/glx/GLXSurface.cpp_sec1
75
{
75
{
76
    GLPlatformSurface::setGeometry(newRect);
76
    GLPlatformSurface::setGeometry(newRect);
77
    m_nativeResource->reSizeWindow(newRect, m_drawable);
77
    m_nativeResource->reSizeWindow(newRect, m_drawable);
78
78
    // Force resize of GL surface after window resize.
79
    // Force resize of GL surface after window resize.
79
    glXSwapBuffers(sharedDisplay(), m_drawable);
80
    glXSwapBuffers(sharedDisplay(), m_drawable);
80
}
81
}
Lines 96-101 void GLXTransportSurface::swapBuffers() Source/WebCore/platform/graphics/surfaces/glx/GLXSurface.cpp_sec2
96
97
97
void GLXTransportSurface::destroy()
98
void GLXTransportSurface::destroy()
98
{
99
{
100
    GLPlatformSurface::destroy();
101
99
    if (m_bufferHandle) {
102
    if (m_bufferHandle) {
100
        m_nativeResource->destroyWindow(m_bufferHandle);
103
        m_nativeResource->destroyWindow(m_bufferHandle);
101
        m_bufferHandle = 0;
104
        m_bufferHandle = 0;
- Source/WebCore/platform/graphics/texmap/TextureBlitter.cpp +651 lines
Line 0 Source/WebCore/platform/graphics/texmap/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
static PFNGLBLITFRAMEBUFFERANGLEPROC m_frameBufferBlit = 0;
64
#else
65
static PFNGLBINDVERTEXARRAYPROC m_glBindVertexArray = 0;
66
static PFNGLDELETEVERTEXARRAYSPROC m_glDeleteVertexArrays = 0;
67
static PFNGLGENVERTEXARRAYSPROC m_glGenVertexArrays = 0;
68
static PFNGLISVERTEXARRAYPROC m_glIsVertexArray = 0;
69
static PFNGLBLITFRAMEBUFFEREXTPROC m_frameBufferBlit = 0;
70
#endif
71
72
static PFNGLSAMPLERPARAMETERIPROC m_glSamplerParameteri = 0;
73
static PFNGLGENSAMPLERSPROC m_glGenSamplers = 0;
74
static PFNGLBINDSAMPLERPROC m_glBindSampler = 0;
75
76
static void initializeGLBindings()
77
{
78
    static bool bindingsInitialized = false;
79
    if (bindingsInitialized)
80
        return;
81
82
    bindingsInitialized = true;
83
84
#if USE(OPENGL_ES_2) && USE(EGL)
85
    if (GLPlatformContext::supportsGLExtension("GL_ANGLE_framebuffer_blit"))
86
        m_frameBufferBlit = reinterpret_cast<PFNGLBLITFRAMEBUFFERANGLEPROC>(eglGetProcAddress("glBlitFramebufferANGLE"));
87
88
    if (m_frameBufferBlit)
89
        return;
90
91
    if (GLPlatformContext::supportsGLExtension("GL_OES_vertex_array_object")) {
92
        m_glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYOESPROC>(eglGetProcAddress("glBindVertexArrayOES"));
93
        m_glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSOESPROC>(eglGetProcAddress("glGenVertexArraysOES"));
94
        m_glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSOESPROC>(eglGetProcAddress("glDeleteVertexArraysOES"));
95
        m_glIsVertexArray = reinterpret_cast<PFNGLISVERTEXARRAYOESPROC>(eglGetProcAddress("glIsVertexArrayOES"));
96
    }
97
98
#else
99
    bool supportsBlitExtension = GLPlatformContext::supportsGLExtension("GL_EXT_framebuffer_blit");
100
    bool supportsVAO = GLPlatformContext::supportsGLExtension("GL_ARB_vertex_array_object");
101
    // 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.
102
    bool supportsSamplerObjects = GLPlatformContext::supportsGLExtension("GL_ARB_sampler_objects");
103
#if USE(GLX)
104
    if (supportsBlitExtension)
105
        m_frameBufferBlit = reinterpret_cast<PFNGLBLITFRAMEBUFFEREXTPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glBlitFramebufferEXT")));
106
107
    if (m_frameBufferBlit)
108
        return;
109
110
    if (supportsVAO) {
111
        m_glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glBindVertexArray")));
112
        m_glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glGenVertexArrays")));
113
        m_glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glDeleteVertexArrays")));
114
        m_glIsVertexArray = reinterpret_cast<PFNGLISVERTEXARRAYPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glIsVertexArray")));
115
    }
116
117
    if (supportsSamplerObjects) {
118
        m_glSamplerParameteri = reinterpret_cast<PFNGLSAMPLERPARAMETERIPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glSamplerParameteri")));
119
        m_glGenSamplers = reinterpret_cast<PFNGLGENSAMPLERSPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glGenSamplers")));
120
        m_glBindSampler = reinterpret_cast<PFNGLBINDSAMPLERPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glBindSampler")));
121
    }
122
123
#elif USE(EGL)
124
    if (supportsBlitExtension)
125
        m_frameBufferBlit = reinterpret_cast<PFNGLBLITFRAMEBUFFEREXTPROC>(eglGetProcAddress("glBlitFramebufferEXT"));
126
127
    if (m_frameBufferBlit)
128
        return;
129
130
    if (supportsVAO) {
131
        m_glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYPROC>(eglGetProcAddress("glBindVertexArray"));
132
        m_glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSPROC>(eglGetProcAddress("glGenVertexArrays"));
133
        m_glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSPROC>(eglGetProcAddress("glDeleteVertexArrays"));
134
        m_glIsVertexArray = reinterpret_cast<PFNGLISVERTEXARRAYPROC>(eglGetProcAddress("glIsVertexArray"));
135
    }
136
137
    if (supportsSamplerObjects) {
138
        m_glSamplerParameteri = reinterpret_cast<PFNGLSAMPLERPARAMETERIPROC>(eglGetProcAddress("glSamplerParameteri"));
139
        m_glGenSamplers = reinterpret_cast<PFNGLGENSAMPLERSPROC>(eglGetProcAddress("glGenSamplers"));
140
        m_glBindSampler = reinterpret_cast<PFNGLBINDSAMPLERPROC>(eglGetProcAddress("glBindSampler"));
141
    }
142
143
#endif
144
#endif
145
}
146
147
class ScopedToggleGLState
148
{
149
    WTF_MAKE_NONCOPYABLE(ScopedToggleGLState);
150
151
public:
152
    ScopedToggleGLState()
153
    {
154
        m_enableBlend = toggleState(GL_BLEND);
155
        m_enableCullFace = toggleState(GL_CULL_FACE);
156
        m_enableDepthTest = toggleState(GL_DEPTH_TEST);
157
        m_enableDitherTest = toggleState(GL_DITHER);
158
        m_enablePolygonOffsetFill = toggleState(GL_POLYGON_OFFSET_FILL);
159
        m_enableSampleAlpha = toggleState(GL_SAMPLE_ALPHA_TO_COVERAGE);
160
        m_enableSampleCoverage = toggleState(GL_SAMPLE_COVERAGE);
161
        m_enableStencilTest = toggleState(GL_STENCIL_TEST);
162
        m_enableScissorTest = toggleState(GL_SCISSOR_TEST);
163
    }
164
165
    ~ScopedToggleGLState()
166
    {
167
        if (m_enableBlend)
168
            ::glEnable(GL_BLEND);
169
170
        if (m_enableCullFace)
171
            ::glEnable(GL_CULL_FACE);
172
173
        if (m_enableDepthTest)
174
            ::glEnable(GL_DEPTH_TEST);
175
176
        if (m_enableDitherTest)
177
            ::glEnable(GL_DITHER);
178
179
        if (m_enablePolygonOffsetFill)
180
            ::glEnable(GL_POLYGON_OFFSET_FILL);
181
182
        if (m_enableSampleAlpha)
183
            ::glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
184
185
        if (m_enableSampleCoverage)
186
            ::glEnable(GL_SAMPLE_COVERAGE);
187
188
        if (m_enableStencilTest)
189
            ::glEnable(GL_STENCIL_TEST);
190
191
        if (m_enableScissorTest)
192
            ::glEnable(GL_SCISSOR_TEST);
193
    }
194
195
private:
196
    bool toggleState(const GLenum capability)
197
    {
198
        bool enabled = ::glIsEnabled(capability);
199
200
        if (!enabled)
201
            return false;
202
203
        ::glDisable(capability);
204
205
        return true;
206
    }
207
208
    bool m_enableBlend :1;
209
    bool m_enableCullFace :1;
210
    bool m_enableDepthTest :1;
211
    bool m_enableDitherTest :1;
212
    bool m_enablePolygonOffsetFill :1;
213
    bool m_enableSampleAlpha :1;
214
    bool m_enableSampleCoverage :1;
215
    bool m_enableStencilTest :1;
216
    bool m_enableScissorTest :1;
217
};
218
219
class ScopedProgramBinding
220
{
221
    WTF_MAKE_NONCOPYABLE(ScopedProgramBinding);
222
223
public:
224
    ScopedProgramBinding(GLuint programId)
225
    {
226
        ::glGetIntegerv(GL_ACTIVE_TEXTURE, &m_boundTexUnit);
227
        ::glGetIntegerv(GL_CURRENT_PROGRAM, &m_boundProgram);
228
        ::glGetBooleanv(GL_COLOR_WRITEMASK, m_colorMask);
229
        ::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
230
        ::glGetIntegerv(GL_VIEWPORT, &m_currentViewport[0]);
231
232
        if (m_glGenVertexArrays)
233
#if USE(OPENGL_ES_2)
234
            ::glGetIntegerv(GL_VERTEX_ARRAY_BINDING_OES, &m_currentVertexArrayBinding);
235
#else
236
            ::glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &m_currentVertexArrayBinding);
237
#endif
238
        else {
239
            ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &m_attribEnabled);
240
            ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_SIZE, &m_attribSize);
241
            ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &m_attribStride);
242
            ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_TYPE, &m_attribType);
243
            ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &m_attribNormalized);
244
            ::glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &m_attribBufferBinding);
245
            ::glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &m_attribPointer);
246
            ::glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &m_currentArrayBufferBinding);
247
            ::glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &m_currentElementryArrayBufferBinding);
248
        }
249
250
        ::glUseProgram(programId);
251
        ::glActiveTexture(GL_TEXTURE0);
252
253
        if (!(m_glGenSamplers && m_glSamplerParameteri)) {
254
            ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
255
            ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
256
            ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
257
            ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
258
        }
259
    }
260
261
    ~ScopedProgramBinding()
262
    {
263
        ::glViewport(m_currentViewport[0], m_currentViewport[1], m_currentViewport[2], m_currentViewport[3]);
264
        ::glColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], m_colorMask[3]);
265
266
        if (m_glGenVertexArrays)
267
            m_glBindVertexArray(m_currentVertexArrayBinding);
268
        else {
269
            if (m_attribEnabled)
270
                ::glEnableVertexAttribArray(0);
271
272
            ::glBindBuffer(GL_ARRAY_BUFFER, m_attribBufferBinding);
273
            ::glVertexAttribPointer(0, m_attribSize, m_attribType, m_attribNormalized, m_attribStride, m_attribPointer);
274
            ::glBindBuffer(GL_ARRAY_BUFFER, m_currentArrayBufferBinding);
275
            ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentElementryArrayBufferBinding);
276
        }
277
278
        ::glUseProgram(m_boundProgram);
279
        ::glActiveTexture(m_boundTexUnit);
280
    }
281
282
private:
283
    GLint m_boundTexUnit;
284
    GLint m_boundProgram;
285
    GLint m_currentArrayBufferBinding;
286
    GLint m_attribEnabled;
287
    GLint m_attribSize;
288
    GLint m_attribStride;
289
    GLint m_attribType;
290
    GLint m_attribNormalized;
291
    GLint m_attribBufferBinding;
292
    GLint m_currentViewport[4];
293
    GLint m_currentVertexArrayBinding;
294
    GLint m_currentElementryArrayBufferBinding;
295
    GLboolean m_colorMask[4];
296
    ScopedToggleGLState m_scopedToggleState;
297
    void* m_attribPointer;
298
};
299
300
#define STRINGIFY(...) #__VA_ARGS__
301
302
const char* GetShaderSource(GLenum type) {
303
    switch (type) {
304
    case GL_VERTEX_SHADER:
305
        return STRINGIFY(
306
                    attribute vec4 m_vPosition;
307
                attribute vec2 m_texCoord;
308
        varying vec2 m_vTexCoord;
309
        void main(void) {
310
            gl_Position = m_vPosition;
311
            m_vTexCoord = m_texCoord;
312
        });
313
    case GL_FRAGMENT_SHADER:
314
        return STRINGIFY(
315
                    uniform sampler2D u_texSampler;
316
                varying vec2 m_vTexCoord;
317
        void main(void) {
318
            gl_FragColor = texture2D(u_texSampler, m_vTexCoord.st);
319
        });
320
    default:
321
        return 0;
322
    }
323
}
324
325
TextureBlitter::TextureBlitter()
326
    : m_vertexHandle(0)
327
    , m_flipVertexHandle(0)
328
    , m_currentVertexHandle(0)
329
    , m_shaderProgram(0)
330
    , m_vertexBuffer(0)
331
    , m_indexBuffer(0)
332
    , m_fboId(0)
333
    , m_flip(false)
334
{
335
}
336
337
TextureBlitter::~TextureBlitter()
338
{
339
    clear();
340
}
341
342
void TextureBlitter::clear()
343
{
344
    if (m_shaderProgram) {
345
        ::glDeleteProgram(m_shaderProgram);
346
        m_shaderProgram = 0;
347
    }
348
349
    if (m_fboId) {
350
        ::glDeleteFramebuffers(1, &m_fboId);
351
        m_fboId = 0;
352
    }
353
354
    if (m_vertexHandle && m_glDeleteVertexArrays) {
355
        m_glDeleteVertexArrays(1, &m_vertexHandle);
356
        m_vertexHandle = 0;
357
    }
358
359
    if (m_flipVertexHandle && m_glDeleteVertexArrays) {
360
        m_glDeleteVertexArrays(1, &m_flipVertexHandle);
361
        m_flipVertexHandle = 0;
362
    }
363
364
    if (m_vertexBuffer) {
365
        ::glDeleteBuffers(1, &m_vertexBuffer);
366
        m_vertexBuffer = 0;
367
    }
368
369
    if (m_indexBuffer) {
370
        ::glDeleteBuffers(1, &m_indexBuffer);
371
        m_indexBuffer = 0;
372
    }
373
}
374
375
GLuint TextureBlitter::loadShader(GLenum type, const GLchar *shaderSrc)
376
{
377
    GLuint shader;
378
    GLint compiled;
379
380
    shader = glCreateShader(type);
381
382
    if (!shader) {
383
        LOG_ERROR("Failed to create shader.");
384
        return 0;
385
    }
386
387
    glShaderSource(shader, 1, &shaderSrc, 0);
388
    glCompileShader(shader);
389
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
390
391
    if (!compiled) {
392
        glDeleteShader(shader);
393
        LOG_ERROR("Failed to compile shader.");
394
        return 0;
395
    }
396
397
    return shader;
398
}
399
400
void TextureBlitter::bindArrayBuffer()
401
{
402
    glEnableVertexAttribArray(VERTEXATTRIB);
403
    glEnableVertexAttribArray(TEXCOORDATTRIB);
404
    glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
405
406
    if (m_flip)
407
        glVertexAttribPointer(VERTEXATTRIB, 4, GL_FLOAT, GL_FALSE, 0, (void*)FLIPOFFSET);
408
    else
409
        glVertexAttribPointer(VERTEXATTRIB, 4, GL_FLOAT, GL_FALSE, 0, (void*)NULL);
410
411
    glVertexAttribPointer(TEXCOORDATTRIB, 2, GL_FLOAT, GL_FALSE, 0, (void*)TEXCOORDOFFSET);
412
}
413
414
void TextureBlitter::enableVertexArray()
415
{
416
    if (m_currentVertexHandle)
417
        m_glBindVertexArray(m_currentVertexHandle);
418
    else {
419
        bindArrayBuffer();
420
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
421
    }
422
}
423
424
void TextureBlitter::disableVertexArray()
425
{
426
    if (m_currentVertexHandle)
427
        return;
428
429
    glDisableVertexAttribArray(VERTEXATTRIB);
430
    glDisableVertexAttribArray(TEXCOORDATTRIB);
431
}
432
433
bool TextureBlitter::linkProgram(const GLuint programId)
434
{
435
    glLinkProgram(programId);
436
#ifdef SHADER_DEBUG
437
    GLint linkStatus = 0;
438
    glGetProgramiv(programId, GL_LINK_STATUS, &linkStatus);
439
440
    if (!linkStatus) {
441
        LOG_ERROR("Failed to link program.");
442
        GLint infoLogLength(0);
443
        glGetProgramiv(m_shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength );
444
445
        if (infoLogLength > 0) {
446
            char* log = (char*) malloc(infoLogLength);
447
448
            if (log == NULL) {
449
                LOG_ERROR("Failed to allocate memory to write ProgamLog.");
450
                return false;
451
            }
452
453
            int written = 0;
454
            glGetProgramInfoLog(m_shaderProgram, infoLogLength, &written, log);
455
            LOG_ERROR("ProgramLog:(%s).\n", log);
456
        }
457
458
        return false;
459
    }
460
#endif
461
    return true;
462
}
463
464
void TextureBlitter::initializeVBO()
465
{
466
    if (m_glGenVertexArrays) {
467
        m_currentVertexHandle = m_flip ? m_flipVertexHandle : m_vertexHandle;
468
469
        if (m_currentVertexHandle)
470
            return;
471
    } else if (m_vertexBuffer)
472
        return;
473
474
    // bind buffers.
475
    GLuint temp[2];
476
    glGenBuffers(2, temp);
477
    m_vertexBuffer = temp[0];
478
    m_indexBuffer = temp[1];
479
    glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
480
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,
481
                 GL_STATIC_DRAW);
482
483
    // Create and set-up the vertex array object
484
    if (m_glGenVertexArrays && m_glBindVertexArray) {
485
        GLuint vertexHandle;
486
        m_glGenVertexArrays(1, &vertexHandle);
487
        m_glBindVertexArray(vertexHandle);
488
        bindArrayBuffer();
489
490
        if (m_flip)
491
            m_flipVertexHandle = vertexHandle;
492
        else
493
            m_vertexHandle = vertexHandle;
494
495
        m_currentVertexHandle = vertexHandle;
496
    }
497
498
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
499
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexVertices), indexVertices,
500
                 GL_STATIC_DRAW);
501
}
502
503
bool TextureBlitter::initializeProgram()
504
{
505
    if (m_shaderProgram)
506
        return true;
507
508
    // create shader.
509
    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, GetShaderSource(GL_VERTEX_SHADER));
510
    if (!vertexShader)
511
        return false;
512
513
    GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, GetShaderSource(GL_FRAGMENT_SHADER));
514
515
    if (!fragmentShader) {
516
        glDeleteShader(vertexShader);
517
        return false;
518
    }
519
520
    m_shaderProgram = glCreateProgram();
521
522
    if (!m_shaderProgram) {
523
        LOG_ERROR("Failed to create program.");
524
        glDeleteShader(vertexShader);
525
        glDeleteShader(fragmentShader);
526
        return false;
527
    }
528
529
    glAttachShader(m_shaderProgram, vertexShader);
530
    glAttachShader(m_shaderProgram, fragmentShader);
531
    glBindAttribLocation(m_shaderProgram, VERTEXATTRIB, "m_vPosition");
532
    glBindAttribLocation(m_shaderProgram, TEXCOORDATTRIB, "m_texCoord");
533
    bool linked = linkProgram(m_shaderProgram);
534
    glDeleteShader(vertexShader);
535
    glDeleteShader(fragmentShader);
536
537
    if (!linked) {
538
        clear();
539
        return false;
540
    }
541
542
    GLuint samplerLocation = glGetUniformLocation(m_shaderProgram, "u_texSampler");
543
    GLuint sampler = 0;
544
    // Create and initialize sampler object. This would help us seperate the texture and sampler state.
545
    if (m_glGenSamplers && m_glSamplerParameteri) {
546
        m_glGenSamplers(1 , &sampler);
547
        m_glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
548
        m_glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
549
        m_glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
550
        m_glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
551
    }
552
553
    GLint boundProgram;
554
    ::glGetIntegerv(GL_CURRENT_PROGRAM, &boundProgram);
555
556
    glUseProgram(m_shaderProgram);
557
    glUniform1i(samplerLocation, 0);
558
559
    if (m_glBindSampler)
560
        m_glBindSampler(0 , sampler);
561
#ifdef SHADER_DEBUG
562
    glValidateProgram(m_shaderProgram);
563
    GLint status;
564
    glGetProgramiv(m_shaderProgram, GL_VALIDATE_STATUS, &status);
565
566
    if (GL_TRUE != status) {
567
        LOG_ERROR("Program validation failed.\n");
568
        return false;
569
    }
570
#endif
571
    glUniform1i(samplerLocation, 0);
572
    glUseProgram(boundProgram);
573
574
    return true;
575
}
576
577
bool TextureBlitter::drawTexture(const GLuint sourceTexture, const GLuint targetFboId, const IntRect& srcRect, const IntRect& destRect, bool flip, GLenum filter)
578
{
579
    initializeGLBindings();
580
581
    if (m_frameBufferBlit) {
582
        bool enableScissorTest = ::glIsEnabled(GL_SCISSOR_TEST);
583
584
        if (enableScissorTest)
585
            ::glDisable(GL_SCISSOR_TEST);
586
587
        if (!m_fboId)
588
            glGenFramebuffers(1, &m_fboId);
589
590
        ::glBindFramebuffer(Extensions3D::READ_FRAMEBUFFER, m_fboId);
591
        ::glBindTexture(GL_TEXTURE_2D, sourceTexture);
592
        ::glFramebufferTexture2D(Extensions3D::READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTexture, 0);
593
        ::glBindFramebuffer(Extensions3D::DRAW_FRAMEBUFFER, targetFboId);
594
595
        if (flip)
596
            m_frameBufferBlit(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);
597
        else
598
            m_frameBufferBlit(srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), destRect.x(), destRect.y(), destRect.width(), destRect.height(), GL_COLOR_BUFFER_BIT, filter);
599
600
        ::glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
601
602
        if (enableScissorTest)
603
            ::glEnable(GL_SCISSOR_TEST);
604
605
        return true;
606
    }
607
608
    if (!initializeProgram())
609
        return false;
610
611
    ScopedProgramBinding program(m_shaderProgram);
612
    m_flip = flip;
613
    initializeVBO();
614
    ::glBindFramebuffer(GL_FRAMEBUFFER, targetFboId);
615
    ::glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
616
    ::glBindTexture(GL_TEXTURE_2D, sourceTexture);
617
    ::glViewport (destRect.x(), destRect.y(), destRect.width(), destRect.height());
618
    enableVertexArray();
619
    ::glDrawElements(GL_TRIANGLE_STRIP, vertexIndexSize, GL_UNSIGNED_SHORT, 0);
620
    disableVertexArray();
621
622
    return true;
623
}
624
625
bool TextureBlitter::copyTexture(const GLuint source, const GLuint destination, bool flip)
626
{
627
    initializeGLBindings();
628
629
    if (!initializeProgram())
630
        return false;
631
632
    if (!m_fboId)
633
        glGenFramebuffers(1, &m_fboId);
634
635
    ScopedProgramBinding program(m_shaderProgram);
636
    m_flip = flip;
637
    initializeVBO();
638
    ::glBindFramebuffer(GL_FRAMEBUFFER, m_fboId);
639
    ::glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
640
    ::glBindTexture(GL_TEXTURE_2D, source);
641
    ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destination, 0);
642
    enableVertexArray();
643
    ::glDrawElements(GL_TRIANGLE_STRIP, vertexIndexSize, GL_UNSIGNED_SHORT, 0);
644
    disableVertexArray();
645
    ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
646
    return true;
647
}
648
649
}
650
651
#endif
- Source/WebCore/platform/graphics/texmap/TextureBlitter.h +89 lines
Line 0 Source/WebCore/platform/graphics/texmap/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