1/*
2 * Copyright (C) 2009 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 COMPUTER, 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 COMPUTER, 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#ifndef GraphicsContext3D_h
27#define GraphicsContext3D_h
28
29#include "core/platform/graphics/Extensions3D.h"
30#include "core/platform/graphics/GraphicsTypes3D.h"
31#include "core/platform/graphics/Image.h"
32#include "core/platform/graphics/IntRect.h"
33#include "third_party/skia/include/core/SkBitmap.h"
34#include "weborigin/KURL.h"
35#include "wtf/HashMap.h"
36#include "wtf/HashSet.h"
37#include "wtf/ListHashSet.h"
38#include "wtf/Noncopyable.h"
39#include "wtf/OwnArrayPtr.h"
40#include "wtf/OwnPtr.h"
41#include "wtf/PassOwnArrayPtr.h"
42#include "wtf/RefCounted.h"
43#include "wtf/text/WTFString.h"
44
45// FIXME: Find a better way to avoid the name confliction for NO_ERROR.
46#if OS(WINDOWS)
47#undef NO_ERROR
48#endif
49
50class GrContext;
51
52namespace WebKit {
53class WebGraphicsContext3D;
54class WebGraphicsContext3DProvider;
55}
56
57namespace WebCore {
58class DrawingBuffer;
59class Extensions3D;
60class GraphicsContext3DContextLostCallbackAdapter;
61class GraphicsContext3DErrorMessageCallbackAdapter;
62class GrMemoryAllocationChangedCallbackAdapter;
63class Image;
64class ImageBuffer;
65class ImageData;
66class IntRect;
67class IntSize;
68
69struct ActiveInfo {
70    String name;
71    GC3Denum type;
72    GC3Dint size;
73};
74
75class GraphicsContext3D : public RefCounted<GraphicsContext3D> {
76public:
77    enum {
78        DEPTH_BUFFER_BIT = 0x00000100,
79        STENCIL_BUFFER_BIT = 0x00000400,
80        COLOR_BUFFER_BIT = 0x00004000,
81        POINTS = 0x0000,
82        LINES = 0x0001,
83        LINE_LOOP = 0x0002,
84        LINE_STRIP = 0x0003,
85        TRIANGLES = 0x0004,
86        TRIANGLE_STRIP = 0x0005,
87        TRIANGLE_FAN = 0x0006,
88        ZERO = 0,
89        ONE = 1,
90        SRC_COLOR = 0x0300,
91        ONE_MINUS_SRC_COLOR = 0x0301,
92        SRC_ALPHA = 0x0302,
93        ONE_MINUS_SRC_ALPHA = 0x0303,
94        DST_ALPHA = 0x0304,
95        ONE_MINUS_DST_ALPHA = 0x0305,
96        DST_COLOR = 0x0306,
97        ONE_MINUS_DST_COLOR = 0x0307,
98        SRC_ALPHA_SATURATE = 0x0308,
99        FUNC_ADD = 0x8006,
100        BLEND_EQUATION = 0x8009,
101        BLEND_EQUATION_RGB = 0x8009,
102        BLEND_EQUATION_ALPHA = 0x883D,
103        FUNC_SUBTRACT = 0x800A,
104        FUNC_REVERSE_SUBTRACT = 0x800B,
105        BLEND_DST_RGB = 0x80C8,
106        BLEND_SRC_RGB = 0x80C9,
107        BLEND_DST_ALPHA = 0x80CA,
108        BLEND_SRC_ALPHA = 0x80CB,
109        CONSTANT_COLOR = 0x8001,
110        ONE_MINUS_CONSTANT_COLOR = 0x8002,
111        CONSTANT_ALPHA = 0x8003,
112        ONE_MINUS_CONSTANT_ALPHA = 0x8004,
113        BLEND_COLOR = 0x8005,
114        ARRAY_BUFFER = 0x8892,
115        ELEMENT_ARRAY_BUFFER = 0x8893,
116        ARRAY_BUFFER_BINDING = 0x8894,
117        ELEMENT_ARRAY_BUFFER_BINDING = 0x8895,
118        STREAM_DRAW = 0x88E0,
119        STATIC_DRAW = 0x88E4,
120        DYNAMIC_DRAW = 0x88E8,
121        BUFFER_SIZE = 0x8764,
122        BUFFER_USAGE = 0x8765,
123        CURRENT_VERTEX_ATTRIB = 0x8626,
124        FRONT = 0x0404,
125        BACK = 0x0405,
126        FRONT_AND_BACK = 0x0408,
127        TEXTURE_2D = 0x0DE1,
128        CULL_FACE = 0x0B44,
129        BLEND = 0x0BE2,
130        DITHER = 0x0BD0,
131        STENCIL_TEST = 0x0B90,
132        DEPTH_TEST = 0x0B71,
133        SCISSOR_TEST = 0x0C11,
134        POLYGON_OFFSET_FILL = 0x8037,
135        SAMPLE_ALPHA_TO_COVERAGE = 0x809E,
136        SAMPLE_COVERAGE = 0x80A0,
137        NO_ERROR = 0,
138        INVALID_ENUM = 0x0500,
139        INVALID_VALUE = 0x0501,
140        INVALID_OPERATION = 0x0502,
141        OUT_OF_MEMORY = 0x0505,
142        CW = 0x0900,
143        CCW = 0x0901,
144        LINE_WIDTH = 0x0B21,
145        ALIASED_POINT_SIZE_RANGE = 0x846D,
146        ALIASED_LINE_WIDTH_RANGE = 0x846E,
147        CULL_FACE_MODE = 0x0B45,
148        FRONT_FACE = 0x0B46,
149        DEPTH_RANGE = 0x0B70,
150        DEPTH_WRITEMASK = 0x0B72,
151        DEPTH_CLEAR_VALUE = 0x0B73,
152        DEPTH_FUNC = 0x0B74,
153        STENCIL_CLEAR_VALUE = 0x0B91,
154        STENCIL_FUNC = 0x0B92,
155        STENCIL_FAIL = 0x0B94,
156        STENCIL_PASS_DEPTH_FAIL = 0x0B95,
157        STENCIL_PASS_DEPTH_PASS = 0x0B96,
158        STENCIL_REF = 0x0B97,
159        STENCIL_VALUE_MASK = 0x0B93,
160        STENCIL_WRITEMASK = 0x0B98,
161        STENCIL_BACK_FUNC = 0x8800,
162        STENCIL_BACK_FAIL = 0x8801,
163        STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802,
164        STENCIL_BACK_PASS_DEPTH_PASS = 0x8803,
165        STENCIL_BACK_REF = 0x8CA3,
166        STENCIL_BACK_VALUE_MASK = 0x8CA4,
167        STENCIL_BACK_WRITEMASK = 0x8CA5,
168        VIEWPORT = 0x0BA2,
169        SCISSOR_BOX = 0x0C10,
170        COLOR_CLEAR_VALUE = 0x0C22,
171        COLOR_WRITEMASK = 0x0C23,
172        UNPACK_ALIGNMENT = 0x0CF5,
173        PACK_ALIGNMENT = 0x0D05,
174        MAX_TEXTURE_SIZE = 0x0D33,
175        MAX_VIEWPORT_DIMS = 0x0D3A,
176        SUBPIXEL_BITS = 0x0D50,
177        RED_BITS = 0x0D52,
178        GREEN_BITS = 0x0D53,
179        BLUE_BITS = 0x0D54,
180        ALPHA_BITS = 0x0D55,
181        DEPTH_BITS = 0x0D56,
182        STENCIL_BITS = 0x0D57,
183        POLYGON_OFFSET_UNITS = 0x2A00,
184        POLYGON_OFFSET_FACTOR = 0x8038,
185        TEXTURE_BINDING_2D = 0x8069,
186        SAMPLE_BUFFERS = 0x80A8,
187        SAMPLES = 0x80A9,
188        SAMPLE_COVERAGE_VALUE = 0x80AA,
189        SAMPLE_COVERAGE_INVERT = 0x80AB,
190        NUM_COMPRESSED_TEXTURE_FORMATS = 0x86A2,
191        COMPRESSED_TEXTURE_FORMATS = 0x86A3,
192        DONT_CARE = 0x1100,
193        FASTEST = 0x1101,
194        NICEST = 0x1102,
195        GENERATE_MIPMAP_HINT = 0x8192,
196        BYTE = 0x1400,
197        UNSIGNED_BYTE = 0x1401,
198        SHORT = 0x1402,
199        UNSIGNED_SHORT = 0x1403,
200        INT = 0x1404,
201        UNSIGNED_INT = 0x1405,
202        FLOAT = 0x1406,
203        HALF_FLOAT_OES = 0x8D61,
204        FIXED = 0x140C,
205        DEPTH_COMPONENT = 0x1902,
206        ALPHA = 0x1906,
207        RGB = 0x1907,
208        RGBA = 0x1908,
209        BGRA = 0x80E1,
210        LUMINANCE = 0x1909,
211        LUMINANCE_ALPHA = 0x190A,
212        UNSIGNED_SHORT_4_4_4_4 = 0x8033,
213        UNSIGNED_SHORT_5_5_5_1 = 0x8034,
214        UNSIGNED_SHORT_5_6_5 = 0x8363,
215        FRAGMENT_SHADER = 0x8B30,
216        VERTEX_SHADER = 0x8B31,
217        MAX_VERTEX_ATTRIBS = 0x8869,
218        MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB,
219        MAX_VARYING_VECTORS = 0x8DFC,
220        MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D,
221        MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C,
222        MAX_TEXTURE_IMAGE_UNITS = 0x8872,
223        MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD,
224        SHADER_TYPE = 0x8B4F,
225        DELETE_STATUS = 0x8B80,
226        LINK_STATUS = 0x8B82,
227        VALIDATE_STATUS = 0x8B83,
228        ATTACHED_SHADERS = 0x8B85,
229        ACTIVE_UNIFORMS = 0x8B86,
230        ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
231        ACTIVE_ATTRIBUTES = 0x8B89,
232        ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
233        SHADING_LANGUAGE_VERSION = 0x8B8C,
234        CURRENT_PROGRAM = 0x8B8D,
235        NEVER = 0x0200,
236        LESS = 0x0201,
237        EQUAL = 0x0202,
238        LEQUAL = 0x0203,
239        GREATER = 0x0204,
240        NOTEQUAL = 0x0205,
241        GEQUAL = 0x0206,
242        ALWAYS = 0x0207,
243        KEEP = 0x1E00,
244        REPLACE = 0x1E01,
245        INCR = 0x1E02,
246        DECR = 0x1E03,
247        INVERT = 0x150A,
248        INCR_WRAP = 0x8507,
249        DECR_WRAP = 0x8508,
250        VENDOR = 0x1F00,
251        RENDERER = 0x1F01,
252        VERSION = 0x1F02,
253        EXTENSIONS = 0x1F03,
254        NEAREST = 0x2600,
255        LINEAR = 0x2601,
256        NEAREST_MIPMAP_NEAREST = 0x2700,
257        LINEAR_MIPMAP_NEAREST = 0x2701,
258        NEAREST_MIPMAP_LINEAR = 0x2702,
259        LINEAR_MIPMAP_LINEAR = 0x2703,
260        TEXTURE_MAG_FILTER = 0x2800,
261        TEXTURE_MIN_FILTER = 0x2801,
262        TEXTURE_WRAP_S = 0x2802,
263        TEXTURE_WRAP_T = 0x2803,
264        TEXTURE = 0x1702,
265        TEXTURE_CUBE_MAP = 0x8513,
266        TEXTURE_BINDING_CUBE_MAP = 0x8514,
267        TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515,
268        TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516,
269        TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517,
270        TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518,
271        TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519,
272        TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A,
273        MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C,
274        TEXTURE0 = 0x84C0,
275        TEXTURE1 = 0x84C1,
276        TEXTURE2 = 0x84C2,
277        TEXTURE3 = 0x84C3,
278        TEXTURE4 = 0x84C4,
279        TEXTURE5 = 0x84C5,
280        TEXTURE6 = 0x84C6,
281        TEXTURE7 = 0x84C7,
282        TEXTURE8 = 0x84C8,
283        TEXTURE9 = 0x84C9,
284        TEXTURE10 = 0x84CA,
285        TEXTURE11 = 0x84CB,
286        TEXTURE12 = 0x84CC,
287        TEXTURE13 = 0x84CD,
288        TEXTURE14 = 0x84CE,
289        TEXTURE15 = 0x84CF,
290        TEXTURE16 = 0x84D0,
291        TEXTURE17 = 0x84D1,
292        TEXTURE18 = 0x84D2,
293        TEXTURE19 = 0x84D3,
294        TEXTURE20 = 0x84D4,
295        TEXTURE21 = 0x84D5,
296        TEXTURE22 = 0x84D6,
297        TEXTURE23 = 0x84D7,
298        TEXTURE24 = 0x84D8,
299        TEXTURE25 = 0x84D9,
300        TEXTURE26 = 0x84DA,
301        TEXTURE27 = 0x84DB,
302        TEXTURE28 = 0x84DC,
303        TEXTURE29 = 0x84DD,
304        TEXTURE30 = 0x84DE,
305        TEXTURE31 = 0x84DF,
306        ACTIVE_TEXTURE = 0x84E0,
307        REPEAT = 0x2901,
308        CLAMP_TO_EDGE = 0x812F,
309        MIRRORED_REPEAT = 0x8370,
310        FLOAT_VEC2 = 0x8B50,
311        FLOAT_VEC3 = 0x8B51,
312        FLOAT_VEC4 = 0x8B52,
313        INT_VEC2 = 0x8B53,
314        INT_VEC3 = 0x8B54,
315        INT_VEC4 = 0x8B55,
316        BOOL = 0x8B56,
317        BOOL_VEC2 = 0x8B57,
318        BOOL_VEC3 = 0x8B58,
319        BOOL_VEC4 = 0x8B59,
320        FLOAT_MAT2 = 0x8B5A,
321        FLOAT_MAT3 = 0x8B5B,
322        FLOAT_MAT4 = 0x8B5C,
323        SAMPLER_2D = 0x8B5E,
324        SAMPLER_CUBE = 0x8B60,
325        VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622,
326        VERTEX_ATTRIB_ARRAY_SIZE = 0x8623,
327        VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624,
328        VERTEX_ATTRIB_ARRAY_TYPE = 0x8625,
329        VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A,
330        VERTEX_ATTRIB_ARRAY_POINTER = 0x8645,
331        VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F,
332        COMPILE_STATUS = 0x8B81,
333        INFO_LOG_LENGTH = 0x8B84,
334        SHADER_SOURCE_LENGTH = 0x8B88,
335        SHADER_COMPILER = 0x8DFA,
336        SHADER_BINARY_FORMATS = 0x8DF8,
337        NUM_SHADER_BINARY_FORMATS = 0x8DF9,
338        LOW_FLOAT = 0x8DF0,
339        MEDIUM_FLOAT = 0x8DF1,
340        HIGH_FLOAT = 0x8DF2,
341        LOW_INT = 0x8DF3,
342        MEDIUM_INT = 0x8DF4,
343        HIGH_INT = 0x8DF5,
344        FRAMEBUFFER = 0x8D40,
345        RENDERBUFFER = 0x8D41,
346        RGBA4 = 0x8056,
347        RGB5_A1 = 0x8057,
348        RGB565 = 0x8D62,
349        DEPTH_COMPONENT16 = 0x81A5,
350        STENCIL_INDEX = 0x1901,
351        STENCIL_INDEX8 = 0x8D48,
352        DEPTH_STENCIL = 0x84F9,
353        UNSIGNED_INT_24_8 = 0x84FA,
354        DEPTH24_STENCIL8 = 0x88F0,
355        RENDERBUFFER_WIDTH = 0x8D42,
356        RENDERBUFFER_HEIGHT = 0x8D43,
357        RENDERBUFFER_INTERNAL_FORMAT = 0x8D44,
358        RENDERBUFFER_RED_SIZE = 0x8D50,
359        RENDERBUFFER_GREEN_SIZE = 0x8D51,
360        RENDERBUFFER_BLUE_SIZE = 0x8D52,
361        RENDERBUFFER_ALPHA_SIZE = 0x8D53,
362        RENDERBUFFER_DEPTH_SIZE = 0x8D54,
363        RENDERBUFFER_STENCIL_SIZE = 0x8D55,
364        FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0,
365        FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1,
366        FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2,
367        FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3,
368        COLOR_ATTACHMENT0 = 0x8CE0,
369        DEPTH_ATTACHMENT = 0x8D00,
370        STENCIL_ATTACHMENT = 0x8D20,
371        DEPTH_STENCIL_ATTACHMENT = 0x821A,
372        NONE = 0,
373        FRAMEBUFFER_COMPLETE = 0x8CD5,
374        FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6,
375        FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7,
376        FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9,
377        FRAMEBUFFER_UNSUPPORTED = 0x8CDD,
378        FRAMEBUFFER_BINDING = 0x8CA6,
379        RENDERBUFFER_BINDING = 0x8CA7,
380        MAX_RENDERBUFFER_SIZE = 0x84E8,
381        INVALID_FRAMEBUFFER_OPERATION = 0x0506,
382
383        // WebGL-specific enums
384        UNPACK_FLIP_Y_WEBGL = 0x9240,
385        UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241,
386        CONTEXT_LOST_WEBGL = 0x9242,
387        UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243,
388        BROWSER_DEFAULT_WEBGL = 0x9244
389    };
390
391    // Context creation attributes.
392    struct Attributes {
393        Attributes()
394            : alpha(true)
395            , depth(true)
396            , stencil(false)
397            , antialias(true)
398            , premultipliedAlpha(true)
399            , preserveDrawingBuffer(false)
400            , noExtensions(false)
401            , shareResources(true)
402            , preferDiscreteGPU(false)
403        {
404        }
405
406        bool alpha;
407        bool depth;
408        bool stencil;
409        bool antialias;
410        bool premultipliedAlpha;
411        bool preserveDrawingBuffer;
412        bool noExtensions;
413        bool shareResources;
414        bool preferDiscreteGPU;
415        KURL topDocumentURL;
416    };
417
418    class ContextLostCallback {
419    public:
420        virtual void onContextLost() = 0;
421        virtual ~ContextLostCallback() {}
422    };
423
424    class ErrorMessageCallback {
425    public:
426        virtual void onErrorMessage(const String& message, GC3Dint id) = 0;
427        virtual ~ErrorMessageCallback() { }
428    };
429
430    void setContextLostCallback(PassOwnPtr<ContextLostCallback>);
431    void setErrorMessageCallback(PassOwnPtr<ErrorMessageCallback>);
432
433    static PassRefPtr<GraphicsContext3D> create(Attributes);
434
435    // Callers must make the context current before using it AND check that the context was created successfully
436    // via ContextLost before using the context in any way. Once made current on a thread, the context cannot
437    // be used on any other thread.
438    static PassRefPtr<GraphicsContext3D> createGraphicsContextFromWebContext(PassOwnPtr<WebKit::WebGraphicsContext3D>, bool preserveDrawingBuffer = false);
439    static PassRefPtr<GraphicsContext3D> createGraphicsContextFromProvider(PassOwnPtr<WebKit::WebGraphicsContext3DProvider>, bool preserveDrawingBuffer = false);
440
441    ~GraphicsContext3D();
442
443    GrContext* grContext();
444    WebKit::WebGraphicsContext3D* webContext() const { return m_impl; }
445
446    bool makeContextCurrent();
447
448    // Helper to texImage2D with pixel==0 case: pixels are initialized to 0.
449    // Return true if no GL error is synthesized.
450    // By default, alignment is 4, the OpenGL default setting.
451    bool texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint alignment = 4);
452
453    //----------------------------------------------------------------------
454    // Helpers for texture uploading and pixel readback.
455    //
456
457    // Computes the components per pixel and bytes per component
458    // for the given format and type combination. Returns false if
459    // either was an invalid enum.
460    static bool computeFormatAndTypeParameters(GC3Denum format,
461                                               GC3Denum type,
462                                               unsigned int* componentsPerPixel,
463                                               unsigned int* bytesPerComponent);
464
465    // Computes the image size in bytes. If paddingInBytes is not null, padding
466    // is also calculated in return. Returns NO_ERROR if succeed, otherwise
467    // return the suggested GL error indicating the cause of the failure:
468    //   INVALID_VALUE if width/height is negative or overflow happens.
469    //   INVALID_ENUM if format/type is illegal.
470    static GC3Denum computeImageSizeInBytes(GC3Denum format,
471                                     GC3Denum type,
472                                     GC3Dsizei width,
473                                     GC3Dsizei height,
474                                     GC3Dint alignment,
475                                     unsigned int* imageSizeInBytes,
476                                     unsigned int* paddingInBytes);
477
478    // Attempt to enumerate all possible native image formats to
479    // reduce the amount of temporary allocations during texture
480    // uploading. This enum must be public because it is accessed
481    // by non-member functions.
482    enum DataFormat {
483        DataFormatRGBA8 = 0,
484        DataFormatRGBA16F,
485        DataFormatRGBA32F,
486        DataFormatRGB8,
487        DataFormatRGB16F,
488        DataFormatRGB32F,
489        DataFormatBGR8,
490        DataFormatBGRA8,
491        DataFormatARGB8,
492        DataFormatABGR8,
493        DataFormatRGBA5551,
494        DataFormatRGBA4444,
495        DataFormatRGB565,
496        DataFormatR8,
497        DataFormatR16F,
498        DataFormatR32F,
499        DataFormatRA8,
500        DataFormatRA16F,
501        DataFormatRA32F,
502        DataFormatAR8,
503        DataFormatA8,
504        DataFormatA16F,
505        DataFormatA32F,
506        DataFormatNumFormats
507    };
508
509    // Check if the format is one of the formats from the ImageData or DOM elements.
510    // The formats from ImageData is always RGBA8.
511    // The formats from DOM elements vary with Graphics ports. It can only be RGBA8 or BGRA8.
512    static ALWAYS_INLINE bool srcFormatComeFromDOMElementOrImageData(DataFormat SrcFormat)
513    {
514    return SrcFormat == DataFormatBGRA8 || SrcFormat == DataFormatRGBA8;
515    }
516
517    //----------------------------------------------------------------------
518    // Entry points for WebGL.
519    //
520
521    void activeTexture(GC3Denum texture);
522    void attachShader(Platform3DObject program, Platform3DObject shader);
523    void bindAttribLocation(Platform3DObject, GC3Duint index, const String& name);
524    void bindBuffer(GC3Denum target, Platform3DObject);
525    void bindFramebuffer(GC3Denum target, Platform3DObject);
526    void bindRenderbuffer(GC3Denum target, Platform3DObject);
527    void bindTexture(GC3Denum target, Platform3DObject);
528    void blendColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha);
529    void blendEquation(GC3Denum mode);
530    void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha);
531    void blendFunc(GC3Denum sfactor, GC3Denum dfactor);
532    void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha);
533
534    void bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage);
535    void bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage);
536    void bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data);
537
538    GC3Denum checkFramebufferStatus(GC3Denum target);
539    void clear(GC3Dbitfield mask);
540    void clearColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha);
541    void clearDepth(GC3Dclampf depth);
542    void clearStencil(GC3Dint s);
543    void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha);
544    void compileShader(Platform3DObject);
545
546    void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Dsizei imageSize, const void* data);
547    void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Dsizei imageSize, const void* data);
548    void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
549    void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
550    void cullFace(GC3Denum mode);
551    void depthFunc(GC3Denum func);
552    void depthMask(GC3Dboolean flag);
553    void depthRange(GC3Dclampf zNear, GC3Dclampf zFar);
554    void detachShader(Platform3DObject, Platform3DObject);
555    void disable(GC3Denum cap);
556    void disableVertexAttribArray(GC3Duint index);
557    void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count);
558    void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset);
559
560    void enable(GC3Denum cap);
561    void enableVertexAttribArray(GC3Duint index);
562    void finish();
563    void flush();
564    void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, Platform3DObject);
565    void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, Platform3DObject, GC3Dint level);
566    void frontFace(GC3Denum mode);
567    void generateMipmap(GC3Denum target);
568
569    bool getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo&);
570    bool getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo&);
571    void getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount, GC3Dsizei* count, Platform3DObject* shaders);
572    GC3Dint getAttribLocation(Platform3DObject, const String& name);
573    void getBooleanv(GC3Denum pname, GC3Dboolean* value);
574    void getBufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value);
575    Attributes getContextAttributes();
576    GC3Denum getError();
577    void getFloatv(GC3Denum pname, GC3Dfloat* value);
578    void getFramebufferAttachmentParameteriv(GC3Denum target, GC3Denum attachment, GC3Denum pname, GC3Dint* value);
579    void getIntegerv(GC3Denum pname, GC3Dint* value);
580    void getProgramiv(Platform3DObject program, GC3Denum pname, GC3Dint* value);
581    String getProgramInfoLog(Platform3DObject);
582    void getRenderbufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value);
583    void getShaderiv(Platform3DObject, GC3Denum pname, GC3Dint* value);
584    String getShaderInfoLog(Platform3DObject);
585    void getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType, GC3Dint* range, GC3Dint* precision);
586    String getShaderSource(Platform3DObject);
587    String getString(GC3Denum name);
588    void getTexParameterfv(GC3Denum target, GC3Denum pname, GC3Dfloat* value);
589    void getTexParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value);
590    void getUniformfv(Platform3DObject program, GC3Dint location, GC3Dfloat* value);
591    void getUniformiv(Platform3DObject program, GC3Dint location, GC3Dint* value);
592    GC3Dint getUniformLocation(Platform3DObject, const String& name);
593    void getVertexAttribfv(GC3Duint index, GC3Denum pname, GC3Dfloat* value);
594    void getVertexAttribiv(GC3Duint index, GC3Denum pname, GC3Dint* value);
595    GC3Dsizeiptr getVertexAttribOffset(GC3Duint index, GC3Denum pname);
596
597    void hint(GC3Denum target, GC3Denum mode);
598    GC3Dboolean isBuffer(Platform3DObject);
599    GC3Dboolean isEnabled(GC3Denum cap);
600    GC3Dboolean isFramebuffer(Platform3DObject);
601    GC3Dboolean isProgram(Platform3DObject);
602    GC3Dboolean isRenderbuffer(Platform3DObject);
603    GC3Dboolean isShader(Platform3DObject);
604    GC3Dboolean isTexture(Platform3DObject);
605    void lineWidth(GC3Dfloat);
606    void linkProgram(Platform3DObject);
607    void pixelStorei(GC3Denum pname, GC3Dint param);
608    void polygonOffset(GC3Dfloat factor, GC3Dfloat units);
609
610    void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data);
611
612    void releaseShaderCompiler();
613
614    void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
615    void sampleCoverage(GC3Dclampf value, GC3Dboolean invert);
616    void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
617    void shaderSource(Platform3DObject, const String& string);
618    void stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask);
619    void stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask);
620    void stencilMask(GC3Duint mask);
621    void stencilMaskSeparate(GC3Denum face, GC3Duint mask);
622    void stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
623    void stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
624
625    void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels);
626    void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param);
627    void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param);
628    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels);
629
630    void uniform1f(GC3Dint location, GC3Dfloat x);
631    void uniform1fv(GC3Dint location, GC3Dsizei, GC3Dfloat* v);
632    void uniform1i(GC3Dint location, GC3Dint x);
633    void uniform1iv(GC3Dint location, GC3Dsizei, GC3Dint* v);
634    void uniform2f(GC3Dint location, GC3Dfloat x, GC3Dfloat y);
635    void uniform2fv(GC3Dint location, GC3Dsizei, GC3Dfloat* v);
636    void uniform2i(GC3Dint location, GC3Dint x, GC3Dint y);
637    void uniform2iv(GC3Dint location, GC3Dsizei, GC3Dint* v);
638    void uniform3f(GC3Dint location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
639    void uniform3fv(GC3Dint location, GC3Dsizei, GC3Dfloat* v);
640    void uniform3i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z);
641    void uniform3iv(GC3Dint location, GC3Dsizei, GC3Dint* v);
642    void uniform4f(GC3Dint location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
643    void uniform4fv(GC3Dint location, GC3Dsizei, GC3Dfloat* v);
644    void uniform4i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w);
645    void uniform4iv(GC3Dint location, GC3Dsizei, GC3Dint* v);
646    void uniformMatrix2fv(GC3Dint location, GC3Dsizei, GC3Dboolean transpose, GC3Dfloat* value);
647    void uniformMatrix3fv(GC3Dint location, GC3Dsizei, GC3Dboolean transpose, GC3Dfloat* value);
648    void uniformMatrix4fv(GC3Dint location, GC3Dsizei, GC3Dboolean transpose, GC3Dfloat* value);
649
650    void useProgram(Platform3DObject);
651    void validateProgram(Platform3DObject);
652
653    void vertexAttrib1f(GC3Duint index, GC3Dfloat x);
654    void vertexAttrib1fv(GC3Duint index, GC3Dfloat* values);
655    void vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y);
656    void vertexAttrib2fv(GC3Duint index, GC3Dfloat* values);
657    void vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
658    void vertexAttrib3fv(GC3Duint index, GC3Dfloat* values);
659    void vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
660    void vertexAttrib4fv(GC3Duint index, GC3Dfloat* values);
661    void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized,
662                             GC3Dsizei stride, GC3Dintptr offset);
663
664    void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
665
666    void reshape(int width, int height);
667
668    void markContextChanged();
669    void markLayerComposited();
670    bool layerComposited() const;
671
672    void paintRenderingResultsToCanvas(ImageBuffer*, DrawingBuffer*);
673    PassRefPtr<ImageData> paintRenderingResultsToImageData(DrawingBuffer*);
674
675    // Support for buffer creation and deletion
676    Platform3DObject createBuffer();
677    Platform3DObject createFramebuffer();
678    Platform3DObject createProgram();
679    Platform3DObject createRenderbuffer();
680    Platform3DObject createShader(GC3Denum);
681    Platform3DObject createTexture();
682
683    void deleteBuffer(Platform3DObject);
684    void deleteFramebuffer(Platform3DObject);
685    void deleteProgram(Platform3DObject);
686    void deleteRenderbuffer(Platform3DObject);
687    void deleteShader(Platform3DObject);
688    void deleteTexture(Platform3DObject);
689
690    // Synthesizes an OpenGL error which will be returned from a
691    // later call to getError. This is used to emulate OpenGL ES
692    // 2.0 behavior on the desktop and to enforce additional error
693    // checking mandated by WebGL.
694    //
695    // Per the behavior of glGetError, this stores at most one
696    // instance of any given error, and returns them from calls to
697    // getError in the order they were added.
698    void synthesizeGLError(GC3Denum error);
699
700    // Support for extensions. Returns a non-null object, though not
701    // all methods it contains may necessarily be supported on the
702    // current hardware. Must call Extensions3D::supports() to
703    // determine this.
704    Extensions3D* getExtensions();
705
706    static unsigned getClearBitsByFormat(GC3Denum);
707
708    enum ChannelBits {
709        ChannelRed = 1,
710        ChannelGreen = 2,
711        ChannelBlue = 4,
712        ChannelAlpha = 8,
713        ChannelDepth = 16,
714        ChannelStencil = 32,
715        ChannelRGB = ChannelRed | ChannelGreen | ChannelBlue,
716        ChannelRGBA = ChannelRGB | ChannelAlpha,
717    };
718
719    static unsigned getChannelBitsByFormat(GC3Denum);
720
721    // Possible alpha operations that may need to occur during
722    // pixel packing. FIXME: kAlphaDoUnmultiply is lossy and must
723    // be removed.
724    enum AlphaOp {
725        AlphaDoNothing = 0,
726        AlphaDoPremultiply = 1,
727        AlphaDoUnmultiply = 2
728    };
729
730    enum ImageHtmlDomSource {
731        HtmlDomImage = 0,
732        HtmlDomCanvas = 1,
733        HtmlDomVideo = 2,
734        HtmlDomNone = 3
735    };
736
737    class ImageExtractor {
738    public:
739        ImageExtractor(Image*, ImageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
740
741        ~ImageExtractor();
742
743        bool extractSucceeded() { return m_extractSucceeded; }
744        const void* imagePixelData() { return m_imagePixelData; }
745        unsigned imageWidth() { return m_imageWidth; }
746        unsigned imageHeight() { return m_imageHeight; }
747        DataFormat imageSourceFormat() { return m_imageSourceFormat; }
748        AlphaOp imageAlphaOp() { return m_alphaOp; }
749        unsigned imageSourceUnpackAlignment() { return m_imageSourceUnpackAlignment; }
750        ImageHtmlDomSource imageHtmlDomSource() { return m_imageHtmlDomSource; }
751    private:
752        // Extract the image and keeps track of its status, such as width, height, Source Alignment, format and AlphaOp etc.
753        // This needs to lock the resources or relevant data if needed and return true upon success
754        bool extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
755
756        RefPtr<NativeImageSkia> m_nativeImage;
757        RefPtr<NativeImageSkia> m_skiaImage;
758        Image* m_image;
759        ImageHtmlDomSource m_imageHtmlDomSource;
760        bool m_extractSucceeded;
761        const void* m_imagePixelData;
762        unsigned m_imageWidth;
763        unsigned m_imageHeight;
764        DataFormat m_imageSourceFormat;
765        AlphaOp m_alphaOp;
766        unsigned m_imageSourceUnpackAlignment;
767    };
768
769    // The Following functions are implemented in GraphicsContext3DImagePacking.cpp
770
771    // Packs the contents of the given Image which is passed in |pixels| into the passed Vector
772    // according to the given format and type, and obeying the flipY and AlphaOp flags.
773    // Returns true upon success.
774    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);
775
776    // Extracts the contents of the given ImageData into the passed Vector,
777    // packing the pixel data according to the given format and type,
778    // and obeying the flipY and premultiplyAlpha flags. Returns true
779    // upon success.
780    static bool extractImageData(ImageData*, GC3Denum format, GC3Denum type, bool flipY, bool premultiplyAlpha, Vector<uint8_t>& data);
781
782    // Helper function which extracts the user-supplied texture
783    // data, applying the flipY and premultiplyAlpha parameters.
784    // If the data is not tightly packed according to the passed
785    // unpackAlignment, the output data will be tightly packed.
786    // Returns true if successful, false if any error occurred.
787    static bool extractTextureData(unsigned width, unsigned height, GC3Denum format, GC3Denum type, unsigned unpackAlignment, bool flipY, bool premultiplyAlpha, const void* pixels, Vector<uint8_t>& data);
788
789    // End GraphicsContext3DImagePacking.cpp functions
790
791    // This is the order of bytes to use when doing a readback.
792    enum ReadbackOrder {
793        ReadbackRGBA,
794        ReadbackSkia
795    };
796
797    // Helper function which does a readback from the currently-bound
798    // framebuffer into a buffer of a certain size with 4-byte pixels.
799    void readBackFramebuffer(unsigned char* pixels, int width, int height, ReadbackOrder, AlphaOp);
800
801private:
802    friend class Extensions3D;
803
804    GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3D>, bool preserveDrawingBuffer);
805    GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3DProvider>, bool preserveDrawingBuffer);
806
807    // Helper for packImageData/extractImageData/extractTextureData which implement packing of pixel
808    // data into the specified OpenGL destination format and type.
809    // A sourceUnpackAlignment of zero indicates that the source
810    // data is tightly packed. Non-zero values may take a slow path.
811    // Destination data will have no gaps between rows.
812    // Implemented in GraphicsContext3DImagePacking.cpp
813    static bool packPixels(const uint8_t* sourceData, DataFormat sourceDataFormat, unsigned width, unsigned height, unsigned sourceUnpackAlignment, unsigned destinationFormat, unsigned destinationType, AlphaOp, void* destinationData, bool flipY);
814
815    void paintFramebufferToCanvas(int framebuffer, int width, int height, bool premultiplyAlpha, ImageBuffer*);
816    // Helper function to flip a bitmap vertically.
817    void flipVertically(uint8_t* data, int width, int height);
818
819    // Extensions3D support.
820    bool supportsExtension(const String& name);
821    bool ensureExtensionEnabled(const String& name);
822    bool isExtensionEnabled(const String& name);
823
824    void initializeExtensions();
825
826    bool preserveDrawingBuffer() const { return m_preserveDrawingBuffer; }
827
828    OwnPtr<WebKit::WebGraphicsContext3DProvider> m_provider;
829    WebKit::WebGraphicsContext3D* m_impl;
830    OwnPtr<GraphicsContext3DContextLostCallbackAdapter> m_contextLostCallbackAdapter;
831    OwnPtr<GraphicsContext3DErrorMessageCallbackAdapter> m_errorMessageCallbackAdapter;
832    OwnPtr<WebKit::WebGraphicsContext3D> m_ownedWebContext;
833    OwnPtr<Extensions3D> m_extensions;
834    OwnPtr<GrMemoryAllocationChangedCallbackAdapter> m_grContextMemoryAllocationCallbackAdapter;
835    bool m_initializedAvailableExtensions;
836    HashSet<String> m_enabledExtensions;
837    HashSet<String> m_requestableExtensions;
838    bool m_layerComposited;
839    bool m_preserveDrawingBuffer;
840    int m_packAlignment;
841
842    enum ResourceSafety {
843        ResourceSafetyUnknown,
844        ResourceSafe,
845        ResourceUnsafe
846    };
847    ResourceSafety m_resourceSafety;
848
849    // If the width and height of the Canvas's backing store don't
850    // match those that we were given in the most recent call to
851    // reshape(), then we need an intermediate bitmap to read back the
852    // frame buffer into. This seems to happen when CSS styles are
853    // used to resize the Canvas.
854    SkBitmap m_resizingBitmap;
855
856    GrContext* m_grContext;
857    SkAutoTUnref<GrContext> m_ownedGrContext;
858
859    // Used to flip a bitmap vertically.
860    Vector<uint8_t> m_scanline;
861};
862
863} // namespace WebCore
864
865#endif // GraphicsContext3D_h
866