1 // Copyright (c) 2016 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_SERVICE_INDEXED_BUFFER_BINDING_HOST_H_ 6 #define GPU_COMMAND_BUFFER_SERVICE_INDEXED_BUFFER_BINDING_HOST_H_ 7 8 #include <vector> 9 10 #include "base/memory/ref_counted.h" 11 #include "gpu/command_buffer/service/gl_utils.h" 12 #include "gpu/gpu_gles2_export.h" 13 14 namespace gpu { 15 namespace gles2 { 16 17 class Buffer; 18 19 // This is a base class for indexed buffer bindings tracking. 20 // TransformFeedback and Program should inherit from this base class, 21 // for tracking indexed TRANSFORM_FEEDBACK_BUFFER / UNIFORM_BUFFER bindings. 22 class GPU_GLES2_EXPORT IndexedBufferBindingHost 23 : public base::RefCounted<IndexedBufferBindingHost> { 24 public: 25 // In theory |needs_emulation| needs to be true on Desktop GL 4.1 or lower. 26 // However, we set it to true everywhere, not to trust drivers to handle 27 // out-of-bounds buffer accesses. 28 IndexedBufferBindingHost(uint32_t max_bindings, 29 GLenum target, 30 bool needs_emulation, 31 bool round_down_uniform_bind_buffer_range_size); 32 33 // The following two functions do state update and call the underlying GL 34 // function. All validations have been done already and the GL function is 35 // guaranteed to succeed. 36 void DoBindBufferBase(GLuint index, Buffer* buffer); 37 void DoBindBufferRange(GLuint index, 38 Buffer* buffer, 39 GLintptr offset, 40 GLsizeiptr size); 41 42 // This is called on the active host when glBufferData is called and buffer 43 // size might change. 44 void OnBufferData(Buffer* buffer); 45 46 void RemoveBoundBuffer(GLenum target, 47 Buffer* buffer, 48 Buffer* target_generic_bound_buffer, 49 bool have_context); 50 51 void SetIsBound(bool bound); 52 53 Buffer* GetBufferBinding(GLuint index) const; 54 // Returns |size| set by glBindBufferRange; 0 if set by glBindBufferBase. 55 GLsizeiptr GetBufferSize(GLuint index) const; 56 // For glBindBufferBase, return the actual buffer size when this function is 57 // called, not when glBindBufferBase is called. 58 // For glBindBufferRange, return the |size| set by glBindBufferRange minus 59 // the range that's beyond the buffer. 60 GLsizeiptr GetEffectiveBufferSize(GLuint index) const; 61 GLintptr GetBufferStart(GLuint index) const; 62 63 // This is used only for UNIFORM_BUFFER bindings in context switching. 64 void RestoreBindings(IndexedBufferBindingHost* prev); 65 66 // Check if |buffer| is currently bound to one of the indexed binding point 67 // from 0 to |used_binding_count| - 1. 68 bool UsesBuffer(size_t used_binding_count, const Buffer* buffer) const; 69 70 protected: 71 friend class base::RefCounted<IndexedBufferBindingHost>; 72 73 virtual ~IndexedBufferBindingHost(); 74 75 // Whether this object is currently bound into the context. 76 bool is_bound_; 77 78 // Whether or not to call Buffer::OnBind/OnUnbind whenever bindings change. 79 // This is only necessary for WebGL contexts to implement 80 // https://crbug.com/696345 81 bool do_buffer_refcounting_; 82 83 private: 84 enum class IndexedBufferBindingType { 85 kBindBufferBase, 86 kBindBufferRange, 87 kBindBufferNone 88 }; 89 90 struct IndexedBufferBinding { 91 IndexedBufferBindingType type; 92 scoped_refptr<Buffer> buffer; 93 94 // The following fields are only used if |type| is kBindBufferRange. 95 GLintptr offset; 96 GLsizeiptr size; 97 // The full buffer size at the last successful glBindBufferRange call. 98 GLsizeiptr effective_full_buffer_size; 99 100 IndexedBufferBinding(); 101 IndexedBufferBinding(const IndexedBufferBinding& other); 102 ~IndexedBufferBinding(); 103 104 bool operator==(const IndexedBufferBinding& other) const; 105 106 void SetBindBufferBase(Buffer* _buffer); 107 void SetBindBufferRange( 108 Buffer* _buffer, GLintptr _offset, GLsizeiptr _size); 109 void Reset(); 110 }; 111 112 // This is called when |needs_emulation_| is true, where the range 113 // (offset + size) can't go beyond the buffer's size. 114 static void DoAdjustedBindBufferRange( 115 GLenum target, 116 GLuint index, 117 GLuint service_id, 118 GLintptr offset, 119 GLsizeiptr size, 120 GLsizeiptr full_buffer_size, 121 bool round_down_uniform_bind_buffer_range_size); 122 123 void UpdateMaxNonNullBindingIndex(size_t changed_index); 124 125 std::vector<IndexedBufferBinding> buffer_bindings_; 126 127 bool needs_emulation_; 128 bool round_down_uniform_bind_buffer_range_size_; 129 130 // This is used for optimization purpose in context switching. 131 size_t max_non_null_binding_index_plus_one_; 132 133 // The GL binding point that this host manages 134 // (e.g. GL_TRANSFORM_FEEDBACK_BUFFER). 135 GLenum target_; 136 }; 137 138 } // namespace gles2 139 } // namespace gpu 140 141 #endif // GPU_COMMAND_BUFFER_SERVICE_INDEXED_BUFFER_BINDING_HOST_H_ 142