1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker // BufferGL.cpp: Implements the class methods for BufferGL.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/BufferGL.h"
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/angletypes.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/formatutils.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/ContextGL.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/FunctionsGL.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/StateManagerGL.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/renderergl_utils.h"
20*8975f5c5SAndroid Build Coastguard Worker
21*8975f5c5SAndroid Build Coastguard Worker namespace rx
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker
24*8975f5c5SAndroid Build Coastguard Worker namespace
25*8975f5c5SAndroid Build Coastguard Worker {
26*8975f5c5SAndroid Build Coastguard Worker
KeepBufferShadowCopy(const gl::Context * context,gl::WebGLBufferType webglType)27*8975f5c5SAndroid Build Coastguard Worker bool KeepBufferShadowCopy(const gl::Context *context, gl::WebGLBufferType webglType)
28*8975f5c5SAndroid Build Coastguard Worker {
29*8975f5c5SAndroid Build Coastguard Worker // Always keep a shadow copy if the feature is enabled. This usually means there is no other way
30*8975f5c5SAndroid Build Coastguard Worker // to read back the data.
31*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
32*8975f5c5SAndroid Build Coastguard Worker if (features.keepBufferShadowCopy.enabled)
33*8975f5c5SAndroid Build Coastguard Worker {
34*8975f5c5SAndroid Build Coastguard Worker return true;
35*8975f5c5SAndroid Build Coastguard Worker }
36*8975f5c5SAndroid Build Coastguard Worker
37*8975f5c5SAndroid Build Coastguard Worker // Shadow WebGL index buffers when the driver is unable to provide robust access.
38*8975f5c5SAndroid Build Coastguard Worker // WebGL element array buffers cannot be bound to other binding points or written to on the GPU
39*8975f5c5SAndroid Build Coastguard Worker // so the shadowed data will never be invalidated.
40*8975f5c5SAndroid Build Coastguard Worker if (context->isWebGL() && context->isBufferAccessValidationEnabled() &&
41*8975f5c5SAndroid Build Coastguard Worker webglType == gl::WebGLBufferType::ElementArray)
42*8975f5c5SAndroid Build Coastguard Worker {
43*8975f5c5SAndroid Build Coastguard Worker return true;
44*8975f5c5SAndroid Build Coastguard Worker }
45*8975f5c5SAndroid Build Coastguard Worker
46*8975f5c5SAndroid Build Coastguard Worker return false;
47*8975f5c5SAndroid Build Coastguard Worker }
48*8975f5c5SAndroid Build Coastguard Worker
49*8975f5c5SAndroid Build Coastguard Worker } // namespace
50*8975f5c5SAndroid Build Coastguard Worker
51*8975f5c5SAndroid Build Coastguard Worker // Use the GL_COPY_READ_BUFFER binding when two buffers need to be bound simultaneously.
52*8975f5c5SAndroid Build Coastguard Worker // GL_ELEMENT_ARRAY_BUFFER is supported on more versions but can modify the state of the currently
53*8975f5c5SAndroid Build Coastguard Worker // bound VAO. Two simultaneous buffer bindings are only needed for glCopyBufferSubData which also
54*8975f5c5SAndroid Build Coastguard Worker // adds the GL_COPY_READ_BUFFER binding.
55*8975f5c5SAndroid Build Coastguard Worker static constexpr gl::BufferBinding SourceBufferOperationTarget = gl::BufferBinding::CopyRead;
56*8975f5c5SAndroid Build Coastguard Worker
57*8975f5c5SAndroid Build Coastguard Worker // Use the GL_ELEMENT_ARRAY_BUFFER binding for most operations since it's available on all
58*8975f5c5SAndroid Build Coastguard Worker // supported GL versions and doesn't affect any current state when it changes.
59*8975f5c5SAndroid Build Coastguard Worker static constexpr gl::BufferBinding DestBufferOperationTarget = gl::BufferBinding::Array;
60*8975f5c5SAndroid Build Coastguard Worker
BufferGL(const gl::BufferState & state,GLuint buffer)61*8975f5c5SAndroid Build Coastguard Worker BufferGL::BufferGL(const gl::BufferState &state, GLuint buffer)
62*8975f5c5SAndroid Build Coastguard Worker : BufferImpl(state),
63*8975f5c5SAndroid Build Coastguard Worker mIsMapped(false),
64*8975f5c5SAndroid Build Coastguard Worker mMapOffset(0),
65*8975f5c5SAndroid Build Coastguard Worker mMapSize(0),
66*8975f5c5SAndroid Build Coastguard Worker mShadowCopy(),
67*8975f5c5SAndroid Build Coastguard Worker mBufferSize(0),
68*8975f5c5SAndroid Build Coastguard Worker mBufferID(buffer)
69*8975f5c5SAndroid Build Coastguard Worker {}
70*8975f5c5SAndroid Build Coastguard Worker
~BufferGL()71*8975f5c5SAndroid Build Coastguard Worker BufferGL::~BufferGL()
72*8975f5c5SAndroid Build Coastguard Worker {
73*8975f5c5SAndroid Build Coastguard Worker ASSERT(mBufferID == 0);
74*8975f5c5SAndroid Build Coastguard Worker }
75*8975f5c5SAndroid Build Coastguard Worker
destroy(const gl::Context * context)76*8975f5c5SAndroid Build Coastguard Worker void BufferGL::destroy(const gl::Context *context)
77*8975f5c5SAndroid Build Coastguard Worker {
78*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
79*8975f5c5SAndroid Build Coastguard Worker stateManager->deleteBuffer(mBufferID);
80*8975f5c5SAndroid Build Coastguard Worker mBufferID = 0;
81*8975f5c5SAndroid Build Coastguard Worker }
82*8975f5c5SAndroid Build Coastguard Worker
setData(const gl::Context * context,gl::BufferBinding target,const void * data,size_t size,gl::BufferUsage usage)83*8975f5c5SAndroid Build Coastguard Worker angle::Result BufferGL::setData(const gl::Context *context,
84*8975f5c5SAndroid Build Coastguard Worker gl::BufferBinding target,
85*8975f5c5SAndroid Build Coastguard Worker const void *data,
86*8975f5c5SAndroid Build Coastguard Worker size_t size,
87*8975f5c5SAndroid Build Coastguard Worker gl::BufferUsage usage)
88*8975f5c5SAndroid Build Coastguard Worker {
89*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
90*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
91*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
92*8975f5c5SAndroid Build Coastguard Worker
93*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
94*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->bufferData(gl::ToGLenum(DestBufferOperationTarget), size, data,
95*8975f5c5SAndroid Build Coastguard Worker ToGLenum(usage)));
96*8975f5c5SAndroid Build Coastguard Worker
97*8975f5c5SAndroid Build Coastguard Worker // Initialize the shadow buffer if needed. Don't delete existing shadow data. WebGL allows users
98*8975f5c5SAndroid Build Coastguard Worker // to bind as an element array buffer first and then copy source/dest later (but not the other
99*8975f5c5SAndroid Build Coastguard Worker // way around).
100*8975f5c5SAndroid Build Coastguard Worker if (KeepBufferShadowCopy(context, mState.getWebGLType()) && !mShadowCopy.has_value())
101*8975f5c5SAndroid Build Coastguard Worker {
102*8975f5c5SAndroid Build Coastguard Worker mShadowCopy = angle::MemoryBuffer();
103*8975f5c5SAndroid Build Coastguard Worker }
104*8975f5c5SAndroid Build Coastguard Worker
105*8975f5c5SAndroid Build Coastguard Worker if (mShadowCopy.has_value())
106*8975f5c5SAndroid Build Coastguard Worker {
107*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_ALLOC(contextGL, mShadowCopy->resize(size));
108*8975f5c5SAndroid Build Coastguard Worker
109*8975f5c5SAndroid Build Coastguard Worker if (size > 0 && data != nullptr)
110*8975f5c5SAndroid Build Coastguard Worker {
111*8975f5c5SAndroid Build Coastguard Worker memcpy(mShadowCopy->data(), data, size);
112*8975f5c5SAndroid Build Coastguard Worker }
113*8975f5c5SAndroid Build Coastguard Worker }
114*8975f5c5SAndroid Build Coastguard Worker
115*8975f5c5SAndroid Build Coastguard Worker mBufferSize = size;
116*8975f5c5SAndroid Build Coastguard Worker
117*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
118*8975f5c5SAndroid Build Coastguard Worker
119*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
120*8975f5c5SAndroid Build Coastguard Worker }
121*8975f5c5SAndroid Build Coastguard Worker
setSubData(const gl::Context * context,gl::BufferBinding target,const void * data,size_t size,size_t offset)122*8975f5c5SAndroid Build Coastguard Worker angle::Result BufferGL::setSubData(const gl::Context *context,
123*8975f5c5SAndroid Build Coastguard Worker gl::BufferBinding target,
124*8975f5c5SAndroid Build Coastguard Worker const void *data,
125*8975f5c5SAndroid Build Coastguard Worker size_t size,
126*8975f5c5SAndroid Build Coastguard Worker size_t offset)
127*8975f5c5SAndroid Build Coastguard Worker {
128*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
129*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
130*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
131*8975f5c5SAndroid Build Coastguard Worker
132*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
133*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->bufferSubData(gl::ToGLenum(DestBufferOperationTarget), offset,
134*8975f5c5SAndroid Build Coastguard Worker size, data));
135*8975f5c5SAndroid Build Coastguard Worker
136*8975f5c5SAndroid Build Coastguard Worker if (mShadowCopy.has_value() && size > 0)
137*8975f5c5SAndroid Build Coastguard Worker {
138*8975f5c5SAndroid Build Coastguard Worker memcpy(mShadowCopy->data() + offset, data, size);
139*8975f5c5SAndroid Build Coastguard Worker }
140*8975f5c5SAndroid Build Coastguard Worker
141*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
142*8975f5c5SAndroid Build Coastguard Worker
143*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
144*8975f5c5SAndroid Build Coastguard Worker }
145*8975f5c5SAndroid Build Coastguard Worker
copySubData(const gl::Context * context,BufferImpl * source,GLintptr sourceOffset,GLintptr destOffset,GLsizeiptr size)146*8975f5c5SAndroid Build Coastguard Worker angle::Result BufferGL::copySubData(const gl::Context *context,
147*8975f5c5SAndroid Build Coastguard Worker BufferImpl *source,
148*8975f5c5SAndroid Build Coastguard Worker GLintptr sourceOffset,
149*8975f5c5SAndroid Build Coastguard Worker GLintptr destOffset,
150*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr size)
151*8975f5c5SAndroid Build Coastguard Worker {
152*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
153*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
154*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
155*8975f5c5SAndroid Build Coastguard Worker
156*8975f5c5SAndroid Build Coastguard Worker BufferGL *sourceGL = GetAs<BufferGL>(source);
157*8975f5c5SAndroid Build Coastguard Worker
158*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
159*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(SourceBufferOperationTarget, sourceGL->getBufferID());
160*8975f5c5SAndroid Build Coastguard Worker
161*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->copyBufferSubData(gl::ToGLenum(SourceBufferOperationTarget),
162*8975f5c5SAndroid Build Coastguard Worker gl::ToGLenum(DestBufferOperationTarget),
163*8975f5c5SAndroid Build Coastguard Worker sourceOffset, destOffset, size));
164*8975f5c5SAndroid Build Coastguard Worker
165*8975f5c5SAndroid Build Coastguard Worker if (mShadowCopy.has_value() && size > 0)
166*8975f5c5SAndroid Build Coastguard Worker {
167*8975f5c5SAndroid Build Coastguard Worker // WebGL only allows copying between buffers that are marked as the same type. Both buffers
168*8975f5c5SAndroid Build Coastguard Worker // would have to be element array buffers and have shadow data.
169*8975f5c5SAndroid Build Coastguard Worker ASSERT(sourceGL->mShadowCopy.has_value());
170*8975f5c5SAndroid Build Coastguard Worker
171*8975f5c5SAndroid Build Coastguard Worker ASSERT(sourceGL->mShadowCopy->size() >= static_cast<size_t>(sourceOffset + size));
172*8975f5c5SAndroid Build Coastguard Worker memcpy(mShadowCopy->data() + destOffset, sourceGL->mShadowCopy->data() + sourceOffset,
173*8975f5c5SAndroid Build Coastguard Worker size);
174*8975f5c5SAndroid Build Coastguard Worker }
175*8975f5c5SAndroid Build Coastguard Worker
176*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
177*8975f5c5SAndroid Build Coastguard Worker
178*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
179*8975f5c5SAndroid Build Coastguard Worker }
180*8975f5c5SAndroid Build Coastguard Worker
map(const gl::Context * context,GLenum access,void ** mapPtr)181*8975f5c5SAndroid Build Coastguard Worker angle::Result BufferGL::map(const gl::Context *context, GLenum access, void **mapPtr)
182*8975f5c5SAndroid Build Coastguard Worker {
183*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
184*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
185*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
186*8975f5c5SAndroid Build Coastguard Worker
187*8975f5c5SAndroid Build Coastguard Worker if (mShadowCopy.has_value())
188*8975f5c5SAndroid Build Coastguard Worker {
189*8975f5c5SAndroid Build Coastguard Worker *mapPtr = mShadowCopy->data();
190*8975f5c5SAndroid Build Coastguard Worker }
191*8975f5c5SAndroid Build Coastguard Worker else
192*8975f5c5SAndroid Build Coastguard Worker {
193*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
194*8975f5c5SAndroid Build Coastguard Worker if (functions->mapBuffer)
195*8975f5c5SAndroid Build Coastguard Worker {
196*8975f5c5SAndroid Build Coastguard Worker *mapPtr = ANGLE_GL_TRY(
197*8975f5c5SAndroid Build Coastguard Worker context, functions->mapBuffer(gl::ToGLenum(DestBufferOperationTarget), access));
198*8975f5c5SAndroid Build Coastguard Worker }
199*8975f5c5SAndroid Build Coastguard Worker else
200*8975f5c5SAndroid Build Coastguard Worker {
201*8975f5c5SAndroid Build Coastguard Worker ASSERT(functions->mapBufferRange && access == GL_WRITE_ONLY_OES);
202*8975f5c5SAndroid Build Coastguard Worker *mapPtr = ANGLE_GL_TRY(
203*8975f5c5SAndroid Build Coastguard Worker context, functions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget), 0,
204*8975f5c5SAndroid Build Coastguard Worker mBufferSize, GL_MAP_WRITE_BIT));
205*8975f5c5SAndroid Build Coastguard Worker }
206*8975f5c5SAndroid Build Coastguard Worker
207*8975f5c5SAndroid Build Coastguard Worker // Unbind the mapped buffer from the array buffer binding. Some drivers generate errors if
208*8975f5c5SAndroid Build Coastguard Worker // any mapped buffer is bound to array buffer bindings.
209*8975f5c5SAndroid Build Coastguard Worker // crbug.com/1345777
210*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(DestBufferOperationTarget, 0);
211*8975f5c5SAndroid Build Coastguard Worker }
212*8975f5c5SAndroid Build Coastguard Worker
213*8975f5c5SAndroid Build Coastguard Worker mIsMapped = true;
214*8975f5c5SAndroid Build Coastguard Worker mMapOffset = 0;
215*8975f5c5SAndroid Build Coastguard Worker mMapSize = mBufferSize;
216*8975f5c5SAndroid Build Coastguard Worker
217*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
218*8975f5c5SAndroid Build Coastguard Worker
219*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
220*8975f5c5SAndroid Build Coastguard Worker }
221*8975f5c5SAndroid Build Coastguard Worker
mapRange(const gl::Context * context,size_t offset,size_t length,GLbitfield access,void ** mapPtr)222*8975f5c5SAndroid Build Coastguard Worker angle::Result BufferGL::mapRange(const gl::Context *context,
223*8975f5c5SAndroid Build Coastguard Worker size_t offset,
224*8975f5c5SAndroid Build Coastguard Worker size_t length,
225*8975f5c5SAndroid Build Coastguard Worker GLbitfield access,
226*8975f5c5SAndroid Build Coastguard Worker void **mapPtr)
227*8975f5c5SAndroid Build Coastguard Worker {
228*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
229*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
230*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
231*8975f5c5SAndroid Build Coastguard Worker
232*8975f5c5SAndroid Build Coastguard Worker if (mShadowCopy.has_value())
233*8975f5c5SAndroid Build Coastguard Worker {
234*8975f5c5SAndroid Build Coastguard Worker *mapPtr = mShadowCopy->data() + offset;
235*8975f5c5SAndroid Build Coastguard Worker }
236*8975f5c5SAndroid Build Coastguard Worker else
237*8975f5c5SAndroid Build Coastguard Worker {
238*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
239*8975f5c5SAndroid Build Coastguard Worker *mapPtr =
240*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget),
241*8975f5c5SAndroid Build Coastguard Worker offset, length, access));
242*8975f5c5SAndroid Build Coastguard Worker
243*8975f5c5SAndroid Build Coastguard Worker // Unbind the mapped buffer from the array buffer binding. Some drivers generate errors if
244*8975f5c5SAndroid Build Coastguard Worker // any mapped buffer is bound to array buffer bindings.
245*8975f5c5SAndroid Build Coastguard Worker // crbug.com/1345777
246*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(DestBufferOperationTarget, 0);
247*8975f5c5SAndroid Build Coastguard Worker }
248*8975f5c5SAndroid Build Coastguard Worker
249*8975f5c5SAndroid Build Coastguard Worker mIsMapped = true;
250*8975f5c5SAndroid Build Coastguard Worker mMapOffset = offset;
251*8975f5c5SAndroid Build Coastguard Worker mMapSize = length;
252*8975f5c5SAndroid Build Coastguard Worker
253*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
254*8975f5c5SAndroid Build Coastguard Worker
255*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
256*8975f5c5SAndroid Build Coastguard Worker }
257*8975f5c5SAndroid Build Coastguard Worker
unmap(const gl::Context * context,GLboolean * result)258*8975f5c5SAndroid Build Coastguard Worker angle::Result BufferGL::unmap(const gl::Context *context, GLboolean *result)
259*8975f5c5SAndroid Build Coastguard Worker {
260*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
261*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
262*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
263*8975f5c5SAndroid Build Coastguard Worker
264*8975f5c5SAndroid Build Coastguard Worker ASSERT(result);
265*8975f5c5SAndroid Build Coastguard Worker ASSERT(mIsMapped);
266*8975f5c5SAndroid Build Coastguard Worker
267*8975f5c5SAndroid Build Coastguard Worker if (mShadowCopy.has_value())
268*8975f5c5SAndroid Build Coastguard Worker {
269*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
270*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
271*8975f5c5SAndroid Build Coastguard Worker functions->bufferSubData(gl::ToGLenum(DestBufferOperationTarget), mMapOffset,
272*8975f5c5SAndroid Build Coastguard Worker mMapSize, mShadowCopy->data() + mMapOffset));
273*8975f5c5SAndroid Build Coastguard Worker *result = GL_TRUE;
274*8975f5c5SAndroid Build Coastguard Worker }
275*8975f5c5SAndroid Build Coastguard Worker else
276*8975f5c5SAndroid Build Coastguard Worker {
277*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
278*8975f5c5SAndroid Build Coastguard Worker *result =
279*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->unmapBuffer(gl::ToGLenum(DestBufferOperationTarget)));
280*8975f5c5SAndroid Build Coastguard Worker }
281*8975f5c5SAndroid Build Coastguard Worker
282*8975f5c5SAndroid Build Coastguard Worker mIsMapped = false;
283*8975f5c5SAndroid Build Coastguard Worker
284*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
285*8975f5c5SAndroid Build Coastguard Worker
286*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
287*8975f5c5SAndroid Build Coastguard Worker }
288*8975f5c5SAndroid Build Coastguard Worker
getIndexRange(const gl::Context * context,gl::DrawElementsType type,size_t offset,size_t count,bool primitiveRestartEnabled,gl::IndexRange * outRange)289*8975f5c5SAndroid Build Coastguard Worker angle::Result BufferGL::getIndexRange(const gl::Context *context,
290*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType type,
291*8975f5c5SAndroid Build Coastguard Worker size_t offset,
292*8975f5c5SAndroid Build Coastguard Worker size_t count,
293*8975f5c5SAndroid Build Coastguard Worker bool primitiveRestartEnabled,
294*8975f5c5SAndroid Build Coastguard Worker gl::IndexRange *outRange)
295*8975f5c5SAndroid Build Coastguard Worker {
296*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
297*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
298*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
299*8975f5c5SAndroid Build Coastguard Worker
300*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mIsMapped);
301*8975f5c5SAndroid Build Coastguard Worker
302*8975f5c5SAndroid Build Coastguard Worker if (mShadowCopy.has_value())
303*8975f5c5SAndroid Build Coastguard Worker {
304*8975f5c5SAndroid Build Coastguard Worker *outRange = gl::ComputeIndexRange(type, mShadowCopy->data() + offset, count,
305*8975f5c5SAndroid Build Coastguard Worker primitiveRestartEnabled);
306*8975f5c5SAndroid Build Coastguard Worker }
307*8975f5c5SAndroid Build Coastguard Worker else
308*8975f5c5SAndroid Build Coastguard Worker {
309*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
310*8975f5c5SAndroid Build Coastguard Worker
311*8975f5c5SAndroid Build Coastguard Worker const GLuint typeBytes = gl::GetDrawElementsTypeSize(type);
312*8975f5c5SAndroid Build Coastguard Worker const uint8_t *bufferData =
313*8975f5c5SAndroid Build Coastguard Worker MapBufferRangeWithFallback(functions, gl::ToGLenum(DestBufferOperationTarget), offset,
314*8975f5c5SAndroid Build Coastguard Worker count * typeBytes, GL_MAP_READ_BIT);
315*8975f5c5SAndroid Build Coastguard Worker if (bufferData)
316*8975f5c5SAndroid Build Coastguard Worker {
317*8975f5c5SAndroid Build Coastguard Worker *outRange = gl::ComputeIndexRange(type, bufferData, count, primitiveRestartEnabled);
318*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->unmapBuffer(gl::ToGLenum(DestBufferOperationTarget)));
319*8975f5c5SAndroid Build Coastguard Worker }
320*8975f5c5SAndroid Build Coastguard Worker else
321*8975f5c5SAndroid Build Coastguard Worker {
322*8975f5c5SAndroid Build Coastguard Worker // Workaround the null driver not having map support.
323*8975f5c5SAndroid Build Coastguard Worker *outRange = gl::IndexRange(0, 0, 1);
324*8975f5c5SAndroid Build Coastguard Worker }
325*8975f5c5SAndroid Build Coastguard Worker }
326*8975f5c5SAndroid Build Coastguard Worker
327*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
328*8975f5c5SAndroid Build Coastguard Worker
329*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
330*8975f5c5SAndroid Build Coastguard Worker }
331*8975f5c5SAndroid Build Coastguard Worker
getBufferSize() const332*8975f5c5SAndroid Build Coastguard Worker size_t BufferGL::getBufferSize() const
333*8975f5c5SAndroid Build Coastguard Worker {
334*8975f5c5SAndroid Build Coastguard Worker return mBufferSize;
335*8975f5c5SAndroid Build Coastguard Worker }
336*8975f5c5SAndroid Build Coastguard Worker
getBufferID() const337*8975f5c5SAndroid Build Coastguard Worker GLuint BufferGL::getBufferID() const
338*8975f5c5SAndroid Build Coastguard Worker {
339*8975f5c5SAndroid Build Coastguard Worker return mBufferID;
340*8975f5c5SAndroid Build Coastguard Worker }
341*8975f5c5SAndroid Build Coastguard Worker } // namespace rx
342