summaryrefslogtreecommitdiffstats
path: root/cc/test/test_web_graphics_context_3d.h
blob: a913edae55aa24de90f61c9db3dbc9ff5408010e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_TEST_TEST_WEB_GRAPHICS_CONTEXT_3D_H_
#define CC_TEST_TEST_WEB_GRAPHICS_CONTEXT_3D_H_

#include <stddef.h>
#include <stdint.h>

#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/stl_util.h"
#include "base/synchronization/lock.h"
#include "cc/output/context_provider.h"
#include "cc/test/ordered_texture_map.h"
#include "cc/test/test_texture.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "ui/gfx/geometry/rect.h"

extern "C" typedef struct _ClientBuffer* ClientBuffer;

namespace cc {
class TestContextSupport;

class TestWebGraphicsContext3D {
 public:
  static scoped_ptr<TestWebGraphicsContext3D> Create();

  virtual ~TestWebGraphicsContext3D();

  void set_context_lost_callback(const base::Closure& callback) {
    context_lost_callback_ = callback;
  }

  virtual void reshapeWithScaleFactor(int width,
                                      int height,
                                      float scale_factor);

  virtual bool isContextLost();

  virtual void discardFramebufferEXT(GLenum target,
                                     GLsizei num_attachments,
                                     const GLenum* attachments) {}

  virtual void activeTexture(GLenum texture) {}
  virtual void attachShader(GLuint program, GLuint shader);
  virtual void bindFramebuffer(GLenum target, GLuint framebuffer);
  virtual void bindRenderbuffer(GLenum target, GLuint renderbuffer);
  virtual void bindTexture(GLenum target, GLuint texture_id);

  virtual void texParameteri(GLenum target, GLenum pname, GLint param);
  virtual void getTexParameteriv(GLenum target, GLenum pname, GLint* value);
  virtual void asyncTexImage2DCHROMIUM(GLenum target,
                                       GLint level,
                                       GLenum internalformat,
                                       GLsizei width,
                                       GLsizei height,
                                       GLint border,
                                       GLenum format,
                                       GLenum type,
                                       const void* pixels) {}
  virtual void asyncTexSubImage2DCHROMIUM(GLenum target,
                                          GLint level,
                                          GLint xoffset,
                                          GLint yoffset,
                                          GLsizei width,
                                          GLsizei height,
                                          GLenum format,
                                          GLenum type,
                                          const void* pixels) {}
  virtual void waitAsyncTexImage2DCHROMIUM(GLenum target) {}
  virtual void releaseTexImage2DCHROMIUM(GLenum target, GLint image_id) {}
  virtual void framebufferRenderbuffer(GLenum target,
                                       GLenum attachment,
                                       GLenum renderbuffertarget,
                                       GLuint renderbuffer) {}
  virtual void framebufferTexture2D(GLenum target,
                                    GLenum attachment,
                                    GLenum textarget,
                                    GLuint texture,
                                    GLint level) {}
  virtual void renderbufferStorage(GLenum target,
                                   GLenum internalformat,
                                   GLsizei width,
                                   GLsizei height) {}

  virtual GLenum checkFramebufferStatus(GLenum target);

  virtual void clear(GLbitfield mask) {}
  virtual void clearColor(GLclampf red,
                          GLclampf green,
                          GLclampf blue,
                          GLclampf alpha) {}
  virtual void clearStencil(GLint s) {}
  virtual void compressedTexImage2D(GLenum target,
                                    GLint level,
                                    GLenum internal_format,
                                    GLsizei width,
                                    GLsizei height,
                                    GLint border,
                                    GLsizei image_size,
                                    const void* data) {}
  virtual GLint getUniformLocation(GLuint program, const GLchar* name);
  virtual GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname);

  virtual GLboolean isBuffer(GLuint buffer);
  virtual GLboolean isEnabled(GLenum cap);
  virtual GLboolean isFramebuffer(GLuint framebuffer);
  virtual GLboolean isProgram(GLuint program);
  virtual GLboolean isRenderbuffer(GLuint renderbuffer);
  virtual GLboolean isShader(GLuint shader);
  virtual GLboolean isTexture(GLuint texture);

  virtual void useProgram(GLuint program);

  virtual void viewport(GLint x, GLint y, GLsizei width, GLsizei height) {}

  virtual void genBuffers(GLsizei count, GLuint* ids);
  virtual void genFramebuffers(GLsizei count, GLuint* ids);
  virtual void genRenderbuffers(GLsizei count, GLuint* ids);
  virtual void genTextures(GLsizei count, GLuint* ids);

  virtual void deleteBuffers(GLsizei count, GLuint* ids);
  virtual void deleteFramebuffers(GLsizei count, GLuint* ids);
  virtual void deleteRenderbuffers(GLsizei count, GLuint* ids);
  virtual void deleteTextures(GLsizei count, GLuint* ids);

  virtual GLuint createBuffer();
  virtual GLuint createFramebuffer();
  virtual GLuint createRenderbuffer();
  virtual GLuint createTexture();

  virtual void deleteBuffer(GLuint id);
  virtual void deleteFramebuffer(GLuint id);
  virtual void deleteRenderbuffer(GLuint id);
  virtual void deleteTexture(GLuint id);

  virtual GLuint createProgram();
  virtual GLuint createShader(GLenum);
  virtual GLuint createExternalTexture();

  virtual void deleteProgram(GLuint id);
  virtual void deleteShader(GLuint id);

  virtual void texStorage2DEXT(GLenum target,
                               GLint levels,
                               GLuint internalformat,
                               GLint width,
                               GLint height) {}

  virtual GLuint createQueryEXT();
  virtual void deleteQueryEXT(GLuint query) {}
  virtual void beginQueryEXT(GLenum target, GLuint query) {}
  virtual void endQueryEXT(GLenum target);
  virtual void getQueryObjectuivEXT(GLuint query, GLenum pname, GLuint* params);

  virtual void scissor(GLint x, GLint y, GLsizei width, GLsizei height) {}

  virtual void texImage2D(GLenum target,
                          GLint level,
                          GLenum internalformat,
                          GLsizei width,
                          GLsizei height,
                          GLint border,
                          GLenum format,
                          GLenum type,
                          const void* pixels) {}

  virtual void texSubImage2D(GLenum target,
                             GLint level,
                             GLint xoffset,
                             GLint yoffset,
                             GLsizei width,
                             GLsizei height,
                             GLenum format,
                             GLenum type,
                             const void* pixels) {}

  virtual void genMailboxCHROMIUM(GLbyte* mailbox);
  virtual void produceTextureCHROMIUM(GLenum target,
                                      const GLbyte* mailbox) { }
  virtual void produceTextureDirectCHROMIUM(GLuint texture,
                                            GLenum target,
                                            const GLbyte* mailbox) {}
  virtual void consumeTextureCHROMIUM(GLenum target,
                                      const GLbyte* mailbox) { }
  virtual GLuint createAndConsumeTextureCHROMIUM(GLenum target,
                                                 const GLbyte* mailbox);

  virtual void loseContextCHROMIUM(GLenum current, GLenum other);

  virtual void bindTexImage2DCHROMIUM(GLenum target, GLint image_id) {}

  virtual void drawArrays(GLenum mode, GLint first, GLsizei count) {}
  virtual void drawElements(GLenum mode,
                            GLsizei count,
                            GLenum type,
                            GLintptr offset) {}
  virtual void disable(GLenum cap) {}
  virtual void enable(GLenum cap) {}
  virtual void finish();
  virtual void flush();
  virtual void shallowFinishCHROMIUM();
  virtual void shallowFlushCHROMIUM() {}

  virtual void getAttachedShaders(GLuint program,
                                  GLsizei max_count,
                                  GLsizei* count,
                                  GLuint* shaders) {}
  virtual GLint getAttribLocation(GLuint program, const GLchar* name);
  virtual void getBooleanv(GLenum pname, GLboolean* value) {}
  virtual void getBufferParameteriv(GLenum target, GLenum pname, GLint* value) {
  }
  virtual GLenum getError();
  virtual void getFloatv(GLenum pname, GLfloat* value) {}
  virtual void getFramebufferAttachmentParameteriv(GLenum target,
                                                   GLenum attachment,
                                                   GLenum pname,
                                                   GLint* value) {}

  virtual void getIntegerv(GLenum pname, GLint* value);

  virtual void getProgramiv(GLuint program, GLenum pname, GLint* value);

  virtual void getRenderbufferParameteriv(GLenum target,
                                          GLenum pname,
                                          GLint* value) {}

  virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value);

  virtual void getShaderPrecisionFormat(GLenum shadertype,
                                        GLenum precisiontype,
                                        GLint* range,
                                        GLint* precision);

  virtual void getTexParameterfv(GLenum target, GLenum pname, GLfloat* value) {}
  virtual void getUniformfv(GLuint program, GLint location, GLfloat* value) {}
  virtual void getUniformiv(GLuint program, GLint location, GLint* value) {}
  virtual void getVertexAttribfv(GLuint index, GLenum pname, GLfloat* value) {}
  virtual void getVertexAttribiv(GLuint index, GLenum pname, GLint* value) {}

  virtual void bindBuffer(GLenum target, GLuint buffer);
  virtual void bufferData(GLenum target,
                          GLsizeiptr size,
                          const void* data,
                          GLenum usage);
  virtual void pixelStorei(GLenum pname, GLint param);
  virtual void* mapBufferCHROMIUM(GLenum target,
                                  GLenum access);
  virtual GLboolean unmapBufferCHROMIUM(GLenum target);

  virtual GLuint createImageCHROMIUM(ClientBuffer buffer,
                                     GLsizei width,
                                     GLsizei height,
                                     GLenum internalformat);
  virtual void destroyImageCHROMIUM(GLuint image_id);
  virtual GLuint createGpuMemoryBufferImageCHROMIUM(GLsizei width,
                                                    GLsizei height,
                                                    GLenum internalformat,
                                                    GLenum usage);

  virtual void texImageIOSurface2DCHROMIUM(GLenum target,
                                           GLsizei width,
                                           GLsizei height,
                                           GLuint io_surface_id,
                                           GLuint plane) {}

  virtual GLuint64 insertFenceSync();
  virtual void genSyncToken(GLuint64 fence_sync, GLbyte* sync_token);
  virtual void waitSyncToken(const GLbyte* sync_token);
  virtual void verifySyncTokens(GLbyte** sync_tokens, GLsizei count);

  const gpu::SyncToken& last_waited_sync_token() const {
    return last_waited_sync_token_;
  }

  const ContextProvider::Capabilities& test_capabilities() const {
    return test_capabilities_;
  }

  void set_context_lost(bool context_lost) { context_lost_ = context_lost; }
  void set_times_bind_texture_succeeds(int times) {
    times_bind_texture_succeeds_ = times;
  }
  void set_times_end_query_succeeds(int times) {
    times_end_query_succeeds_ = times;
  }

  // When set, mapBufferCHROMIUM will return NULL after this many times.
  void set_times_map_buffer_chromium_succeeds(int times) {
    times_map_buffer_chromium_succeeds_ = times;
  }

  size_t NumTextures() const;
  GLuint TextureAt(int i) const;

  size_t NumUsedTextures() const { return used_textures_.size(); }
  bool UsedTexture(int texture) const {
    return ContainsKey(used_textures_, texture);
  }
  void ResetUsedTextures() { used_textures_.clear(); }

  void set_have_extension_io_surface(bool have) {
    test_capabilities_.gpu.iosurface = have;
    test_capabilities_.gpu.texture_rectangle = have;
  }
  void set_have_extension_egl_image(bool have) {
    test_capabilities_.gpu.egl_image_external = have;
  }
  void set_have_post_sub_buffer(bool have) {
    test_capabilities_.gpu.post_sub_buffer = have;
  }
  void set_have_commit_overlay_planes(bool have) {
    test_capabilities_.gpu.commit_overlay_planes = have;
  }
  void set_have_discard_framebuffer(bool have) {
    test_capabilities_.gpu.discard_framebuffer = have;
  }
  void set_support_compressed_texture_etc1(bool support) {
    test_capabilities_.gpu.texture_format_etc1 = support;
  }
  void set_support_texture_format_bgra8888(bool support) {
    test_capabilities_.gpu.texture_format_bgra8888 = support;
  }
  void set_support_texture_storage(bool support) {
    test_capabilities_.gpu.texture_storage = support;
  }
  void set_support_texture_usage(bool support) {
    test_capabilities_.gpu.texture_usage = support;
  }
  void set_support_sync_query(bool support) {
    test_capabilities_.gpu.sync_query = support;
  }
  void set_support_image(bool support) {
    test_capabilities_.gpu.image = support;
  }
  void set_support_texture_rectangle(bool support) {
    test_capabilities_.gpu.texture_rectangle = support;
  }
  void set_support_texture_half_float_linear(bool support) {
    test_capabilities_.gpu.texture_half_float_linear = support;
  }
  void set_msaa_is_slow(bool msaa_is_slow) {
    test_capabilities_.gpu.msaa_is_slow = msaa_is_slow;
  }

  // When this context is lost, all contexts in its share group are also lost.
  void add_share_group_context(TestWebGraphicsContext3D* context3d) {
    shared_contexts_.push_back(context3d);
  }

  void set_max_texture_size(int size) { max_texture_size_ = size; }

  static const GLuint kExternalTextureId;
  virtual GLuint NextTextureId();
  virtual void RetireTextureId(GLuint id);

  virtual GLuint NextBufferId();
  virtual void RetireBufferId(GLuint id);

  virtual GLuint NextImageId();
  virtual void RetireImageId(GLuint id);

  virtual GLuint NextFramebufferId();
  virtual void RetireFramebufferId(GLuint id);

  virtual GLuint NextRenderbufferId();
  virtual void RetireRenderbufferId(GLuint id);

  void SetMaxTransferBufferUsageBytes(size_t max_transfer_buffer_usage_bytes);
  size_t max_used_transfer_buffer_usage_bytes() const {
    return max_used_transfer_buffer_usage_bytes_;
  }

  void SetMaxSamples(int max_samples);
  void set_test_support(TestContextSupport* test_support) {
    test_support_ = test_support;
  }

  int width() const { return width_; }
  int height() const { return height_; }
  bool reshape_called() const { return reshape_called_; }
  void clear_reshape_called() { reshape_called_ = false; }
  float scale_factor() const { return scale_factor_; }

  enum UpdateType { NO_UPDATE = 0, PREPARE_TEXTURE, POST_SUB_BUFFER };

  gfx::Rect update_rect() const { return update_rect_; }

  UpdateType last_update_type() { return last_update_type_; }

 protected:
  struct TextureTargets {
    TextureTargets();
    ~TextureTargets();

    void BindTexture(GLenum target, GLuint id);
    void UnbindTexture(GLuint id);

    GLuint BoundTexture(GLenum target);

   private:
    using TargetTextureMap = std::unordered_map<GLenum, GLuint>;
    TargetTextureMap bound_textures_;
  };

  struct Buffer {
    Buffer();
    ~Buffer();

    GLenum target;
    scoped_ptr<uint8_t[]> pixels;
    size_t size;

   private:
    DISALLOW_COPY_AND_ASSIGN(Buffer);
  };

  struct Image {
    Image();
    ~Image();

    scoped_ptr<uint8_t[]> pixels;

   private:
    DISALLOW_COPY_AND_ASSIGN(Image);
  };

  struct Namespace : public base::RefCountedThreadSafe<Namespace> {
    Namespace();

    // Protects all fields.
    base::Lock lock;
    unsigned next_buffer_id;
    unsigned next_image_id;
    unsigned next_texture_id;
    unsigned next_renderbuffer_id;
    std::unordered_map<unsigned, scoped_ptr<Buffer>> buffers;
    std::unordered_set<unsigned> images;
    OrderedTextureMap textures;
    std::unordered_set<unsigned> renderbuffer_set;

   private:
    friend class base::RefCountedThreadSafe<Namespace>;
    ~Namespace();
    DISALLOW_COPY_AND_ASSIGN(Namespace);
  };

  TestWebGraphicsContext3D();

  void CreateNamespace();
  GLuint BoundTextureId(GLenum target);
  scoped_refptr<TestTexture> BoundTexture(GLenum target);
  scoped_refptr<TestTexture> UnboundTexture(GLuint texture);
  void CheckTextureIsBound(GLenum target);

  unsigned context_id_;
  ContextProvider::Capabilities test_capabilities_;
  int times_bind_texture_succeeds_;
  int times_end_query_succeeds_;
  bool context_lost_;
  int times_map_buffer_chromium_succeeds_;
  int current_used_transfer_buffer_usage_bytes_;
  int max_used_transfer_buffer_usage_bytes_;
  base::Closure context_lost_callback_;
  std::unordered_set<unsigned> used_textures_;
  unsigned next_program_id_;
  std::unordered_set<unsigned> program_set_;
  unsigned next_shader_id_;
  std::unordered_set<unsigned> shader_set_;
  unsigned next_framebuffer_id_;
  std::unordered_set<unsigned> framebuffer_set_;
  unsigned current_framebuffer_;
  std::vector<TestWebGraphicsContext3D*> shared_contexts_;
  int max_texture_size_;
  bool reshape_called_;
  int width_;
  int height_;
  float scale_factor_;
  TestContextSupport* test_support_;
  gfx::Rect update_rect_;
  UpdateType last_update_type_;
  GLuint64 next_insert_fence_sync_;
  gpu::SyncToken last_waited_sync_token_;
  int unpack_alignment_;

  unsigned bound_buffer_;
  TextureTargets texture_targets_;

  scoped_refptr<Namespace> namespace_;
  static Namespace* shared_namespace_;

  base::WeakPtrFactory<TestWebGraphicsContext3D> weak_ptr_factory_;
};

}  // namespace cc

#endif  // CC_TEST_TEST_WEB_GRAPHICS_CONTEXT_3D_H_