1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_H_
6#define GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_H_
7
8#include <GLES2/gl2.h>
9
10#include <list>
11#include <map>
12#include <queue>
13#include <set>
14#include <string>
15#include <utility>
16#include <vector>
17
18#include "base/compiler_specific.h"
19#include "base/memory/scoped_ptr.h"
20#include "base/memory/weak_ptr.h"
21#include "gpu/command_buffer/client/buffer_tracker.h"
22#include "gpu/command_buffer/client/client_context_state.h"
23#include "gpu/command_buffer/client/context_support.h"
24#include "gpu/command_buffer/client/gles2_cmd_helper.h"
25#include "gpu/command_buffer/client/gles2_impl_export.h"
26#include "gpu/command_buffer/client/gles2_interface.h"
27#include "gpu/command_buffer/client/gpu_memory_buffer_tracker.h"
28#include "gpu/command_buffer/client/mapped_memory.h"
29#include "gpu/command_buffer/client/query_tracker.h"
30#include "gpu/command_buffer/client/ref_counted.h"
31#include "gpu/command_buffer/client/ring_buffer.h"
32#include "gpu/command_buffer/client/share_group.h"
33#include "gpu/command_buffer/common/capabilities.h"
34#include "gpu/command_buffer/common/debug_marker_manager.h"
35#include "gpu/command_buffer/common/gles2_cmd_utils.h"
36#include "gpu/command_buffer/common/id_allocator.h"
37
38#if !defined(NDEBUG) && !defined(__native_client__) && !defined(GLES2_CONFORMANCE_TESTS)  // NOLINT
39  #if defined(GLES2_INLINE_OPTIMIZATION)
40    // TODO(gman): Replace with macros that work with inline optmization.
41    #define GPU_CLIENT_SINGLE_THREAD_CHECK()
42    #define GPU_CLIENT_LOG(args)
43    #define GPU_CLIENT_LOG_CODE_BLOCK(code)
44    #define GPU_CLIENT_DCHECK_CODE_BLOCK(code)
45  #else
46    #include "base/logging.h"
47    #define GPU_CLIENT_SINGLE_THREAD_CHECK() SingleThreadChecker checker(this);
48    #define GPU_CLIENT_LOG(args)  DLOG_IF(INFO, debug_) << args;
49    #define GPU_CLIENT_LOG_CODE_BLOCK(code) code
50    #define GPU_CLIENT_DCHECK_CODE_BLOCK(code) code
51    #define GPU_CLIENT_DEBUG
52  #endif
53#else
54  #define GPU_CLIENT_SINGLE_THREAD_CHECK()
55  #define GPU_CLIENT_LOG(args)
56  #define GPU_CLIENT_LOG_CODE_BLOCK(code)
57  #define GPU_CLIENT_DCHECK_CODE_BLOCK(code)
58#endif
59
60#if defined(GPU_CLIENT_DEBUG)
61  // Set to 1 to have the client fail when a GL error is generated.
62  // This helps find bugs in the renderer since the debugger stops on the error.
63#  if 0
64#    define GL_CLIENT_FAIL_GL_ERRORS
65#  endif
66#endif
67
68// Check that destination pointers point to initialized memory.
69// When the context is lost, calling GL function has no effect so if destination
70// pointers point to initialized memory it can often lead to crash bugs. eg.
71//
72// GLsizei len;
73// glGetShaderSource(shader, max_size, &len, buffer);
74// std::string src(buffer, buffer + len);  // len can be uninitialized here!!!
75//
76// Because this check is not official GL this check happens only on Chrome code,
77// not Pepper.
78//
79// If it was up to us we'd just always write to the destination but the OpenGL
80// spec defines the behavior of OpenGL functions, not us. :-(
81#if defined(__native_client__) || defined(GLES2_CONFORMANCE_TESTS)
82  #define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(v)
83  #define GPU_CLIENT_DCHECK(v)
84#elif defined(GPU_DCHECK)
85  #define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(v) GPU_DCHECK(v)
86  #define GPU_CLIENT_DCHECK(v) GPU_DCHECK(v)
87#elif defined(DCHECK)
88  #define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(v) DCHECK(v)
89  #define GPU_CLIENT_DCHECK(v) DCHECK(v)
90#else
91  #define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(v) ASSERT(v)
92  #define GPU_CLIENT_DCHECK(v) ASSERT(v)
93#endif
94
95#define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(type, ptr) \
96    GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(ptr && \
97        (ptr[0] == static_cast<type>(0) || ptr[0] == static_cast<type>(-1)));
98
99#define GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(type, ptr) \
100    GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(!ptr || \
101        (ptr[0] == static_cast<type>(0) || ptr[0] == static_cast<type>(-1)));
102
103struct GLUniformDefinitionCHROMIUM;
104
105namespace gpu {
106
107class GpuControl;
108class ScopedTransferBufferPtr;
109class TransferBufferInterface;
110
111namespace gles2 {
112
113class ImageFactory;
114class VertexArrayObjectManager;
115
116class GLES2ImplementationErrorMessageCallback {
117 public:
118  virtual ~GLES2ImplementationErrorMessageCallback() { }
119  virtual void OnErrorMessage(const char* msg, int id) = 0;
120};
121
122// This class emulates GLES2 over command buffers. It can be used by a client
123// program so that the program does not need deal with shared memory and command
124// buffer management. See gl2_lib.h.  Note that there is a performance gain to
125// be had by changing your code to use command buffers directly by using the
126// GLES2CmdHelper but that entails changing your code to use and deal with
127// shared memory and synchronization issues.
128class GLES2_IMPL_EXPORT GLES2Implementation
129    : NON_EXPORTED_BASE(public GLES2Interface),
130      NON_EXPORTED_BASE(public ContextSupport) {
131 public:
132  enum MappedMemoryLimit {
133    kNoLimit = MappedMemoryManager::kNoLimit,
134  };
135
136  // Stores GL state that never changes.
137  struct GLES2_IMPL_EXPORT GLStaticState {
138    GLStaticState();
139    ~GLStaticState();
140
141    struct GLES2_IMPL_EXPORT IntState {
142      IntState();
143      GLint max_combined_texture_image_units;
144      GLint max_cube_map_texture_size;
145      GLint max_fragment_uniform_vectors;
146      GLint max_renderbuffer_size;
147      GLint max_texture_image_units;
148      GLint max_texture_size;
149      GLint max_varying_vectors;
150      GLint max_vertex_attribs;
151      GLint max_vertex_texture_image_units;
152      GLint max_vertex_uniform_vectors;
153      GLint num_compressed_texture_formats;
154      GLint num_shader_binary_formats;
155      GLint bind_generates_resource_chromium;
156    };
157    IntState int_state;
158
159    typedef std::pair<GLenum, GLenum> ShaderPrecisionKey;
160    typedef std::map<ShaderPrecisionKey,
161                     cmds::GetShaderPrecisionFormat::Result>
162        ShaderPrecisionMap;
163    ShaderPrecisionMap shader_precisions;
164  };
165
166  // The maxiumum result size from simple GL get commands.
167  static const size_t kMaxSizeOfSimpleResult = 16 * sizeof(uint32);  // NOLINT.
168
169  // used for testing only. If more things are reseved add them here.
170  static const unsigned int kStartingOffset = kMaxSizeOfSimpleResult;
171
172  // Size in bytes to issue async flush for transfer buffer.
173  static const unsigned int kSizeToFlush = 256 * 1024;
174
175  // The bucket used for results. Public for testing only.
176  static const uint32 kResultBucketId = 1;
177
178  // Alignment of allocations.
179  static const unsigned int kAlignment = 4;
180
181  // GL names for the buffers used to emulate client side buffers.
182  static const GLuint kClientSideArrayId = 0xFEDCBA98u;
183  static const GLuint kClientSideElementArrayId = 0xFEDCBA99u;
184
185  // Number of swap buffers allowed before waiting.
186  static const size_t kMaxSwapBuffers = 2;
187
188  GLES2Implementation(GLES2CmdHelper* helper,
189                      ShareGroup* share_group,
190                      TransferBufferInterface* transfer_buffer,
191                      bool bind_generates_resource,
192                      bool lose_context_when_out_of_memory,
193                      GpuControl* gpu_control);
194
195  virtual ~GLES2Implementation();
196
197  bool Initialize(
198      unsigned int starting_transfer_buffer_size,
199      unsigned int min_transfer_buffer_size,
200      unsigned int max_transfer_buffer_size,
201      unsigned int mapped_memory_limit);
202
203  // The GLES2CmdHelper being used by this GLES2Implementation. You can use
204  // this to issue cmds at a lower level for certain kinds of optimization.
205  GLES2CmdHelper* helper() const;
206
207  // Gets client side generated errors.
208  GLenum GetClientSideGLError();
209
210  // Include the auto-generated part of this class. We split this because
211  // it means we can easily edit the non-auto generated parts right here in
212  // this file instead of having to edit some template or the code generator.
213  #include "gpu/command_buffer/client/gles2_implementation_autogen.h"
214
215  virtual void DisableVertexAttribArray(GLuint index) OVERRIDE;
216  virtual void EnableVertexAttribArray(GLuint index) OVERRIDE;
217  virtual void GetVertexAttribfv(
218      GLuint index, GLenum pname, GLfloat* params) OVERRIDE;
219  virtual void GetVertexAttribiv(
220      GLuint index, GLenum pname, GLint* params) OVERRIDE;
221
222  // ContextSupport implementation.
223  virtual void Swap() OVERRIDE;
224  virtual void PartialSwapBuffers(const gfx::Rect& sub_buffer) OVERRIDE;
225  virtual void SetSwapBuffersCompleteCallback(
226      const base::Closure& swap_buffers_complete_callback)
227          OVERRIDE;
228  virtual void ScheduleOverlayPlane(int plane_z_order,
229                                    gfx::OverlayTransform plane_transform,
230                                    unsigned overlay_texture_id,
231                                    const gfx::Rect& display_bounds,
232                                    const gfx::RectF& uv_rect) OVERRIDE;
233  virtual GLuint InsertFutureSyncPointCHROMIUM() OVERRIDE;
234  virtual void RetireSyncPointCHROMIUM(GLuint sync_point) OVERRIDE;
235
236  void GetProgramInfoCHROMIUMHelper(GLuint program, std::vector<int8>* result);
237  GLint GetAttribLocationHelper(GLuint program, const char* name);
238  GLint GetUniformLocationHelper(GLuint program, const char* name);
239  bool GetActiveAttribHelper(
240      GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
241      GLint* size, GLenum* type, char* name);
242  bool GetActiveUniformHelper(
243      GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
244      GLint* size, GLenum* type, char* name);
245
246  void FreeUnusedSharedMemory();
247  void FreeEverything();
248
249  // ContextSupport implementation.
250  virtual void SignalSyncPoint(uint32 sync_point,
251                               const base::Closure& callback) OVERRIDE;
252  virtual void SignalQuery(uint32 query,
253                           const base::Closure& callback) OVERRIDE;
254  virtual void SetSurfaceVisible(bool visible) OVERRIDE;
255
256  void SetErrorMessageCallback(
257      GLES2ImplementationErrorMessageCallback* callback) {
258    error_message_callback_ = callback;
259  }
260
261  ShareGroup* share_group() const {
262    return share_group_.get();
263  }
264
265  const Capabilities& capabilities() const {
266    return capabilities_;
267  }
268
269  GpuControl* gpu_control() {
270    return gpu_control_;
271  }
272
273  ShareGroupContextData* share_group_context_data() {
274    return &share_group_context_data_;
275  }
276
277 private:
278  friend class GLES2ImplementationTest;
279  friend class VertexArrayObjectManager;
280
281  // Used to track whether an extension is available
282  enum ExtensionStatus {
283      kAvailableExtensionStatus,
284      kUnavailableExtensionStatus,
285      kUnknownExtensionStatus
286  };
287
288  // Base class for mapped resources.
289  struct MappedResource {
290    MappedResource(GLenum _access, int _shm_id, void* mem, unsigned int offset)
291        : access(_access),
292          shm_id(_shm_id),
293          shm_memory(mem),
294          shm_offset(offset) {
295    }
296
297    // access mode. Currently only GL_WRITE_ONLY is valid
298    GLenum access;
299
300    // Shared memory ID for buffer.
301    int shm_id;
302
303    // Address of shared memory
304    void* shm_memory;
305
306    // Offset of shared memory
307    unsigned int shm_offset;
308  };
309
310  // Used to track mapped textures.
311  struct MappedTexture : public MappedResource {
312    MappedTexture(
313        GLenum access,
314        int shm_id,
315        void* shm_mem,
316        unsigned int shm_offset,
317        GLenum _target,
318        GLint _level,
319        GLint _xoffset,
320        GLint _yoffset,
321        GLsizei _width,
322        GLsizei _height,
323        GLenum _format,
324        GLenum _type)
325        : MappedResource(access, shm_id, shm_mem, shm_offset),
326          target(_target),
327          level(_level),
328          xoffset(_xoffset),
329          yoffset(_yoffset),
330          width(_width),
331          height(_height),
332          format(_format),
333          type(_type) {
334    }
335
336    // These match the arguments to TexSubImage2D.
337    GLenum target;
338    GLint level;
339    GLint xoffset;
340    GLint yoffset;
341    GLsizei width;
342    GLsizei height;
343    GLenum format;
344    GLenum type;
345  };
346
347  // Used to track mapped buffers.
348  struct MappedBuffer : public MappedResource {
349    MappedBuffer(
350        GLenum access,
351        int shm_id,
352        void* shm_mem,
353        unsigned int shm_offset,
354        GLenum _target,
355        GLintptr _offset,
356        GLsizeiptr _size)
357        : MappedResource(access, shm_id, shm_mem, shm_offset),
358          target(_target),
359          offset(_offset),
360          size(_size) {
361    }
362
363    // These match the arguments to BufferSubData.
364    GLenum target;
365    GLintptr offset;
366    GLsizeiptr size;
367  };
368
369  struct TextureUnit {
370    TextureUnit()
371        : bound_texture_2d(0),
372          bound_texture_cube_map(0),
373          bound_texture_external_oes(0) {}
374
375    // texture currently bound to this unit's GL_TEXTURE_2D with glBindTexture
376    GLuint bound_texture_2d;
377
378    // texture currently bound to this unit's GL_TEXTURE_CUBE_MAP with
379    // glBindTexture
380    GLuint bound_texture_cube_map;
381
382    // texture currently bound to this unit's GL_TEXTURE_EXTERNAL_OES with
383    // glBindTexture
384    GLuint bound_texture_external_oes;
385  };
386
387  // Checks for single threaded access.
388  class SingleThreadChecker {
389   public:
390    explicit SingleThreadChecker(GLES2Implementation* gles2_implementation);
391    ~SingleThreadChecker();
392
393   private:
394    GLES2Implementation* gles2_implementation_;
395  };
396
397  // Gets the value of the result.
398  template <typename T>
399  T GetResultAs() {
400    return static_cast<T>(GetResultBuffer());
401  }
402
403  void* GetResultBuffer();
404  int32 GetResultShmId();
405  uint32 GetResultShmOffset();
406
407  bool QueryAndCacheStaticState();
408
409  // Helpers used to batch synchronous GetIntergerv calls with other
410  // synchronous calls.
411  struct GetMultipleIntegervState {
412    GetMultipleIntegervState(const GLenum* pnames, GLuint pnames_count,
413                             GLint* results, GLsizeiptr results_size)
414       : pnames(pnames),
415         pnames_count(pnames_count),
416         results(results),
417         results_size(results_size)
418    { }
419    // inputs
420    const GLenum* pnames;
421    GLuint pnames_count;
422    // outputs
423    GLint* results;
424    GLsizeiptr results_size;
425    // transfer buffer
426    int num_results;
427    int transfer_buffer_size_needed;
428    void* buffer;
429    void* results_buffer;
430  };
431  bool GetMultipleIntegervSetup(
432      GetMultipleIntegervState* state);
433  void GetMultipleIntegervRequest(
434      GetMultipleIntegervState* state);
435  void GetMultipleIntegervOnCompleted(
436      GetMultipleIntegervState* state);
437
438  // Helpers used to batch synchronous GetShaderPrecision calls with other
439  // synchronous calls.
440  struct GetAllShaderPrecisionFormatsState {
441    GetAllShaderPrecisionFormatsState(
442        const GLenum (*precision_params)[2],
443        int precision_params_count)
444        : precision_params(precision_params),
445          precision_params_count(precision_params_count)
446    { }
447    const GLenum (*precision_params)[2];
448    int precision_params_count;
449    int transfer_buffer_size_needed;
450    void* results_buffer;
451  };
452  void GetAllShaderPrecisionFormatsSetup(
453      GetAllShaderPrecisionFormatsState* state);
454  void GetAllShaderPrecisionFormatsRequest(
455      GetAllShaderPrecisionFormatsState* state);
456  void GetAllShaderPrecisionFormatsOnCompleted(
457      GetAllShaderPrecisionFormatsState* state);
458
459  // Lazily determines if GL_ANGLE_pack_reverse_row_order is available
460  bool IsAnglePackReverseRowOrderAvailable();
461  bool IsChromiumFramebufferMultisampleAvailable();
462
463  bool IsExtensionAvailableHelper(
464      const char* extension, ExtensionStatus* status);
465
466  // Gets the GLError through our wrapper.
467  GLenum GetGLError();
468
469  // Sets our wrapper for the GLError.
470  void SetGLError(GLenum error, const char* function_name, const char* msg);
471  void SetGLErrorInvalidEnum(
472      const char* function_name, GLenum value, const char* label);
473
474  // Returns the last error and clears it. Useful for debugging.
475  const std::string& GetLastError() {
476    return last_error_;
477  }
478
479  // Waits for all commands to execute.
480  void WaitForCmd();
481
482  // TODO(gman): These bucket functions really seem like they belong in
483  // CommandBufferHelper (or maybe BucketHelper?). Unfortunately they need
484  // a transfer buffer to function which is currently managed by this class.
485
486  // Gets the contents of a bucket.
487  bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data);
488
489  // Sets the contents of a bucket.
490  void SetBucketContents(uint32 bucket_id, const void* data, size_t size);
491
492  // Sets the contents of a bucket as a string.
493  void SetBucketAsCString(uint32 bucket_id, const char* str);
494
495  // Gets the contents of a bucket as a string. Returns false if there is no
496  // string available which is a separate case from the empty string.
497  bool GetBucketAsString(uint32 bucket_id, std::string* str);
498
499  // Sets the contents of a bucket as a string.
500  void SetBucketAsString(uint32 bucket_id, const std::string& str);
501
502  // Returns true if id is reserved.
503  bool IsBufferReservedId(GLuint id);
504  bool IsFramebufferReservedId(GLuint id) { return false;  }
505  bool IsRenderbufferReservedId(GLuint id) { return false; }
506  bool IsTextureReservedId(GLuint id) { return false; }
507  bool IsVertexArrayReservedId(GLuint id) { return false; }
508  bool IsProgramReservedId(GLuint id) { return false; }
509
510  bool BindBufferHelper(GLenum target, GLuint texture);
511  bool BindFramebufferHelper(GLenum target, GLuint texture);
512  bool BindRenderbufferHelper(GLenum target, GLuint texture);
513  bool BindTextureHelper(GLenum target, GLuint texture);
514  bool BindVertexArrayOESHelper(GLuint array);
515  bool UseProgramHelper(GLuint program);
516
517  void GenBuffersHelper(GLsizei n, const GLuint* buffers);
518  void GenFramebuffersHelper(GLsizei n, const GLuint* framebuffers);
519  void GenRenderbuffersHelper(GLsizei n, const GLuint* renderbuffers);
520  void GenTexturesHelper(GLsizei n, const GLuint* textures);
521  void GenVertexArraysOESHelper(GLsizei n, const GLuint* arrays);
522  void GenQueriesEXTHelper(GLsizei n, const GLuint* queries);
523
524  void DeleteBuffersHelper(GLsizei n, const GLuint* buffers);
525  void DeleteFramebuffersHelper(GLsizei n, const GLuint* framebuffers);
526  void DeleteRenderbuffersHelper(GLsizei n, const GLuint* renderbuffers);
527  void DeleteTexturesHelper(GLsizei n, const GLuint* textures);
528  bool DeleteProgramHelper(GLuint program);
529  bool DeleteShaderHelper(GLuint shader);
530  void DeleteQueriesEXTHelper(GLsizei n, const GLuint* queries);
531  void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* arrays);
532
533  void DeleteBuffersStub(GLsizei n, const GLuint* buffers);
534  void DeleteFramebuffersStub(GLsizei n, const GLuint* framebuffers);
535  void DeleteRenderbuffersStub(GLsizei n, const GLuint* renderbuffers);
536  void DeleteTexturesStub(GLsizei n, const GLuint* textures);
537  void DeleteProgramStub(GLsizei n, const GLuint* programs);
538  void DeleteShaderStub(GLsizei n, const GLuint* shaders);
539  void DeleteVertexArraysOESStub(GLsizei n, const GLuint* arrays);
540
541  void BufferDataHelper(
542      GLenum target, GLsizeiptr size, const void* data, GLenum usage);
543  void BufferSubDataHelper(
544      GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
545  void BufferSubDataHelperImpl(
546      GLenum target, GLintptr offset, GLsizeiptr size, const void* data,
547      ScopedTransferBufferPtr* buffer);
548
549  GLuint CreateImageCHROMIUMHelper(GLsizei width,
550                                   GLsizei height,
551                                   GLenum internalformat,
552                                   GLenum usage);
553  void DestroyImageCHROMIUMHelper(GLuint image_id);
554  void* MapImageCHROMIUMHelper(GLuint image_id);
555  void UnmapImageCHROMIUMHelper(GLuint image_id);
556  void GetImageParameterivCHROMIUMHelper(
557      GLuint image_id, GLenum pname, GLint* params);
558
559  // Helper for GetVertexAttrib
560  bool GetVertexAttribHelper(GLuint index, GLenum pname, uint32* param);
561
562  GLuint GetMaxValueInBufferCHROMIUMHelper(
563      GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
564
565  void RestoreElementAndArrayBuffers(bool restore);
566  void RestoreArrayBuffer(bool restrore);
567
568  // The pixels pointer should already account for unpack skip rows and skip
569  // pixels.
570  void TexSubImage2DImpl(
571      GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
572      GLsizei height, GLenum format, GLenum type, uint32 unpadded_row_size,
573      const void* pixels, uint32 pixels_padded_row_size, GLboolean internal,
574      ScopedTransferBufferPtr* buffer, uint32 buffer_padded_row_size);
575
576  // Helpers for query functions.
577  bool GetHelper(GLenum pname, GLint* params);
578  bool GetBooleanvHelper(GLenum pname, GLboolean* params);
579  bool GetBufferParameterivHelper(GLenum target, GLenum pname, GLint* params);
580  bool GetFloatvHelper(GLenum pname, GLfloat* params);
581  bool GetFramebufferAttachmentParameterivHelper(
582      GLenum target, GLenum attachment, GLenum pname, GLint* params);
583  bool GetIntegervHelper(GLenum pname, GLint* params);
584  bool GetProgramivHelper(GLuint program, GLenum pname, GLint* params);
585  bool GetRenderbufferParameterivHelper(
586      GLenum target, GLenum pname, GLint* params);
587  bool GetShaderivHelper(GLuint shader, GLenum pname, GLint* params);
588  bool GetTexParameterfvHelper(GLenum target, GLenum pname, GLfloat* params);
589  bool GetTexParameterivHelper(GLenum target, GLenum pname, GLint* params);
590  const GLubyte* GetStringHelper(GLenum name);
591
592  bool IsExtensionAvailable(const char* ext);
593
594  // Caches certain capabilties state. Return true if cached.
595  bool SetCapabilityState(GLenum cap, bool enabled);
596
597  IdHandlerInterface* GetIdHandler(int id_namespace) const;
598  // IdAllocators for objects that can't be shared among contexts.
599  // For now, used only for Queries. TODO(hj.r.chung) Should be added for
600  // Framebuffer and Vertex array objects.
601  IdAllocatorInterface* GetIdAllocator(int id_namespace) const;
602
603  void FinishHelper();
604
605  void RunIfContextNotLost(const base::Closure& callback);
606
607  void OnSwapBuffersComplete();
608
609  // Validate if an offset is valid, i.e., non-negative and fit into 32-bit.
610  // If not, generate an approriate error, and return false.
611  bool ValidateOffset(const char* func, GLintptr offset);
612
613  // Validate if a size is valid, i.e., non-negative and fit into 32-bit.
614  // If not, generate an approriate error, and return false.
615  bool ValidateSize(const char* func, GLsizeiptr offset);
616
617  // Remove the transfer buffer from the buffer tracker. For buffers used
618  // asynchronously the memory is free:ed if the upload has completed. For
619  // other buffers, the memory is either free:ed immediately or free:ed pending
620  // a token.
621  void RemoveTransferBuffer(BufferTracker::Buffer* buffer);
622
623  // Returns true if the async upload token has passed.
624  //
625  // NOTE: This will detect wrapped async tokens by checking if the most
626  // significant  bit of async token to check is 1 but the last read is 0, i.e.
627  // the uint32 wrapped.
628  bool HasAsyncUploadTokenPassed(uint32 token) const {
629    return async_upload_sync_->HasAsyncUploadTokenPassed(token);
630  }
631
632  // Get the next async upload token.
633  uint32 NextAsyncUploadToken();
634
635  // Ensure that the shared memory used for synchronizing async upload tokens
636  // has been mapped.
637  //
638  // Returns false on error, true on success.
639  bool EnsureAsyncUploadSync();
640
641  // Checks the last read asynchronously upload token and frees any unmanaged
642  // transfer buffer that has its async token passed.
643  void PollAsyncUploads();
644
645  // Free every async upload buffer. If some async upload buffer is still in use
646  // wait for them to finish before freeing.
647  void FreeAllAsyncUploadBuffers();
648
649  bool GetBoundPixelTransferBuffer(
650      GLenum target, const char* function_name, GLuint* buffer_id);
651  BufferTracker::Buffer* GetBoundPixelUnpackTransferBufferIfValid(
652      GLuint buffer_id,
653      const char* function_name, GLuint offset, GLsizei size);
654
655  const std::string& GetLogPrefix() const;
656
657#if defined(GL_CLIENT_FAIL_GL_ERRORS)
658  void CheckGLError();
659  void FailGLError(GLenum error);
660#else
661  void CheckGLError() { }
662  void FailGLError(GLenum /* error */) { }
663#endif
664
665  GLES2Util util_;
666  GLES2CmdHelper* helper_;
667  TransferBufferInterface* transfer_buffer_;
668  std::string last_error_;
669  DebugMarkerManager debug_marker_manager_;
670  std::string this_in_hex_;
671
672  std::queue<int32> swap_buffers_tokens_;
673  std::queue<int32> rate_limit_tokens_;
674
675  ExtensionStatus angle_pack_reverse_row_order_status_;
676  ExtensionStatus chromium_framebuffer_multisample_;
677
678  GLStaticState static_state_;
679  ClientContextState state_;
680
681  // pack alignment as last set by glPixelStorei
682  GLint pack_alignment_;
683
684  // unpack alignment as last set by glPixelStorei
685  GLint unpack_alignment_;
686
687  // unpack yflip as last set by glPixelstorei
688  bool unpack_flip_y_;
689
690  // unpack row length as last set by glPixelStorei
691  GLint unpack_row_length_;
692
693  // unpack skip rows as last set by glPixelStorei
694  GLint unpack_skip_rows_;
695
696  // unpack skip pixels as last set by glPixelStorei
697  GLint unpack_skip_pixels_;
698
699  // pack reverse row order as last set by glPixelstorei
700  bool pack_reverse_row_order_;
701
702  scoped_ptr<TextureUnit[]> texture_units_;
703
704  // 0 to gl_state_.max_combined_texture_image_units.
705  GLuint active_texture_unit_;
706
707  GLuint bound_framebuffer_;
708  GLuint bound_read_framebuffer_;
709  GLuint bound_renderbuffer_;
710
711  // The program in use by glUseProgram
712  GLuint current_program_;
713
714  // The currently bound array buffer.
715  GLuint bound_array_buffer_id_;
716
717  // The currently bound pixel transfer buffers.
718  GLuint bound_pixel_pack_transfer_buffer_id_;
719  GLuint bound_pixel_unpack_transfer_buffer_id_;
720
721  // The current asynchronous pixel buffer upload token.
722  uint32 async_upload_token_;
723
724  // The shared memory used for synchronizing asynchronous upload tokens.
725  AsyncUploadSync* async_upload_sync_;
726  int32 async_upload_sync_shm_id_;
727  unsigned int async_upload_sync_shm_offset_;
728
729  // Unmanaged pixel transfer buffer memory pending asynchronous upload token.
730  typedef std::list<std::pair<void*, uint32> > DetachedAsyncUploadMemoryList;
731  DetachedAsyncUploadMemoryList detached_async_upload_memory_;
732
733  // Client side management for vertex array objects. Needed to correctly
734  // track client side arrays.
735  scoped_ptr<VertexArrayObjectManager> vertex_array_object_manager_;
736
737  GLuint reserved_ids_[2];
738
739  // Current GL error bits.
740  uint32 error_bits_;
741
742  // Whether or not to print debugging info.
743  bool debug_;
744
745  // When true, the context is lost when a GL_OUT_OF_MEMORY error occurs.
746  bool lose_context_when_out_of_memory_;
747
748  // Used to check for single threaded access.
749  int use_count_;
750
751  // Map of GLenum to Strings for glGetString.  We need to cache these because
752  // the pointer passed back to the client has to remain valid for eternity.
753  typedef std::map<uint32, std::set<std::string> > GLStringMap;
754  GLStringMap gl_strings_;
755
756  // Similar cache for glGetRequestableExtensionsCHROMIUM. We don't
757  // have an enum for this so handle it separately.
758  std::set<std::string> requestable_extensions_set_;
759
760  typedef std::map<const void*, MappedBuffer> MappedBufferMap;
761  MappedBufferMap mapped_buffers_;
762
763  typedef std::map<const void*, MappedTexture> MappedTextureMap;
764  MappedTextureMap mapped_textures_;
765
766  scoped_ptr<MappedMemoryManager> mapped_memory_;
767
768  scoped_refptr<ShareGroup> share_group_;
769  ShareGroupContextData share_group_context_data_;
770
771  scoped_ptr<QueryTracker> query_tracker_;
772  typedef std::map<GLuint, QueryTracker::Query*> QueryMap;
773  QueryMap current_queries_;
774  scoped_ptr<IdAllocatorInterface> query_id_allocator_;
775
776  scoped_ptr<BufferTracker> buffer_tracker_;
777
778  scoped_ptr<GpuMemoryBufferTracker> gpu_memory_buffer_tracker_;
779
780  GLES2ImplementationErrorMessageCallback* error_message_callback_;
781
782  scoped_ptr<std::string> current_trace_name_;
783
784  GpuControl* gpu_control_;
785
786  Capabilities capabilities_;
787
788  base::Closure swap_buffers_complete_callback_;
789
790  base::WeakPtrFactory<GLES2Implementation> weak_ptr_factory_;
791
792  DISALLOW_COPY_AND_ASSIGN(GLES2Implementation);
793};
794
795inline bool GLES2Implementation::GetBufferParameterivHelper(
796    GLenum /* target */, GLenum /* pname */, GLint* /* params */) {
797  return false;
798}
799
800inline bool GLES2Implementation::GetFramebufferAttachmentParameterivHelper(
801    GLenum /* target */,
802    GLenum /* attachment */,
803    GLenum /* pname */,
804    GLint* /* params */) {
805  return false;
806}
807
808inline bool GLES2Implementation::GetRenderbufferParameterivHelper(
809    GLenum /* target */, GLenum /* pname */, GLint* /* params */) {
810  return false;
811}
812
813inline bool GLES2Implementation::GetShaderivHelper(
814    GLuint /* shader */, GLenum /* pname */, GLint* /* params */) {
815  return false;
816}
817
818inline bool GLES2Implementation::GetTexParameterfvHelper(
819    GLenum /* target */, GLenum /* pname */, GLfloat* /* params */) {
820  return false;
821}
822
823inline bool GLES2Implementation::GetTexParameterivHelper(
824    GLenum /* target */, GLenum /* pname */, GLint* /* params */) {
825  return false;
826}
827
828}  // namespace gles2
829}  // namespace gpu
830
831#endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_H_
832