~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLBase.cpp

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
 
3
 * Copyright (C) 2011 Google Inc. All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 * 1. Redistributions of source code must retain the above copyright
 
9
 *    notice, this list of conditions and the following disclaimer.
 
10
 * 2. Redistributions in binary form must reproduce the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer in the
 
12
 *    documentation and/or other materials provided with the distribution.
 
13
 *
 
14
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 
15
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
17
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 
18
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
19
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
20
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
21
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 
22
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
25
 */
 
26
 
 
27
#include "config.h"
 
28
#include "GraphicsContextGLOpenGL.h"
 
29
 
 
30
#if ENABLE(GRAPHICS_CONTEXT_GL) && (USE(OPENGL) || (PLATFORM(COCOA) && USE(OPENGL_ES)))
 
31
 
 
32
#if PLATFORM(IOS_FAMILY)
 
33
#include "GraphicsContextGLOpenGLESIOS.h"
 
34
#endif
 
35
#include "ExtensionsGLOpenGL.h"
 
36
#include "IntRect.h"
 
37
#include "IntSize.h"
 
38
#include "NotImplemented.h"
 
39
#include "TemporaryOpenGLSetting.h"
 
40
#include <algorithm>
 
41
#include <cstring>
 
42
#include <wtf/MainThread.h>
 
43
#include <wtf/text/CString.h>
 
44
 
 
45
#if USE(ACCELERATE)
 
46
#include <Accelerate/Accelerate.h>
 
47
#endif
 
48
 
 
49
#if PLATFORM(GTK) || PLATFORM(WIN)
 
50
#include "OpenGLShims.h"
 
51
#elif USE(OPENGL_ES)
 
52
#import <OpenGLES/ES2/glext.h>
 
53
// From <OpenGLES/glext.h>
 
54
#define GL_RGBA32F_ARB                      0x8814
 
55
#define GL_RGB32F_ARB                       0x8815
 
56
#elif USE(OPENGL)
 
57
#define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
 
58
#include <OpenGL/gl.h>
 
59
#include <OpenGL/gl3.h>
 
60
#undef GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
 
61
#endif
 
62
 
 
63
namespace WebCore {
 
64
 
 
65
void GraphicsContextGLOpenGL::releaseShaderCompiler()
 
66
{
 
67
    makeContextCurrent();
 
68
    notImplemented();
 
69
}
 
70
 
 
71
#if PLATFORM(MAC)
 
72
static void wipeAlphaChannelFromPixels(int width, int height, unsigned char* pixels)
 
73
{
 
74
    // We can assume this doesn't overflow because the calling functions
 
75
    // use checked arithmetic.
 
76
    int totalBytes = width * height * 4;
 
77
    for (int i = 0; i < totalBytes; i += 4)
 
78
        pixels[i + 3] = 255;
 
79
}
 
80
#endif
 
81
 
 
82
void GraphicsContextGLOpenGL::readPixelsAndConvertToBGRAIfNecessary(int x, int y, int width, int height, unsigned char* pixels)
 
83
{
 
84
    auto attrs = contextAttributes();
 
85
 
 
86
    // NVIDIA drivers have a bug where calling readPixels in BGRA can return the wrong values for the alpha channel when the alpha is off for the context.
 
87
    if (!attrs.alpha && getExtensions().isNVIDIA()) {
 
88
        ::glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 
89
#if USE(ACCELERATE)
 
90
        vImage_Buffer src;
 
91
        src.height = height;
 
92
        src.width = width;
 
93
        src.rowBytes = width * 4;
 
94
        src.data = pixels;
 
95
 
 
96
        vImage_Buffer dest;
 
97
        dest.height = height;
 
98
        dest.width = width;
 
99
        dest.rowBytes = width * 4;
 
100
        dest.data = pixels;
 
101
 
 
102
        // Swap pixel channels from RGBA to BGRA.
 
103
        const uint8_t map[4] = { 2, 1, 0, 3 };
 
104
        vImagePermuteChannels_ARGB8888(&src, &dest, map, kvImageNoFlags);
 
105
#else
 
106
        int totalBytes = width * height * 4;
 
107
        for (int i = 0; i < totalBytes; i += 4)
 
108
            std::swap(pixels[i], pixels[i + 2]);
 
109
#endif
 
110
    } else
 
111
        ::glReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
 
112
 
 
113
#if PLATFORM(MAC)
 
114
    if (!attrs.alpha)
 
115
        wipeAlphaChannelFromPixels(width, height, pixels);
 
116
#endif
 
117
}
 
118
 
 
119
void GraphicsContextGLOpenGL::validateAttributes()
 
120
{
 
121
    validateDepthStencil("GL_EXT_packed_depth_stencil");
 
122
}
 
123
 
 
124
bool GraphicsContextGLOpenGL::reshapeFBOs(const IntSize& size)
 
125
{
 
126
    auto attrs = contextAttributes();
 
127
    const int width = size.width();
 
128
    const int height = size.height();
 
129
    GLuint colorFormat, internalDepthStencilFormat = 0;
 
130
    if (attrs.alpha) {
 
131
        m_internalColorFormat = GL_RGBA8;
 
132
        colorFormat = GL_RGBA;
 
133
    } else {
 
134
        m_internalColorFormat = GL_RGB8;
 
135
        colorFormat = GL_RGB;
 
136
    }
 
137
    if (attrs.stencil || attrs.depth) {
 
138
        // We don't allow the logic where stencil is required and depth is not.
 
139
        // See GraphicsContextGLOpenGL::validateAttributes.
 
140
 
 
141
        ExtensionsGL& extensions = getExtensions();
 
142
        // Use a 24 bit depth buffer where we know we have it.
 
143
        if (extensions.supports("GL_EXT_packed_depth_stencil"))
 
144
            internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
 
145
        else
 
146
#if PLATFORM(COCOA) && USE(OPENGL_ES)
 
147
            internalDepthStencilFormat = GL_DEPTH_COMPONENT16;
 
148
#else
 
149
            internalDepthStencilFormat = GL_DEPTH_COMPONENT;
 
150
#endif
 
151
    }
 
152
 
 
153
    // Resize multisample FBO.
 
154
    if (attrs.antialias) {
 
155
        GLint maxSampleCount;
 
156
        ::glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount);
 
157
        // Using more than 4 samples is slow on some hardware and is unlikely to
 
158
        // produce a significantly better result.
 
159
        GLint sampleCount = std::min(4, maxSampleCount);
 
160
        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
 
161
        ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
 
162
#if PLATFORM(COCOA) && USE(OPENGL_ES)
 
163
        ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, GL_RGBA8_OES, width, height);
 
164
#else
 
165
        ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, m_internalColorFormat, width, height);
 
166
#endif
 
167
        ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
 
168
        if (attrs.stencil || attrs.depth) {
 
169
            ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
 
170
            ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height);
 
171
            if (attrs.stencil)
 
172
                ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
 
173
            if (attrs.depth)
 
174
                ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
 
175
        }
 
176
        ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
 
177
        if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
 
178
            // FIXME: cleanup.
 
179
            notImplemented();
 
180
        }
 
181
    }
 
182
 
 
183
    // resize regular FBO
 
184
    ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
 
185
    ASSERT(m_texture);
 
186
#if PLATFORM(COCOA)
 
187
#if USE(OPENGL_ES)
 
188
    ::glBindRenderbuffer(GL_RENDERBUFFER, m_texture);
 
189
    ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_texture);
 
190
    setRenderbufferStorageFromDrawable(m_currentWidth, m_currentHeight);
 
191
#else
 
192
    allocateIOSurfaceBackingStore(IntSize(width, height));
 
193
    updateFramebufferTextureBackingStoreFromLayer();
 
194
    ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_texture, 0);
 
195
#endif // !USE(OPENGL_ES))
 
196
#else
 
197
    ::glBindTexture(GL_TEXTURE_2D, m_texture);
 
198
    ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
 
199
    ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
 
200
 
 
201
#if USE(COORDINATED_GRAPHICS)
 
202
    if (m_compositorTexture) {
 
203
        ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
 
204
        ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
 
205
        ::glBindTexture(GL_TEXTURE_2D, 0);
 
206
        ::glBindTexture(GL_TEXTURE_2D, m_intermediateTexture);
 
207
        ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
 
208
        ::glBindTexture(GL_TEXTURE_2D, 0);
 
209
    }
 
210
#endif
 
211
#endif
 
212
 
 
213
    attachDepthAndStencilBufferIfNeeded(internalDepthStencilFormat, width, height);
 
214
 
 
215
    bool mustRestoreFBO = true;
 
216
    if (attrs.antialias) {
 
217
        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
 
218
        if (m_state.boundFBO == m_multisampleFBO)
 
219
            mustRestoreFBO = false;
 
220
    } else {
 
221
        if (m_state.boundFBO == m_fbo)
 
222
            mustRestoreFBO = false;
 
223
    }
 
224
 
 
225
    return mustRestoreFBO;
 
226
}
 
227
 
 
228
void GraphicsContextGLOpenGL::attachDepthAndStencilBufferIfNeeded(GLuint internalDepthStencilFormat, int width, int height)
 
229
{
 
230
    auto attrs = contextAttributes();
 
231
 
 
232
    if (!attrs.antialias && (attrs.stencil || attrs.depth)) {
 
233
        ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
 
234
        ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
 
235
        if (attrs.stencil)
 
236
            ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
 
237
        if (attrs.depth)
 
238
            ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
 
239
        ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
 
240
    }
 
241
 
 
242
    if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
 
243
        // FIXME: cleanup
 
244
        notImplemented();
 
245
    }
 
246
}
 
247
 
 
248
void GraphicsContextGLOpenGL::resolveMultisamplingIfNecessary(const IntRect& rect)
 
249
{
 
250
    TemporaryOpenGLSetting scopedScissor(GL_SCISSOR_TEST, GL_FALSE);
 
251
    TemporaryOpenGLSetting scopedDither(GL_DITHER, GL_FALSE);
 
252
    TemporaryOpenGLSetting scopedDepth(GL_DEPTH_TEST, GL_FALSE);
 
253
    TemporaryOpenGLSetting scopedStencil(GL_STENCIL_TEST, GL_FALSE);
 
254
 
 
255
#if PLATFORM(COCOA) && USE(OPENGL_ES)
 
256
    GLint boundFrameBuffer;
 
257
    ::glGetIntegerv(GL_FRAMEBUFFER_BINDING, &boundFrameBuffer);
 
258
#endif
 
259
 
 
260
    ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
 
261
    ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
 
262
#if PLATFORM(COCOA) && USE(OPENGL_ES)
 
263
    UNUSED_PARAM(rect);
 
264
    ::glFlush();
 
265
    ::glResolveMultisampleFramebufferAPPLE();
 
266
    const GLenum discards[] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
 
267
    ::glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 2, discards);
 
268
    ::glBindFramebuffer(GL_FRAMEBUFFER, boundFrameBuffer);
 
269
#else
 
270
    IntRect resolveRect = rect;
 
271
    if (rect.isEmpty())
 
272
        resolveRect = IntRect(0, 0, m_currentWidth, m_currentHeight);
 
273
 
 
274
    ::glBlitFramebufferEXT(resolveRect.x(), resolveRect.y(), resolveRect.maxX(), resolveRect.maxY(), resolveRect.x(), resolveRect.y(), resolveRect.maxX(), resolveRect.maxY(), GL_COLOR_BUFFER_BIT, GL_LINEAR);
 
275
#endif
 
276
}
 
277
 
 
278
void GraphicsContextGLOpenGL::renderbufferStorage(GCGLenum target, GCGLenum internalformat, GCGLsizei width, GCGLsizei height)
 
279
{
 
280
    makeContextCurrent();
 
281
#if USE(OPENGL)
 
282
    switch (internalformat) {
 
283
    case DEPTH_STENCIL:
 
284
        internalformat = GL_DEPTH24_STENCIL8_EXT;
 
285
        break;
 
286
    case DEPTH_COMPONENT16:
 
287
        internalformat = GL_DEPTH_COMPONENT;
 
288
        break;
 
289
    case RGBA4:
 
290
    case RGB5_A1:
 
291
        internalformat = GL_RGBA;
 
292
        break;
 
293
    case RGB565:
 
294
        internalformat = GL_RGB;
 
295
        break;
 
296
    }
 
297
#endif
 
298
    ::glRenderbufferStorageEXT(target, internalformat, width, height);
 
299
}
 
300
 
 
301
void GraphicsContextGLOpenGL::getIntegerv(GCGLenum pname, GCGLint* value)
 
302
{
 
303
    // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS
 
304
    // because desktop GL's corresponding queries return the number of components
 
305
    // whereas GLES2 return the number of vectors (each vector has 4 components).
 
306
    // Therefore, the value returned by desktop GL needs to be divided by 4.
 
307
    makeContextCurrent();
 
308
    switch (pname) {
 
309
#if USE(OPENGL)
 
310
    case MAX_FRAGMENT_UNIFORM_VECTORS:
 
311
        ::glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value);
 
312
        *value /= 4;
 
313
        break;
 
314
    case MAX_VERTEX_UNIFORM_VECTORS:
 
315
        ::glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, value);
 
316
        *value /= 4;
 
317
        break;
 
318
    case MAX_VARYING_VECTORS:
 
319
        if (isGLES2Compliant()) {
 
320
            ASSERT(::glGetError() == GL_NO_ERROR);
 
321
            ::glGetIntegerv(GL_MAX_VARYING_VECTORS, value);
 
322
            if (::glGetError() == GL_INVALID_ENUM) {
 
323
                ::glGetIntegerv(GL_MAX_VARYING_COMPONENTS, value);
 
324
                *value /= 4;
 
325
            }
 
326
        } else {
 
327
            ::glGetIntegerv(GL_MAX_VARYING_FLOATS, value);
 
328
            *value /= 4;
 
329
        }
 
330
        break;
 
331
#endif
 
332
    case MAX_TEXTURE_SIZE:
 
333
        ::glGetIntegerv(MAX_TEXTURE_SIZE, value);
 
334
        if (getExtensions().requiresRestrictedMaximumTextureSize())
 
335
            *value = std::min(4096, *value);
 
336
        break;
 
337
    case MAX_CUBE_MAP_TEXTURE_SIZE:
 
338
        ::glGetIntegerv(MAX_CUBE_MAP_TEXTURE_SIZE, value);
 
339
        if (getExtensions().requiresRestrictedMaximumTextureSize())
 
340
            *value = std::min(1024, *value);
 
341
        break;
 
342
#if PLATFORM(MAC)
 
343
    // Some older hardware advertises a larger maximum than they
 
344
    // can actually handle. Rather than detecting such devices, simply
 
345
    // clamp the maximum to 8192, which is big enough for a 5K display.
 
346
    case MAX_RENDERBUFFER_SIZE:
 
347
        ::glGetIntegerv(MAX_RENDERBUFFER_SIZE, value);
 
348
        *value = std::min(8192, *value);
 
349
        break;
 
350
    case MAX_VIEWPORT_DIMS:
 
351
        ::glGetIntegerv(MAX_VIEWPORT_DIMS, value);
 
352
        value[0] = std::min(8192, value[0]);
 
353
        value[1] = std::min(8192, value[1]);
 
354
        break;
 
355
#endif
 
356
    default:
 
357
        ::glGetIntegerv(pname, value);
 
358
    }
 
359
}
 
360
 
 
361
void GraphicsContextGLOpenGL::getShaderPrecisionFormat(GCGLenum shaderType, GCGLenum precisionType, GCGLint* range, GCGLint* precision)
 
362
{
 
363
    UNUSED_PARAM(shaderType);
 
364
    ASSERT(range);
 
365
    ASSERT(precision);
 
366
 
 
367
    makeContextCurrent();
 
368
 
 
369
    switch (precisionType) {
 
370
    case GraphicsContextGL::LOW_INT:
 
371
    case GraphicsContextGL::MEDIUM_INT:
 
372
    case GraphicsContextGL::HIGH_INT:
 
373
        // These values are for a 32-bit twos-complement integer format.
 
374
        range[0] = 31;
 
375
        range[1] = 30;
 
376
        precision[0] = 0;
 
377
        break;
 
378
    case GraphicsContextGL::LOW_FLOAT:
 
379
    case GraphicsContextGL::MEDIUM_FLOAT:
 
380
    case GraphicsContextGL::HIGH_FLOAT:
 
381
        // These values are for an IEEE single-precision floating-point format.
 
382
        range[0] = 127;
 
383
        range[1] = 127;
 
384
        precision[0] = 23;
 
385
        break;
 
386
    default:
 
387
        ASSERT_NOT_REACHED();
 
388
        break;
 
389
    }
 
390
}
 
391
 
 
392
bool GraphicsContextGLOpenGL::texImage2D(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLenum format, GCGLenum type, const void* pixels)
 
393
{
 
394
    if (width && height && !pixels) {
 
395
        synthesizeGLError(INVALID_VALUE);
 
396
        return false;
 
397
    }
 
398
 
 
399
    GCGLenum openGLFormat = format;
 
400
    GCGLenum openGLInternalFormat = internalformat;
 
401
#if USE(OPENGL)
 
402
    if (type == GL_FLOAT) {
 
403
        if (format == GL_RGBA)
 
404
            openGLInternalFormat = GL_RGBA32F_ARB;
 
405
        else if (format == GL_RGB)
 
406
            openGLInternalFormat = GL_RGB32F_ARB;
 
407
    } else if (type == HALF_FLOAT_OES) {
 
408
        if (format == GL_RGBA)
 
409
            openGLInternalFormat = GL_RGBA16F_ARB;
 
410
        else if (format == GL_RGB)
 
411
            openGLInternalFormat = GL_RGB16F_ARB;
 
412
        else if (format == GL_LUMINANCE)
 
413
            openGLInternalFormat = GL_LUMINANCE16F_ARB;
 
414
        else if (format == GL_ALPHA)
 
415
            openGLInternalFormat = GL_ALPHA16F_ARB;
 
416
        else if (format == GL_LUMINANCE_ALPHA)
 
417
            openGLInternalFormat = GL_LUMINANCE_ALPHA16F_ARB;
 
418
        type = GL_HALF_FLOAT_ARB;
 
419
    }
 
420
 
 
421
    ASSERT(format != ExtensionsGL::SRGB8_ALPHA8_EXT);
 
422
    if (format == ExtensionsGL::SRGB_ALPHA_EXT)
 
423
        openGLFormat = GL_RGBA;
 
424
    else if (format == ExtensionsGL::SRGB_EXT)
 
425
        openGLFormat = GL_RGB;
 
426
#endif
 
427
 
 
428
    if (m_usingCoreProfile) {
 
429
        // There are some format values used in WebGL that are deprecated when using a core profile, so we need
 
430
        // to adapt them.
 
431
        switch (openGLInternalFormat) {
 
432
        case ALPHA:
 
433
            // The format is a simple component containing an alpha value. It needs to be backed with a GL_RED plane.
 
434
            // We change the formats to GL_RED (both need to be GL_ALPHA in WebGL) and instruct the texture to swizzle
 
435
            // the red component values with the alpha component values.
 
436
            openGLInternalFormat = openGLFormat = RED;
 
437
            texParameteri(target, TEXTURE_SWIZZLE_A, RED);
 
438
            break;
 
439
        case LUMINANCE_ALPHA:
 
440
            // The format has 2 components, an alpha one and a luminance one (same value for red, green and blue).
 
441
            // It needs to be backed with a GL_RG plane, using the red component for the colors and the green component
 
442
            // for alpha. We change the formats to GL_RG and swizzle the components.
 
443
            openGLInternalFormat = openGLFormat = RG;
 
444
            texParameteri(target, TEXTURE_SWIZZLE_R, RED);
 
445
            texParameteri(target, TEXTURE_SWIZZLE_G, RED);
 
446
            texParameteri(target, TEXTURE_SWIZZLE_B, RED);
 
447
            texParameteri(target, TEXTURE_SWIZZLE_A, GREEN);
 
448
            break;
 
449
        default:
 
450
            break;
 
451
        }
 
452
    }
 
453
 
 
454
    texImage2DDirect(target, level, openGLInternalFormat, width, height, border, openGLFormat, type, pixels);
 
455
    return true;
 
456
}
 
457
 
 
458
void GraphicsContextGLOpenGL::depthRange(GCGLclampf zNear, GCGLclampf zFar)
 
459
{
 
460
    makeContextCurrent();
 
461
#if PLATFORM(COCOA) && USE(OPENGL_ES)
 
462
    ::glDepthRangef(static_cast<float>(zNear), static_cast<float>(zFar));
 
463
#else
 
464
    ::glDepthRange(zNear, zFar);
 
465
#endif
 
466
}
 
467
 
 
468
void GraphicsContextGLOpenGL::clearDepth(GCGLclampf depth)
 
469
{
 
470
    makeContextCurrent();
 
471
#if PLATFORM(COCOA) && USE(OPENGL_ES)
 
472
    ::glClearDepthf(static_cast<float>(depth));
 
473
#else
 
474
    ::glClearDepth(depth);
 
475
#endif
 
476
}
 
477
 
 
478
#if !PLATFORM(GTK)
 
479
ExtensionsGL& GraphicsContextGLOpenGL::getExtensions()
 
480
{
 
481
    if (!m_extensions)
 
482
#if PLATFORM(COCOA) && USE(OPENGL_ES)
 
483
        m_extensions = makeUnique<ExtensionsGLOpenGL>(this, false);
 
484
#else
 
485
        m_extensions = makeUnique<ExtensionsGLOpenGL>(this, isGLES2Compliant());
 
486
#endif
 
487
    return *m_extensions;
 
488
}
 
489
#endif
 
490
 
 
491
void GraphicsContextGLOpenGL::readPixels(GCGLint x, GCGLint y, GCGLsizei width, GCGLsizei height, GCGLenum format, GCGLenum type, void* data)
 
492
{
 
493
    auto attrs = contextAttributes();
 
494
 
 
495
    // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e.,
 
496
    // all previous rendering calls should be done before reading pixels.
 
497
    makeContextCurrent();
 
498
    ::glFlush();
 
499
    if (attrs.antialias && m_state.boundFBO == m_multisampleFBO) {
 
500
        resolveMultisamplingIfNecessary(IntRect(x, y, width, height));
 
501
        ::glBindFramebufferEXT(GraphicsContextGL::FRAMEBUFFER, m_fbo);
 
502
        ::glFlush();
 
503
    }
 
504
    ::glReadPixels(x, y, width, height, format, type, data);
 
505
    if (attrs.antialias && m_state.boundFBO == m_multisampleFBO)
 
506
        ::glBindFramebufferEXT(GraphicsContextGL::FRAMEBUFFER, m_multisampleFBO);
 
507
 
 
508
#if PLATFORM(MAC)
 
509
    if (!attrs.alpha && (format == GraphicsContextGL::RGBA || format == GraphicsContextGL::BGRA) && (m_state.boundFBO == m_fbo || (attrs.antialias && m_state.boundFBO == m_multisampleFBO)))
 
510
        wipeAlphaChannelFromPixels(width, height, static_cast<unsigned char*>(data));
 
511
#endif
 
512
}
 
513
 
 
514
}
 
515
 
 
516
#endif // ENABLE(GRAPHICS_CONTEXT_GL) && (USE(OPENGL) || (PLATFORM(COCOA) && USE(OPENGL_ES)))