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