[WebGL] Add a pure virtual base class for GraphicsContext3D
[WebKit-https.git] / Source / WebCore / platform / graphics / GraphicsContext3D.h
1 /*
2  * Copyright (C) 2009, 2014-2019 Apple Inc. 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #if ENABLE(WEBGL)
29
30 #include "ANGLEWebKitBridge.h"
31 #include "GraphicsContext3DBase.h"
32 #include <memory>
33 #include <wtf/HashCountedSet.h>
34 #include <wtf/HashMap.h>
35 #include <wtf/ListHashSet.h>
36 #include <wtf/RetainPtr.h>
37 #include <wtf/UniqueArray.h>
38
39 #if USE(CA)
40 #include "PlatformCALayer.h"
41 #endif
42
43 // FIXME: Find a better way to avoid the name confliction for NO_ERROR.
44 #if PLATFORM(WIN)
45 #undef NO_ERROR
46 #elif PLATFORM(GTK)
47 // This define is from the X11 headers, but it's used below, so we must undefine it.
48 #undef VERSION
49 #endif
50
51 #if PLATFORM(COCOA)
52 #if USE(OPENGL_ES)
53 #include <OpenGLES/ES2/gl.h>
54 #ifdef __OBJC__
55 #import <OpenGLES/EAGL.h>
56 #endif // __OBJC__
57 #endif // USE(OPENGL_ES)
58 OBJC_CLASS CALayer;
59 OBJC_CLASS WebGLLayer;
60 typedef struct __IOSurface* IOSurfaceRef;
61 #endif // PLATFORM(COCOA)
62
63 #if USE(NICOSIA)
64 namespace Nicosia {
65 class GC3DLayer;
66 }
67 #endif
68
69 namespace WebCore {
70 class Extensions3D;
71 #if USE(ANGLE)
72 class Extensions3DANGLE;
73 #elif !PLATFORM(COCOA) && USE(OPENGL_ES)
74 class Extensions3DOpenGLES;
75 #elif USE(OPENGL) || (PLATFORM(COCOA) && USE(OPENGL_ES))
76 class Extensions3DOpenGL;
77 #endif
78 class HostWindow;
79 class ImageBuffer;
80 class ImageData;
81 #if USE(TEXTURE_MAPPER)
82 class TextureMapperGC3DPlatformLayer;
83 #endif
84
85 typedef WTF::HashMap<CString, uint64_t> ShaderNameHash;
86
87 class GraphicsContext3DPrivate;
88
89 class GraphicsContext3D : public GraphicsContext3DBase {
90 public:
91     class Client {
92     public:
93         virtual ~Client() { }
94         virtual void didComposite() = 0;
95         virtual void forceContextLost() = 0;
96         virtual void recycleContext() = 0;
97         virtual void dispatchContextChangedNotification() = 0;
98     };
99
100     static RefPtr<GraphicsContext3D> create(GraphicsContext3DAttributes, HostWindow*, Destination = Destination::Offscreen);
101     virtual ~GraphicsContext3D();
102
103 #if PLATFORM(COCOA)
104     static Ref<GraphicsContext3D> createShared(GraphicsContext3D& sharedContext);
105 #endif
106
107 #if PLATFORM(COCOA)
108     PlatformGraphicsContext3D platformGraphicsContext3D() const override { return m_contextObj; }
109     Platform3DObject platformTexture() const override { return m_texture; }
110     CALayer* platformLayer() const override { return reinterpret_cast<CALayer*>(m_webGLLayer.get()); }
111 #if USE(ANGLE)
112     PlatformGraphicsContext3DDisplay platformDisplay() const { return m_displayObj; }
113     PlatformGraphicsContext3DConfig platformConfig() const { return m_configObj; }
114 #endif // USE(ANGLE)
115 #else
116     PlatformGraphicsContext3D platformGraphicsContext3D() const override;
117     Platform3DObject platformTexture() const override;
118     PlatformLayer* platformLayer() const override;
119 #endif
120
121     bool makeContextCurrent();
122
123     void addClient(Client& client) { m_clients.add(&client); }
124     void removeClient(Client& client) { m_clients.remove(&client); }
125
126     // With multisampling on, blit from multisampleFBO to regular FBO.
127     void prepareTexture();
128
129     // Equivalent to ::glTexImage2D(). Allows pixels==0 with no allocation.
130     void texImage2DDirect(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels);
131
132     // Get an attribute location without checking the name -> mangledname mapping.
133     int getAttribLocationDirect(Platform3DObject program, const String& name);
134
135     // Compile a shader without going through ANGLE.
136     void compileShaderDirect(Platform3DObject);
137
138     // Helper to texImage2D with pixel==0 case: pixels are initialized to 0.
139     // Return true if no GL error is synthesized.
140     // By default, alignment is 4, the OpenGL default setting.
141     bool texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint alignment = 4);
142
143     bool isGLES2Compliant() const;
144
145     //----------------------------------------------------------------------
146     // Helpers for texture uploading and pixel readback.
147     //
148
149     // Computes the components per pixel and bytes per component
150     // for the given format and type combination. Returns false if
151     // either was an invalid enum.
152     static bool computeFormatAndTypeParameters(GC3Denum format,
153                                                GC3Denum type,
154                                                unsigned int* componentsPerPixel,
155                                                unsigned int* bytesPerComponent);
156
157     // Computes the image size in bytes. If paddingInBytes is not null, padding
158     // is also calculated in return. Returns NO_ERROR if succeed, otherwise
159     // return the suggested GL error indicating the cause of the failure:
160     //   INVALID_VALUE if width/height is negative or overflow happens.
161     //   INVALID_ENUM if format/type is illegal.
162     static GC3Denum computeImageSizeInBytes(GC3Denum format,
163                                      GC3Denum type,
164                                      GC3Dsizei width,
165                                      GC3Dsizei height,
166                                      GC3Dint alignment,
167                                      unsigned int* imageSizeInBytes,
168                                      unsigned int* paddingInBytes);
169
170     static bool possibleFormatAndTypeForInternalFormat(GC3Denum internalFormat, GC3Denum& format, GC3Denum& type);
171
172     // Extracts the contents of the given ImageData into the passed Vector,
173     // packing the pixel data according to the given format and type,
174     // and obeying the flipY and premultiplyAlpha flags. Returns true
175     // upon success.
176     static bool extractImageData(ImageData*,
177                           GC3Denum format,
178                           GC3Denum type,
179                           bool flipY,
180                           bool premultiplyAlpha,
181                           Vector<uint8_t>& data);
182
183     // Helper function which extracts the user-supplied texture
184     // data, applying the flipY and premultiplyAlpha parameters.
185     // If the data is not tightly packed according to the passed
186     // unpackAlignment, the output data will be tightly packed.
187     // Returns true if successful, false if any error occurred.
188     static bool extractTextureData(unsigned int width, unsigned int height,
189                             GC3Denum format, GC3Denum type,
190                             unsigned int unpackAlignment,
191                             bool flipY, bool premultiplyAlpha,
192                             const void* pixels,
193                             Vector<uint8_t>& data);
194
195     //----------------------------------------------------------------------
196     // Entry points for WebGL.
197     //
198
199     void activeTexture(GC3Denum texture) override;
200     void attachShader(Platform3DObject program, Platform3DObject shader) override;
201     void bindAttribLocation(Platform3DObject, GC3Duint index, const String& name) override;
202     void bindBuffer(GC3Denum target, Platform3DObject) override;
203     void bindFramebuffer(GC3Denum target, Platform3DObject) override;
204     void bindRenderbuffer(GC3Denum target, Platform3DObject) override;
205     void bindTexture(GC3Denum target, Platform3DObject) override;
206     void blendColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha) override;
207     void blendEquation(GC3Denum mode) override;
208     void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha) override;
209     void blendFunc(GC3Denum sfactor, GC3Denum dfactor) override;
210     void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha) override;
211
212     void bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage) override;
213     void bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage) override;
214     void bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data) override;
215
216     void* mapBufferRange(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr length, GC3Dbitfield access) override;
217     GC3Dboolean unmapBuffer(GC3Denum target) override;
218     void copyBufferSubData(GC3Denum readTarget, GC3Denum writeTarget, GC3Dintptr readOffset, GC3Dintptr writeOffset, GC3Dsizeiptr) override;
219
220     void getInternalformativ(GC3Denum target, GC3Denum internalformat, GC3Denum pname, GC3Dsizei bufSize, GC3Dint* params) override;
221     void renderbufferStorageMultisample(GC3Denum target, GC3Dsizei samples, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) override;
222
223     void texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) override;
224     void texStorage3D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth) override;
225
226     void getActiveUniforms(Platform3DObject program, const Vector<GC3Duint>& uniformIndices, GC3Denum pname, Vector<GC3Dint>& params) override;
227
228     GC3Denum checkFramebufferStatus(GC3Denum target) override;
229     void clear(GC3Dbitfield mask) override;
230     void clearColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha) override;
231     void clearDepth(GC3Dclampf depth) override;
232     void clearStencil(GC3Dint s) override;
233     void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha) override;
234     void compileShader(Platform3DObject) override;
235
236     void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Dsizei imageSize, const void* data) override;
237     void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Dsizei imageSize, const void* data) override;
238     void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) override;
239     void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height) override;
240     void cullFace(GC3Denum mode) override;
241     void depthFunc(GC3Denum func) override;
242     void depthMask(GC3Dboolean flag) override;
243     void depthRange(GC3Dclampf zNear, GC3Dclampf zFar) override;
244     void detachShader(Platform3DObject, Platform3DObject) override;
245     void disable(GC3Denum cap) override;
246     void disableVertexAttribArray(GC3Duint index) override;
247     void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count) override;
248     void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset) override;
249
250     void enable(GC3Denum cap) override;
251     void enableVertexAttribArray(GC3Duint index) override;
252     void finish() override;
253     void flush() override;
254     void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, Platform3DObject) override;
255     void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, Platform3DObject, GC3Dint level) override;
256     void frontFace(GC3Denum mode) override;
257     void generateMipmap(GC3Denum target) override;
258
259     bool getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo&) override;
260     bool getActiveAttribImpl(Platform3DObject program, GC3Duint index, ActiveInfo&);
261     bool getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo&) override;
262     bool getActiveUniformImpl(Platform3DObject program, GC3Duint index, ActiveInfo&);
263     void getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount, GC3Dsizei* count, Platform3DObject* shaders) override;
264     GC3Dint getAttribLocation(Platform3DObject, const String& name) override;
265     void getBooleanv(GC3Denum pname, GC3Dboolean* value) override;
266     void getBufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value) override;
267     GC3Denum getError() override;
268     void getFloatv(GC3Denum pname, GC3Dfloat* value) override;
269     void getFramebufferAttachmentParameteriv(GC3Denum target, GC3Denum attachment, GC3Denum pname, GC3Dint* value) override;
270     void getIntegerv(GC3Denum pname, GC3Dint* value) override;
271     void getInteger64v(GC3Denum pname, GC3Dint64* value) override;
272     void getProgramiv(Platform3DObject program, GC3Denum pname, GC3Dint* value) override;
273 #if !USE(ANGLE)
274     void getNonBuiltInActiveSymbolCount(Platform3DObject program, GC3Denum pname, GC3Dint* value);
275 #endif // !USE(ANGLE)
276     String getProgramInfoLog(Platform3DObject) override;
277     String getUnmangledInfoLog(Platform3DObject[2], GC3Dsizei, const String&);
278     void getRenderbufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value) override;
279     void getShaderiv(Platform3DObject, GC3Denum pname, GC3Dint* value) override;
280     String getShaderInfoLog(Platform3DObject) override;
281     void getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType, GC3Dint* range, GC3Dint* precision) override;
282     String getShaderSource(Platform3DObject) override;
283     String getString(GC3Denum name) override;
284     void getTexParameterfv(GC3Denum target, GC3Denum pname, GC3Dfloat* value) override;
285     void getTexParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value) override;
286     void getUniformfv(Platform3DObject program, GC3Dint location, GC3Dfloat* value) override;
287     void getUniformiv(Platform3DObject program, GC3Dint location, GC3Dint* value) override;
288     GC3Dint getUniformLocation(Platform3DObject, const String& name) override;
289     void getVertexAttribfv(GC3Duint index, GC3Denum pname, GC3Dfloat* value) override;
290     void getVertexAttribiv(GC3Duint index, GC3Denum pname, GC3Dint* value) override;
291     GC3Dsizeiptr getVertexAttribOffset(GC3Duint index, GC3Denum pname) override;
292
293     void hint(GC3Denum target, GC3Denum mode) override;
294     GC3Dboolean isBuffer(Platform3DObject) override;
295     GC3Dboolean isEnabled(GC3Denum cap) override;
296     GC3Dboolean isFramebuffer(Platform3DObject) override;
297     GC3Dboolean isProgram(Platform3DObject) override;
298     GC3Dboolean isRenderbuffer(Platform3DObject) override;
299     GC3Dboolean isShader(Platform3DObject) override;
300     GC3Dboolean isTexture(Platform3DObject) override;
301     void lineWidth(GC3Dfloat) override;
302     void linkProgram(Platform3DObject) override;
303     void pixelStorei(GC3Denum pname, GC3Dint param) override;
304     void polygonOffset(GC3Dfloat factor, GC3Dfloat units) override;
305
306     void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data) override;
307
308     void releaseShaderCompiler();
309
310     void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) override;
311     void sampleCoverage(GC3Dclampf value, GC3Dboolean invert) override;
312     void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height) override;
313     void shaderSource(Platform3DObject, const String& string) override;
314     void stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask) override;
315     void stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask) override;
316     void stencilMask(GC3Duint mask) override;
317     void stencilMaskSeparate(GC3Denum face, GC3Duint mask) override;
318     void stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass) override;
319     void stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass) override;
320
321     bool texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels) override;
322     void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param) override;
323     void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param) override;
324     void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels) override;
325
326     void uniform1f(GC3Dint location, GC3Dfloat x) override;
327     void uniform1fv(GC3Dint location, GC3Dsizei, const GC3Dfloat* v) override;
328     void uniform1i(GC3Dint location, GC3Dint x) override;
329     void uniform1iv(GC3Dint location, GC3Dsizei, const GC3Dint* v) override;
330     void uniform2f(GC3Dint location, GC3Dfloat x, GC3Dfloat y) override;
331     void uniform2fv(GC3Dint location, GC3Dsizei, const GC3Dfloat* v) override;
332     void uniform2i(GC3Dint location, GC3Dint x, GC3Dint y) override;
333     void uniform2iv(GC3Dint location, GC3Dsizei, const GC3Dint* v) override;
334     void uniform3f(GC3Dint location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z) override;
335     void uniform3fv(GC3Dint location, GC3Dsizei, const GC3Dfloat* v) override;
336     void uniform3i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z) override;
337     void uniform3iv(GC3Dint location, GC3Dsizei, const GC3Dint* v) override;
338     void uniform4f(GC3Dint location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w) override;
339     void uniform4fv(GC3Dint location, GC3Dsizei, const GC3Dfloat* v) override;
340     void uniform4i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w) override;
341     void uniform4iv(GC3Dint location, GC3Dsizei, const GC3Dint* v) override;
342     void uniformMatrix2fv(GC3Dint location, GC3Dsizei, GC3Dboolean transpose, const GC3Dfloat* value) override;
343     void uniformMatrix3fv(GC3Dint location, GC3Dsizei, GC3Dboolean transpose, const GC3Dfloat* value) override;
344     void uniformMatrix4fv(GC3Dint location, GC3Dsizei, GC3Dboolean transpose, const GC3Dfloat* value) override;
345
346     void useProgram(Platform3DObject) override;
347     void validateProgram(Platform3DObject) override;
348 #if !USE(ANGLE)
349     bool checkVaryingsPacking(Platform3DObject vertexShader, Platform3DObject fragmentShader) const;
350     bool precisionsMatch(Platform3DObject vertexShader, Platform3DObject fragmentShader) const;
351 #endif
352
353     void vertexAttrib1f(GC3Duint index, GC3Dfloat x) override;
354     void vertexAttrib1fv(GC3Duint index, const GC3Dfloat* values) override;
355     void vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y) override;
356     void vertexAttrib2fv(GC3Duint index, const GC3Dfloat* values) override;
357     void vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z) override;
358     void vertexAttrib3fv(GC3Duint index, const GC3Dfloat* values) override;
359     void vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w) override;
360     void vertexAttrib4fv(GC3Duint index, const GC3Dfloat* values) override;
361     void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset) override;
362
363     void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height) override;
364
365     void reshape(int width, int height);
366
367     void drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount) override;
368     void drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount) override;
369     void vertexAttribDivisor(GC3Duint index, GC3Duint divisor) override;
370
371     // VertexArrayOject calls
372     Platform3DObject createVertexArray() override;
373     void deleteVertexArray(Platform3DObject) override;
374     GC3Dboolean isVertexArray(Platform3DObject) override;
375     void bindVertexArray(Platform3DObject) override;
376
377     void paintToCanvas(const unsigned char* imagePixels, const IntSize& imageSize, const IntSize& canvasSize, GraphicsContext&);
378
379     void markContextChanged();
380     void markLayerComposited();
381     bool layerComposited() const;
382     void forceContextLost();
383     void recycleContext();
384
385     void dispatchContextChangedNotification();
386     void simulateContextChanged();
387
388     void paintRenderingResultsToCanvas(ImageBuffer*);
389     RefPtr<ImageData> paintRenderingResultsToImageData();
390     bool paintCompositedResultsToCanvas(ImageBuffer*);
391
392 #if USE(OPENGL) && ENABLE(WEBGL2)
393     void primitiveRestartIndex(GC3Duint) override;
394 #endif
395
396 #if PLATFORM(COCOA)
397     bool texImageIOSurface2D(GC3Denum target, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, IOSurfaceRef, GC3Duint plane);
398
399 #if USE(OPENGL_ES)
400     void presentRenderbuffer();
401 #endif
402
403 #if USE(OPENGL) || USE(ANGLE)
404     void allocateIOSurfaceBackingStore(IntSize);
405     void updateFramebufferTextureBackingStoreFromLayer();
406 #if PLATFORM(MAC) || PLATFORM(MACCATALYST)
407     void updateCGLContext();
408 #endif
409 #endif
410 #endif // PLATFORM(COCOA)
411
412     void setContextVisibility(bool);
413
414     GraphicsContext3DPowerPreference powerPreferenceUsedForCreation() const { return m_powerPreferenceUsedForCreation; }
415
416     // Support for buffer creation and deletion
417     Platform3DObject createBuffer() override;
418     Platform3DObject createFramebuffer() override;
419     Platform3DObject createProgram() override;
420     Platform3DObject createRenderbuffer() override;
421     Platform3DObject createShader(GC3Denum) override;
422     Platform3DObject createTexture() override;
423
424     void deleteBuffer(Platform3DObject) override;
425     void deleteFramebuffer(Platform3DObject) override;
426     void deleteProgram(Platform3DObject) override;
427     void deleteRenderbuffer(Platform3DObject) override;
428     void deleteShader(Platform3DObject) override;
429     void deleteTexture(Platform3DObject) override;
430
431     // Synthesizes an OpenGL error which will be returned from a
432     // later call to getError. This is used to emulate OpenGL ES
433     // 2.0 behavior on the desktop and to enforce additional error
434     // checking mandated by WebGL.
435     //
436     // Per the behavior of glGetError, this stores at most one
437     // instance of any given error, and returns them from calls to
438     // getError in the order they were added.
439     void synthesizeGLError(GC3Denum error);
440
441     // Read real OpenGL errors, and move them to the synthetic
442     // error list. Return true if at least one error is moved.
443     bool moveErrorsToSyntheticErrorList();
444
445     // Support for extensions. Returns a non-null object, though not
446     // all methods it contains may necessarily be supported on the
447     // current hardware. Must call Extensions3D::supports() to
448     // determine this.
449     Extensions3D& getExtensions() override;
450
451     IntSize getInternalFramebufferSize() const;
452
453     // Packs the contents of the given Image which is passed in |pixels| into the passed Vector
454     // according to the given format and type, and obeying the flipY and AlphaOp flags.
455     // Returns true upon success.
456     static bool packImageData(Image*, const void* pixels, GC3Denum format, GC3Denum type, bool flipY, AlphaOp, DataFormat sourceFormat, unsigned width, unsigned height, unsigned sourceUnpackAlignment, Vector<uint8_t>& data);
457
458     class ImageExtractor {
459     public:
460         ImageExtractor(Image*, DOMSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
461
462         // Each platform must provide an implementation of this method to deallocate or release resources
463         // associated with the image if needed.
464         ~ImageExtractor();
465
466         bool extractSucceeded() { return m_extractSucceeded; }
467         const void* imagePixelData() { return m_imagePixelData; }
468         unsigned imageWidth() { return m_imageWidth; }
469         unsigned imageHeight() { return m_imageHeight; }
470         DataFormat imageSourceFormat() { return m_imageSourceFormat; }
471         AlphaOp imageAlphaOp() { return m_alphaOp; }
472         unsigned imageSourceUnpackAlignment() { return m_imageSourceUnpackAlignment; }
473         DOMSource imageHtmlDomSource() { return m_imageHtmlDomSource; }
474     private:
475         // Each platform must provide an implementation of this method.
476         // Extracts the image and keeps track of its status, such as width, height, Source Alignment, format and AlphaOp etc,
477         // needs to lock the resources or relevant data if needed and returns true upon success
478         bool extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
479
480 #if USE(CAIRO)
481         RefPtr<cairo_surface_t> m_imageSurface;
482 #elif USE(CG)
483         RetainPtr<CGImageRef> m_cgImage;
484         RetainPtr<CGImageRef> m_decodedImage;
485         RetainPtr<CFDataRef> m_pixelData;
486         UniqueArray<uint8_t> m_formalizedRGBA8Data;
487 #endif
488         Image* m_image;
489         DOMSource m_imageHtmlDomSource;
490         bool m_extractSucceeded;
491         const void* m_imagePixelData;
492         unsigned m_imageWidth;
493         unsigned m_imageHeight;
494         DataFormat m_imageSourceFormat;
495         AlphaOp m_alphaOp;
496         unsigned m_imageSourceUnpackAlignment;
497     };
498
499     void setFailNextGPUStatusCheck() { m_failNextStatusCheck = true; }
500
501     GC3Denum activeTextureUnit() const { return m_state.activeTextureUnit; }
502     GC3Denum currentBoundTexture() const { return m_state.currentBoundTexture(); }
503     GC3Denum currentBoundTarget() const { return m_state.currentBoundTarget(); }
504     unsigned textureSeed(GC3Duint texture) { return m_state.textureSeedCount.count(texture); }
505
506 #if PLATFORM(MAC)
507     using PlatformDisplayID = uint32_t;
508     void screenDidChange(PlatformDisplayID);
509 #endif
510
511 private:
512     GraphicsContext3D(GraphicsContext3DAttributes, HostWindow*, Destination = Destination::Offscreen, GraphicsContext3D* sharedContext = nullptr);
513
514     // Helper for packImageData/extractImageData/extractTextureData which implement packing of pixel
515     // data into the specified OpenGL destination format and type.
516     // A sourceUnpackAlignment of zero indicates that the source
517     // data is tightly packed. Non-zero values may take a slow path.
518     // Destination data will have no gaps between rows.
519     static bool packPixels(const uint8_t* sourceData, DataFormat sourceDataFormat, unsigned width, unsigned height, unsigned sourceUnpackAlignment, unsigned destinationFormat, unsigned destinationType, AlphaOp, void* destinationData, bool flipY);
520
521     // Take into account the user's requested context creation attributes,
522     // in particular stencil and antialias, and determine which could or
523     // could not be honored based on the capabilities of the OpenGL
524     // implementation.
525     void validateDepthStencil(const char* packedDepthStencilExtension);
526     void validateAttributes();
527     
528     // Did the most recent drawing operation leave the GPU in an acceptable state?
529     void checkGPUStatus();
530
531     // Read rendering results into a pixel array with the same format as the
532     // backbuffer.
533     void readRenderingResults(unsigned char* pixels, int pixelsSize);
534     void readPixelsAndConvertToBGRAIfNecessary(int x, int y, int width, int height, unsigned char* pixels);
535
536 #if USE(OPENGL_ES)
537     void setRenderbufferStorageFromDrawable(GC3Dsizei width, GC3Dsizei height);
538 #endif
539
540     bool reshapeFBOs(const IntSize&);
541     void resolveMultisamplingIfNecessary(const IntRect& = IntRect());
542     void attachDepthAndStencilBufferIfNeeded(GLuint internalDepthStencilFormat, int width, int height);
543
544 #if PLATFORM(COCOA)
545     bool allowOfflineRenderers() const;
546 #endif
547
548     int m_currentWidth { 0 };
549     int m_currentHeight { 0 };
550
551 #if PLATFORM(COCOA)
552     RetainPtr<WebGLLayer> m_webGLLayer;
553     PlatformGraphicsContext3D m_contextObj { nullptr };
554 #if USE(ANGLE)
555     PlatformGraphicsContext3DDisplay m_displayObj { nullptr };
556     PlatformGraphicsContext3DConfig m_configObj { nullptr };
557 #endif // USE(ANGLE)
558 #endif // PLATFORM(COCOA)
559
560 #if PLATFORM(WIN) && USE(CA)
561     RefPtr<PlatformCALayer> m_webGLLayer;
562 #endif
563
564     typedef HashMap<String, sh::ShaderVariable> ShaderSymbolMap;
565
566     struct ShaderSourceEntry {
567         GC3Denum type;
568         String source;
569         String translatedSource;
570         String log;
571         bool isValid;
572         ShaderSymbolMap attributeMap;
573         ShaderSymbolMap uniformMap;
574         ShaderSymbolMap varyingMap;
575         ShaderSourceEntry()
576             : type(VERTEX_SHADER)
577             , isValid(false)
578         {
579         }
580         
581         ShaderSymbolMap& symbolMap(enum ANGLEShaderSymbolType symbolType)
582         {
583             ASSERT(symbolType == SHADER_SYMBOL_TYPE_ATTRIBUTE || symbolType == SHADER_SYMBOL_TYPE_UNIFORM || symbolType == SHADER_SYMBOL_TYPE_VARYING);
584             if (symbolType == SHADER_SYMBOL_TYPE_ATTRIBUTE)
585                 return attributeMap;
586             if (symbolType == SHADER_SYMBOL_TYPE_VARYING)
587                 return varyingMap;
588             return uniformMap;
589         }
590     };
591
592 #if !USE(ANGLE)
593     // FIXME: Shaders are never removed from this map, even if they and their program are deleted.
594     // This is bad, and it also relies on the fact we never reuse Platform3DObject numbers.
595     typedef HashMap<Platform3DObject, ShaderSourceEntry> ShaderSourceMap;
596     ShaderSourceMap m_shaderSourceMap;
597
598     typedef HashMap<Platform3DObject, std::pair<Platform3DObject, Platform3DObject>> LinkedShaderMap;
599     LinkedShaderMap m_linkedShaderMap;
600
601     struct ActiveShaderSymbolCounts {
602         Vector<GC3Dint> filteredToActualAttributeIndexMap;
603         Vector<GC3Dint> filteredToActualUniformIndexMap;
604
605         ActiveShaderSymbolCounts()
606         {
607         }
608
609         GC3Dint countForType(GC3Denum activeType)
610         {
611             ASSERT(activeType == ACTIVE_ATTRIBUTES || activeType == ACTIVE_UNIFORMS);
612             if (activeType == ACTIVE_ATTRIBUTES)
613                 return filteredToActualAttributeIndexMap.size();
614
615             return filteredToActualUniformIndexMap.size();
616         }
617     };
618     typedef HashMap<Platform3DObject, ActiveShaderSymbolCounts> ShaderProgramSymbolCountMap;
619     ShaderProgramSymbolCountMap m_shaderProgramSymbolCountMap;
620
621     typedef HashMap<String, String> HashedSymbolMap;
622     HashedSymbolMap m_possiblyUnusedAttributeMap;
623
624     String mappedSymbolName(Platform3DObject program, ANGLEShaderSymbolType, const String& name);
625     String mappedSymbolName(Platform3DObject shaders[2], size_t count, const String& name);
626     String originalSymbolName(Platform3DObject program, ANGLEShaderSymbolType, const String& name);
627     Optional<String> mappedSymbolInShaderSourceMap(Platform3DObject shader, ANGLEShaderSymbolType, const String& name);
628     Optional<String> originalSymbolInShaderSourceMap(Platform3DObject shader, ANGLEShaderSymbolType, const String& name);
629
630     std::unique_ptr<ShaderNameHash> nameHashMapForShaders;
631 #endif // !USE(ANGLE)
632
633 #if USE(ANGLE)
634     friend class Extensions3DANGLE;
635     std::unique_ptr<Extensions3DANGLE> m_extensions;
636 #elif !PLATFORM(COCOA) && USE(OPENGL_ES)
637     friend class Extensions3DOpenGLES;
638     friend class Extensions3DOpenGLCommon;
639     std::unique_ptr<Extensions3DOpenGLES> m_extensions;
640 #elif USE(OPENGL) || (PLATFORM(COCOA) && USE(OPENGL_ES))
641     friend class Extensions3DOpenGL;
642     friend class Extensions3DOpenGLCommon;
643     std::unique_ptr<Extensions3DOpenGL> m_extensions;
644 #endif
645
646     GraphicsContext3DPowerPreference m_powerPreferenceUsedForCreation { GraphicsContext3DPowerPreference::Default };
647     Vector<Vector<float>> m_vertexArray;
648
649 #if !USE(ANGLE)
650     ANGLEWebKitBridge m_compiler;
651 #endif
652
653     GC3Duint m_texture { 0 };
654     GC3Duint m_fbo { 0 };
655 #if USE(COORDINATED_GRAPHICS)
656     GC3Duint m_compositorTexture { 0 };
657     GC3Duint m_intermediateTexture { 0 };
658 #endif
659
660     GC3Duint m_depthBuffer { 0 };
661     GC3Duint m_stencilBuffer { 0 };
662     GC3Duint m_depthStencilBuffer { 0 };
663
664     bool m_layerComposited { false };
665     GC3Duint m_internalColorFormat { 0 };
666
667 #if USE(ANGLE) && PLATFORM(COCOA)
668     PlatformGraphicsContext3DSurface m_pbuffer;
669 #endif
670
671     struct GraphicsContext3DState {
672         GC3Duint boundFBO { 0 };
673         GC3Denum activeTextureUnit { GraphicsContext3D::TEXTURE0 };
674
675         using BoundTextureMap = HashMap<GC3Denum,
676             std::pair<GC3Duint, GC3Denum>,
677             WTF::IntHash<GC3Denum>, 
678             WTF::UnsignedWithZeroKeyHashTraits<GC3Duint>,
679             WTF::PairHashTraits<WTF::UnsignedWithZeroKeyHashTraits<GC3Duint>, WTF::UnsignedWithZeroKeyHashTraits<GC3Duint>>
680         >;
681         BoundTextureMap boundTextureMap;
682         GC3Duint currentBoundTexture() const { return boundTexture(activeTextureUnit); }
683         GC3Duint boundTexture(GC3Denum textureUnit) const
684         {
685             auto iterator = boundTextureMap.find(textureUnit);
686             if (iterator != boundTextureMap.end())
687                 return iterator->value.first;
688             return 0;
689         }
690
691         GC3Duint currentBoundTarget() const { return boundTarget(activeTextureUnit); }
692         GC3Denum boundTarget(GC3Denum textureUnit) const
693         {
694             auto iterator = boundTextureMap.find(textureUnit);
695             if (iterator != boundTextureMap.end())
696                 return iterator->value.second;
697             return 0;
698         }
699
700         void setBoundTexture(GC3Denum textureUnit, GC3Duint texture, GC3Denum target)
701         {
702             boundTextureMap.set(textureUnit, std::make_pair(texture, target));
703         }
704
705         using TextureSeedCount = HashCountedSet<GC3Duint, WTF::IntHash<GC3Duint>, WTF::UnsignedWithZeroKeyHashTraits<GC3Duint>>;
706         TextureSeedCount textureSeedCount;
707     };
708
709     GraphicsContext3DState m_state;
710
711     // For multisampling
712     GC3Duint m_multisampleFBO { 0 };
713     GC3Duint m_multisampleDepthStencilBuffer { 0 };
714     GC3Duint m_multisampleColorBuffer { 0 };
715
716     // Errors raised by synthesizeGLError().
717     ListHashSet<GC3Denum> m_syntheticErrors;
718
719 #if USE(NICOSIA) && USE(TEXTURE_MAPPER)
720     friend class Nicosia::GC3DLayer;
721     std::unique_ptr<Nicosia::GC3DLayer> m_nicosiaLayer;
722 #elif USE(TEXTURE_MAPPER)
723     friend class TextureMapperGC3DPlatformLayer;
724     std::unique_ptr<TextureMapperGC3DPlatformLayer> m_texmapLayer;
725 #else
726     friend class GraphicsContext3DPrivate;
727     std::unique_ptr<GraphicsContext3DPrivate> m_private;
728 #endif
729
730     HashSet<Client*> m_clients;
731
732     bool m_isForWebGL2 { false };
733     bool m_usingCoreProfile { false };
734
735     unsigned m_statusCheckCount { 0 };
736     bool m_failNextStatusCheck { false };
737
738 #if USE(CAIRO)
739     Platform3DObject m_vao { 0 };
740 #endif
741
742 #if PLATFORM(COCOA) && (USE(OPENGL) || USE(ANGLE))
743     bool m_hasSwitchedToHighPerformanceGPU { false };
744 #endif
745 };
746
747 } // namespace WebCore
748
749 #endif