Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: third_party/WebKit/Source/modules/webgl/WebGLGetBufferSubDataAsync.cpp

Issue 2569863005: Move getBufferSubDataAsync to an extension (Closed)
Patch Set: fixup Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 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 #include "modules/webgl/WebGLGetBufferSubDataAsync.h"
6
7 #include "core/dom/DOMException.h"
8 #include "gpu/GLES2/gl2extchromium.h"
9 #include "gpu/command_buffer/client/gles2_interface.h"
10 #include "modules/webgl/WebGL2RenderingContextBase.h"
11
12 namespace blink {
13
14 WebGLGetBufferSubDataAsync::WebGLGetBufferSubDataAsync(
15 WebGLRenderingContextBase* context)
16 : WebGLExtension(context) {}
17
18 WebGLExtensionName WebGLGetBufferSubDataAsync::name() const {
19 return WebGLGetBufferSubDataAsyncName;
20 }
21
22 WebGLGetBufferSubDataAsync* WebGLGetBufferSubDataAsync::create(
23 WebGLRenderingContextBase* context) {
24 return new WebGLGetBufferSubDataAsync(context);
25 }
26
27 bool WebGLGetBufferSubDataAsync::supported(WebGLRenderingContextBase* context) {
28 return true;
29 }
30
31 const char* WebGLGetBufferSubDataAsync::extensionName() {
32 return "WEBGL_get_buffer_sub_data_async";
33 }
34
35 ScriptPromise WebGLGetBufferSubDataAsync::getBufferSubDataAsync(
36 ScriptState* scriptState,
37 GLenum target,
38 GLintptr srcByteOffset,
39 DOMArrayBufferView* dstData,
40 GLuint dstOffset,
41 GLuint length) {
42 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
43 ScriptPromise promise = resolver->promise();
44
45 WebGLExtensionScopedContext scoped(this);
46 if (scoped.isLost()) {
47 DOMException* exception =
48 DOMException::create(InvalidStateError, "context lost");
49 resolver->reject(exception);
50 return promise;
51 }
52
53 WebGL2RenderingContextBase* context = nullptr;
54 {
55 WebGLRenderingContextBase* contextBase = scoped.context();
56 DCHECK_GE(contextBase->version(), 2u);
57 context = static_cast<WebGL2RenderingContextBase*>(contextBase);
58 }
59
60 WebGLBuffer* sourceBuffer = nullptr;
61 void* destinationDataPtr = nullptr;
62 long long destinationByteLength = 0;
63 const char* message = context->validateGetBufferSubData(
64 __FUNCTION__, target, srcByteOffset, dstData, dstOffset, length,
65 &sourceBuffer, &destinationDataPtr, &destinationByteLength);
66 if (message) {
67 // If there was a GL error, it was already synthesized in
68 // validateGetBufferSubData, so it's not done here.
69 DOMException* exception = DOMException::create(InvalidStateError, message);
70 resolver->reject(exception);
71 return promise;
72 }
73
74 message = context->validateGetBufferSubDataBounds(
75 __FUNCTION__, sourceBuffer, srcByteOffset, destinationByteLength);
76 if (message) {
77 // If there was a GL error, it was already synthesized in
78 // validateGetBufferSubDataBounds, so it's not done here.
79 DOMException* exception = DOMException::create(InvalidStateError, message);
80 resolver->reject(exception);
81 return promise;
82 }
83
84 // If the length of the copy is zero, this is a no-op.
85 if (!destinationByteLength) {
86 resolver->resolve(dstData);
87 return promise;
88 }
89
90 GLuint queryID;
91 context->contextGL()->GenQueriesEXT(1, &queryID);
92 context->contextGL()->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, queryID);
93 void* mappedData = context->contextGL()->GetBufferSubDataAsyncCHROMIUM(
94 target, srcByteOffset, destinationByteLength);
95 context->contextGL()->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
96 if (!mappedData) {
97 DOMException* exception =
98 DOMException::create(InvalidStateError, "Out of memory");
99 resolver->reject(exception);
100 return promise;
101 }
102
103 auto callbackObject = new WebGLGetBufferSubDataAsyncCallback(
104 context, resolver, mappedData, queryID, dstData, destinationDataPtr,
105 destinationByteLength);
106 context->registerGetBufferSubDataAsyncCallback(callbackObject);
107 auto callback = WTF::bind(&WebGLGetBufferSubDataAsyncCallback::resolve,
108 wrapPersistent(callbackObject));
109 context->drawingBuffer()->contextProvider()->signalQuery(
110 queryID, convertToBaseCallback(std::move(callback)));
111
112 return promise;
113 }
114
115 WebGLGetBufferSubDataAsyncCallback::WebGLGetBufferSubDataAsyncCallback(
116 WebGL2RenderingContextBase* context,
117 ScriptPromiseResolver* promiseResolver,
118 void* shmReadbackResultData,
119 GLuint commandsIssuedQueryID,
120 DOMArrayBufferView* destinationArrayBufferView,
121 void* destinationDataPtr,
122 long long destinationByteLength)
123 : m_context(context),
124 m_promiseResolver(promiseResolver),
125 m_shmReadbackResultData(shmReadbackResultData),
126 m_commandsIssuedQueryID(commandsIssuedQueryID),
127 m_destinationArrayBufferView(destinationArrayBufferView),
128 m_destinationDataPtr(destinationDataPtr),
129 m_destinationByteLength(destinationByteLength) {
130 DCHECK(shmReadbackResultData);
131 DCHECK(destinationDataPtr);
132 }
133
134 void WebGLGetBufferSubDataAsyncCallback::destroy() {
135 DCHECK(m_shmReadbackResultData);
136 m_context->contextGL()->FreeSharedMemory(m_shmReadbackResultData);
137 m_shmReadbackResultData = nullptr;
138 DOMException* exception =
139 DOMException::create(InvalidStateError, "Context lost or destroyed");
140 m_promiseResolver->reject(exception);
141 }
142
143 void WebGLGetBufferSubDataAsyncCallback::resolve() {
144 if (!m_context || !m_shmReadbackResultData) {
145 DOMException* exception =
146 DOMException::create(InvalidStateError, "Context lost or destroyed");
147 m_promiseResolver->reject(exception);
148 return;
149 }
150 if (m_destinationArrayBufferView->buffer()->isNeutered()) {
151 DOMException* exception = DOMException::create(
152 InvalidStateError, "ArrayBufferView became invalid asynchronously");
153 m_promiseResolver->reject(exception);
154 return;
155 }
156 memcpy(m_destinationDataPtr, m_shmReadbackResultData,
157 m_destinationByteLength);
158 // TODO(kainino): What would happen if the DOM was suspended when the
159 // promise became resolved? Could another JS task happen between the memcpy
160 // and the promise resolution task, which would see the wrong data?
161 m_promiseResolver->resolve(m_destinationArrayBufferView);
162
163 m_context->contextGL()->DeleteQueriesEXT(1, &m_commandsIssuedQueryID);
164 this->destroy();
165 m_context->unregisterGetBufferSubDataAsyncCallback(this);
166 }
167
168 DEFINE_TRACE(WebGLGetBufferSubDataAsyncCallback) {
169 visitor->trace(m_context);
170 visitor->trace(m_promiseResolver);
171 visitor->trace(m_destinationArrayBufferView);
172 }
173
174 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698