blob: bf674601f1919271bf43676f9b21ebbe415679aa [file] [log] [blame]
[email protected]529c6672012-01-04 02:18:261// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]96449d2c2009-11-25 00:01:322// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]8a837bb2010-01-05 00:21:245#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
[email protected]74470702010-01-06 18:51:166
7#include <stdio.h>
8
[email protected]1aef98132010-02-23 18:00:079#include <algorithm>
mateuszs3371ab02015-04-24 13:20:2310#include <cmath>
[email protected]f39f4b3f2010-05-12 17:04:0811#include <list>
[email protected]96449d2c2009-11-25 00:01:3212#include <map>
dcastagna504d45c2015-04-06 19:30:3913#include <queue>
[email protected]5a6db6c2010-04-22 18:32:0614
[email protected]00eb49a2010-08-12 20:46:5715#include "base/at_exit.h"
[email protected]9d37f062011-11-22 01:24:5216#include "base/bind.h"
martina.kollarovaa34211d2015-06-25 11:49:0717#include "base/callback.h"
[email protected]e3c4a9ab2014-03-31 09:07:0218#include "base/callback_helpers.h"
[email protected]e844ae22012-01-14 03:36:2619#include "base/command_line.h"
[email protected]3b63f8f42011-03-28 01:54:1520#include "base/memory/scoped_ptr.h"
[email protected]e3c4a9ab2014-03-31 09:07:0221#include "base/numerics/safe_math.h"
[email protected]f4390962013-06-11 07:29:2222#include "base/strings/string_number_conversions.h"
[email protected]6d668892013-12-04 21:37:1223#include "base/strings/string_split.h"
primiano05dadf012015-01-28 13:10:3224#include "base/trace_event/trace_event.h"
25#include "base/trace_event/trace_event_synthetic_delay.h"
[email protected]d37231fa2010-04-09 21:16:0226#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3227#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2228#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3229#include "gpu/command_buffer/common/gles2_cmd_format.h"
30#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1031#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5132#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2233#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
34#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5035#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3236#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5037#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2438#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5039#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1140#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5841#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3242#include "gpu/command_buffer/service/gl_utils.h"
sievers2384f2b2014-11-18 02:10:3543#include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h"
[email protected]43410e92012-04-20 17:06:2844#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4645#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1346#include "gpu/command_buffer/service/gpu_state_tracer.h"
[email protected]e844ae22012-01-14 03:36:2647#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1448#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3749#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5950#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2551#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4752#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5353#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5854#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4755#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4556#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0457#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]a93bb842010-02-16 23:03:4758#include "gpu/command_buffer/service/texture_manager.h"
orglofchcad5a6742014-11-07 19:51:1259#include "gpu/command_buffer/service/valuebuffer_manager.h"
[email protected]944b62f32012-09-27 02:20:4660#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2261#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]6896d7f2014-04-28 20:24:1562#include "third_party/smhasher/src/City.h"
martina.kollarovaa34211d2015-06-25 11:49:0763#include "ui/gfx/geometry/size.h"
64#include "ui/gl/gl_context.h"
[email protected]5a36dc132013-07-23 23:17:5565#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3766#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2767#include "ui/gl/gl_implementation.h"
68#include "ui/gl/gl_surface.h"
dyen1fa421962015-06-17 21:25:3969#include "ui/gl/gpu_timing.h"
[email protected]423e644f2013-06-19 00:48:2770
[email protected]e51bdf32011-11-23 22:21:4671#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:5372#include <IOSurface/IOSurfaceAPI.h>
73// Note that this must be included after gl_bindings.h to avoid conflicts.
74#include <OpenGL/CGLIOSurface.h>
[email protected]e51bdf32011-11-23 22:21:4675#endif
[email protected]de17df392010-04-23 21:09:4176
[email protected]a7a27ace2009-12-12 00:11:2577namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3278namespace gles2 {
79
[email protected]f0d74742011-10-03 16:31:0480namespace {
[email protected]693ca512012-11-13 18:09:1381
dongseong.hwang46305b12015-03-05 18:28:0482const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
83const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
84const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
85const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
86
87const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
88 0.0f, 1.0f, 0.0f, 0.0f,
89 0.0f, 0.0f, 1.0f, 0.0f,
90 0.0f, 0.0f, 0.0f, 1.0f};
[email protected]693ca512012-11-13 18:09:1391
zmo4c0c3532015-05-22 20:04:4892bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
[email protected]448e459e2013-06-12 17:00:4193 GLint rangeMax,
94 GLint precision) {
95 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
96}
97
zmo4c0c3532015-05-22 20:04:4898void GetShaderPrecisionFormatImpl(GLenum shader_type,
[email protected]8dc1bf92013-03-12 03:58:2199 GLenum precision_type,
dcastagna504d45c2015-04-06 19:30:39100 GLint* range, GLint* precision) {
[email protected]8dc1bf92013-03-12 03:58:21101 switch (precision_type) {
102 case GL_LOW_INT:
103 case GL_MEDIUM_INT:
104 case GL_HIGH_INT:
105 // These values are for a 32-bit twos-complement integer format.
106 range[0] = 31;
107 range[1] = 30;
108 *precision = 0;
109 break;
110 case GL_LOW_FLOAT:
111 case GL_MEDIUM_FLOAT:
112 case GL_HIGH_FLOAT:
113 // These values are for an IEEE single-precision floating-point format.
114 range[0] = 127;
115 range[1] = 127;
116 *precision = 23;
117 break;
118 default:
119 NOTREACHED();
120 break;
121 }
122
[email protected]8af4d5e2013-03-15 23:55:33123 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
124 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21125 // This function is sometimes defined even though it's really just
126 // a stub, so we need to set range and precision as if it weren't
127 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44128 // On Mac OS with some GPUs, calling this generates a
129 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
130 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21131 glGetShaderPrecisionFormat(shader_type, precision_type,
132 range, precision);
[email protected]448e459e2013-06-12 17:00:41133
134 // TODO(brianderson): Make the following official workarounds.
135
136 // Some drivers have bugs where they report the ranges as a negative number.
137 // Taking the absolute value here shouldn't hurt because negative numbers
138 // aren't expected anyway.
139 range[0] = abs(range[0]);
140 range[1] = abs(range[1]);
141
142 // If the driver reports a precision for highp float that isn't actually
143 // highp, don't pretend like it's supported because shader compilation will
144 // fail anyway.
145 if (precision_type == GL_HIGH_FLOAT &&
146 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
147 range[0] = 0;
148 range[1] = 0;
149 *precision = 0;
150 }
[email protected]8dc1bf92013-03-12 03:58:21151 }
152}
153
zmo4c0c3532015-05-22 20:04:48154gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
[email protected]d286ebbc2014-07-03 17:19:10155 switch (plane_transform) {
156 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
157 return gfx::OVERLAY_TRANSFORM_NONE;
158 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
159 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
160 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
161 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
162 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
163 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
164 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
165 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
166 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
167 return gfx::OVERLAY_TRANSFORM_ROTATE_270;
168 default:
169 return gfx::OVERLAY_TRANSFORM_INVALID;
170 }
171}
172
zmo4c0c3532015-05-22 20:04:48173template <typename MANAGER_TYPE, typename OBJECT_TYPE>
174GLuint GetClientId(const MANAGER_TYPE* manager, const OBJECT_TYPE* object) {
175 DCHECK(manager);
176 GLuint client_id = 0;
177 if (object) {
178 manager->GetClientId(object->service_id(), &client_id);
179 }
180 return client_id;
181}
182
zmo5ee097e2015-05-14 19:13:52183struct Vec4f {
184 explicit Vec4f(const Vec4& data) {
185 data.GetValues(v);
186 }
187
188 GLfloat v[4];
189};
190
reveman7c4a13b2015-06-05 22:28:15191// Returns the union of |rect1| and |rect2| if one of the rectangles is empty,
192// contains the other rectangle or shares an edge with the other rectangle.
193bool CombineAdjacentRects(const gfx::Rect& rect1,
194 const gfx::Rect& rect2,
195 gfx::Rect* result) {
196 // Return |rect2| if |rect1| is empty or |rect2| contains |rect1|.
197 if (rect1.IsEmpty() || rect2.Contains(rect1)) {
198 *result = rect2;
199 return true;
200 }
201
202 // Return |rect1| if |rect2| is empty or |rect1| contains |rect2|.
203 if (rect2.IsEmpty() || rect1.Contains(rect2)) {
204 *result = rect1;
205 return true;
206 }
207
208 // Return the union of |rect1| and |rect2| if they share an edge.
209 if (rect1.SharesEdgeWith(rect2)) {
210 *result = gfx::UnionRects(rect1, rect2);
211 return true;
212 }
213
214 // Return false if it's not possible to combine |rect1| and |rect2|.
215 return false;
216}
217
[email protected]b04e24c2013-01-08 18:35:25218} // namespace
[email protected]f0d74742011-10-03 16:31:04219
[email protected]6217d392010-03-25 22:08:35220class GLES2DecoderImpl;
221
[email protected]ab09b612013-03-11 22:11:51222// Local versions of the SET_GL_ERROR macros
223#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50224 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51225#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50226 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
227 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51228#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50229 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
230 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51231#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50232 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
233 function_name)
[email protected]ab09b612013-03-11 22:11:51234#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50235 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51236#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50237 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51238#define LOCAL_PERFORMANCE_WARNING(msg) \
239 PerformanceWarning(__FILE__, __LINE__, msg)
240#define LOCAL_RENDER_WARNING(msg) \
241 RenderWarning(__FILE__, __LINE__, msg)
242
[email protected]07f54fcc2009-12-22 02:46:30243// Check that certain assumptions the code makes are true. There are places in
244// the code where shared memory is passed direclty to GL. Example, glUniformiv,
245// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
246// a few others) are 32bits. If they are not 32bits the code will have to change
247// to call those GL functions with service side memory and then copy the results
248// to shared memory, converting the sizes.
mostynb7f032092014-12-20 00:36:44249static_assert(sizeof(GLint) == sizeof(uint32), // NOLINT
250 "GLint should be the same size as uint32");
251static_assert(sizeof(GLsizei) == sizeof(uint32), // NOLINT
252 "GLsizei should be the same size as uint32");
253static_assert(sizeof(GLfloat) == sizeof(float), // NOLINT
254 "GLfloat should be the same size as float");
[email protected]07f54fcc2009-12-22 02:46:30255
[email protected]43f28f832010-02-03 02:28:48256// TODO(kbr): the use of this anonymous namespace core dumps the
257// linker on Mac OS X 10.6 when the symbol ordering file is used
258// namespace {
[email protected]96449d2c2009-11-25 00:01:32259
260// Returns the address of the first byte after a struct.
261template <typename T>
262const void* AddressAfterStruct(const T& pod) {
263 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
264}
265
[email protected]07f54fcc2009-12-22 02:46:30266// Returns the address of the frst byte after the struct or NULL if size >
267// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32268template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30269RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
270 uint32 size,
271 uint32 immediate_data_size) {
272 return (size <= immediate_data_size) ?
273 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
274 NULL;
[email protected]96449d2c2009-11-25 00:01:32275}
276
[email protected]07f54fcc2009-12-22 02:46:30277// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18278bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32279 GLuint count,
280 size_t size,
[email protected]a76b0052010-03-05 00:33:18281 unsigned int elements_per_unit,
282 uint32* dst) {
283 uint32 value;
284 if (!SafeMultiplyUint32(count, size, &value)) {
285 return false;
286 }
287 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
288 return false;
289 }
290 *dst = value;
291 return true;
[email protected]96449d2c2009-11-25 00:01:32292}
293
[email protected]258a3313f2011-10-18 20:13:57294// Return true if a character belongs to the ASCII subset as defined in
295// GLSL ES 1.0 spec section 3.1.
296static bool CharacterIsValidForGLES(unsigned char c) {
297 // Printing characters are valid except " $ ` @ \ ' DEL.
298 if (c >= 32 && c <= 126 &&
299 c != '"' &&
300 c != '$' &&
301 c != '`' &&
302 c != '@' &&
303 c != '\\' &&
304 c != '\'') {
305 return true;
306 }
307 // Horizontal tab, line feed, vertical tab, form feed, carriage return
308 // are also valid.
309 if (c >= 9 && c <= 13) {
310 return true;
311 }
312
313 return false;
314}
315
316static bool StringIsValidForGLES(const char* str) {
317 for (; *str; ++str) {
318 if (!CharacterIsValidForGLES(*str)) {
319 return false;
320 }
321 }
322 return true;
323}
324
[email protected]6217d392010-03-25 22:08:35325// This class prevents any GL errors that occur when it is in scope from
326// being reported to the client.
327class ScopedGLErrorSuppressor {
328 public:
[email protected]ab09b612013-03-11 22:11:51329 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30330 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35331 ~ScopedGLErrorSuppressor();
332 private:
[email protected]ab09b612013-03-11 22:11:51333 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30334 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35335 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
336};
337
[email protected]2b10c02d2014-01-29 16:43:02338// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35339// object goes out of scope. Also temporarily switches to using active texture
340// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02341class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35342 public:
[email protected]00c2cf92014-03-14 00:08:37343 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02344 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35345
346 private:
[email protected]ce296892013-10-24 22:04:36347 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02348 GLenum target_;
349 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35350};
351
352// Temporarily changes a decoder's bound render buffer and restore it when this
353// object goes out of scope.
354class ScopedRenderBufferBinder {
355 public:
[email protected]00c2cf92014-03-14 00:08:37356 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35357 ~ScopedRenderBufferBinder();
358
359 private:
[email protected]18e785a2013-10-09 03:29:41360 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35361 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
362};
363
364// Temporarily changes a decoder's bound frame buffer and restore it when this
365// object goes out of scope.
366class ScopedFrameBufferBinder {
367 public:
[email protected]00c2cf92014-03-14 00:08:37368 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35369 ~ScopedFrameBufferBinder();
370
371 private:
372 GLES2DecoderImpl* decoder_;
373 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
374};
375
[email protected]34ff8b0c2010-10-01 20:06:02376// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52377// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27378// if it is bound or enforce_internal_framebuffer is true. If internal is
379// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02380class ScopedResolvedFrameBufferBinder {
381 public:
[email protected]00c2cf92014-03-14 00:08:37382 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
383 bool enforce_internal_framebuffer,
384 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02385 ~ScopedResolvedFrameBufferBinder();
386
387 private:
388 GLES2DecoderImpl* decoder_;
389 bool resolve_and_bind_;
390 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
391};
392
[email protected]00c2cf92014-03-14 00:08:37393class ScopedModifyPixels {
394 public:
395 explicit ScopedModifyPixels(TextureRef* ref);
396 ~ScopedModifyPixels();
397
398 private:
399 TextureRef* ref_;
400};
401
402ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
403 if (ref_)
404 ref_->texture()->OnWillModifyPixels();
405}
406
407ScopedModifyPixels::~ScopedModifyPixels() {
408 if (ref_)
409 ref_->texture()->OnDidModifyPixels();
410}
411
412class ScopedRenderTo {
413 public:
414 explicit ScopedRenderTo(Framebuffer* framebuffer);
415 ~ScopedRenderTo();
416
417 private:
418 const Framebuffer* framebuffer_;
419};
420
421ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
422 : framebuffer_(framebuffer) {
423 if (framebuffer)
424 framebuffer_->OnWillRenderTo();
425}
426
427ScopedRenderTo::~ScopedRenderTo() {
428 if (framebuffer_)
429 framebuffer_->OnDidRenderTo();
430}
431
[email protected]6217d392010-03-25 22:08:35432// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35433class BackTexture {
[email protected]6217d392010-03-25 22:08:35434 public:
[email protected]ce296892013-10-24 22:04:36435 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35436 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35437
438 // Create a new render texture.
439 void Create();
440
441 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09442 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35443
444 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58445 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35446
447 // Destroy the render texture. This must be explicitly called before
448 // destroying this object.
449 void Destroy();
450
[email protected]97872062010-11-03 19:07:05451 // Invalidate the texture. This can be used when a context is lost and it is
452 // not possible to make it current in order to free the resource.
453 void Invalidate();
454
[email protected]6217d392010-03-25 22:08:35455 GLuint id() const {
456 return id_;
457 }
458
[email protected]d37231fa2010-04-09 21:16:02459 gfx::Size size() const {
460 return size_;
461 }
462
[email protected]6217d392010-03-25 22:08:35463 private:
[email protected]ff6493f2012-07-31 19:52:25464 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36465 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48466 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35467 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02468 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35469 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35470};
471
472// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35473class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35474 public:
[email protected]d5a28e452013-10-10 01:01:40475 explicit BackRenderbuffer(
476 RenderbufferManager* renderbuffer_manager,
477 MemoryTracker* memory_tracker,
478 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35479 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35480
481 // Create a new render buffer.
482 void Create();
483
484 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18485 bool AllocateStorage(const FeatureInfo* feature_info,
486 const gfx::Size& size,
487 GLenum format,
488 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35489
490 // Destroy the render buffer. This must be explicitly called before destroying
491 // this object.
492 void Destroy();
493
[email protected]97872062010-11-03 19:07:05494 // Invalidate the render buffer. This can be used when a context is lost and
495 // it is not possible to make it current in order to free the resource.
496 void Invalidate();
497
[email protected]6217d392010-03-25 22:08:35498 GLuint id() const {
499 return id_;
500 }
501
502 private:
[email protected]d5a28e452013-10-10 01:01:40503 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25504 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40505 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48506 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35507 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35508 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35509};
510
511// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35512class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35513 public:
[email protected]ed9f9cd2013-02-27 21:12:35514 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
515 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35516
517 // Create a new frame buffer.
518 void Create();
519
520 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35521 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35522
[email protected]b9363b22010-06-09 22:06:15523 // Attach a render buffer to a frame buffer. Note that this unbinds any
524 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35525 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35526
[email protected]6217d392010-03-25 22:08:35527 // Destroy the frame buffer. This must be explicitly called before destroying
528 // this object.
529 void Destroy();
530
[email protected]97872062010-11-03 19:07:05531 // Invalidate the frame buffer. This can be used when a context is lost and it
532 // is not possible to make it current in order to free the resource.
533 void Invalidate();
534
[email protected]6217d392010-03-25 22:08:35535 // See glCheckFramebufferStatusEXT.
536 GLenum CheckStatus();
537
538 GLuint id() const {
539 return id_;
540 }
541
542 private:
543 GLES2DecoderImpl* decoder_;
544 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35545 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35546};
[email protected]34ff8b0c2010-10-01 20:06:02547
[email protected]5a36dc132013-07-23 23:17:55548struct FenceCallback {
dcastagna504d45c2015-04-06 19:30:39549 FenceCallback()
[email protected]5a36dc132013-07-23 23:17:55550 : fence(gfx::GLFence::Create()) {
551 DCHECK(fence);
552 }
[email protected]5a36dc132013-07-23 23:17:55553 std::vector<base::Closure> callbacks;
554 scoped_ptr<gfx::GLFence> fence;
555};
556
[email protected]e3c4a9ab2014-03-31 09:07:02557class AsyncUploadTokenCompletionObserver
558 : public AsyncPixelTransferCompletionObserver {
559 public:
560 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
561 : async_upload_token_(async_upload_token) {
562 }
563
dcheng1f4d1d72014-10-21 16:21:58564 void DidComplete(const AsyncMemoryParams& mem_params) override {
dcheng6ef3c5552014-08-30 05:34:19565 DCHECK(mem_params.buffer().get());
[email protected]e3c4a9ab2014-03-31 09:07:02566 void* data = mem_params.GetDataAddress();
567 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
568 sync->SetAsyncUploadToken(async_upload_token_);
569 }
570
571 private:
dcheng1f4d1d72014-10-21 16:21:58572 ~AsyncUploadTokenCompletionObserver() override {}
[email protected]e3c4a9ab2014-03-31 09:07:02573
574 uint32 async_upload_token_;
575
576 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
577};
578
[email protected]43f28f832010-02-03 02:28:48579// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32580
[email protected]efc87712014-07-09 00:22:47581// static
582const unsigned int GLES2Decoder::kDefaultStencilMask =
583 static_cast<unsigned int>(-1);
584
[email protected]ddb1e5a2010-12-13 20:10:45585bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
586 uint32* service_texture_id) {
587 return false;
588}
589
[email protected]a3ded6d2010-10-19 06:44:39590GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06591 : initialized_(false),
592 debug_(false),
zmo84c08202014-11-23 15:28:40593 log_commands_(false),
594 unsafe_es3_apis_enabled_(false) {
[email protected]96449d2c2009-11-25 00:01:32595}
596
[email protected]3916c97e2010-02-25 03:20:50597GLES2Decoder::~GLES2Decoder() {
598}
599
[email protected]cac16542014-01-15 17:53:51600void GLES2Decoder::BeginDecoding() {}
601
602void GLES2Decoder::EndDecoding() {}
603
[email protected]f39f4b3f2010-05-12 17:04:08604// This class implements GLES2Decoder so we don't have to expose all the GLES2
605// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54606class GLES2DecoderImpl : public GLES2Decoder,
[email protected]828a3932014-04-02 14:43:13607 public FramebufferManager::TextureDetachObserver,
608 public ErrorStateClient {
[email protected]f39f4b3f2010-05-12 17:04:08609 public:
[email protected]aa7666122011-09-02 19:45:52610 explicit GLES2DecoderImpl(ContextGroup* group);
dcheng1f4d1d72014-10-21 16:21:58611 ~GLES2DecoderImpl() override;
[email protected]f39f4b3f2010-05-12 17:04:08612
[email protected]96449d2c2009-11-25 00:01:32613 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58614 Error DoCommand(unsigned int command,
615 unsigned int arg_count,
616 const void* args) override;
[email protected]96449d2c2009-11-25 00:01:32617
dcheng1f4d1d72014-10-21 16:21:58618 error::Error DoCommands(unsigned int num_commands,
619 const void* buffer,
620 int num_entries,
621 int* entries_processed) override;
vmiura8266ca72014-09-09 21:37:00622
vmiura1c2b1de2014-09-19 19:03:24623 template <bool DebugImpl>
624 error::Error DoCommandsImpl(unsigned int num_commands,
625 const void* buffer,
626 int num_entries,
627 int* entries_processed);
628
[email protected]96449d2c2009-11-25 00:01:32629 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58630 const char* GetCommandName(unsigned int command_id) const override;
[email protected]96449d2c2009-11-25 00:01:32631
632 // Overridden from GLES2Decoder.
dcheng1f4d1d72014-10-21 16:21:58633 bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
634 const scoped_refptr<gfx::GLContext>& context,
635 bool offscreen,
dongseong.hwang4c04a162015-03-04 07:27:33636 const gfx::Size& offscreen_size,
dcheng1f4d1d72014-10-21 16:21:58637 const DisallowedFeatures& disallowed_features,
638 const std::vector<int32>& attribs) override;
639 void Destroy(bool have_context) override;
640 void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
641 void ProduceFrontBuffer(const Mailbox& mailbox) override;
642 bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
[email protected]9a5afa432011-07-22 18:16:39643 void UpdateParentTextureInfo();
dcheng1f4d1d72014-10-21 16:21:58644 bool MakeCurrent() override;
645 GLES2Util* GetGLES2Util() override { return &util_; }
646 gfx::GLContext* GetGLContext() override { return context_.get(); }
647 ContextGroup* GetContextGroup() override { return group_.get(); }
648 Capabilities GetCapabilities() override;
649 void RestoreState(const ContextState* prev_state) override;
[email protected]29a4d902013-02-26 20:18:06650
dcheng1f4d1d72014-10-21 16:21:58651 void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); }
652 void RestoreAllTextureUnitBindings(
mohan.reddy5e1b8952014-10-08 01:38:17653 const ContextState* prev_state) const override {
[email protected]5baa86bc2014-01-16 04:33:16654 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55655 }
dcheng1f4d1d72014-10-21 16:21:58656 void RestoreActiveTextureUnitBinding(unsigned int target) const override {
[email protected]4b2d2b262014-03-21 22:05:27657 state_.RestoreActiveTextureUnitBinding(target);
658 }
dcheng1f4d1d72014-10-21 16:21:58659 void RestoreBufferBindings() const override {
[email protected]29a4d902013-02-26 20:18:06660 state_.RestoreBufferBindings();
661 }
dcheng1f4d1d72014-10-21 16:21:58662 void RestoreGlobalState() const override { state_.RestoreGlobalState(NULL); }
663 void RestoreProgramBindings() const override {
[email protected]29a4d902013-02-26 20:18:06664 state_.RestoreProgramBindings();
665 }
dcheng1f4d1d72014-10-21 16:21:58666 void RestoreTextureUnitBindings(unsigned unit) const override {
[email protected]5baa86bc2014-01-16 04:33:16667 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06668 }
dcheng1f4d1d72014-10-21 16:21:58669 void RestoreFramebufferBindings() const override;
670 void RestoreRenderbufferBindings() override;
671 void RestoreTextureState(unsigned service_id) const override;
[email protected]29a4d902013-02-26 20:18:06672
dcheng1f4d1d72014-10-21 16:21:58673 void ClearAllAttributes() const override;
674 void RestoreAllAttributes() const override;
[email protected]cd2ef752014-02-12 23:16:03675
dcheng1f4d1d72014-10-21 16:21:58676 QueryManager* GetQueryManager() override { return query_manager_.get(); }
677 VertexArrayManager* GetVertexArrayManager() override {
[email protected]944b62f32012-09-27 02:20:46678 return vertex_array_manager_.get();
679 }
dcheng1f4d1d72014-10-21 16:21:58680 ImageManager* GetImageManager() override { return image_manager_.get(); }
orglofch33edd842014-12-03 05:32:15681
682 ValuebufferManager* GetValuebufferManager() override {
683 return valuebuffer_manager();
684 }
685
revemancc241eb2014-11-11 03:30:37686 bool ProcessPendingQueries(bool did_finish) override;
orglofch33edd842014-12-03 05:32:15687
dcheng1f4d1d72014-10-21 16:21:58688 bool HasMoreIdleWork() override;
689 void PerformIdleWork() override;
[email protected]43f28f832010-02-03 02:28:48690
dcheng1f4d1d72014-10-21 16:21:58691 void WaitForReadPixels(base::Closure callback) override;
[email protected]5a36dc132013-07-23 23:17:55692
dcheng1f4d1d72014-10-21 16:21:58693 void SetResizeCallback(
mohan.reddy5e1b8952014-10-08 01:38:17694 const base::Callback<void(gfx::Size, float)>& callback) override;
[email protected]22f320a2011-08-30 01:17:00695
dcheng1f4d1d72014-10-21 16:21:58696 Logger* GetLogger() override;
[email protected]cac16542014-01-15 17:53:51697
dcheng1f4d1d72014-10-21 16:21:58698 void BeginDecoding() override;
699 void EndDecoding() override;
[email protected]cac16542014-01-15 17:53:51700
dcheng1f4d1d72014-10-21 16:21:58701 ErrorState* GetErrorState() override;
702 const ContextState* GetContextState() override { return &state_; }
[email protected]1d82e822013-04-10 21:32:32703
dcheng1f4d1d72014-10-21 16:21:58704 void SetShaderCacheCallback(const ShaderCacheCallback& callback) override;
705 void SetWaitSyncPointCallback(const WaitSyncPointCallback& callback) override;
[email protected]22f320a2011-08-30 01:17:00706
dcheng1f4d1d72014-10-21 16:21:58707 AsyncPixelTransferManager* GetAsyncPixelTransferManager() override;
708 void ResetAsyncPixelTransferManagerForTest() override;
709 void SetAsyncPixelTransferManagerForTest(
mohan.reddy5e1b8952014-10-08 01:38:17710 AsyncPixelTransferManager* manager) override;
dcheng1f4d1d72014-10-21 16:21:58711 void SetIgnoreCachedStateForTest(bool ignore) override;
[email protected]69a8701e2013-03-07 21:31:09712 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59713
dcheng1f4d1d72014-10-21 16:21:58714 bool GetServiceTextureId(uint32 client_texture_id,
715 uint32* service_texture_id) override;
[email protected]43f28f832010-02-03 02:28:48716
dcheng1f4d1d72014-10-21 16:21:58717 uint32 GetTextureUploadCount() override;
718 base::TimeDelta GetTotalTextureUploadTime() override;
719 base::TimeDelta GetTotalProcessingCommandsTime() override;
720 void AddProcessingCommandsTime(base::TimeDelta) override;
[email protected]63b465922012-09-06 02:04:52721
[email protected]8e3e0662010-08-23 18:46:30722 // Restores the current state to the user's settings.
723 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30724
[email protected]297ca1c2011-06-20 23:08:46725 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
726 void ApplyDirtyState();
727
728 // These check the state of the currently bound framebuffer or the
729 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54730 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
731 // check with all attached and enabled color attachments.
732 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46733 bool BoundFramebufferHasDepthAttachment();
734 bool BoundFramebufferHasStencilAttachment();
735
dcheng1f4d1d72014-10-21 16:21:58736 error::ContextLostReason GetContextLostReason() override;
[email protected]38d139d2011-07-14 00:38:43737
[email protected]91c94eb2013-10-22 10:32:54738 // Overridden from FramebufferManager::TextureDetachObserver:
dcheng1f4d1d72014-10-21 16:21:58739 void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) override;
[email protected]91c94eb2013-10-22 10:32:54740
[email protected]828a3932014-04-02 14:43:13741 // Overriden from ErrorStateClient.
oetuaho37cc50e2014-10-31 11:19:20742 void OnContextLostError() override;
dcheng1f4d1d72014-10-21 16:21:58743 void OnOutOfMemoryError() override;
[email protected]828a3932014-04-02 14:43:13744
[email protected]8875a5f2014-06-27 08:33:47745 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
746 void EnsureRenderbufferBound();
747
[email protected]f42f05b2013-11-15 21:46:18748 // Helpers to facilitate calling into compatible extensions.
749 static void RenderbufferStorageMultisampleHelper(
750 const FeatureInfo* feature_info,
751 GLenum target,
752 GLsizei samples,
753 GLenum internal_format,
754 GLsizei width,
755 GLsizei height);
756
757 void BlitFramebufferHelper(GLint srcX0,
758 GLint srcY0,
759 GLint srcX1,
760 GLint srcY1,
761 GLint dstX0,
762 GLint dstY0,
763 GLint dstX1,
764 GLint dstY1,
765 GLbitfield mask,
766 GLenum filter);
[email protected]345ba902013-11-14 21:39:00767
[email protected]96449d2c2009-11-25 00:01:32768 private:
[email protected]70d34263c2013-01-09 00:27:45769 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02770 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35771 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35772
[email protected]c2f8c8402010-12-06 18:07:24773 // Initialize or re-initialize the shader translator.
774 bool InitializeShaderTranslator();
775
[email protected]302ce6d2011-07-07 23:28:11776 void UpdateCapabilities();
777
[email protected]ae51d192010-04-27 00:48:03778 // Helpers for the glGen and glDelete functions.
779 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
780 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
781 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
782 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
783 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
784 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
785 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
786 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
orglofchcad5a6742014-11-07 19:51:12787 bool GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
788 void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53789 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
790 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46791 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
792 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47793
[email protected]e3c4a9ab2014-03-31 09:07:02794 // Helper for async upload token completion notification callback.
795 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
796 uint32 sync_data_shm_id,
797 uint32 sync_data_shm_offset);
798
799
800
[email protected]70d34263c2013-01-09 00:27:45801 // Workarounds
802 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51803 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45804
sieversfbaa5dc2015-04-28 00:45:31805 error::ContextLostReason GetContextLostReasonFromResetStatus(
806 GLenum reset_status) const;
807
[email protected]3916c97e2010-02-25 03:20:50808 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50809 BufferManager* buffer_manager() {
810 return group_->buffer_manager();
811 }
812
[email protected]a25fa872010-03-25 02:57:58813 RenderbufferManager* renderbuffer_manager() {
814 return group_->renderbuffer_manager();
815 }
816
817 FramebufferManager* framebuffer_manager() {
818 return group_->framebuffer_manager();
819 }
820
orglofchcad5a6742014-11-07 19:51:12821 ValuebufferManager* valuebuffer_manager() {
822 return group_->valuebuffer_manager();
823 }
824
[email protected]3916c97e2010-02-25 03:20:50825 ProgramManager* program_manager() {
826 return group_->program_manager();
827 }
828
829 ShaderManager* shader_manager() {
830 return group_->shader_manager();
831 }
832
[email protected]03cef9b2014-04-03 15:58:14833 ShaderTranslatorCache* shader_translator_cache() {
834 return group_->shader_translator_cache();
835 }
836
[email protected]29a4d902013-02-26 20:18:06837 const TextureManager* texture_manager() const {
838 return group_->texture_manager();
839 }
840
[email protected]3916c97e2010-02-25 03:20:50841 TextureManager* texture_manager() {
842 return group_->texture_manager();
843 }
844
[email protected]78b514b2012-05-01 21:50:59845 MailboxManager* mailbox_manager() {
846 return group_->mailbox_manager();
847 }
848
[email protected]b63f1d62014-07-18 15:40:59849 ImageManager* image_manager() { return image_manager_.get(); }
[email protected]09d50362012-10-18 20:54:37850
[email protected]944b62f32012-09-27 02:20:46851 VertexArrayManager* vertex_array_manager() {
852 return vertex_array_manager_.get();
853 }
854
[email protected]7989c9e2013-01-23 06:39:26855 MemoryTracker* memory_tracker() {
856 return group_->memory_tracker();
857 }
858
859 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
860 MemoryTracker* tracker = memory_tracker();
861 if (tracker) {
862 return tracker->EnsureGPUMemoryAvailable(estimated_size);
863 }
864 return true;
865 }
866
zmo539d22c2015-06-09 04:14:19867 bool IsWebGLContext() const {
868 return webgl_version_ == 1 || webgl_version_ == 2;
869 }
870
[email protected]34ff8b0c2010-10-01 20:06:02871 bool IsOffscreenBufferMultisampled() const {
872 return offscreen_target_samples_ > 1;
873 }
874
[email protected]ed9f9cd2013-02-27 21:12:35875 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49876 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03877 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35878 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47879 }
880
881 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49882 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07883 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47884 }
885
886 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35887 void RemoveTexture(GLuint client_id) {
888 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50889 }
[email protected]a93bb842010-02-16 23:03:47890
[email protected]d37231fa2010-04-09 21:16:02891 // Get the size (in pixels) of the currently bound frame buffer (either FBO
892 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30893 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02894
[email protected]9edc6b22010-12-23 02:00:26895 // Get the format of the currently bound frame buffer (either FBO or regular
896 // back buffer)
[email protected]68586372013-12-11 01:27:59897 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26898 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46899 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26900
[email protected]a93bb842010-02-16 23:03:47901 // Wrapper for CompressedTexImage2D commands.
902 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37903 GLenum target,
904 GLint level,
905 GLenum internal_format,
906 GLsizei width,
907 GLsizei height,
908 GLint border,
909 GLsizei image_size,
910 const void* data);
[email protected]a93bb842010-02-16 23:03:47911
zmoea06a6f2015-04-30 01:15:46912 // Wrapper for CompressedTexImage3D commands.
913 error::Error DoCompressedTexImage3D(
914 GLenum target,
915 GLint level,
916 GLenum internal_format,
917 GLsizei width,
918 GLsizei height,
919 GLsizei depth,
920 GLint border,
921 GLsizei image_size,
922 const void* data);
923
[email protected]cadde4a2010-07-31 17:10:43924 // Wrapper for CompressedTexSubImage2D.
925 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37926 GLenum target,
927 GLint level,
928 GLint xoffset,
929 GLint yoffset,
930 GLsizei width,
931 GLsizei height,
932 GLenum format,
933 GLsizei imageSize,
934 const void * data);
[email protected]cadde4a2010-07-31 17:10:43935
zmo9a7b17e2015-05-06 00:22:33936 // Wrapper for CompressedTexSubImage3D.
937 void DoCompressedTexSubImage3D(
938 GLenum target,
939 GLint level,
940 GLint xoffset,
941 GLint yoffset,
942 GLint zoffset,
943 GLsizei width,
944 GLsizei height,
945 GLsizei depth,
946 GLenum format,
947 GLsizei image_size,
948 const void* data);
949
[email protected]cadde4a2010-07-31 17:10:43950 // Wrapper for CopyTexImage2D.
951 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37952 GLenum target,
953 GLint level,
954 GLenum internal_format,
955 GLint x,
956 GLint y,
957 GLsizei width,
958 GLsizei height,
959 GLint border);
[email protected]cadde4a2010-07-31 17:10:43960
[email protected]6d792ee12013-05-15 00:40:56961 // Wrapper for SwapBuffers.
962 void DoSwapBuffers();
963
bajones2345c1f2014-12-09 04:45:51964 // Wrapper for SwapInterval.
965 void DoSwapInterval(int interval);
966
[email protected]cadde4a2010-07-31 17:10:43967 // Wrapper for CopyTexSubImage2D.
968 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37969 GLenum target,
970 GLint level,
971 GLint xoffset,
972 GLint yoffset,
973 GLint x,
974 GLint y,
975 GLsizei width,
976 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43977
[email protected]f598f422012-12-07 08:30:03978 // Validation for TexSubImage2D.
979 bool ValidateTexSubImage2D(
980 error::Error* error,
981 const char* function_name,
982 GLenum target,
983 GLint level,
984 GLint xoffset,
985 GLint yoffset,
986 GLsizei width,
987 GLsizei height,
988 GLenum format,
989 GLenum type,
990 const void * data);
991
[email protected]cadde4a2010-07-31 17:10:43992 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03993 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37994 GLenum target,
995 GLint level,
996 GLint xoffset,
997 GLint yoffset,
998 GLsizei width,
999 GLsizei height,
1000 GLenum format,
1001 GLenum type,
1002 const void * data);
[email protected]cadde4a2010-07-31 17:10:431003
zmode7b4382015-05-21 21:23:001004 // Wrapper for TexSubImage3D.
1005 error::Error DoTexSubImage3D(
1006 GLenum target,
1007 GLint level,
1008 GLint xoffset,
1009 GLint yoffset,
1010 GLint zoffset,
1011 GLsizei width,
1012 GLsizei height,
1013 GLsizei depth,
1014 GLenum format,
1015 GLenum type,
1016 const void * data);
1017
[email protected]32145a92012-12-17 09:01:591018 // Extra validation for async tex(Sub)Image2D.
1019 bool ValidateAsyncTransfer(
1020 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:471021 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:591022 GLenum target,
1023 GLint level,
1024 const void * data);
1025
[email protected]e51bdf32011-11-23 22:21:461026 // Wrapper for TexImageIOSurface2DCHROMIUM.
1027 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:371028 GLenum target,
1029 GLsizei width,
1030 GLsizei height,
1031 GLuint io_surface_id,
1032 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:461033
dongseong.hwang46305b12015-03-05 18:28:041034 void DoCopyTextureCHROMIUM(GLenum target,
1035 GLuint source_id,
1036 GLuint dest_id,
1037 GLenum internal_format,
zmodbea74da2015-06-23 20:41:511038 GLenum dest_type,
1039 GLboolean unpack_flip_y,
1040 GLboolean unpack_premultiply_alpha,
1041 GLboolean unpack_unmultiply_alpha);
dongseong.hwang46305b12015-03-05 18:28:041042
1043 void DoCopySubTextureCHROMIUM(GLenum target,
1044 GLuint source_id,
1045 GLuint dest_id,
1046 GLint xoffset,
revemanb6643fb02015-05-26 06:05:341047 GLint yoffset,
1048 GLint x,
1049 GLint y,
1050 GLsizei width,
zmodbea74da2015-06-23 20:41:511051 GLsizei height,
1052 GLboolean unpack_flip_y,
1053 GLboolean unpack_premultiply_alpha,
1054 GLboolean unpack_unmultiply_alpha);
[email protected]43410e92012-04-20 17:06:281055
christiank83120092015-06-17 11:40:101056 void DoCompressedCopyTextureCHROMIUM(GLenum target,
1057 GLuint source_id,
1058 GLuint dest_id);
1059
[email protected]97dc7cbe2011-12-06 17:26:171060 // Wrapper for TexStorage2DEXT.
1061 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:371062 GLenum target,
1063 GLint levels,
1064 GLenum internal_format,
1065 GLsizei width,
1066 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:171067
[email protected]78b514b2012-05-01 21:50:591068 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:221069 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
1070 const GLbyte* key);
1071 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
1072 GLenum target, const GLbyte* data);
1073
bajonesd8388be02015-04-04 00:15:431074 void EnsureTextureForClientId(GLenum target, GLuint client_id);
[email protected]78b514b2012-05-01 21:50:591075 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:221076 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
1077 GLuint client_id);
[email protected]78b514b2012-05-01 21:50:591078
orglofchcad5a6742014-11-07 19:51:121079 bool DoIsValuebufferCHROMIUM(GLuint client_id);
1080 void DoBindValueBufferCHROMIUM(GLenum target, GLuint valuebuffer);
1081 void DoSubscribeValueCHROMIUM(GLenum target, GLenum subscription);
1082 void DoPopulateSubscribedValuesCHROMIUM(GLenum target);
1083 void DoUniformValueBufferCHROMIUM(GLint location,
1084 GLenum target,
1085 GLenum subscription);
1086
[email protected]09d50362012-10-18 20:54:371087 void DoBindTexImage2DCHROMIUM(
1088 GLenum target,
1089 GLint image_id);
1090 void DoReleaseTexImage2DCHROMIUM(
1091 GLenum target,
1092 GLint image_id);
1093
[email protected]94307712012-11-16 23:26:111094 void DoTraceEndCHROMIUM(void);
1095
[email protected]2f143d482013-03-14 18:04:491096 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
1097
[email protected]a6a09f852014-05-23 13:05:031098 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
1099
kkinnunen337d59632014-08-26 10:19:571100 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
1101 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
1102
[email protected]ed9f9cd2013-02-27 21:12:351103 // Creates a Program for the given program.
1104 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:571105 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:351106 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471107 }
1108
[email protected]07f54fcc2009-12-22 02:46:301109 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351110 Program* GetProgram(GLuint client_id) {
1111 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:461112 }
[email protected]07f54fcc2009-12-22 02:46:301113
[email protected]cae20172012-12-07 00:06:191114#if defined(NDEBUG)
1115 void LogClientServiceMapping(
1116 const char* /* function_name */,
1117 GLuint /* client_id */,
1118 GLuint /* service_id */) {
1119 }
1120 template<typename T>
1121 void LogClientServiceForInfo(
1122 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
1123 }
1124#else
1125 void LogClientServiceMapping(
1126 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:261127 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:471128 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
1129 << ": client_id = " << client_id
1130 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:261131 }
[email protected]cae20172012-12-07 00:06:191132 }
1133 template<typename T>
1134 void LogClientServiceForInfo(
1135 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:261136 if (info) {
[email protected]cae20172012-12-07 00:06:191137 LogClientServiceMapping(function_name, client_id, info->service_id());
1138 }
1139 }
1140#endif
1141
[email protected]6b8cf1a2010-05-06 16:13:581142 // Gets the program info for the given program. If it's not a program
1143 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:351144 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:581145 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421146 Program* program = GetProgram(client_id);
1147 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351148 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511149 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431150 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581151 } else {
[email protected]ab09b612013-03-11 22:11:511152 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581153 }
1154 }
[email protected]df37b9932013-03-08 05:21:421155 LogClientServiceForInfo(program, client_id, function_name);
1156 return program;
[email protected]6b8cf1a2010-05-06 16:13:581157 }
1158
1159
[email protected]ed9f9cd2013-02-27 21:12:351160 // Creates a Shader for the given shader.
1161 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571162 GLuint client_id,
1163 GLuint service_id,
1164 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351165 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571166 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311167 }
1168
1169 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351170 Shader* GetShader(GLuint client_id) {
1171 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311172 }
1173
[email protected]6b8cf1a2010-05-06 16:13:581174 // Gets the shader info for the given shader. If it's not a shader generates a
1175 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351176 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581177 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421178 Shader* shader = GetShader(client_id);
1179 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351180 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511181 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431182 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581183 } else {
[email protected]ab09b612013-03-11 22:11:511184 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431185 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581186 }
1187 }
[email protected]df37b9932013-03-08 05:21:421188 LogClientServiceForInfo(shader, client_id, function_name);
1189 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581190 }
1191
[email protected]a93bb842010-02-16 23:03:471192 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351193 void CreateBuffer(GLuint client_id, GLuint service_id) {
1194 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471195 }
1196
[email protected]07f54fcc2009-12-22 02:46:301197 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211198 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071199 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1200 return buffer;
[email protected]1d32bc82010-01-13 22:06:461201 }
[email protected]07f54fcc2009-12-22 02:46:301202
[email protected]a93bb842010-02-16 23:03:471203 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1204 // on glDeleteBuffers so we can make sure the user does not try to render
1205 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351206 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471207
[email protected]a25fa872010-03-25 02:57:581208 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351209 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1210 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581211 }
1212
1213 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061214 Framebuffer* GetFramebuffer(GLuint client_id) {
1215 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581216 }
1217
1218 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351219 void RemoveFramebuffer(GLuint client_id) {
1220 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581221 }
1222
1223 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351224 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1225 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031226 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581227 }
1228
1229 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271230 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1231 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581232 }
1233
1234 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351235 void RemoveRenderbuffer(GLuint client_id) {
1236 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581237 }
1238
orglofchcad5a6742014-11-07 19:51:121239 // Creates a valuebuffer info for the given valuebuffer.
1240 void CreateValuebuffer(GLuint client_id) {
1241 return valuebuffer_manager()->CreateValuebuffer(client_id);
1242 }
1243
1244 // Gets the valuebuffer info for a given valuebuffer.
1245 Valuebuffer* GetValuebuffer(GLuint client_id) {
1246 return valuebuffer_manager()->GetValuebuffer(client_id);
1247 }
1248
1249 // Removes the valuebuffer info for the given valuebuffer.
1250 void RemoveValuebuffer(GLuint client_id) {
1251 valuebuffer_manager()->RemoveValuebuffer(client_id);
1252 }
1253
[email protected]944b62f32012-09-27 02:20:461254 // Gets the vertex attrib manager for the given vertex array.
1255 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1256 VertexAttribManager* info =
1257 vertex_array_manager()->GetVertexAttribManager(client_id);
1258 return info;
1259 }
1260
1261 // Removes the vertex attrib manager for the given vertex array.
1262 void RemoveVertexAttribManager(GLuint client_id) {
1263 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1264 }
1265
1266 // Creates a vertex attrib manager for the given vertex array.
[email protected]da364812014-05-09 21:39:481267 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1268 GLuint client_id,
1269 GLuint service_id,
1270 bool client_visible) {
1271 return vertex_array_manager()->CreateVertexAttribManager(
1272 client_id, service_id, group_->max_vertex_attribs(), client_visible);
[email protected]944b62f32012-09-27 02:20:461273 }
1274
[email protected]258a3313f2011-10-18 20:13:571275 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331276 void DoBindUniformLocationCHROMIUM(
1277 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571278
[email protected]558847a2010-03-24 07:02:541279 error::Error GetAttribLocationHelper(
zmo4a16ff992015-02-05 22:18:411280 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1281 const std::string& name_str);
[email protected]558847a2010-03-24 07:02:541282
1283 error::Error GetUniformLocationHelper(
zmo4a16ff992015-02-05 22:18:411284 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1285 const std::string& name_str);
[email protected]558847a2010-03-24 07:02:541286
zmo5393fb52015-01-27 01:50:481287 error::Error GetFragDataLocationHelper(
zmo4a16ff992015-02-05 22:18:411288 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1289 const std::string& name_str);
zmo5393fb52015-01-27 01:50:481290
zmo1bb3d1d2015-01-21 20:29:431291 // Wrapper for glShaderSource.
1292 void DoShaderSource(
1293 GLuint client_id, GLsizei count, const char** data, const GLint* length);
[email protected]07f54fcc2009-12-22 02:46:301294
zmo38923562015-01-29 20:17:391295 // Wrapper for glTransformFeedbackVaryings.
1296 void DoTransformFeedbackVaryings(
1297 GLuint client_program_id, GLsizei count, const char* const* varyings,
1298 GLenum buffer_mode);
1299
[email protected]0d6bfdc2011-11-02 01:32:201300 // Clear any textures used by the current program.
1301 bool ClearUnclearedTextures();
1302
[email protected]0d6bfdc2011-11-02 01:32:201303 // Clears any uncleared attachments attached to the given frame buffer.
1304 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061305 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281306
[email protected]0d6bfdc2011-11-02 01:32:201307 // overridden from GLES2Decoder
boliu45dc77a2015-02-25 23:26:311308 bool ClearLevel(Texture* texture,
dcheng1f4d1d72014-10-21 16:21:581309 unsigned target,
1310 int level,
dcheng1f4d1d72014-10-21 16:21:581311 unsigned format,
1312 unsigned type,
reveman7c4a13b2015-06-05 22:28:151313 int xoffset,
1314 int yoffset,
dcheng1f4d1d72014-10-21 16:21:581315 int width,
reveman7c4a13b2015-06-05 22:28:151316 int height) override;
[email protected]0d6bfdc2011-11-02 01:32:201317
[email protected]c007aa02010-09-02 22:22:401318 // Restore all GL state that affects clearing.
1319 void RestoreClearState();
1320
[email protected]3a2e7c7b2010-08-06 01:12:281321 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461322 // Returns: true if glEnable/glDisable should actually be called.
1323 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281324
[email protected]0d6bfdc2011-11-02 01:32:201325 // Check that the currently bound framebuffers are valid.
1326 // Generates GL error if not.
1327 bool CheckBoundFramebuffersValid(const char* func_name);
1328
[email protected]2ea5950d2014-07-09 18:20:341329 // Check that the currently bound read framebuffer has a color image
1330 // attached. Generates GL error if not.
1331 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1332
zmo383512cf2014-10-14 00:11:001333 // Check that the currently bound read framebuffer's color image
1334 // isn't the target texture of the glCopyTex{Sub}Image2D.
1335 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
1336
[email protected]0d6bfdc2011-11-02 01:32:201337 // Check if a framebuffer meets our requirements.
1338 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351339 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201340 GLenum target,
1341 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271342
orglofchcad5a6742014-11-07 19:51:121343 // Check if the current valuebuffer exists and is valid. If not generates
1344 // the appropriate GL error. Returns true if the current valuebuffer is in
1345 // a usable state.
1346 bool CheckCurrentValuebuffer(const char* function_name);
1347
1348 // Check if the current valuebuffer exists and is valiud and that the
1349 // value buffer is actually subscribed to the given subscription
1350 bool CheckCurrentValuebufferForSubscription(GLenum subscription,
1351 const char* function_name);
1352
1353 // Check if the location can be used for the given subscription target. If not
1354 // generates the appropriate GL error. Returns true if the location is usable
1355 bool CheckSubscriptionTarget(GLint location,
1356 GLenum subscription,
1357 const char* function_name);
1358
[email protected]939e7362010-05-13 20:49:101359 // Checks if the current program exists and is valid. If not generates the
1360 // appropriate GL error. Returns true if the current program is in a usable
1361 // state.
1362 bool CheckCurrentProgram(const char* function_name);
1363
1364 // Checks if the current program exists and is valid and that location is not
1365 // -1. If the current program is not valid generates the appropriate GL
1366 // error. Returns true if the current program is in a usable state and
1367 // location is not -1.
1368 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1369
zmof9a81360f2014-10-17 00:06:141370 // Checks if the current program samples a texture that is also the color
1371 // image of the current bound framebuffer, i.e., the source and destination
1372 // of the draw operation are the same.
1373 bool CheckDrawingFeedbackLoops();
1374
orglofchcad5a6742014-11-07 19:51:121375 // Checks if |api_type| is valid for the given uniform
1376 // If the api type is not valid generates the appropriate GL
1377 // error. Returns true if |api_type| is valid for the uniform
1378 bool CheckUniformForApiType(const Program::UniformInfo* info,
1379 const char* function_name,
1380 Program::UniformApiType api_type);
1381
[email protected]939e7362010-05-13 20:49:101382 // Gets the type of a uniform for a location in the current program. Sets GL
1383 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361384 // program is valid and the location exists. Adjusts count so it
1385 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131386 bool PrepForSetUniformByLocation(GLint fake_location,
1387 const char* function_name,
1388 Program::UniformApiType api_type,
1389 GLint* real_location,
1390 GLenum* type,
1391 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101392
[email protected]b177ae22011-11-01 03:29:111393 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021394 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111395
[email protected]b273e432010-04-12 17:23:581396 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1397 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1398
[email protected]ac77603c72013-03-08 13:52:061399 // Helper for glGetVertexAttrib
1400 void GetVertexAttribHelper(
1401 const VertexAttrib* attrib, GLenum pname, GLint* param);
1402
[email protected]3916c97e2010-02-25 03:20:501403 // Wrapper for glActiveTexture
1404 void DoActiveTexture(GLenum texture_unit);
1405
[email protected]ae51d192010-04-27 00:48:031406 // Wrapper for glAttachShader
1407 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1408
[email protected]96449d2c2009-11-25 00:01:321409 // Wrapper for glBindBuffer since we need to track the current targets.
1410 void DoBindBuffer(GLenum target, GLuint buffer);
1411
[email protected]86093972010-03-11 00:13:561412 // Wrapper for glBindFramebuffer since we need to track the current targets.
1413 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1414
1415 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1416 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1417
[email protected]a93bb842010-02-16 23:03:471418 // Wrapper for glBindTexture since we need to track the current targets.
1419 void DoBindTexture(GLenum target, GLuint texture);
1420
[email protected]944b62f32012-09-27 02:20:461421 // Wrapper for glBindVertexArrayOES
1422 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571423 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461424
[email protected]49cabed2013-11-13 18:15:181425 // Wrapper for glBlitFramebufferCHROMIUM.
1426 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301427 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1428 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1429 GLbitfield mask, GLenum filter);
1430
[email protected]36cef8ce2010-03-16 07:34:451431 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111432 void DoBufferSubData(
1433 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1434
[email protected]36cef8ce2010-03-16 07:34:451435 // Wrapper for glCheckFramebufferStatus
1436 GLenum DoCheckFramebufferStatus(GLenum target);
1437
[email protected]3a03a8f2011-03-19 00:51:271438 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081439 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271440
[email protected]88a61bf2012-10-27 13:00:421441 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421442 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251443 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281444
[email protected]45bf5152010-02-12 00:11:311445 // Wrapper for glCompileShader.
1446 void DoCompileShader(GLuint shader);
1447
[email protected]ae51d192010-04-27 00:48:031448 // Wrapper for glDetachShader
1449 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1450
[email protected]3a2e7c7b2010-08-06 01:12:281451 // Wrapper for glDisable
1452 void DoDisable(GLenum cap);
1453
[email protected]07f54fcc2009-12-22 02:46:301454 // Wrapper for glDisableVertexAttribArray.
1455 void DoDisableVertexAttribArray(GLuint index);
1456
[email protected]60f22d32012-12-12 00:31:581457 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1458 // attachments.
1459 void DoDiscardFramebufferEXT(GLenum target,
1460 GLsizei numAttachments,
1461 const GLenum* attachments);
1462
[email protected]3a2e7c7b2010-08-06 01:12:281463 // Wrapper for glEnable
1464 void DoEnable(GLenum cap);
1465
[email protected]07f54fcc2009-12-22 02:46:301466 // Wrapper for glEnableVertexAttribArray.
1467 void DoEnableVertexAttribArray(GLuint index);
1468
[email protected]882ba1e22012-03-08 19:02:531469 // Wrapper for glFinish.
1470 void DoFinish();
1471
1472 // Wrapper for glFlush.
1473 void DoFlush();
1474
[email protected]36cef8ce2010-03-16 07:34:451475 // Wrapper for glFramebufferRenderbufffer.
1476 void DoFramebufferRenderbuffer(
1477 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1478 GLuint renderbuffer);
1479
1480 // Wrapper for glFramebufferTexture2D.
1481 void DoFramebufferTexture2D(
1482 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1483 GLint level);
1484
[email protected]7d3c36e2013-07-12 14:13:161485 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1486 void DoFramebufferTexture2DMultisample(
1487 GLenum target, GLenum attachment, GLenum textarget,
1488 GLuint texture, GLint level, GLsizei samples);
1489
1490 // Common implementation for both DoFramebufferTexture2D wrappers.
1491 void DoFramebufferTexture2DCommon(const char* name,
1492 GLenum target, GLenum attachment, GLenum textarget,
1493 GLuint texture, GLint level, GLsizei samples);
1494
zmo84c08202014-11-23 15:28:401495 // Wrapper for glFramebufferTextureLayer.
1496 void DoFramebufferTextureLayer(
1497 GLenum target, GLenum attachment, GLuint texture, GLint level,
1498 GLint layer);
1499
[email protected]a93bb842010-02-16 23:03:471500 // Wrapper for glGenerateMipmap
1501 void DoGenerateMipmap(GLenum target);
1502
[email protected]7d3c36e2013-07-12 14:13:161503 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1504 // to account for different pname values defined in different extension
1505 // variants.
1506 GLenum AdjustGetPname(GLenum pname);
1507
[email protected]b273e432010-04-12 17:23:581508 // Wrapper for DoGetBooleanv.
1509 void DoGetBooleanv(GLenum pname, GLboolean* params);
1510
1511 // Wrapper for DoGetFloatv.
1512 void DoGetFloatv(GLenum pname, GLfloat* params);
1513
[email protected]36cef8ce2010-03-16 07:34:451514 // Wrapper for glGetFramebufferAttachmentParameteriv.
1515 void DoGetFramebufferAttachmentParameteriv(
1516 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1517
zmo8ac3bab2015-04-18 02:30:581518 // Wrapper for glGetInteger64v.
1519 void DoGetInteger64v(GLenum pname, GLint64* params);
1520
[email protected]a0c3e972010-04-21 00:49:131521 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581522 void DoGetIntegerv(GLenum pname, GLint* params);
1523
[email protected]29a9eb52010-04-13 09:04:231524 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061525 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231526 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1527
[email protected]17cfbe0e2013-03-07 01:26:081528 // Wrapper for glGetBufferParameteriv.
1529 void DoGetBufferParameteriv(
1530 GLenum target, GLenum pname, GLint* params);
1531
[email protected]a0c3e972010-04-21 00:49:131532 // Wrapper for glGetProgramiv.
1533 void DoGetProgramiv(
1534 GLuint program_id, GLenum pname, GLint* params);
1535
[email protected]36cef8ce2010-03-16 07:34:451536 // Wrapper for glRenderbufferParameteriv.
1537 void DoGetRenderbufferParameteriv(
1538 GLenum target, GLenum pname, GLint* params);
1539
[email protected]ddd968b82010-03-02 00:44:291540 // Wrapper for glGetShaderiv
1541 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1542
[email protected]4c6f5462014-03-05 00:26:561543 // Wrappers for glGetTexParameter.
1544 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1545 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1546 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1547
[email protected]b1122982010-05-17 23:04:241548 // Wrappers for glGetVertexAttrib.
zmo5ee097e2015-05-14 19:13:521549 template <typename T>
1550 void DoGetVertexAttribImpl(GLuint index, GLenum pname, T* params);
1551 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
1552 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
1553 void DoGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params);
1554 void DoGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params);
[email protected]b1122982010-05-17 23:04:241555
[email protected]1958e0e2010-04-22 05:17:151556 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241557 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151558 bool DoIsBuffer(GLuint client_id);
1559 bool DoIsFramebuffer(GLuint client_id);
1560 bool DoIsProgram(GLuint client_id);
1561 bool DoIsRenderbuffer(GLuint client_id);
1562 bool DoIsShader(GLuint client_id);
1563 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461564 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151565
[email protected]07f54fcc2009-12-22 02:46:301566 // Wrapper for glLinkProgram
1567 void DoLinkProgram(GLuint program);
1568
[email protected]36cef8ce2010-03-16 07:34:451569 // Wrapper for glRenderbufferStorage.
1570 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031571 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451572
[email protected]49cabed2013-11-13 18:15:181573 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1574 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301575 GLenum target, GLsizei samples, GLenum internalformat,
1576 GLsizei width, GLsizei height);
1577
[email protected]49cabed2013-11-13 18:15:181578 // Handler for glRenderbufferStorageMultisampleEXT
1579 // (multisampled_render_to_texture).
1580 void DoRenderbufferStorageMultisampleEXT(
1581 GLenum target, GLsizei samples, GLenum internalformat,
1582 GLsizei width, GLsizei height);
1583
1584 // Common validation for multisample extensions.
1585 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1586 GLenum internalformat,
1587 GLsizei width,
1588 GLsizei height);
1589
[email protected]4a4c18b2013-09-13 22:50:101590 // Verifies that the currently bound multisample renderbuffer is valid
1591 // Very slow! Only done on platforms with driver bugs that return invalid
1592 // buffers under memory pressure
1593 bool VerifyMultisampleRenderbufferIntegrity(
1594 GLuint renderbuffer, GLenum format);
1595
[email protected]b273e432010-04-12 17:23:581596 // Wrapper for glReleaseShaderCompiler.
1597 void DoReleaseShaderCompiler() { }
1598
zmobcb3fdd62014-12-11 00:49:031599 // Wrappers for glSamplerParameter*v functions.
1600 void DoSamplerParameterfv(
1601 GLuint sampler, GLenum pname, const GLfloat* params);
1602 void DoSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* params);
1603
[email protected]3916c97e2010-02-25 03:20:501604 // Wrappers for glTexParameter functions.
1605 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1606 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1607 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1608 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1609
1610 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1611 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121612 void DoUniform1i(GLint fake_location, GLint v0);
1613 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1614 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1615 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1616 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101617
1618 // Wrappers for glUniformfv because some drivers don't correctly accept
1619 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121620 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1621 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1622 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1623 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501624
[email protected]43c2f1f2011-03-25 18:35:361625 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121626 GLint fake_location, GLsizei count, GLboolean transpose,
1627 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361628 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121629 GLint fake_location, GLsizei count, GLboolean transpose,
1630 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361631 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121632 GLint fake_location, GLsizei count, GLboolean transpose,
1633 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361634
zmo143c51a2015-05-15 03:04:071635 template <typename T>
[email protected]af6380962012-11-29 23:24:131636 bool SetVertexAttribValue(
zmo143c51a2015-05-15 03:04:071637 const char* function_name, GLuint index, const T* value);
[email protected]af6380962012-11-29 23:24:131638
[email protected]b1122982010-05-17 23:04:241639 // Wrappers for glVertexAttrib??
1640 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1641 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1642 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1643 void DoVertexAttrib4f(
1644 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
zmo143c51a2015-05-15 03:04:071645 void DoVertexAttrib1fv(GLuint index, const GLfloat* v);
1646 void DoVertexAttrib2fv(GLuint index, const GLfloat* v);
1647 void DoVertexAttrib3fv(GLuint index, const GLfloat* v);
1648 void DoVertexAttrib4fv(GLuint index, const GLfloat* v);
1649 void DoVertexAttribI4i(GLuint index, GLint v0, GLint v1, GLint v2, GLint v3);
1650 void DoVertexAttribI4iv(GLuint index, const GLint* v);
1651 void DoVertexAttribI4ui(
1652 GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
1653 void DoVertexAttribI4uiv(GLuint index, const GLuint* v);
[email protected]b1122982010-05-17 23:04:241654
[email protected]43410e92012-04-20 17:06:281655 // Wrapper for glViewport
1656 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1657
[email protected]07f54fcc2009-12-22 02:46:301658 // Wrapper for glUseProgram
1659 void DoUseProgram(GLuint program);
1660
[email protected]ae51d192010-04-27 00:48:031661 // Wrapper for glValidateProgram.
1662 void DoValidateProgram(GLuint program_client_id);
1663
[email protected]d2a0e1a2012-08-12 02:25:011664 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1665 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1666 void DoPopGroupMarkerEXT(void);
1667
[email protected]4e8a5b122010-05-08 22:00:101668 // Gets the number of values that will be returned by glGetXXX. Returns
1669 // false if pname is unknown.
1670 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1671
[email protected]07f54fcc2009-12-22 02:46:301672 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431673 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101674 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1675 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301676
[email protected]c13e1da62011-09-09 21:48:301677 // Returns true if successful, simulated will be true if attrib0 was
1678 // simulated.
[email protected]c6aef902012-02-14 03:31:421679 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431680 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231681 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241682
[email protected]91c94eb2013-10-22 10:32:541683 // If an image is bound to texture, this will call Will/DidUseTexImage
1684 // if needed.
1685 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1686 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1687
1688 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111689 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541690 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501691
[email protected]8fbedc02010-11-18 18:43:401692 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421693 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431694 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421695 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401696 void RestoreStateForSimulatedFixedAttribs();
1697
[email protected]c6aef902012-02-14 03:31:421698 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101699 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421700 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431701 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421702 bool instanced, GLenum mode, GLint first, GLsizei count,
1703 GLsizei primcount);
1704 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431705 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421706 bool instanced, GLenum mode, GLsizei count, GLenum type,
1707 int32 offset, GLsizei primcount);
1708
[email protected]61eeb33f2011-07-26 15:30:311709 GLenum GetBindTargetForSamplerType(GLenum type) {
1710 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461711 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1712 switch (type) {
1713 case GL_SAMPLER_2D:
1714 return GL_TEXTURE_2D;
1715 case GL_SAMPLER_CUBE:
1716 return GL_TEXTURE_CUBE_MAP;
1717 case GL_SAMPLER_EXTERNAL_OES:
1718 return GL_TEXTURE_EXTERNAL_OES;
1719 case GL_SAMPLER_2D_RECT_ARB:
1720 return GL_TEXTURE_RECTANGLE_ARB;
1721 }
1722
1723 NOTREACHED();
1724 return 0;
[email protected]61eeb33f2011-07-26 15:30:311725 }
1726
[email protected]8e3e0662010-08-23 18:46:301727 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061728 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1729 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301730 switch (target) {
1731 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451732 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341733 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301734 break;
[email protected]ebfb73c2012-08-15 02:37:451735 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341736 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301737 break;
1738 default:
1739 NOTREACHED();
1740 break;
1741 }
[email protected]4d8f0dd2013-03-09 14:37:061742 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301743 }
1744
[email protected]ed9f9cd2013-02-27 21:12:351745 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201746 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271747 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201748 switch (target) {
1749 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111750 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201751 break;
1752 default:
1753 NOTREACHED();
1754 break;
1755 }
[email protected]ee2a79c32013-03-10 03:50:271756 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201757 }
1758
[email protected]f7b85372010-02-03 01:11:371759 // Validates the program and location for a glGetUniform call and returns
1760 // a SizeResult setup to receive the result. Returns true if glGetUniform
1761 // should be called.
zmoc9ea7b82015-05-08 03:44:441762 template <class T>
vmiura181c74002015-03-20 01:32:511763 bool GetUniformSetup(GLuint program,
1764 GLint fake_location,
1765 uint32 shm_id,
1766 uint32 shm_offset,
1767 error::Error* error,
1768 GLint* real_location,
1769 GLuint* service_id,
zmoc9ea7b82015-05-08 03:44:441770 SizedResult<T>** result,
vmiura181c74002015-03-20 01:32:511771 GLenum* result_type,
1772 GLsizei* result_size);
[email protected]f7b85372010-02-03 01:11:371773
sieversfbaa5dc2015-04-28 00:45:311774 bool WasContextLost() const override;
1775 bool WasContextLostByRobustnessExtension() const override;
1776 void MarkContextLost(error::ContextLostReason reason) override;
1777 bool CheckResetStatus();
[email protected]38d139d2011-07-14 00:38:431778
[email protected]e51bdf32011-11-23 22:21:461779#if defined(OS_MACOSX)
1780 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1781#endif
1782
christiank83120092015-06-17 11:40:101783 bool GetCompressedTexSizeInBytes(
1784 const char* function_name, GLsizei width, GLsizei height, GLsizei depth,
1785 GLenum format, GLsizei* size_in_bytes);
1786
[email protected]ad84a3a2012-06-08 21:42:431787 bool ValidateCompressedTexDimensions(
zmoea06a6f2015-04-30 01:15:461788 const char* function_name, GLenum target, GLint level,
1789 GLsizei width, GLsizei height, GLsizei depth, GLenum format);
[email protected]ad84a3a2012-06-08 21:42:431790 bool ValidateCompressedTexFuncData(
zmoea06a6f2015-04-30 01:15:461791 const char* function_name, GLsizei width, GLsizei height, GLsizei depth,
1792 GLenum format, GLsizei size);
[email protected]ad84a3a2012-06-08 21:42:431793 bool ValidateCompressedTexSubDimensions(
1794 const char* function_name,
zmo9a7b17e2015-05-06 00:22:331795 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
1796 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351797 Texture* texture);
dongseong.hwang46305b12015-03-05 18:28:041798 bool ValidateCopyTextureCHROMIUM(const char* function_name,
1799 GLenum target,
1800 TextureRef* source_texture_ref,
1801 TextureRef* dest_texture_ref,
1802 GLenum dest_internal_format);
christiank83120092015-06-17 11:40:101803 bool ValidateCompressedCopyTextureCHROMIUM(const char* function_name,
1804 GLenum target,
1805 TextureRef* source_texture_ref,
1806 TextureRef* dest_texture_ref);
[email protected]ad84a3a2012-06-08 21:42:431807
[email protected]ab09b612013-03-11 22:11:511808 void RenderWarning(const char* filename, int line, const std::string& msg);
1809 void PerformanceWarning(
1810 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011811
[email protected]62e155e2012-10-23 22:43:151812 const FeatureInfo::FeatureFlags& features() const {
1813 return feature_info_->feature_flags();
1814 }
1815
1816 const FeatureInfo::Workarounds& workarounds() const {
1817 return feature_info_->workarounds();
1818 }
1819
[email protected]a7266a92012-06-28 02:11:081820 bool ShouldDeferDraws() {
1821 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341822 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081823 surface_->DeferDraws();
1824 }
1825
[email protected]09e17272012-11-30 10:30:441826 bool ShouldDeferReads() {
1827 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341828 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441829 surface_->DeferDraws();
1830 }
1831
dongseong.hwange1cb2aa2015-02-11 09:33:331832 bool IsRobustnessSupported() {
1833 return has_robustness_extension_ &&
1834 context_->WasAllocatedUsingRobustnessExtension();
1835 }
1836
[email protected]c76fe672013-12-13 23:30:221837 error::Error WillAccessBoundFramebufferForDraw() {
1838 if (ShouldDeferDraws())
1839 return error::kDeferCommandUntilLater;
1840 if (!offscreen_target_frame_buffer_.get() &&
1841 !framebuffer_state_.bound_draw_framebuffer.get() &&
1842 !surface_->SetBackbufferAllocation(true))
1843 return error::kLostContext;
1844 return error::kNoError;
1845 }
1846
1847 error::Error WillAccessBoundFramebufferForRead() {
1848 if (ShouldDeferReads())
1849 return error::kDeferCommandUntilLater;
1850 if (!offscreen_target_frame_buffer_.get() &&
1851 !framebuffer_state_.bound_read_framebuffer.get() &&
1852 !surface_->SetBackbufferAllocation(true))
1853 return error::kLostContext;
1854 return error::kNoError;
1855 }
1856
vmiura8266ca72014-09-09 21:37:001857 // Set remaining commands to process to 0 to force DoCommands to return
1858 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1859 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1860
[email protected]5a36dc132013-07-23 23:17:551861 void ProcessPendingReadPixels();
1862 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1863
[email protected]96449d2c2009-11-25 00:01:321864 // Generate a member function prototype for each command in an automated and
1865 // typesafe way.
vmiuracd108592014-09-08 14:36:341866#define GLES2_CMD_OP(name) \
1867 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321868
1869 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1870
1871 #undef GLES2_CMD_OP
1872
[email protected]2f2d7042010-04-14 21:45:581873 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381874 scoped_refptr<gfx::GLSurface> surface_;
1875 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021876
[email protected]a3ded6d2010-10-19 06:44:391877 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351878 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391879
[email protected]1d82e822013-04-10 21:32:321880 DebugMarkerManager debug_marker_manager_;
1881 Logger logger_;
1882
[email protected]e259eb412012-10-13 05:47:241883 // All the state for this context.
1884 ContextState state_;
1885
[email protected]34ff8b0c2010-10-01 20:06:021886 // Current width and height of the offscreen frame buffer.
1887 gfx::Size offscreen_size_;
1888
[email protected]96449d2c2009-11-25 00:01:321889 // Util to help with GL.
1890 GLES2Util util_;
1891
[email protected]b1122982010-05-17 23:04:241892 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1893 GLuint attrib_0_buffer_id_;
1894
1895 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131896 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241897
[email protected]fc753442011-02-04 19:49:491898 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1899 bool attrib_0_buffer_matches_value_;
1900
[email protected]b1122982010-05-17 23:04:241901 // The size of attrib 0.
1902 GLsizei attrib_0_size_;
1903
[email protected]8fbedc02010-11-18 18:43:401904 // The buffer used to simulate GL_FIXED attribs.
1905 GLuint fixed_attrib_buffer_id_;
1906
1907 // The size of fiixed attrib buffer.
1908 GLsizei fixed_attrib_buffer_size_;
1909
[email protected]b9363b22010-06-09 22:06:151910 // The offscreen frame buffer that the client renders to. With EGL, the
1911 // depth and stencil buffers are separate. With regular GL there is a single
1912 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1913 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351914 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1915 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1916 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1917 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1918 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021919 GLenum offscreen_target_color_format_;
1920 GLenum offscreen_target_depth_format_;
1921 GLenum offscreen_target_stencil_format_;
1922 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561923 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351924
[email protected]de26b3c2011-08-03 21:54:271925 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351926 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1927 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491928 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351929 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271930
1931 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351932 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1933 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051934 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351935
[email protected]882ba1e22012-03-08 19:02:531936 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531937
[email protected]944b62f32012-09-27 02:20:461938 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1939
[email protected]b63f1d62014-07-18 15:40:591940 scoped_ptr<ImageManager> image_manager_;
1941
[email protected]729c0b42013-05-26 02:05:071942 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001943
[email protected]840a7e462013-02-27 01:29:511944 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481945
[email protected]e3932abb2013-03-13 00:01:371946 ShaderCacheCallback shader_cache_callback_;
1947
[email protected]85a4ac22013-05-31 01:58:471948 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421949
[email protected]32fe9aa2011-01-21 23:47:131950 // The format of the back buffer_
1951 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461952 bool back_buffer_has_depth_;
1953 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131954
achaulkcf5316f2014-09-26 19:28:421955 bool surfaceless_;
1956
[email protected]60f22d32012-12-12 00:31:581957 // Backbuffer attachments that are currently undefined.
1958 uint32 backbuffer_needs_clear_bits_;
1959
[email protected]a6a09f852014-05-23 13:05:031960 // The current decoder error communicates the decoder error through command
1961 // processing functions that do not return the error value. Should be set only
1962 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561963 error::Error current_decoder_error_;
1964
[email protected]b1d2dcb2010-05-17 19:24:181965 bool use_shader_translator_;
dyen0ff9e4402015-02-12 22:27:431966 scoped_refptr<ShaderTranslatorInterface> vertex_translator_;
1967 scoped_refptr<ShaderTranslatorInterface> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181968
[email protected]e82fb792011-09-22 00:33:291969 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411970
[email protected]915a59a12010-09-30 21:29:111971 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051972 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351973 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051974
[email protected]65225772011-05-12 21:10:241975 int frame_number_;
1976
vmiura8266ca72014-09-09 21:37:001977 // Number of commands remaining to be processed in DoCommands().
1978 int commands_to_process_;
1979
[email protected]706b69f2012-07-27 04:59:301980 bool has_robustness_extension_;
sieversfbaa5dc2015-04-28 00:45:311981 error::ContextLostReason context_lost_reason_;
1982 bool context_was_lost_;
[email protected]93a7d98f2013-07-11 00:04:221983 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431984 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431985
zmo539d22c2015-06-09 04:14:191986 // Indicates whether this is a context for WebGL1, WebGL2, or others.
1987 // 0: other types
1988 // 1: WebGL 1
1989 // 2: WebGL 2
1990 unsigned webgl_version_;
1991
[email protected]f0d74742011-10-03 16:31:041992 // These flags are used to override the state of the shared feature_info_
1993 // member. Because the same FeatureInfo instance may be shared among many
1994 // contexts, the assumptions on the availablity of extensions in WebGL
1995 // contexts may be broken. These flags override the shared state to preserve
1996 // WebGL semantics.
[email protected]f0d74742011-10-03 16:31:041997 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491998 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131999 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:062000 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:042001
[email protected]062c38b2012-01-18 03:25:102002 bool compile_shader_always_succeeds_;
2003
[email protected]828a3932014-04-02 14:43:132004 // An optional behaviour to lose the context and group when OOM.
2005 bool lose_context_when_out_of_memory_;
2006
[email protected]cae20172012-12-07 00:06:192007 // Log extra info.
2008 bool service_logging_;
2009
[email protected]e51bdf32011-11-23 22:21:462010#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:532011 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:462012 TextureToIOSurfaceMap texture_to_io_surface_map_;
2013#endif
2014
[email protected]43410e92012-04-20 17:06:282015 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
sievers2384f2b2014-11-18 02:10:352016 scoped_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_;
[email protected]43410e92012-04-20 17:06:282017
[email protected]1868a342012-11-07 15:56:022018 // Cached values of the currently assigned viewport dimensions.
2019 GLsizei viewport_max_width_;
2020 GLsizei viewport_max_height_;
2021
[email protected]63b465922012-09-06 02:04:522022 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:522023 base::TimeDelta total_processing_commands_time_;
2024
[email protected]c986af502013-08-14 01:04:442025 // States related to each manager.
2026 DecoderTextureState texture_state_;
2027 DecoderFramebufferState framebuffer_state_;
2028
[email protected]fb97b662013-02-20 23:02:142029 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:132030 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:242031 const unsigned char* cb_command_trace_category_;
dyencb86f2f2014-12-09 18:35:412032 const unsigned char* gpu_decoder_category_;
[email protected]cac16542014-01-15 17:53:512033 int gpu_trace_level_;
2034 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:242035 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:112036
[email protected]5a36dc132013-07-23 23:17:552037 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
2038
[email protected]4a4c18b2013-09-13 22:50:102039 // Used to validate multisample renderbuffers if needed
2040 GLuint validation_texture_;
2041 GLuint validation_fbo_multisample_;
2042 GLuint validation_fbo_;
2043
vmiuracd108592014-09-08 14:36:342044 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
2045 uint32 immediate_data_size,
2046 const void* data);
2047
2048 // A struct to hold info about each command.
2049 struct CommandInfo {
2050 CmdHandler cmd_handler;
2051 uint8 arg_flags; // How to handle the arguments for this command
2052 uint8 cmd_flags; // How to handle this command
2053 uint16 arg_count; // How many arguments are expected for this command.
2054 };
2055
2056 // A table of CommandInfo for all the commands.
2057 static const CommandInfo command_info[kNumCommands - kStartPoint];
2058
[email protected]96449d2c2009-11-25 00:01:322059 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
2060};
2061
vmiuracd108592014-09-08 14:36:342062const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
2063#define GLES2_CMD_OP(name) \
2064 { \
2065 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
2066 cmds::name::cmd_flags, \
2067 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
2068 } \
2069 , /* NOLINT */
2070 GLES2_COMMAND_LIST(GLES2_CMD_OP)
2071#undef GLES2_CMD_OP
2072};
2073
[email protected]ab09b612013-03-11 22:11:512074ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:302075 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:512076 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:302077 error_state_(error_state) {
2078 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:352079}
2080
2081ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:302082 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:352083}
2084
[email protected]2b10c02d2014-01-29 16:43:022085static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:362086 TextureUnit& info = state->texture_units[0];
2087 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:022088 scoped_refptr<TextureRef> texture_ref;
2089 switch (target) {
2090 case GL_TEXTURE_2D:
2091 texture_ref = info.bound_texture_2d;
2092 break;
2093 case GL_TEXTURE_CUBE_MAP:
2094 texture_ref = info.bound_texture_cube_map;
2095 break;
2096 case GL_TEXTURE_EXTERNAL_OES:
2097 texture_ref = info.bound_texture_external_oes;
2098 break;
2099 case GL_TEXTURE_RECTANGLE_ARB:
2100 texture_ref = info.bound_texture_rectangle_arb;
2101 break;
2102 default:
2103 NOTREACHED();
2104 break;
2105 }
2106 if (texture_ref.get()) {
2107 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:362108 } else {
2109 last_id = 0;
2110 }
2111
[email protected]2b10c02d2014-01-29 16:43:022112 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:362113 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
2114}
2115
[email protected]2b10c02d2014-01-29 16:43:022116ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
2117 GLuint id,
2118 GLenum target)
2119 : state_(state),
2120 target_(target) {
[email protected]ab09b612013-03-11 22:11:512121 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:022122 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352123
2124 // TODO(apatrick): Check if there are any other states that need to be reset
2125 // before binding a new texture.
2126 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:022127 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:352128}
2129
[email protected]2b10c02d2014-01-29 16:43:022130ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:512131 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:022132 "ScopedTextureBinder::dtor", state_->GetErrorState());
2133 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:352134}
2135
[email protected]18e785a2013-10-09 03:29:412136ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:352137 GLuint id)
[email protected]18e785a2013-10-09 03:29:412138 : state_(state) {
[email protected]ab09b612013-03-11 22:11:512139 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:412140 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352141 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
2142}
2143
2144ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512145 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:412146 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
2147 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:352148}
2149
2150ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
2151 GLuint id)
2152 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:512153 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302154 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352155 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:452156 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:352157}
2158
2159ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512160 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302161 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:302162 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:352163}
2164
[email protected]34ff8b0c2010-10-01 20:06:022165ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:272166 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:522167 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:342168 resolve_and_bind_ = (
2169 decoder_->offscreen_target_frame_buffer_.get() &&
2170 decoder_->IsOffscreenBufferMultisampled() &&
2171 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
2172 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:022173 if (!resolve_and_bind_)
2174 return;
2175
[email protected]ab09b612013-03-11 22:11:512176 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302177 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022178 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
2179 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:272180 GLuint targetid;
2181 if (internal) {
2182 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
2183 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:352184 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:272185 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352186 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:362187 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:272188 decoder_->offscreen_resolved_color_texture_->Create();
2189
2190 DCHECK(decoder_->offscreen_saved_color_format_);
2191 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:092192 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
2193 false);
[email protected]de26b3c2011-08-03 21:54:272194 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
2195 decoder_->offscreen_resolved_color_texture_.get());
2196 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
2197 GL_FRAMEBUFFER_COMPLETE) {
2198 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
2199 << "because offscreen resolved FBO was incomplete.";
2200 return;
2201 }
2202 }
2203 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
2204 } else {
2205 targetid = decoder_->offscreen_saved_frame_buffer_->id();
2206 }
2207 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022208 const int width = decoder_->offscreen_size_.width();
2209 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:452210 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:182211 decoder->BlitFramebufferHelper(0,
2212 0,
2213 width,
2214 height,
2215 0,
2216 0,
2217 width,
2218 height,
2219 GL_COLOR_BUFFER_BIT,
2220 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:272221 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022222}
2223
2224ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
2225 if (!resolve_and_bind_)
2226 return;
2227
[email protected]ab09b612013-03-11 22:11:512228 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302229 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022230 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222231 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452232 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182233 }
[email protected]34ff8b0c2010-10-01 20:06:022234}
2235
[email protected]ce296892013-10-24 22:04:362236BackTexture::BackTexture(
2237 MemoryTracker* memory_tracker,
2238 ContextState* state)
2239 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2240 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482241 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252242 id_(0) {
[email protected]6217d392010-03-25 22:08:352243}
2244
[email protected]ed9f9cd2013-02-27 21:12:352245BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352246 // This does not destroy the render texture because that would require that
2247 // the associated GL context was current. Just check that it was explicitly
2248 // destroyed.
2249 DCHECK_EQ(id_, 0u);
2250}
2251
[email protected]ed9f9cd2013-02-27 21:12:352252void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302253 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362254 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352255 Destroy();
2256 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022257 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262258 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2259 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582260 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2261 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162262
2263 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2264 // never called on an offscreen context, no data will ever be uploaded to the
2265 // saved offscreen color texture (it is deferred until to when SwapBuffers
2266 // is called). My idea is that some nvidia drivers might have a bug where
2267 // deleting a texture that has never been populated might cause a
2268 // crash.
2269 glTexImage2D(
2270 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482271
2272 bytes_allocated_ = 16u * 16u * 4u;
2273 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352274}
2275
[email protected]ed9f9cd2013-02-27 21:12:352276bool BackTexture::AllocateStorage(
2277 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352278 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302279 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362280 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022281 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092282 uint32 image_size = 0;
2283 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:422284 size.width(), size.height(), 1, format, GL_UNSIGNED_BYTE, 8, &image_size,
[email protected]678a73f2012-12-19 19:22:092285 NULL, NULL);
2286
[email protected]7989c9e2013-01-23 06:39:262287 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2288 return false;
2289 }
2290
[email protected]40d90a22013-04-09 03:39:552291 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092292 if (zero) {
2293 zero_data.reset(new char[image_size]);
2294 memset(zero_data.get(), 0, image_size);
2295 }
[email protected]6217d392010-03-25 22:08:352296
[email protected]8f1d2aa2013-05-10 23:45:382297 glTexImage2D(GL_TEXTURE_2D,
2298 0, // mip level
2299 format,
2300 size.width(),
2301 size.height(),
2302 0, // border
2303 format,
2304 GL_UNSIGNED_BYTE,
2305 zero_data.get());
[email protected]6217d392010-03-25 22:08:352306
[email protected]d37231fa2010-04-09 21:16:022307 size_ = size;
2308
[email protected]1078f912011-12-23 13:12:142309 bool success = glGetError() == GL_NO_ERROR;
2310 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482311 memory_tracker_.TrackMemFree(bytes_allocated_);
2312 bytes_allocated_ = image_size;
2313 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142314 }
2315 return success;
[email protected]6217d392010-03-25 22:08:352316}
2317
[email protected]ed9f9cd2013-02-27 21:12:352318void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352319 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302320 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362321 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022322 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352323 glCopyTexImage2D(GL_TEXTURE_2D,
2324 0, // level
[email protected]3a4d0c52011-06-29 23:11:582325 format,
[email protected]6217d392010-03-25 22:08:352326 0, 0,
2327 size.width(),
2328 size.height(),
2329 0); // border
2330}
2331
[email protected]ed9f9cd2013-02-27 21:12:352332void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352333 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302334 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362335 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352336 glDeleteTextures(1, &id_);
2337 id_ = 0;
2338 }
[email protected]68e81a4a62012-12-13 01:16:482339 memory_tracker_.TrackMemFree(bytes_allocated_);
2340 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352341}
2342
[email protected]ed9f9cd2013-02-27 21:12:352343void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052344 id_ = 0;
2345}
2346
[email protected]d5a28e452013-10-10 01:01:402347BackRenderbuffer::BackRenderbuffer(
2348 RenderbufferManager* renderbuffer_manager,
2349 MemoryTracker* memory_tracker,
2350 ContextState* state)
2351 : renderbuffer_manager_(renderbuffer_manager),
2352 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2353 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482354 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252355 id_(0) {
[email protected]6217d392010-03-25 22:08:352356}
2357
[email protected]ed9f9cd2013-02-27 21:12:352358BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352359 // This does not destroy the render buffer because that would require that
2360 // the associated GL context was current. Just check that it was explicitly
2361 // destroyed.
2362 DCHECK_EQ(id_, 0u);
2363}
2364
[email protected]ed9f9cd2013-02-27 21:12:352365void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302366 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402367 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352368 Destroy();
2369 glGenRenderbuffersEXT(1, &id_);
2370}
2371
[email protected]f42f05b2013-11-15 21:46:182372bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2373 const gfx::Size& size,
2374 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352375 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512376 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402377 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2378 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262379
2380 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402381 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232382 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262383 return false;
2384 }
2385
2386 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2387 return false;
2388 }
2389
[email protected]34ff8b0c2010-10-01 20:06:022390 if (samples <= 1) {
2391 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2392 format,
2393 size.width(),
2394 size.height());
2395 } else {
[email protected]f42f05b2013-11-15 21:46:182396 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2397 GL_RENDERBUFFER,
2398 samples,
2399 format,
2400 size.width(),
2401 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022402 }
[email protected]1078f912011-12-23 13:12:142403 bool success = glGetError() == GL_NO_ERROR;
2404 if (success) {
[email protected]d5a28e452013-10-10 01:01:402405 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482406 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262407 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402408 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482409 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142410 }
2411 return success;
[email protected]6217d392010-03-25 22:08:352412}
2413
[email protected]ed9f9cd2013-02-27 21:12:352414void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352415 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302416 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402417 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352418 glDeleteRenderbuffersEXT(1, &id_);
2419 id_ = 0;
2420 }
[email protected]68e81a4a62012-12-13 01:16:482421 memory_tracker_.TrackMemFree(bytes_allocated_);
2422 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352423}
2424
[email protected]ed9f9cd2013-02-27 21:12:352425void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052426 id_ = 0;
2427}
2428
[email protected]ed9f9cd2013-02-27 21:12:352429BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352430 : decoder_(decoder),
2431 id_(0) {
2432}
2433
[email protected]ed9f9cd2013-02-27 21:12:352434BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352435 // This does not destroy the frame buffer because that would require that
2436 // the associated GL context was current. Just check that it was explicitly
2437 // destroyed.
2438 DCHECK_EQ(id_, 0u);
2439}
2440
[email protected]ed9f9cd2013-02-27 21:12:352441void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302442 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2443 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352444 Destroy();
2445 glGenFramebuffersEXT(1, &id_);
2446}
2447
[email protected]ed9f9cd2013-02-27 21:12:352448void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352449 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512450 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302451 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352452 ScopedFrameBufferBinder binder(decoder_, id_);
2453 GLuint attach_id = texture ? texture->id() : 0;
2454 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2455 GL_COLOR_ATTACHMENT0,
2456 GL_TEXTURE_2D,
2457 attach_id,
2458 0);
2459}
2460
[email protected]ed9f9cd2013-02-27 21:12:352461void BackFramebuffer::AttachRenderBuffer(GLenum target,
2462 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352463 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512464 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302465 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352466 ScopedFrameBufferBinder binder(decoder_, id_);
2467 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2468 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152469 target,
[email protected]6217d392010-03-25 22:08:352470 GL_RENDERBUFFER,
2471 attach_id);
2472}
2473
[email protected]ed9f9cd2013-02-27 21:12:352474void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352475 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302476 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2477 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352478 glDeleteFramebuffersEXT(1, &id_);
2479 id_ = 0;
2480 }
2481}
2482
[email protected]ed9f9cd2013-02-27 21:12:352483void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052484 id_ = 0;
2485}
2486
[email protected]ed9f9cd2013-02-27 21:12:352487GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352488 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302489 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2490 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352491 ScopedFrameBufferBinder binder(decoder_, id_);
2492 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2493}
2494
[email protected]aa7666122011-09-02 19:45:522495GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2496 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322497}
2498
[email protected]aa7666122011-09-02 19:45:522499GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392500 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572501 group_(group),
[email protected]1d82e822013-04-10 21:32:322502 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132503 state_(group_->feature_info(), this, &logger_),
[email protected]b1122982010-05-17 23:04:242504 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492505 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242506 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402507 fixed_attrib_buffer_id_(0),
2508 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022509 offscreen_target_color_format_(0),
2510 offscreen_target_depth_format_(0),
2511 offscreen_target_stencil_format_(0),
2512 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562513 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052514 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132515 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462516 back_buffer_has_depth_(false),
2517 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422518 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582519 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562520 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052521 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112522 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002523 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432524 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302525 has_robustness_extension_(false),
sieversfbaa5dc2015-04-28 00:45:312526 context_lost_reason_(error::kUnknown),
2527 context_was_lost_(false),
[email protected]93a7d98f2013-07-11 00:04:222528 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432529 supports_post_sub_buffer_(false),
zmo539d22c2015-06-09 04:14:192530 webgl_version_(0),
[email protected]062c38b2012-01-18 03:25:102531 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492532 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132533 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062534 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282535 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132536 lose_context_when_out_of_memory_(false),
avi9ab037202014-12-22 23:49:532537 service_logging_(base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]cae20172012-12-07 00:06:192538 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022539 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102540 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002541 texture_state_(group_->feature_info()
2542 ->workarounds()
zmo54f23712015-05-28 19:28:492543 .texsubimage_faster_than_teximage),
vmiura1c2b1de2014-09-19 19:03:242544 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2545 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
dyencb86f2f2014-12-09 18:35:412546 gpu_decoder_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2547 TRACE_DISABLED_BY_DEFAULT("gpu_decoder"))),
vmiura1c2b1de2014-09-19 19:03:242548 gpu_trace_level_(2),
2549 gpu_trace_commands_(false),
2550 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102551 validation_texture_(0),
2552 validation_fbo_multisample_(0),
sievers8694f6332015-06-09 18:58:472553 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572554 DCHECK(group);
2555
[email protected]c2f8c8402010-12-06 18:07:242556 // The shader translator is used for WebGL even when running on EGL
2557 // because additional restrictions are needed (like only enabling
2558 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562559 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2560 // the empty string to CompileShader and this is not a valid shader.
2561 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
avi9ab037202014-12-22 23:49:532562 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]39ba4f02012-03-26 01:16:002563 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152564 use_shader_translator_ = false;
2565 }
[email protected]96449d2c2009-11-25 00:01:322566}
2567
[email protected]80eb6b52012-01-19 00:14:412568GLES2DecoderImpl::~GLES2DecoderImpl() {
2569}
2570
[email protected]c410da802011-03-14 19:17:412571bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382572 const scoped_refptr<gfx::GLSurface>& surface,
2573 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232574 bool offscreen,
dongseong.hwang4c04a162015-03-04 07:27:332575 const gfx::Size& offscreen_size,
[email protected]e82fb792011-09-22 00:33:292576 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242577 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322578 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382579 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302580 DCHECK(!context_.get());
hendrikw2e3b5c8c2015-04-27 23:52:252581 DCHECK(!offscreen || !offscreen_size.IsEmpty());
[email protected]66791e382010-07-14 20:48:302582
zmo0ee15862015-03-04 03:50:182583 ContextCreationAttribHelper attrib_parser;
2584 if (!attrib_parser.Parse(attribs))
2585 return false;
zmo539d22c2015-06-09 04:14:192586 webgl_version_ = attrib_parser.webgl_version;
zmo0ee15862015-03-04 03:50:182587
jbaumana7604692014-10-17 02:00:392588 surfaceless_ = surface->IsSurfaceless() && !offscreen;
achaulkcf5316f2014-09-26 19:28:422589
[email protected]55e136f2013-04-03 18:50:062590 set_initialized();
[email protected]8f9b8dd2013-09-12 18:05:132591 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142592
avi9ab037202014-12-22 23:49:532593 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2594 switches::kEnableGPUDebugging)) {
[email protected]e844ae22012-01-14 03:36:262595 set_debug(true);
2596 }
2597
avi9ab037202014-12-22 23:49:532598 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2599 switches::kEnableGPUCommandLogging)) {
[email protected]39ba4f02012-03-26 01:16:002600 set_log_commands(true);
2601 }
2602
avi9ab037202014-12-22 23:49:532603 compile_shader_always_succeeds_ =
2604 base::CommandLine::ForCurrentProcess()->HasSwitch(
2605 switches::kCompileShaderAlwaysSucceeds);
[email protected]062c38b2012-01-18 03:25:102606
[email protected]63c9b052012-05-17 18:27:382607 // Take ownership of the context and surface. The surface can be replaced with
2608 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382609 context_ = context;
[email protected]63c9b052012-05-17 18:27:382610 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182611
dyen5b1c02ff2015-02-26 01:54:002612 // Create GPU Tracer for timing values.
2613 gpu_tracer_.reset(new GPUTracer(this));
2614
dyen1fa421962015-06-17 21:25:392615 if (feature_info_->workarounds().disable_timestamp_queries) {
2616 // Forcing time elapsed query for any GPU Timing Client forces it for all
2617 // clients in the context.
2618 GetGLContext()->CreateGPUTimingClient()->ForceTimeElapsedQuery();
2619 }
2620
[email protected]828a3932014-04-02 14:43:132621 // Save the loseContextWhenOutOfMemory context creation attribute.
2622 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402623 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132624
[email protected]65f7efe2013-11-28 03:11:472625 // If the failIfMajorPerformanceCaveat context creation attribute was true
2626 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402627 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472628 feature_info_->feature_flags().is_swiftshader) {
2629 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2630 Destroy(true);
2631 return false;
2632 }
2633
zmo539d22c2015-06-09 04:14:192634 disallowed_features_ = disallowed_features;
2635 if (webgl_version_ == 1) {
2636 disallowed_features_.npot_support = true;
2637 }
2638
2639 if (!group_->Initialize(this,
2640 ContextGroup::GetContextType(webgl_version_),
2641 disallowed_features_)) {
[email protected]1871a092011-10-10 21:46:422642 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382643 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032644 return false;
[email protected]a3ded6d2010-10-19 06:44:392645 }
[email protected]b64c24952012-04-19 03:20:272646 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282647
zmo539d22c2015-06-09 04:14:192648 if (webgl_version_ == 2) {
2649 if (!feature_info_->IsES3Capable()) {
2650 LOG(ERROR) << "Underlying driver does not support ES3.";
2651 Destroy(true);
2652 return false;
2653 }
zmoac89bdd2015-03-10 02:09:052654 feature_info_->EnableES3Validators();
2655 set_unsafe_es3_apis_enabled(true);
2656 }
2657
[email protected]af6380962012-11-29 23:24:132658 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482659 vertex_array_manager_.reset(new VertexArrayManager());
2660
2661 GLuint default_vertex_attrib_service_id = 0;
2662 if (features().native_vertex_array_object) {
2663 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2664 glBindVertexArrayOES(default_vertex_attrib_service_id);
2665 }
2666
2667 state_.default_vertex_attrib_manager =
2668 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2669
[email protected]81f20a622014-04-18 01:54:522670 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002671 group_->max_vertex_attribs(),
2672 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462673
[email protected]81f20a622014-04-18 01:54:522674 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572675 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322676
[email protected]7cd76fd2013-06-02 21:11:112677 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532678
[email protected]b63f1d62014-07-18 15:40:592679 image_manager_.reset(new ImageManager);
2680
[email protected]302ce6d2011-07-07 23:28:112681 util_.set_num_compressed_texture_formats(
2682 validators_->compressed_texture_format.GetValues().size());
2683
[email protected]1071e572011-02-09 20:00:122684 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2685 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2686 // OpenGL ES 2.0 does not have this issue.
2687 glEnableVertexAttribArray(0);
2688 }
[email protected]b1122982010-05-17 23:04:242689 glGenBuffersARB(1, &attrib_0_buffer_id_);
2690 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2691 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2692 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402693 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082694
[email protected]1868a342012-11-07 15:56:022695 state_.texture_units.resize(group_->max_texture_units());
2696 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492697 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312698 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492699 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152700 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492701 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072702 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492703 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572704 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312705 }
[email protected]62e155e2012-10-23 22:43:152706 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492707 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072708 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492709 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572710 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462711 }
[email protected]370eaf12013-05-18 09:19:492712 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2713 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572714 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492715 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2716 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572717 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152718 }
[email protected]00f893d2010-08-24 18:55:492719 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502720 CHECK_GL_ERROR();
2721
jmadill653daa72015-05-06 20:29:042722 // cache ALPHA_BITS result for re-use with clear behaviour
2723 GLint alpha_bits = 0;
2724
[email protected]069944672012-04-25 20:52:232725 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402726 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542727 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022728 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432729 // max_sample_count must be initialized to a sane value. If
2730 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2731 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022732 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402733 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022734 max_sample_count);
2735 } else {
2736 offscreen_target_samples_ = 1;
2737 }
[email protected]845c4e32014-08-13 11:50:402738 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022739
2740 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2741 const bool rgb8_supported =
2742 context_->HasExtension("GL_OES_rgb8_rgba8");
2743 // The only available default render buffer formats in GLES2 have very
2744 // little precision. Don't enable multisampling unless 8-bit render
2745 // buffer formats are available--instead fall back to 8-bit textures.
2746 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402747 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022748 GL_RGBA8 : GL_RGB8;
2749 } else {
2750 offscreen_target_samples_ = 1;
rahul.g0aaf8db12015-04-29 14:18:042751 offscreen_target_color_format_ =
2752 attrib_parser.alpha_size > 0 || workarounds().disable_gl_rgb_format
2753 ? GL_RGBA
2754 : GL_RGB;
[email protected]34ff8b0c2010-10-01 20:06:022755 }
2756
2757 // ANGLE only supports packed depth/stencil formats, so use it if it is
2758 // available.
2759 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182760 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272761 VLOG(1) << "GL_OES_packed_depth_stencil "
2762 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402763 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002764 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022765 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2766 offscreen_target_stencil_format_ = 0;
2767 } else {
2768 // It may be the case that this depth/stencil combination is not
2769 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402770 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022771 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402772 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022773 GL_STENCIL_INDEX8 : 0;
2774 }
2775 } else {
rahul.g0aaf8db12015-04-29 14:18:042776 offscreen_target_color_format_ =
2777 attrib_parser.alpha_size > 0 || workarounds().disable_gl_rgb_format
2778 ? GL_RGBA
2779 : GL_RGB;
[email protected]34ff8b0c2010-10-01 20:06:022780
2781 // If depth is requested at all, use the packed depth stencil format if
2782 // it's available, as some desktop GL drivers don't support any non-packed
2783 // formats for depth attachments.
2784 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182785 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272786 VLOG(1) << "GL_EXT_packed_depth_stencil "
2787 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022788
[email protected]845c4e32014-08-13 11:50:402789 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002790 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022791 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2792 offscreen_target_stencil_format_ = 0;
2793 } else {
[email protected]845c4e32014-08-13 11:50:402794 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022795 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402796 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022797 GL_STENCIL_INDEX : 0;
2798 }
2799 }
2800
rahul.g0aaf8db12015-04-29 14:18:042801 offscreen_saved_color_format_ =
2802 attrib_parser.alpha_size > 0 || workarounds().disable_gl_rgb_format
2803 ? GL_RGBA
2804 : GL_RGB;
[email protected]97872062010-11-03 19:07:052805
[email protected]6217d392010-03-25 22:08:352806 // Create the target frame buffer. This is the one that the client renders
2807 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352808 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352809 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022810 // Due to GLES2 format limitations, either the color texture (for
2811 // non-multisampling) or the color render buffer (for multisampling) will be
2812 // attached to the offscreen frame buffer. The render buffer has more
2813 // limited formats available to it, but the texture can't do multisampling.
2814 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402815 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2816 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022817 offscreen_target_color_render_buffer_->Create();
2818 } else {
[email protected]ce296892013-10-24 22:04:362819 offscreen_target_color_texture_.reset(new BackTexture(
2820 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022821 offscreen_target_color_texture_->Create();
2822 }
[email protected]d5a28e452013-10-10 01:01:402823 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2824 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152825 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402826 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2827 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152828 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352829
2830 // Create the saved offscreen texture. The target frame buffer is copied
2831 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352832 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022833 offscreen_saved_frame_buffer_->Create();
2834 //
[email protected]ce296892013-10-24 22:04:362835 offscreen_saved_color_texture_.reset(new BackTexture(
2836 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352837 offscreen_saved_color_texture_->Create();
2838
[email protected]6217d392010-03-25 22:08:352839 // Allocate the render buffers at their initial size and check the status
2840 // of the frame buffers is okay.
dongseong.hwang4c04a162015-03-04 07:27:332841 if (!ResizeOffscreenFrameBuffer(offscreen_size)) {
[email protected]d0498742010-09-20 20:27:012842 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382843 Destroy(true);
[email protected]6217d392010-03-25 22:08:352844 return false;
2845 }
2846
dongseong.hwang4c04a162015-03-04 07:27:332847 state_.viewport_width = offscreen_size.width();
2848 state_.viewport_height = offscreen_size.height();
2849
[email protected]678a73f2012-12-19 19:22:092850 // Allocate the offscreen saved color texture.
2851 DCHECK(offscreen_saved_color_format_);
2852 offscreen_saved_color_texture_->AllocateStorage(
2853 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2854
2855 offscreen_saved_frame_buffer_->AttachRenderTexture(
2856 offscreen_saved_color_texture_.get());
2857 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2858 GL_FRAMEBUFFER_COMPLETE) {
2859 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2860 Destroy(true);
2861 return false;
2862 }
2863
[email protected]6217d392010-03-25 22:08:352864 // Bind to the new default frame buffer (the offscreen target frame buffer).
2865 // This should now be associated with ID zero.
2866 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102867 } else {
2868 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2869 // These are NOT if the back buffer has these proprorties. They are
2870 // if we want the command buffer to enforce them regardless of what
2871 // the real backbuffer is assuming the real back buffer gives us more than
2872 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2873 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2874 // can't do anything about that.
2875
achaulkcf5316f2014-09-26 19:28:422876 if (!surfaceless_) {
kbrc9f0e10c2015-03-31 19:49:122877 GLint depth_bits = 0;
2878 GLint stencil_bits = 0;
2879
2880 bool default_fb = (GetBackbufferServiceId() == 0);
2881
marcheu1856f5d52015-04-04 01:42:532882 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:122883 glGetFramebufferAttachmentParameterivEXT(
2884 GL_FRAMEBUFFER,
2885 default_fb ? GL_BACK_LEFT : GL_COLOR_ATTACHMENT0,
2886 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits);
2887 glGetFramebufferAttachmentParameterivEXT(
2888 GL_FRAMEBUFFER,
2889 default_fb ? GL_DEPTH : GL_DEPTH_ATTACHMENT,
2890 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits);
2891 glGetFramebufferAttachmentParameterivEXT(
2892 GL_FRAMEBUFFER,
2893 default_fb ? GL_STENCIL : GL_STENCIL_ATTACHMENT,
2894 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits);
2895 } else {
2896 glGetIntegerv(GL_ALPHA_BITS, &alpha_bits);
2897 glGetIntegerv(GL_DEPTH_BITS, &depth_bits);
2898 glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
2899 }
2900
achaulkcf5316f2014-09-26 19:28:422901 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2902 // the user requested RGB then RGB. If the user did not specify a
2903 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2904 back_buffer_color_format_ =
kbrc9f0e10c2015-03-31 19:49:122905 (attrib_parser.alpha_size != 0 && alpha_bits > 0) ? GL_RGBA : GL_RGB;
2906 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && depth_bits > 0;
2907 back_buffer_has_stencil_ =
2908 attrib_parser.stencil_size != 0 && stencil_bits > 0;
achaulkcf5316f2014-09-26 19:28:422909 }
dongseong.hwang4c04a162015-03-04 07:27:332910
2911 state_.viewport_width = surface->GetSize().width();
2912 state_.viewport_height = surface->GetSize().height();
[email protected]6217d392010-03-25 22:08:352913 }
2914
[email protected]76a0ee102010-04-07 21:03:042915 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2916 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2917 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372918 // mailing list archives. It also implicitly enables the desktop GL
2919 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2920 // variable in fragment shaders.
marcheu1856f5d52015-04-04 01:42:532921 if (!feature_info_->gl_version_info().BehavesLikeGLES()) {
[email protected]b9363b22010-06-09 22:06:152922 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372923 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152924 }
[email protected]de17df392010-04-23 21:09:412925
[email protected]706b69f2012-07-27 04:59:302926 has_robustness_extension_ =
2927 context->HasExtension("GL_ARB_robustness") ||
oetuaho37cc50e2014-10-31 11:19:202928 context->HasExtension("GL_KHR_robustness") ||
[email protected]706b69f2012-07-27 04:59:302929 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432930
[email protected]c2f8c8402010-12-06 18:07:242931 if (!InitializeShaderTranslator()) {
2932 return false;
[email protected]de17df392010-04-23 21:09:412933 }
[email protected]76a0ee102010-04-07 21:03:042934
[email protected]5904806b2012-05-08 18:10:222935 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282936 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022937 viewport_max_width_ = viewport_params[0];
2938 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282939
[email protected]88a61bf2012-10-27 13:00:422940 state_.scissor_width = state_.viewport_width;
2941 state_.scissor_height = state_.viewport_height;
2942
[email protected]11f3e702012-06-19 19:00:012943 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342944 state_.InitCapabilities(NULL);
2945 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242946 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012947
2948 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2949 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2950 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2951 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
orglofchcad5a6742014-11-07 19:51:122952 DoBindValueBufferCHROMIUM(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, 0);
[email protected]11f3e702012-06-19 19:00:012953
achaulkcf5316f2014-09-26 19:28:422954 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002955#if defined(OS_ANDROID)
2956 // Temporary workaround for Android WebView because this clear ignores the
2957 // clip and corrupts that external UI of the App. Not calling glClear is ok
2958 // because the system already clears the buffer before each draw. Proper
2959 // fix might be setting the scissor clip properly before initialize. See
2960 // crbug.com/259023 for details.
2961 call_gl_clear = surface_->GetHandle();
2962#endif
2963 if (call_gl_clear) {
jmadill653daa72015-05-06 20:29:042964 // On configs where we report no alpha, if the underlying surface has
2965 // alpha, clear the surface alpha to 1.0 to be correct on ReadPixels/etc.
2966 bool clear_alpha = back_buffer_color_format_ == GL_RGB && alpha_bits > 0;
2967 if (clear_alpha) {
2968 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
2969 }
2970
[email protected]88cfd132013-07-11 00:59:002971 // Clear the backbuffer.
2972 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
jmadill653daa72015-05-06 20:29:042973
2974 // Restore alpha clear value if we changed it.
2975 if (clear_alpha) {
2976 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2977 }
[email protected]88cfd132013-07-11 00:59:002978 }
[email protected]561cc0a62013-05-07 18:34:452979
[email protected]b381ee32014-03-22 02:43:432980 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2981 if (feature_info_->workarounds()
2982 .disable_post_sub_buffers_for_onscreen_surfaces &&
2983 !surface->IsOffscreen())
2984 supports_post_sub_buffer_ = false;
2985
[email protected]62e155e2012-10-23 22:43:152986 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462987 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2988 }
[email protected]dd289a5d62012-06-30 22:05:462989
[email protected]9b753992013-04-27 02:04:412990 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2991 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242992 }
[email protected]85cb4682013-04-20 00:54:242993
[email protected]97419c02013-04-10 02:52:382994 // Only compositor contexts are known to use only the subset of GL
2995 // that can be safely migrated between the iGPU and the dGPU. Mark
2996 // those contexts as safe to forcibly transition between the GPUs.
2997 // http://crbug.com/180876, http://crbug.com/227228
2998 if (!offscreen)
2999 context_->SetSafeToForceGpuSwitch();
3000
[email protected]85a4ac22013-05-31 01:58:473001 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:073002 AsyncPixelTransferManager::Create(context.get()));
3003 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:593004
sievers2384f2b2014-11-18 02:10:353005 if (workarounds().gl_clear_broken) {
3006 DCHECK(!clear_framebuffer_blit_.get());
3007 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit");
3008 clear_framebuffer_blit_.reset(new ClearFramebufferResourceManager(this));
3009 if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR)
3010 return false;
3011 }
3012
[email protected]91c94eb2013-10-22 10:32:543013 framebuffer_manager()->AddObserver(this);
3014
[email protected]246a70452010-03-05 21:53:503015 return true;
[email protected]96449d2c2009-11-25 00:01:323016}
3017
[email protected]6d668892013-12-04 21:37:123018Capabilities GLES2DecoderImpl::GetCapabilities() {
3019 DCHECK(initialized());
[email protected]6d668892013-12-04 21:37:123020 Capabilities caps;
piman1c2e0a852014-11-12 05:17:553021 caps.VisitPrecisions([](GLenum shader, GLenum type,
3022 Capabilities::ShaderPrecision* shader_precision) {
3023 GLint range[2] = {0, 0};
3024 GLint precision = 0;
3025 GetShaderPrecisionFormatImpl(shader, type, range, &precision);
3026 shader_precision->min_range = range[0];
3027 shader_precision->max_range = range[1];
3028 shader_precision->precision = precision;
3029 });
3030 DoGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
3031 &caps.max_combined_texture_image_units);
3032 DoGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps.max_cube_map_texture_size);
3033 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
3034 &caps.max_fragment_uniform_vectors);
3035 DoGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps.max_renderbuffer_size);
3036 DoGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps.max_texture_image_units);
3037 DoGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.max_texture_size);
3038 DoGetIntegerv(GL_MAX_VARYING_VECTORS, &caps.max_varying_vectors);
3039 DoGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps.max_vertex_attribs);
3040 DoGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
3041 &caps.max_vertex_texture_image_units);
3042 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
3043 &caps.max_vertex_uniform_vectors);
3044 DoGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
3045 &caps.num_compressed_texture_formats);
3046 DoGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps.num_shader_binary_formats);
3047 DoGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM,
3048 &caps.bind_generates_resource_chromium);
heejin.r.chung8f143292015-02-05 02:44:003049 if (unsafe_es3_apis_enabled()) {
zmoba1fe9d22015-04-15 21:42:513050 // TODO(zmo): Note that some parameter values could be more than 32-bit,
3051 // but for now we clamp them to 32-bit max.
3052 DoGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &caps.max_3d_texture_size);
3053 DoGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &caps.max_array_texture_layers);
3054 DoGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &caps.max_color_attachments);
zmo0e679b22015-05-19 00:26:333055 DoGetInteger64v(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,
3056 &caps.max_combined_fragment_uniform_components);
zmoba1fe9d22015-04-15 21:42:513057 DoGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS,
3058 &caps.max_combined_uniform_blocks);
zmo0e679b22015-05-19 00:26:333059 DoGetInteger64v(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,
3060 &caps.max_combined_vertex_uniform_components);
zmoba1fe9d22015-04-15 21:42:513061 DoGetIntegerv(GL_MAX_DRAW_BUFFERS, &caps.max_draw_buffers);
zmo0e679b22015-05-19 00:26:333062 DoGetInteger64v(GL_MAX_ELEMENT_INDEX, &caps.max_element_index);
zmoba1fe9d22015-04-15 21:42:513063 DoGetIntegerv(GL_MAX_ELEMENTS_INDICES, &caps.max_elements_indices);
3064 DoGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &caps.max_elements_vertices);
3065 DoGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS,
3066 &caps.max_fragment_input_components);
3067 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS,
3068 &caps.max_fragment_uniform_blocks);
3069 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,
3070 &caps.max_fragment_uniform_components);
3071 DoGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET,
3072 &caps.max_program_texel_offset);
zmo0e679b22015-05-19 00:26:333073 DoGetInteger64v(GL_MAX_SERVER_WAIT_TIMEOUT, &caps.max_server_wait_timeout);
3074 // Work around Linux NVIDIA driver bug where GL_TIMEOUT_IGNORED is
3075 // returned.
3076 if (caps.max_server_wait_timeout < 0)
3077 caps.max_server_wait_timeout = 0;
3078 DoGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &caps.max_texture_lod_bias);
zmoba1fe9d22015-04-15 21:42:513079 DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
3080 &caps.max_transform_feedback_interleaved_components);
heejin.r.chung8f143292015-02-05 02:44:003081 DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
3082 &caps.max_transform_feedback_separate_attribs);
zmoba1fe9d22015-04-15 21:42:513083 DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
3084 &caps.max_transform_feedback_separate_components);
zmo0e679b22015-05-19 00:26:333085 DoGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &caps.max_uniform_block_size);
heejin.r.chung8f143292015-02-05 02:44:003086 DoGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
3087 &caps.max_uniform_buffer_bindings);
zmoba1fe9d22015-04-15 21:42:513088 DoGetIntegerv(GL_MAX_VARYING_COMPONENTS, &caps.max_varying_components);
3089 DoGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS,
3090 &caps.max_vertex_output_components);
3091 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS,
3092 &caps.max_vertex_uniform_blocks);
3093 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS,
3094 &caps.max_vertex_uniform_components);
3095 DoGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps.min_program_texel_offset);
3096 DoGetIntegerv(GL_NUM_EXTENSIONS, &caps.num_extensions);
3097 DoGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS,
3098 &caps.num_program_binary_formats);
heejin.r.chung8f143292015-02-05 02:44:003099 DoGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
3100 &caps.uniform_buffer_offset_alignment);
zmoba1fe9d22015-04-15 21:42:513101 // TODO(zmo): once we switch to MANGLE, we should query version numbers.
3102 caps.major_version = 3;
3103 caps.minor_version = 0;
heejin.r.chung8f143292015-02-05 02:44:003104 }
senorblanco0aecd69f2015-05-01 18:24:053105 if (feature_info_->feature_flags().multisampled_render_to_texture ||
3106 feature_info_->feature_flags().chromium_framebuffer_multisample ||
3107 unsafe_es3_apis_enabled()) {
3108 DoGetIntegerv(GL_MAX_SAMPLES, &caps.max_samples);
3109 }
[email protected]6d668892013-12-04 21:37:123110
[email protected]6d668892013-12-04 21:37:123111 caps.egl_image_external =
3112 feature_info_->feature_flags().oes_egl_image_external;
christiank07b6d8b2015-02-25 09:41:253113 caps.texture_format_atc =
3114 feature_info_->feature_flags().ext_texture_format_atc;
[email protected]6d668892013-12-04 21:37:123115 caps.texture_format_bgra8888 =
3116 feature_info_->feature_flags().ext_texture_format_bgra8888;
christiank07b6d8b2015-02-25 09:41:253117 caps.texture_format_dxt1 =
3118 feature_info_->feature_flags().ext_texture_format_dxt1;
3119 caps.texture_format_dxt5 =
3120 feature_info_->feature_flags().ext_texture_format_dxt5;
[email protected]6d668892013-12-04 21:37:123121 caps.texture_format_etc1 =
3122 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:203123 caps.texture_format_etc1_npot =
3124 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:123125 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
3126 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
3127 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
3128 caps.discard_framebuffer =
3129 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:353130 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:123131
3132#if defined(OS_MACOSX)
3133 // This is unconditionally true on mac, no need to test for it at runtime.
3134 caps.iosurface = true;
3135#endif
3136
[email protected]b381ee32014-03-22 02:43:433137 caps.post_sub_buffer = supports_post_sub_buffer_;
reveman340109182014-09-30 15:36:453138 caps.image = true;
[email protected]6d668892013-12-04 21:37:123139
ed9198b422014-10-23 15:01:373140 caps.blend_equation_advanced =
3141 feature_info_->feature_flags().blend_equation_advanced;
3142 caps.blend_equation_advanced_coherent =
3143 feature_info_->feature_flags().blend_equation_advanced_coherent;
hendrikwfc25ca6192014-12-02 06:05:133144 caps.texture_rg = feature_info_->feature_flags().ext_texture_rg;
revemane92ab032015-06-10 01:39:263145 caps.max_copy_texture_chromium_size =
3146 feature_info_->workarounds().max_copy_texture_chromium_size;
hendrikw316921852015-06-19 23:45:433147 caps.render_buffer_format_bgra8888 =
3148 feature_info_->feature_flags().ext_render_buffer_format_bgra8888;
[email protected]6d668892013-12-04 21:37:123149 return caps;
3150}
3151
[email protected]302ce6d2011-07-07 23:28:113152void GLES2DecoderImpl::UpdateCapabilities() {
3153 util_.set_num_compressed_texture_formats(
3154 validators_->compressed_texture_format.GetValues().size());
3155 util_.set_num_shader_binary_formats(
3156 validators_->shader_binary_format.GetValues().size());
3157}
3158
[email protected]c2f8c8402010-12-06 18:07:243159bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:443160 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
3161
[email protected]c2f8c8402010-12-06 18:07:243162 if (!use_shader_translator_) {
3163 return true;
3164 }
3165 ShBuiltInResources resources;
3166 ShInitBuiltInResources(&resources);
3167 resources.MaxVertexAttribs = group_->max_vertex_attribs();
3168 resources.MaxVertexUniformVectors =
3169 group_->max_vertex_uniform_vectors();
3170 resources.MaxVaryingVectors = group_->max_varying_vectors();
3171 resources.MaxVertexTextureImageUnits =
3172 group_->max_vertex_texture_image_units();
3173 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
3174 resources.MaxTextureImageUnits = group_->max_texture_image_units();
3175 resources.MaxFragmentUniformVectors =
3176 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:493177 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:243178 resources.MaxExpressionComplexity = 256;
3179 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:043180
[email protected]46c86752013-05-21 05:08:393181 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:213182 GLint precision = 0;
3183 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
3184 range, &precision);
[email protected]448e459e2013-06-12 17:00:413185 resources.FragmentPrecisionHigh =
3186 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:143187
zmo539d22c2015-06-09 04:14:193188 if (IsWebGLContext()) {
[email protected]f0d74742011-10-03 16:31:043189 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:493190 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:133191 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:443192 if (!draw_buffers_explicitly_enabled_)
3193 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:063194 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
oetuaho0decd442014-10-13 08:40:463195 resources.NV_draw_buffers =
3196 draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
[email protected]f0d74742011-10-03 16:31:043197 } else {
3198 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:153199 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:463200 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:153201 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:063202 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:153203 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:493204 resources.EXT_draw_buffers =
3205 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:493206 resources.EXT_frag_depth =
3207 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:063208 resources.EXT_shader_texture_lod =
3209 features().ext_shader_texture_lod ? 1 : 0;
oetuaho0decd442014-10-13 08:40:463210 resources.NV_draw_buffers =
3211 features().nv_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:043212 }
3213
zmo0ee15862015-03-04 03:50:183214 ShShaderSpec shader_spec;
zmo539d22c2015-06-09 04:14:193215 if (IsWebGLContext()) {
3216 shader_spec = webgl_version_ == 2 ? SH_WEBGL2_SPEC : SH_WEBGL_SPEC;
zmo0ee15862015-03-04 03:50:183217 } else {
3218 shader_spec = unsafe_es3_apis_enabled() ? SH_GLES3_SPEC : SH_GLES2_SPEC;
3219 }
3220
3221 if ((shader_spec == SH_WEBGL_SPEC || shader_spec == SH_WEBGL2_SPEC) &&
3222 features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:023223 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:053224 else
3225 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:123226 ShaderTranslatorInterface::GlslImplementationType implementation_type =
marcheu1856f5d52015-04-04 01:42:533227 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
3228 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:213229 int driver_bug_workarounds = 0;
3230 if (workarounds().needs_glsl_built_in_function_emulation)
3231 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:543232 if (workarounds().init_gl_position_in_vertex_shader)
3233 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:113234 if (workarounds().unfold_short_circuit_as_ternary_operation)
3235 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:053236 if (workarounds().init_varyings_without_static_use)
3237 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:063238 if (workarounds().unroll_for_loop_with_sampler_array_index)
3239 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:253240 if (workarounds().scalarize_vec_and_mat_constructor_args)
3241 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:273242 if (workarounds().regenerate_struct_names)
3243 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
oetuaho6458e052015-06-04 17:46:273244 if (workarounds().remove_pow_with_constant_exponent)
3245 driver_bug_workarounds |= SH_REMOVE_POW_WITH_CONSTANT_EXPONENT;
[email protected]87fb6ab2012-06-13 22:28:043246
avi9ab037202014-12-22 23:49:533247 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
3248 switches::kEmulateShaderPrecision))
oetuahoaffd85abe2014-12-11 09:47:093249 resources.WEBGL_debug_shader_precision = true;
3250
[email protected]03cef9b2014-04-03 15:58:143251 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:263252 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:143253 shader_spec,
3254 &resources,
[email protected]a6739bc2013-09-07 04:45:213255 implementation_type,
3256 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:043257 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:243258 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:383259 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:243260 return false;
3261 }
[email protected]87fb6ab2012-06-13 22:28:043262
[email protected]03cef9b2014-04-03 15:58:143263 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:263264 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:143265 shader_spec,
3266 &resources,
[email protected]a6739bc2013-09-07 04:45:213267 implementation_type,
3268 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:043269 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:243270 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:383271 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:243272 return false;
3273 }
3274 return true;
3275}
3276
[email protected]ae51d192010-04-27 00:48:033277bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:473278 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353279 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033280 return false;
3281 }
3282 }
[email protected]40d90a22013-04-09 03:39:553283 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033284 glGenBuffersARB(n, service_ids.get());
3285 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353286 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033287 }
3288 return true;
3289}
3290
3291bool GLES2DecoderImpl::GenFramebuffersHelper(
3292 GLsizei n, const GLuint* client_ids) {
3293 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353294 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033295 return false;
3296 }
3297 }
[email protected]40d90a22013-04-09 03:39:553298 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033299 glGenFramebuffersEXT(n, service_ids.get());
3300 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353301 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033302 }
3303 return true;
3304}
3305
3306bool GLES2DecoderImpl::GenRenderbuffersHelper(
3307 GLsizei n, const GLuint* client_ids) {
3308 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353309 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033310 return false;
3311 }
3312 }
[email protected]40d90a22013-04-09 03:39:553313 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033314 glGenRenderbuffersEXT(n, service_ids.get());
3315 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353316 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033317 }
3318 return true;
3319}
3320
orglofchcad5a6742014-11-07 19:51:123321bool GLES2DecoderImpl::GenValuebuffersCHROMIUMHelper(GLsizei n,
3322 const GLuint* client_ids) {
3323 for (GLsizei ii = 0; ii < n; ++ii) {
3324 if (GetValuebuffer(client_ids[ii])) {
3325 return false;
3326 }
3327 }
3328 for (GLsizei ii = 0; ii < n; ++ii) {
3329 CreateValuebuffer(client_ids[ii]);
3330 }
3331 return true;
3332}
3333
[email protected]ae51d192010-04-27 00:48:033334bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
3335 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353336 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033337 return false;
3338 }
3339 }
[email protected]40d90a22013-04-09 03:39:553340 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033341 glGenTextures(n, service_ids.get());
3342 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353343 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033344 }
3345 return true;
3346}
3347
3348void GLES2DecoderImpl::DeleteBuffersHelper(
3349 GLsizei n, const GLuint* client_ids) {
3350 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:213351 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103352 if (buffer && !buffer->IsDeleted()) {
zmo2a09dc052015-03-12 00:48:253353 buffer->RemoveMappedRange();
zmo4c0c3532015-05-22 20:04:483354 state_.RemoveBoundBuffer(buffer);
[email protected]ed9f9cd2013-02-27 21:12:353355 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033356 }
[email protected]a93bb842010-02-16 23:03:473357 }
[email protected]07f54fcc2009-12-22 02:46:303358}
3359
[email protected]ae51d192010-04-27 00:48:033360void GLES2DecoderImpl::DeleteFramebuffersHelper(
3361 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453362 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153363 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:113364
[email protected]a25fa872010-03-25 02:57:583365 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353366 Framebuffer* framebuffer =
3367 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103368 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:343369 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]ebfb73c2012-08-15 02:37:453370 GLenum target = supports_separate_framebuffer_binds ?
3371 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
vmiura7d08fee52015-02-18 18:39:343372
3373 // Unbind attachments on FBO before deletion.
3374 if (workarounds().unbind_attachments_on_bound_render_fbo_delete)
3375 framebuffer->DoUnbindGLAttachmentsForWorkaround(target);
3376
[email protected]b177ae22011-11-01 03:29:113377 glBindFramebufferEXT(target, GetBackbufferServiceId());
vmiura7d08fee52015-02-18 18:39:343378 framebuffer_state_.bound_draw_framebuffer = NULL;
3379 framebuffer_state_.clear_state_dirty = true;
[email protected]b177ae22011-11-01 03:29:113380 }
[email protected]9d3b2e12013-10-02 01:04:343381 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
3382 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:453383 GLenum target = supports_separate_framebuffer_binds ?
3384 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113385 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:463386 }
[email protected]70d34263c2013-01-09 00:27:453387 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:353388 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033389 }
[email protected]a25fa872010-03-25 02:57:583390 }
[email protected]07f54fcc2009-12-22 02:46:303391}
3392
[email protected]ae51d192010-04-27 00:48:033393void GLES2DecoderImpl::DeleteRenderbuffersHelper(
3394 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453395 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153396 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:583397 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353398 Renderbuffer* renderbuffer =
3399 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103400 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:113401 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:243402 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103403 }
3404 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453405 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343406 if (framebuffer_state_.bound_read_framebuffer.get()) {
3407 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113408 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103409 }
[email protected]9d3b2e12013-10-02 01:04:343410 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3411 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113412 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103413 }
3414 } else {
[email protected]9d3b2e12013-10-02 01:04:343415 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3416 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113417 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103418 }
3419 }
[email protected]c986af502013-08-14 01:04:443420 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:353421 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033422 }
[email protected]a25fa872010-03-25 02:57:583423 }
[email protected]07f54fcc2009-12-22 02:46:303424}
3425
orglofchcad5a6742014-11-07 19:51:123426void GLES2DecoderImpl::DeleteValuebuffersCHROMIUMHelper(
3427 GLsizei n,
3428 const GLuint* client_ids) {
3429 for (GLsizei ii = 0; ii < n; ++ii) {
3430 Valuebuffer* valuebuffer = GetValuebuffer(client_ids[ii]);
3431 if (valuebuffer) {
3432 if (state_.bound_valuebuffer.get() == valuebuffer) {
3433 state_.bound_valuebuffer = NULL;
3434 }
3435 RemoveValuebuffer(client_ids[ii]);
3436 }
3437 }
3438}
3439
[email protected]ae51d192010-04-27 00:48:033440void GLES2DecoderImpl::DeleteTexturesHelper(
3441 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453442 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153443 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:473444 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:493445 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3446 if (texture_ref) {
3447 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103448 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443449 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463450 }
[email protected]370eaf12013-05-18 09:19:493451 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023452 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493453 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103454 }
3455 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453456 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343457 if (framebuffer_state_.bound_read_framebuffer.get()) {
3458 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113459 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103460 }
[email protected]9d3b2e12013-10-02 01:04:343461 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3462 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113463 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103464 }
3465 } else {
[email protected]9d3b2e12013-10-02 01:04:343466 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3467 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113468 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103469 }
3470 }
[email protected]e51bdf32011-11-23 22:21:463471#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073472 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463473 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3474 ReleaseIOSurfaceForTexture(service_id);
3475 }
3476#endif
[email protected]ed9f9cd2013-02-27 21:12:353477 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033478 }
[email protected]a93bb842010-02-16 23:03:473479 }
[email protected]07f54fcc2009-12-22 02:46:303480}
3481
[email protected]43f28f832010-02-03 02:28:483482// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323483
[email protected]eb54a562010-01-20 21:55:183484bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343485 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383486 return false;
3487
sieversfbaa5dc2015-04-28 00:45:313488 if (WasContextLost()) {
3489 LOG(ERROR) << " GLES2DecoderImpl: Trying to make lost context current.";
3490 return false;
3491 }
3492
3493 if (!context_->MakeCurrent(surface_.get())) {
[email protected]38d139d2011-07-14 00:38:433494 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
sieversfbaa5dc2015-04-28 00:45:313495 MarkContextLost(error::kMakeCurrentFailed);
3496 group_->LoseContexts(error::kUnknown);
3497 return false;
3498 }
[email protected]e9f0ca82013-04-01 23:52:293499
sieversfbaa5dc2015-04-28 00:45:313500 if (CheckResetStatus()) {
3501 LOG(ERROR)
3502 << " GLES2DecoderImpl: Context reset detected after MakeCurrent.";
3503 group_->LoseContexts(error::kUnknown);
[email protected]63c9b052012-05-17 18:27:383504 return false;
[email protected]38d139d2011-07-14 00:38:433505 }
3506
[email protected]69a8701e2013-03-07 21:31:093507 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093508
[email protected]9b753992013-04-27 02:04:413509 // Rebind the FBO if it was unbound by the context.
3510 if (workarounds().unbind_fbo_on_context_switch)
3511 RestoreFramebufferBindings();
3512
[email protected]c986af502013-08-14 01:04:443513 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493514
[email protected]69a8701e2013-03-07 21:31:093515 return true;
3516}
3517
3518void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553519 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323520 if (engine() && query_manager_.get())
3521 query_manager_->ProcessPendingTransferQueries();
3522
[email protected]5b3a8e02013-03-13 05:36:443523 // TODO(epenner): Is there a better place to do this?
3524 // This needs to occur before we execute any batch of commands
3525 // from the client, as the client may have recieved an async
3526 // completion while issuing those commands.
3527 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483528 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183529}
3530
[email protected]8e3e0662010-08-23 18:46:303531static void RebindCurrentFramebuffer(
3532 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063533 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243534 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063535 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463536
[email protected]a3783712012-01-20 22:18:243537 if (framebuffer_id == 0) {
3538 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303539 }
[email protected]297ca1c2011-06-20 23:08:463540
[email protected]8e3e0662010-08-23 18:46:303541 glBindFramebufferEXT(target, framebuffer_id);
3542}
3543
3544void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443545 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463546
[email protected]62e155e2012-10-23 22:43:153547 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303548 RebindCurrentFramebuffer(
3549 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343550 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243551 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303552 } else {
3553 RebindCurrentFramebuffer(
3554 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343555 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243556 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303557 RebindCurrentFramebuffer(
3558 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343559 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243560 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303561 }
[email protected]70d34263c2013-01-09 00:27:453562 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303563}
3564
[email protected]0d6bfdc2011-11-02 01:32:203565bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353566 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203567 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103568 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423569 if (surfaceless_)
3570 return false;
[email protected]60f22d32012-12-12 00:31:583571 if (backbuffer_needs_clear_bits_) {
3572 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323573 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453574 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583575 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473576 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3577 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583578 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453579 state_.SetDeviceDepthMask(GL_TRUE);
3580 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423581 bool reset_draw_buffer = false;
brucedawson18249152014-10-31 23:02:323582 if ((backbuffer_needs_clear_bits_ & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]ee757922014-06-06 05:21:423583 group_->draw_buffer() == GL_NONE) {
3584 reset_draw_buffer = true;
3585 GLenum buf = GL_BACK;
3586 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3587 buf = GL_COLOR_ATTACHMENT0;
3588 glDrawBuffersARB(1, &buf);
3589 }
[email protected]60f22d32012-12-12 00:31:583590 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423591 if (reset_draw_buffer) {
3592 GLenum buf = GL_NONE;
3593 glDrawBuffersARB(1, &buf);
3594 }
[email protected]60f22d32012-12-12 00:31:583595 backbuffer_needs_clear_bits_ = 0;
3596 RestoreClearState();
3597 }
[email protected]0d6bfdc2011-11-02 01:32:203598 return true;
3599 }
3600
[email protected]968351b2011-12-20 08:26:513601 if (framebuffer_manager()->IsComplete(framebuffer)) {
3602 return true;
3603 }
3604
[email protected]0d6bfdc2011-11-02 01:32:203605 GLenum completeness = framebuffer->IsPossiblyComplete();
3606 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513607 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433608 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273609 return false;
3610 }
[email protected]0d6bfdc2011-11-02 01:32:203611
3612 // Are all the attachments cleared?
3613 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3614 texture_manager()->HaveUnclearedMips()) {
3615 if (!framebuffer->IsCleared()) {
3616 // Can we clear them?
[email protected]73276522012-11-09 05:50:203617 if (framebuffer->GetStatus(texture_manager(), target) !=
3618 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513619 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433620 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3621 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203622 return false;
3623 }
3624 ClearUnclearedAttachments(target, framebuffer);
3625 }
3626 }
3627
[email protected]968351b2011-12-20 08:26:513628 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203629 if (framebuffer->GetStatus(texture_manager(), target) !=
3630 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513631 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433632 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3633 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513634 return false;
3635 }
3636 framebuffer_manager()->MarkAsComplete(framebuffer);
3637 }
3638
[email protected]0d6bfdc2011-11-02 01:32:203639 // NOTE: At this point we don't know if the framebuffer is complete but
3640 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273641 return true;
3642}
3643
[email protected]0d6bfdc2011-11-02 01:32:203644bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153645 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513646 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343647 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3648 func_name);
[email protected]28718a92013-04-04 12:12:513649
3650 if (valid)
3651 OnUseFramebuffer();
3652
3653 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203654 }
[email protected]9d3b2e12013-10-02 01:04:343655 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113656 GL_DRAW_FRAMEBUFFER_EXT,
3657 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343658 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113659 GL_READ_FRAMEBUFFER_EXT,
3660 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203661}
3662
[email protected]2ea5950d2014-07-09 18:20:343663bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3664 const char* func_name) {
3665 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3666 framebuffer_state_.bound_read_framebuffer.get() :
3667 framebuffer_state_.bound_draw_framebuffer.get();
3668 if (!framebuffer)
3669 return true;
3670 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3671 LOCAL_SET_GL_ERROR(
3672 GL_INVALID_OPERATION, func_name, "no color image attached");
3673 return false;
3674 }
3675 return true;
3676}
3677
zmo383512cf2014-10-14 00:11:003678bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
3679 TextureRef* texture, GLint level) {
3680 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3681 framebuffer_state_.bound_read_framebuffer.get() :
3682 framebuffer_state_.bound_draw_framebuffer.get();
3683 if (!framebuffer)
3684 return false;
3685 const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
3686 GL_COLOR_ATTACHMENT0);
3687 if (!attachment)
3688 return false;
3689 return attachment->FormsFeedbackLoop(texture, level);
3690}
3691
[email protected]8e3e0662010-08-23 18:46:303692gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353693 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453694 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203695 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353696 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203697 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263698 if (attachment) {
3699 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503700 }
[email protected]9edc6b22010-12-23 02:00:263701 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023702 } else if (offscreen_target_frame_buffer_.get()) {
3703 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353704 } else {
[email protected]f62a5ab2011-05-23 20:34:153705 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023706 }
[email protected]246a70452010-03-05 21:53:503707}
3708
[email protected]68586372013-12-11 01:27:593709GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3710 Framebuffer* framebuffer =
3711 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3712 if (framebuffer != NULL) {
3713 return framebuffer->GetColorAttachmentTextureType();
3714 } else {
3715 return GL_UNSIGNED_BYTE;
3716 }
3717}
3718
[email protected]9edc6b22010-12-23 02:00:263719GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353720 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453721 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203722 if (framebuffer != NULL) {
3723 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463724 } else if (offscreen_target_frame_buffer_.get()) {
3725 return offscreen_target_color_format_;
3726 } else {
3727 return back_buffer_color_format_;
3728 }
3729}
3730
3731GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353732 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453733 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203734 if (framebuffer != NULL) {
3735 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263736 } else if (offscreen_target_frame_buffer_.get()) {
3737 return offscreen_target_color_format_;
3738 } else {
[email protected]32fe9aa2011-01-21 23:47:133739 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263740 }
3741}
3742
[email protected]9a5afa432011-07-22 18:16:393743void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513744 if (!offscreen_saved_color_texture_info_.get())
3745 return;
3746 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3747 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3748 texture_manager()->SetLevelInfo(
reveman7c4a13b2015-06-05 22:28:153749 offscreen_saved_color_texture_info_.get(), GL_TEXTURE_2D,
[email protected]2ad674132013-06-05 07:48:513750 0, // level
reveman7c4a13b2015-06-05 22:28:153751 GL_RGBA, offscreen_size_.width(), offscreen_size_.height(),
[email protected]2ad674132013-06-05 07:48:513752 1, // depth
3753 0, // border
reveman7c4a13b2015-06-05 22:28:153754 GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect(offscreen_size_));
[email protected]737191ee72014-03-09 08:02:423755 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513756 "UpdateParentTextureInfo",
3757 GetErrorState(),
3758 offscreen_saved_color_texture_info_.get(),
3759 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263760 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423761 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513762 "UpdateParentTextureInfo",
3763 GetErrorState(),
3764 offscreen_saved_color_texture_info_.get(),
3765 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263766 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423767 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513768 "UpdateParentTextureInfo",
3769 GetErrorState(),
3770 offscreen_saved_color_texture_info_.get(),
3771 GL_TEXTURE_WRAP_S,
3772 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423773 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513774 "UpdateParentTextureInfo",
3775 GetErrorState(),
3776 offscreen_saved_color_texture_info_.get(),
3777 GL_TEXTURE_WRAP_T,
3778 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443779 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3780 &state_, target);
[email protected]2ad674132013-06-05 07:48:513781 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353782}
3783
[email protected]799b4b22011-08-22 17:09:593784void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073785 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523786 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003787}
3788
[email protected]1d82e822013-04-10 21:32:323789Logger* GLES2DecoderImpl::GetLogger() {
3790 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523791}
3792
[email protected]cac16542014-01-15 17:53:513793void GLES2DecoderImpl::BeginDecoding() {
3794 gpu_tracer_->BeginDecoding();
dyencb86f2f2014-12-09 18:35:413795 gpu_trace_commands_ = gpu_tracer_->IsTracing() && *gpu_decoder_category_;
vmiura1c2b1de2014-09-19 19:03:243796 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3797 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513798}
3799
3800void GLES2DecoderImpl::EndDecoding() {
3801 gpu_tracer_->EndDecoding();
3802}
3803
[email protected]d3eba342013-04-18 21:11:503804ErrorState* GLES2DecoderImpl::GetErrorState() {
3805 return state_.GetErrorState();
3806}
3807
[email protected]e3932abb2013-03-13 00:01:373808void GLES2DecoderImpl::SetShaderCacheCallback(
3809 const ShaderCacheCallback& callback) {
3810 shader_cache_callback_ = callback;
3811}
3812
[email protected]840a7e462013-02-27 01:29:513813void GLES2DecoderImpl::SetWaitSyncPointCallback(
3814 const WaitSyncPointCallback& callback) {
3815 wait_sync_point_callback_ = callback;
3816}
3817
[email protected]85a4ac22013-05-31 01:58:473818AsyncPixelTransferManager*
3819 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3820 return async_pixel_transfer_manager_.get();
3821}
3822
3823void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3824 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593825}
3826
[email protected]498b5c072013-06-04 19:30:073827void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3828 AsyncPixelTransferManager* manager) {
3829 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3830}
3831
[email protected]1318e922010-09-17 22:03:163832bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3833 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493834 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3835 if (texture_ref) {
3836 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163837 return true;
3838 }
3839 return false;
3840}
3841
[email protected]63b465922012-09-06 02:04:523842uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443843 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483844 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523845}
3846
3847base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443848 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483849 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523850}
3851
3852base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3853 return total_processing_commands_time_;
3854}
3855
[email protected]dc25dda2012-09-27 21:36:303856void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3857 total_processing_commands_time_ += time;
3858}
3859
[email protected]63c9b052012-05-17 18:27:383860void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063861 if (!initialized())
3862 return;
3863
[email protected]63c9b052012-05-17 18:27:383864 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053865
[email protected]80eb6b52012-01-19 00:14:413866 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243867 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523868 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023869 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243870 state_.bound_array_buffer = NULL;
zmo4c0c3532015-05-22 20:04:483871 state_.bound_copy_read_buffer = NULL;
3872 state_.bound_copy_write_buffer = NULL;
3873 state_.bound_pixel_pack_buffer = NULL;
3874 state_.bound_pixel_unpack_buffer = NULL;
3875 state_.bound_transform_feedback_buffer = NULL;
3876 state_.bound_uniform_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133877 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343878 framebuffer_state_.bound_read_framebuffer = NULL;
3879 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243880 state_.bound_renderbuffer = NULL;
orglofchcad5a6742014-11-07 19:51:123881 state_.bound_valuebuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413882
[email protected]cadac622013-06-11 16:46:363883 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513884 DCHECK(offscreen_target_color_texture_);
3885 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3886 offscreen_saved_color_texture_->id());
3887 offscreen_saved_color_texture_->Invalidate();
3888 offscreen_saved_color_texture_info_ = NULL;
3889 }
[email protected]eadc96792010-10-27 19:39:393890 if (have_context) {
[email protected]c322e882012-05-23 18:06:183891 if (copy_texture_CHROMIUM_.get()) {
3892 copy_texture_CHROMIUM_->Destroy();
3893 copy_texture_CHROMIUM_.reset();
3894 }
[email protected]43410e92012-04-20 17:06:283895
sievers2384f2b2014-11-18 02:10:353896 clear_framebuffer_blit_.reset();
3897
[email protected]7cd76fd2013-06-02 21:11:113898 if (state_.current_program.get()) {
3899 program_manager()->UnuseProgram(shader_manager(),
3900 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143901 }
3902
[email protected]b1122982010-05-17 23:04:243903 if (attrib_0_buffer_id_) {
3904 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3905 }
[email protected]8fbedc02010-11-18 18:43:403906 if (fixed_attrib_buffer_id_) {
3907 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3908 }
[email protected]b1122982010-05-17 23:04:243909
[email protected]4a4c18b2013-09-13 22:50:103910 if (validation_texture_) {
3911 glDeleteTextures(1, &validation_texture_);
3912 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3913 glDeleteFramebuffersEXT(1, &validation_fbo_);
3914 }
3915
[email protected]97872062010-11-03 19:07:053916 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543917 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053918 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543919 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053920 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023921 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053922 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153923 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053924 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153925 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053926 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023927 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053928 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543929 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273930 if (offscreen_resolved_frame_buffer_.get())
3931 offscreen_resolved_frame_buffer_->Destroy();
3932 if (offscreen_resolved_color_texture_.get())
3933 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053934 } else {
3935 if (offscreen_target_frame_buffer_.get())
3936 offscreen_target_frame_buffer_->Invalidate();
3937 if (offscreen_target_color_texture_.get())
3938 offscreen_target_color_texture_->Invalidate();
3939 if (offscreen_target_color_render_buffer_.get())
3940 offscreen_target_color_render_buffer_->Invalidate();
3941 if (offscreen_target_depth_render_buffer_.get())
3942 offscreen_target_depth_render_buffer_->Invalidate();
3943 if (offscreen_target_stencil_render_buffer_.get())
3944 offscreen_target_stencil_render_buffer_->Invalidate();
3945 if (offscreen_saved_frame_buffer_.get())
3946 offscreen_saved_frame_buffer_->Invalidate();
3947 if (offscreen_saved_color_texture_.get())
3948 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273949 if (offscreen_resolved_frame_buffer_.get())
3950 offscreen_resolved_frame_buffer_->Invalidate();
3951 if (offscreen_resolved_color_texture_.get())
3952 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023953 }
[email protected]83a52d032013-07-24 10:30:373954
3955 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3956 // Otherwise, we can leak objects. http://crbug.com/258772.
3957 // state_.current_program must be reset before group_ is reset because
3958 // the later deletes the ProgramManager object that referred by
3959 // state_.current_program object.
3960 state_.current_program = NULL;
3961
[email protected]43410e92012-04-20 17:06:283962 copy_texture_CHROMIUM_.reset();
sievers2384f2b2014-11-18 02:10:353963 clear_framebuffer_blit_.reset();
[email protected]97872062010-11-03 19:07:053964
[email protected]882ba1e22012-03-08 19:02:533965 if (query_manager_.get()) {
3966 query_manager_->Destroy(have_context);
3967 query_manager_.reset();
3968 }
3969
[email protected]944b62f32012-09-27 02:20:463970 if (vertex_array_manager_ .get()) {
3971 vertex_array_manager_->Destroy(have_context);
3972 vertex_array_manager_.reset();
3973 }
3974
[email protected]d2eaf52f2014-07-31 15:01:243975 if (image_manager_.get()) {
3976 image_manager_->Destroy(have_context);
3977 image_manager_.reset();
3978 }
3979
[email protected]97872062010-11-03 19:07:053980 offscreen_target_frame_buffer_.reset();
3981 offscreen_target_color_texture_.reset();
3982 offscreen_target_color_render_buffer_.reset();
3983 offscreen_target_depth_render_buffer_.reset();
3984 offscreen_target_stencil_render_buffer_.reset();
3985 offscreen_saved_frame_buffer_.reset();
3986 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273987 offscreen_resolved_frame_buffer_.reset();
3988 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463989
[email protected]03cef9b2014-04-03 15:58:143990 // Need to release these before releasing |group_| which may own the
3991 // ShaderTranslatorCache.
3992 fragment_translator_ = NULL;
3993 vertex_translator_ = NULL;
3994
[email protected]85a4ac22013-05-31 01:58:473995 // Should destroy the transfer manager before the texture manager held
3996 // by the context group.
3997 async_pixel_transfer_manager_.reset();
3998
dyendbfb90d2015-03-26 02:41:463999 // Destroy the GPU Tracer which may own some in process GPU Timings.
dyen8ef659882015-03-26 23:32:514000 if (gpu_tracer_) {
4001 gpu_tracer_->Destroy(have_context);
4002 gpu_tracer_.reset();
4003 }
dyendbfb90d2015-03-26 02:41:464004
[email protected]7cd76fd2013-06-02 21:11:114005 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:394006 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:234007 group_->Destroy(this, have_context);
4008 group_ = NULL;
4009 }
4010
4011 if (context_.get()) {
4012 context_->ReleaseCurrent(NULL);
4013 context_ = NULL;
4014 }
4015
[email protected]e51bdf32011-11-23 22:21:464016#if defined(OS_MACOSX)
4017 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
4018 it != texture_to_io_surface_map_.end(); ++it) {
4019 CFRelease(it->second);
4020 }
4021 texture_to_io_surface_map_.clear();
4022#endif
[email protected]96449d2c2009-11-25 00:01:324023}
4024
[email protected]63c9b052012-05-17 18:27:384025void GLES2DecoderImpl::SetSurface(
4026 const scoped_refptr<gfx::GLSurface>& surface) {
4027 DCHECK(context_->IsCurrent(NULL));
4028 DCHECK(surface_.get());
4029 surface_ = surface;
4030 RestoreCurrentFramebufferBindings();
4031}
4032
[email protected]aba551b2014-02-08 03:38:324033void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
4034 if (!offscreen_saved_color_texture_.get()) {
4035 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
4036 return;
4037 }
[email protected]2ad674132013-06-05 07:48:514038 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:244039 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:074040 offscreen_saved_color_texture_info_ = TextureRef::Create(
4041 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:514042 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
4043 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:394044 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:244045 }
[email protected]aba551b2014-02-08 03:38:324046 mailbox_manager()->ProduceTexture(
sievers8b373ec52014-10-24 23:04:064047 mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:244048}
4049
[email protected]799b4b22011-08-22 17:09:594050bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
4051 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
4052 if (!is_offscreen) {
4053 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
4054 << " with an onscreen framebuffer.";
4055 return false;
4056 }
4057
4058 if (offscreen_size_ == size)
4059 return true;
4060
4061 offscreen_size_ = size;
4062 int w = offscreen_size_.width();
4063 int h = offscreen_size_.height();
4064 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
4065 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
4066 << "to allocate storage due to excessive dimensions.";
4067 return false;
4068 }
4069
4070 // Reallocate the offscreen target buffers.
4071 DCHECK(offscreen_target_color_format_);
4072 if (IsOffscreenBufferMultisampled()) {
4073 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:254074 feature_info_.get(),
4075 offscreen_size_,
4076 offscreen_target_color_format_,
4077 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:594078 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
4079 << "to allocate storage for offscreen target color buffer.";
4080 return false;
4081 }
4082 } else {
4083 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:094084 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:594085 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
4086 << "to allocate storage for offscreen target color texture.";
4087 return false;
4088 }
4089 }
4090 if (offscreen_target_depth_format_ &&
4091 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:254092 feature_info_.get(),
4093 offscreen_size_,
4094 offscreen_target_depth_format_,
4095 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:594096 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
4097 << "to allocate storage for offscreen target depth buffer.";
4098 return false;
4099 }
4100 if (offscreen_target_stencil_format_ &&
4101 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:254102 feature_info_.get(),
4103 offscreen_size_,
4104 offscreen_target_stencil_format_,
4105 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:594106 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
4107 << "to allocate storage for offscreen target stencil buffer.";
4108 return false;
4109 }
4110
4111 // Attach the offscreen target buffers to the target frame buffer.
4112 if (IsOffscreenBufferMultisampled()) {
4113 offscreen_target_frame_buffer_->AttachRenderBuffer(
4114 GL_COLOR_ATTACHMENT0,
4115 offscreen_target_color_render_buffer_.get());
4116 } else {
4117 offscreen_target_frame_buffer_->AttachRenderTexture(
4118 offscreen_target_color_texture_.get());
4119 }
4120 if (offscreen_target_depth_format_) {
4121 offscreen_target_frame_buffer_->AttachRenderBuffer(
4122 GL_DEPTH_ATTACHMENT,
4123 offscreen_target_depth_render_buffer_.get());
4124 }
4125 const bool packed_depth_stencil =
4126 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4127 if (packed_depth_stencil) {
4128 offscreen_target_frame_buffer_->AttachRenderBuffer(
4129 GL_STENCIL_ATTACHMENT,
4130 offscreen_target_depth_render_buffer_.get());
4131 } else if (offscreen_target_stencil_format_) {
4132 offscreen_target_frame_buffer_->AttachRenderBuffer(
4133 GL_STENCIL_ATTACHMENT,
4134 offscreen_target_stencil_render_buffer_.get());
4135 }
4136
4137 if (offscreen_target_frame_buffer_->CheckStatus() !=
4138 GL_FRAMEBUFFER_COMPLETE) {
4139 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
4140 << "because offscreen FBO was incomplete.";
4141 return false;
4142 }
4143
4144 // Clear the target frame buffer.
4145 {
4146 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
4147 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:324148 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:454149 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:594150 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:474151 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
4152 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:594153 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:454154 state_.SetDeviceDepthMask(GL_TRUE);
4155 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:594156 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4157 RestoreClearState();
4158 }
[email protected]d85ef76d2011-09-08 22:21:434159
4160 // Destroy the offscreen resolved framebuffers.
4161 if (offscreen_resolved_frame_buffer_.get())
4162 offscreen_resolved_frame_buffer_->Destroy();
4163 if (offscreen_resolved_color_texture_.get())
4164 offscreen_resolved_color_texture_->Destroy();
4165 offscreen_resolved_color_texture_.reset();
4166 offscreen_resolved_frame_buffer_.reset();
4167
[email protected]799b4b22011-08-22 17:09:594168 return true;
[email protected]6217d392010-03-25 22:08:354169}
4170
vmiuracd108592014-09-08 14:36:344171error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
4172 const void* cmd_data) {
4173 const gles2::cmds::ResizeCHROMIUM& c =
4174 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:444175 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:024176 return error::kDeferCommandUntilLater;
4177
[email protected]799b4b22011-08-22 17:09:594178 GLuint width = static_cast<GLuint>(c.width);
4179 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:074180 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:594181 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:414182
4183 width = std::max(1U, width);
4184 height = std::max(1U, height);
4185
[email protected]a0d989162011-11-22 13:15:074186#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
4187 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:004188 // Make sure that we are done drawing to the back buffer before resizing.
4189 glFinish();
4190#endif
[email protected]799b4b22011-08-22 17:09:594191 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
4192 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:494193 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
4194 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
4195 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:594196 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:494197 }
[email protected]7ff86b92010-11-25 17:50:004198 }
[email protected]799b4b22011-08-22 17:09:594199
[email protected]9d37f062011-11-22 01:24:524200 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:074201 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:444202 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:494203 if (!context_->IsCurrent(surface_.get())) {
4204 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
4205 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:054206 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:494207 }
[email protected]658f7562011-09-09 05:24:054208 }
[email protected]799b4b22011-08-22 17:09:594209
4210 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:394211}
4212
[email protected]96449d2c2009-11-25 00:01:324213const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
4214 if (command_id > kStartPoint && command_id < kNumCommands) {
4215 return gles2::GetCommandName(static_cast<CommandId>(command_id));
4216 }
4217 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
4218}
4219
vmiura8266ca72014-09-09 21:37:004220// Decode a command, and call the corresponding GL functions.
4221// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
4222// of commands at once, and is now only used for tests that need to track
4223// individual commands.
4224error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
4225 unsigned int arg_count,
4226 const void* cmd_data) {
4227 return DoCommands(1, cmd_data, arg_count + 1, 0);
4228}
4229
4230// Decode multiple commands, and call the corresponding GL functions.
4231// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
4232// changed by a (malicious) client at any time, so if validation has to happen,
4233// it should operate on a copy of them.
4234// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
4235// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:244236template <bool DebugImpl>
4237error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
4238 const void* buffer,
4239 int num_entries,
4240 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:004241 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:144242 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:004243 const CommandBufferEntry* cmd_data =
4244 static_cast<const CommandBufferEntry*>(buffer);
4245 int process_pos = 0;
4246 unsigned int command = 0;
4247
4248 while (process_pos < num_entries && result == error::kNoError &&
4249 commands_to_process_--) {
4250 const unsigned int size = cmd_data->value_header.size;
4251 command = cmd_data->value_header.command;
4252
4253 if (size == 0) {
4254 result = error::kInvalidSize;
4255 break;
4256 }
4257
4258 if (static_cast<int>(size) + process_pos > num_entries) {
4259 result = error::kOutOfBounds;
4260 break;
4261 }
4262
vmiura1c2b1de2014-09-19 19:03:244263 if (DebugImpl) {
4264 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
4265 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:004266
vmiura1c2b1de2014-09-19 19:03:244267 if (log_commands()) {
4268 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
4269 << "cmd: " << GetCommandName(command);
4270 }
vmiura8266ca72014-09-09 21:37:004271 }
4272
4273 const unsigned int arg_count = size - 1;
4274 unsigned int command_index = command - kStartPoint - 1;
4275 if (command_index < arraysize(command_info)) {
4276 const CommandInfo& info = command_info[command_index];
4277 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
4278 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
4279 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
4280 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:244281 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:004282 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
4283 doing_gpu_trace = true;
dyencb86f2f2014-12-09 18:35:414284 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_decoder"),
4285 GetCommandName(command),
4286 kTraceDecoder);
vmiura8266ca72014-09-09 21:37:004287 }
[email protected]cac16542014-01-15 17:53:514288 }
[email protected]cac16542014-01-15 17:53:514289
vmiura8266ca72014-09-09 21:37:004290 uint32 immediate_data_size = (arg_count - info_arg_count) *
4291 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:324292
vmiura8266ca72014-09-09 21:37:004293 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:514294
vmiura1c2b1de2014-09-19 19:03:244295 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:004296 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:514297
vmiura1c2b1de2014-09-19 19:03:244298 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:004299 GLenum error;
4300 while ((error = glGetError()) != GL_NO_ERROR) {
4301 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
4302 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
4303 << " : " << GetCommandName(command);
4304 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
4305 }
[email protected]b9849abf2009-11-25 19:13:194306 }
vmiura8266ca72014-09-09 21:37:004307 } else {
4308 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:324309 }
4310 } else {
vmiura8266ca72014-09-09 21:37:004311 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:324312 }
vmiura1c2b1de2014-09-19 19:03:244313
4314 if (DebugImpl) {
4315 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
4316 GetCommandName(command));
4317 }
4318
vmiura8266ca72014-09-09 21:37:004319 if (result == error::kNoError &&
4320 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:564321 result = current_decoder_error_;
4322 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:004323 }
4324
4325 if (result != error::kDeferCommandUntilLater) {
4326 process_pos += size;
4327 cmd_data += size;
4328 }
[email protected]a3a93e7b2010-08-28 00:48:564329 }
vmiura8266ca72014-09-09 21:37:004330
4331 if (entries_processed)
4332 *entries_processed = process_pos;
4333
4334 if (error::IsError(result)) {
4335 LOG(ERROR) << "Error: " << result << " for Command "
4336 << GetCommandName(command);
4337 }
4338
[email protected]b9849abf2009-11-25 19:13:194339 return result;
[email protected]96449d2c2009-11-25 00:01:324340}
4341
vmiura1c2b1de2014-09-19 19:03:244342error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
4343 const void* buffer,
4344 int num_entries,
4345 int* entries_processed) {
4346 if (gpu_debug_commands_) {
4347 return DoCommandsImpl<true>(
4348 num_commands, buffer, num_entries, entries_processed);
4349 } else {
4350 return DoCommandsImpl<false>(
4351 num_commands, buffer, num_entries, entries_processed);
4352 }
4353}
4354
[email protected]ed9f9cd2013-02-27 21:12:354355void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
4356 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:504357}
4358
[email protected]882ba1e22012-03-08 19:02:534359void GLES2DecoderImpl::DoFinish() {
4360 glFinish();
[email protected]5a36dc132013-07-23 23:17:554361 ProcessPendingReadPixels();
revemancc241eb2014-11-11 03:30:374362 ProcessPendingQueries(true);
[email protected]882ba1e22012-03-08 19:02:534363}
4364
4365void GLES2DecoderImpl::DoFlush() {
4366 glFlush();
revemancc241eb2014-11-11 03:30:374367 ProcessPendingQueries(false);
[email protected]882ba1e22012-03-08 19:02:534368}
4369
[email protected]3916c97e2010-02-25 03:20:504370void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:454371 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:024372 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:514373 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:534374 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:504375 return;
4376 }
[email protected]e259eb412012-10-13 05:47:244377 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:454378 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:504379}
4380
[email protected]051b1372010-04-12 02:42:084381void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:074382 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:084383 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034384 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:074385 buffer = GetBuffer(client_id);
4386 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:354387 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224388 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4389 "glBindBuffer",
4390 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:354391 return;
4392 }
4393
[email protected]b10492f2013-03-08 05:24:074394 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:034395 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354396 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:074397 buffer = GetBuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034398 }
[email protected]051b1372010-04-12 02:42:084399 }
[email protected]b10492f2013-03-08 05:24:074400 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
4401 if (buffer) {
4402 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:514403 LOCAL_SET_GL_ERROR(
4404 GL_INVALID_OPERATION,
4405 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:474406 return;
4407 }
[email protected]b10492f2013-03-08 05:24:074408 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:474409 }
zmo4c0c3532015-05-22 20:04:484410 state_.SetBoundBuffer(target, buffer);
[email protected]051b1372010-04-12 02:42:084411 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:324412}
4413
[email protected]f3b191b2013-06-19 03:43:544414bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
4415 bool all_draw_buffers) {
4416 Framebuffer* framebuffer =
4417 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4418 if (!all_draw_buffers || !framebuffer) {
4419 return (GLES2Util::GetChannelsForFormat(
4420 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
4421 }
4422 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:464423}
4424
4425bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354426 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454427 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204428 if (framebuffer) {
4429 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:464430 }
4431 if (offscreen_target_frame_buffer_.get()) {
4432 return offscreen_target_depth_format_ != 0;
4433 }
4434 return back_buffer_has_depth_;
4435}
4436
4437bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354438 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454439 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204440 if (framebuffer) {
4441 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464442 }
4443 if (offscreen_target_frame_buffer_.get()) {
4444 return offscreen_target_stencil_format_ != 0 ||
4445 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4446 }
4447 return back_buffer_has_stencil_;
4448}
4449
4450void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444451 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454452 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4453 state_.SetDeviceColorMask(state_.color_mask_red,
4454 state_.color_mask_green,
4455 state_.color_mask_blue,
4456 state_.color_mask_alpha && have_alpha);
4457
[email protected]297ca1c2011-06-20 23:08:464458 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454459 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4460
[email protected]297ca1c2011-06-20 23:08:464461 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454462 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424463 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454464 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424465 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454466
4467 state_.SetDeviceCapabilityState(
4468 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4469 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224470 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444471 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464472 }
4473}
4474
[email protected]1868a342012-11-07 15:56:024475GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114476 return (offscreen_target_frame_buffer_.get())
4477 ? offscreen_target_frame_buffer_->id()
4478 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024479}
4480
[email protected]8875a5f2014-06-27 08:33:474481void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144482 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4483 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064484 // Restore the Framebuffer first because of bugs in Intel drivers.
4485 // Intel drivers incorrectly clip the viewport settings to
4486 // the size of the current framebuffer object.
4487 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164488 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064489}
4490
4491void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344492 GLuint service_id =
4493 framebuffer_state_.bound_draw_framebuffer.get()
4494 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4495 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064496 if (!features().chromium_framebuffer_multisample) {
4497 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4498 } else {
4499 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344500 service_id = framebuffer_state_.bound_read_framebuffer.get()
4501 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114502 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064503 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4504 }
[email protected]70d34263c2013-01-09 00:27:454505 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064506}
4507
[email protected]8875a5f2014-06-27 08:33:474508void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4509 state_.RestoreRenderbufferBindings();
4510}
4511
[email protected]29a4d902013-02-26 20:18:064512void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104513 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4514 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254515 GLenum target = texture->target();
4516 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064517 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254518 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064519 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254520 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064521 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254522 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064523 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254524 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064525 RestoreTextureUnitBindings(state_.active_texture_unit);
4526 }
[email protected]70d34263c2013-01-09 00:27:454527}
4528
[email protected]cd2ef752014-02-12 23:16:034529void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524530 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4531 // other VAOs.
4532 if (feature_info_->feature_flags().native_vertex_array_object)
4533 glBindVertexArrayOES(0);
4534
[email protected]cd2ef752014-02-12 23:16:034535 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
dcastagna504d45c2015-04-06 19:30:394536 if (i != 0) // Never disable attribute 0
[email protected]cd2ef752014-02-12 23:16:034537 glDisableVertexAttribArray(i);
dcastagna504d45c2015-04-06 19:30:394538 if (features().angle_instanced_arrays)
[email protected]cd2ef752014-02-12 23:16:034539 glVertexAttribDivisorANGLE(i, 0);
4540 }
4541}
4542
4543void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524544 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034545}
4546
[email protected]454157e2014-05-03 02:49:454547void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4548 state_.SetIgnoreCachedStateForTest(ignore);
4549}
4550
[email protected]70d34263c2013-01-09 00:27:454551void GLES2DecoderImpl::OnFboChanged() const {
4552 if (workarounds().restore_scissor_on_fbo_change)
zmo8ac3bab2015-04-18 02:30:584553 state_.fbo_binding_for_scissor_workaround_dirty = true;
ccameron4ff12a732014-12-12 21:38:194554
4555 if (workarounds().gl_begin_gl_end_on_fbo_change_to_backbuffer) {
4556 GLint bound_fbo_unsigned = -1;
4557 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_fbo_unsigned);
4558 GLuint bound_fbo = static_cast<GLuint>(bound_fbo_unsigned);
4559 if (surface_ && surface_->GetBackingFrameBufferObject() == bound_fbo)
4560 surface_->NotifyWasBound();
4561 }
[email protected]28718a92013-04-04 12:12:514562}
4563
4564// Called after the FBO is checked for completeness.
4565void GLES2DecoderImpl::OnUseFramebuffer() const {
zmo8ac3bab2015-04-18 02:30:584566 if (state_.fbo_binding_for_scissor_workaround_dirty) {
4567 state_.fbo_binding_for_scissor_workaround_dirty = false;
[email protected]81fc9d02013-03-14 23:53:324568 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514569 glScissor(state_.scissor_x,
4570 state_.scissor_y,
4571 state_.scissor_width,
4572 state_.scissor_height);
4573
4574 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4575 // it's unclear how this bug works.
4576 glFlush();
4577 }
[email protected]b177ae22011-11-01 03:29:114578}
4579
[email protected]051b1372010-04-12 02:42:084580void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064581 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084582 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034583 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064584 framebuffer = GetFramebuffer(client_id);
4585 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354586 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224587 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4588 "glBindFramebuffer",
4589 "id not generated by glGenFramebuffers");
4590 return;
[email protected]bf5a8d132011-08-16 08:39:354591 }
4592
[email protected]4d8f0dd2013-03-09 14:37:064593 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034594 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354595 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064596 framebuffer = GetFramebuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034597 } else {
[email protected]4d8f0dd2013-03-09 14:37:064598 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084599 }
[email protected]4d8f0dd2013-03-09 14:37:064600 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084601 }
[email protected]4d8f0dd2013-03-09 14:37:064602 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304603
4604 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344605 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304606 }
[email protected]cac16542014-01-15 17:53:514607
4608 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304609 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344610 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304611 }
[email protected]6217d392010-03-25 22:08:354612
[email protected]c986af502013-08-14 01:04:444613 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464614
[email protected]b177ae22011-11-01 03:29:114615 // If we are rendering to the backbuffer get the FBO id for any simulated
4616 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064617 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114618 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464619 }
[email protected]6217d392010-03-25 22:08:354620
[email protected]051b1372010-04-12 02:42:084621 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454622 OnFboChanged();
[email protected]86093972010-03-11 00:13:564623}
4624
[email protected]051b1372010-04-12 02:42:084625void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274626 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084627 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034628 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274629 renderbuffer = GetRenderbuffer(client_id);
4630 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354631 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224632 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4633 "glBindRenderbuffer",
4634 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354635 return;
4636 }
4637
[email protected]8875a5f2014-06-27 08:33:474638 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034639 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354640 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274641 renderbuffer = GetRenderbuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034642 } else {
[email protected]ee2a79c32013-03-10 03:50:274643 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084644 }
[email protected]ee2a79c32013-03-10 03:50:274645 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084646 }
[email protected]caa13ed2014-02-17 11:29:204647 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274648 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474649 state_.bound_renderbuffer_valid = true;
4650 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564651}
4652
[email protected]051b1372010-04-12 02:42:084653void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494654 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084655 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034656 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494657 texture_ref = GetTexture(client_id);
4658 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354659 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224660 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4661 "glBindTexture",
4662 "id not generated by glGenTextures");
4663 return;
[email protected]bf5a8d132011-08-16 08:39:354664 }
4665
[email protected]02965c22013-03-09 02:40:074666 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034667 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414668 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354669 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494670 texture_ref = GetTexture(client_id);
[email protected]ae51d192010-04-27 00:48:034671 }
4672 } else {
[email protected]370eaf12013-05-18 09:19:494673 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084674 }
[email protected]ae51d192010-04-27 00:48:034675
[email protected]1958e0e2010-04-22 05:17:154676 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574677 if (texture_ref) {
4678 Texture* texture = texture_ref->texture();
4679 // Check that we are not trying to bind it to a different target.
4680 if (texture->target() != 0 && texture->target() != target) {
4681 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4682 "glBindTexture",
4683 "texture bound to more than 1 target.");
4684 return;
4685 }
4686 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4687 if (texture->target() == 0) {
4688 texture_manager()->SetTarget(texture_ref, target);
4689 }
4690 glBindTexture(target, texture->service_id());
4691 } else {
4692 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154693 }
[email protected]32145a92012-12-17 09:01:594694
[email protected]e259eb412012-10-13 05:47:244695 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504696 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474697 switch (target) {
4698 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494699 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474700 break;
4701 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494702 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474703 break;
[email protected]61eeb33f2011-07-26 15:30:314704 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494705 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314706 break;
[email protected]e51bdf32011-11-23 22:21:464707 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494708 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464709 break;
zmoea06a6f2015-04-30 01:15:464710 case GL_TEXTURE_3D:
4711 unit.bound_texture_3d = texture_ref;
4712 break;
4713 case GL_TEXTURE_2D_ARRAY:
4714 unit.bound_texture_2d_array = texture_ref;
4715 break;
[email protected]a93bb842010-02-16 23:03:474716 default:
4717 NOTREACHED(); // Validation should prevent us getting here.
4718 break;
4719 }
4720}
4721
[email protected]07f54fcc2009-12-22 02:46:304722void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244723 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124724 if (index != 0 ||
4725 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244726 glDisableVertexAttribArray(index);
4727 }
[email protected]07f54fcc2009-12-22 02:46:304728 } else {
[email protected]ab09b612013-03-11 22:11:514729 LOCAL_SET_GL_ERROR(
4730 GL_INVALID_VALUE,
4731 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304732 }
4733}
4734
[email protected]60f22d32012-12-12 00:31:584735void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4736 GLsizei numAttachments,
4737 const GLenum* attachments) {
aelias8ef99b8a2015-04-07 23:19:354738 if (workarounds().disable_discard_framebuffer)
dyen5f38cadc2015-03-26 16:58:424739 return;
4740
[email protected]ed9f9cd2013-02-27 21:12:354741 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584742 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4743
4744 // Validates the attachments. If one of them fails
4745 // the whole command fails.
4746 for (GLsizei i = 0; i < numAttachments; ++i) {
4747 if ((framebuffer &&
4748 !validators_->attachment.IsValid(attachments[i])) ||
4749 (!framebuffer &&
4750 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514751 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4752 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584753 return;
4754 }
4755 }
4756
4757 // Marks each one of them as not cleared
4758 for (GLsizei i = 0; i < numAttachments; ++i) {
4759 if (framebuffer) {
4760 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4761 texture_manager(),
4762 attachments[i],
4763 false);
4764 } else {
4765 switch (attachments[i]) {
4766 case GL_COLOR_EXT:
4767 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4768 break;
4769 case GL_DEPTH_EXT:
4770 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4771 case GL_STENCIL_EXT:
4772 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4773 break;
4774 default:
4775 NOTREACHED();
4776 break;
4777 }
4778 }
4779 }
4780
[email protected]d49c5402013-09-11 15:39:024781 // If the default framebuffer is bound but we are still rendering to an
4782 // FBO, translate attachment names that refer to default framebuffer
4783 // channels to corresponding framebuffer attachments.
4784 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4785 for (GLsizei i = 0; i < numAttachments; ++i) {
4786 GLenum attachment = attachments[i];
4787 if (!framebuffer && GetBackbufferServiceId()) {
4788 switch (attachment) {
4789 case GL_COLOR_EXT:
4790 attachment = GL_COLOR_ATTACHMENT0;
4791 break;
4792 case GL_DEPTH_EXT:
4793 attachment = GL_DEPTH_ATTACHMENT;
4794 break;
4795 case GL_STENCIL_EXT:
4796 attachment = GL_STENCIL_ATTACHMENT;
4797 break;
4798 default:
4799 NOTREACHED();
4800 return;
4801 }
4802 }
4803 translated_attachments[i] = attachment;
4804 }
4805
boliu2e7d8a7a2014-10-16 20:35:204806 ScopedRenderTo do_render(framebuffer);
marcheu1856f5d52015-04-04 01:42:534807 if (feature_info_->gl_version_info().is_es3) {
zmo68fcdc62014-12-05 21:51:494808 glInvalidateFramebuffer(
4809 target, numAttachments, translated_attachments.get());
4810 } else {
4811 glDiscardFramebufferEXT(
4812 target, numAttachments, translated_attachments.get());
4813 }
[email protected]60f22d32012-12-12 00:31:584814}
4815
[email protected]07f54fcc2009-12-22 02:46:304816void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244817 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304818 glEnableVertexAttribArray(index);
4819 } else {
[email protected]ab09b612013-03-11 22:11:514820 LOCAL_SET_GL_ERROR(
4821 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304822 }
4823}
4824
[email protected]a93bb842010-02-16 23:03:474825void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444826 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4827 &state_, target);
[email protected]370eaf12013-05-18 09:19:494828 if (!texture_ref ||
4829 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514830 LOCAL_SET_GL_ERROR(
4831 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474832 return;
4833 }
[email protected]38c0a972012-05-12 00:48:024834
[email protected]12d95352012-12-14 07:23:544835 if (target == GL_TEXTURE_CUBE_MAP) {
4836 for (int i = 0; i < 6; ++i) {
4837 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494838 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514839 LOCAL_SET_GL_ERROR(
4840 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544841 return;
4842 }
4843 }
4844 } else {
[email protected]370eaf12013-05-18 09:19:494845 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514846 LOCAL_SET_GL_ERROR(
4847 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544848 return;
4849 }
[email protected]7687479c2012-05-14 23:54:044850 }
4851
[email protected]ab09b612013-03-11 22:11:514852 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194853 // Workaround for Mac driver bug. In the large scheme of things setting
4854 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564855 // hit so there's probably no need to make this conditional. The bug appears
4856 // to be that if the filtering mode is set to something that doesn't require
4857 // mipmaps for rendering, or is never set to something other than the default,
4858 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154859 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194860 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4861 }
[email protected]a93bb842010-02-16 23:03:474862 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154863 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494864 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4865 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194866 }
[email protected]ab09b612013-03-11 22:11:514867 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024868 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494869 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024870 }
[email protected]a93bb842010-02-16 23:03:474871}
4872
[email protected]b273e432010-04-12 17:23:584873bool GLES2DecoderImpl::GetHelper(
4874 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584875 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154876 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4877 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434878 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4879 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214880 // Return the GL implementation's preferred format and (see below type)
4881 // if we have the GL extension that exposes this. This allows the GPU
4882 // client to use the implementation's preferred format for glReadPixels
4883 // for optimisation.
4884 //
4885 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4886 // case when requested on integer/floating point buffers but which is
4887 // acceptable on GLES2 and with the GL_OES_read_format extension.
4888 //
4889 // Therefore if an error occurs we swallow the error and use the
4890 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434891 if (params) {
[email protected]c959a09a2014-03-27 11:44:214892 if (context_->HasExtension("GL_OES_read_format")) {
4893 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4894 GetErrorState());
4895 glGetIntegerv(pname, params);
4896 if (glGetError() == GL_NO_ERROR)
4897 return true;
4898 }
[email protected]68586372013-12-11 01:27:594899 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4900 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434901 }
4902 return true;
4903 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4904 *num_written = 1;
4905 if (params) {
[email protected]c959a09a2014-03-27 11:44:214906 if (context_->HasExtension("GL_OES_read_format")) {
4907 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4908 GetErrorState());
4909 glGetIntegerv(pname, params);
4910 if (glGetError() == GL_NO_ERROR)
4911 return true;
4912 }
[email protected]68586372013-12-11 01:27:594913 *params = GLES2Util::GetPreferredGLReadPixelsType(
4914 GetBoundReadFrameBufferInternalFormat(),
4915 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434916 }
4917 return true;
4918 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4919 *num_written = 1;
4920 if (params) {
4921 *params = group_->max_fragment_uniform_vectors();
4922 }
4923 return true;
4924 case GL_MAX_VARYING_VECTORS:
4925 *num_written = 1;
4926 if (params) {
4927 *params = group_->max_varying_vectors();
4928 }
4929 return true;
4930 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4931 *num_written = 1;
4932 if (params) {
4933 *params = group_->max_vertex_uniform_vectors();
4934 }
4935 return true;
[email protected]4e8a5b122010-05-08 22:00:104936 }
[email protected]5cb735d2011-10-13 01:37:234937 }
kbr9370c842015-05-22 02:36:294938 if (unsafe_es3_apis_enabled()) {
4939 switch (pname) {
4940 case GL_MAX_VARYING_COMPONENTS: {
4941 if (feature_info_->gl_version_info().is_es) {
4942 // We can just delegate this query to the driver.
4943 return false;
4944 }
4945
4946 // GL_MAX_VARYING_COMPONENTS is deprecated in the desktop
4947 // OpenGL core profile, so for simplicity, just compute it
4948 // from GL_MAX_VARYING_VECTORS on non-OpenGL ES
4949 // configurations.
4950 GLint max_varying_vectors = 0;
4951 glGetIntegerv(GL_MAX_VARYING_VECTORS, &max_varying_vectors);
4952 *num_written = 1;
4953 if (params) {
4954 *params = max_varying_vectors * 4;
4955 }
4956 return true;
4957 }
4958 }
4959 }
[email protected]5cb735d2011-10-13 01:37:234960 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244961 case GL_MAX_VIEWPORT_DIMS:
4962 if (offscreen_target_frame_buffer_.get()) {
4963 *num_written = 2;
4964 if (params) {
4965 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4966 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4967 }
4968 return true;
4969 }
[email protected]5cb735d2011-10-13 01:37:234970 return false;
[email protected]84afefa2011-10-19 21:45:534971 case GL_MAX_SAMPLES:
4972 *num_written = 1;
4973 if (params) {
4974 params[0] = renderbuffer_manager()->max_samples();
4975 }
4976 return true;
4977 case GL_MAX_RENDERBUFFER_SIZE:
4978 *num_written = 1;
4979 if (params) {
4980 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4981 }
4982 return true;
[email protected]5cb735d2011-10-13 01:37:234983 case GL_MAX_TEXTURE_SIZE:
4984 *num_written = 1;
4985 if (params) {
4986 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4987 }
4988 return true;
4989 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4990 *num_written = 1;
4991 if (params) {
4992 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4993 }
4994 return true;
[email protected]2f143d482013-03-14 18:04:494995 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4996 *num_written = 1;
4997 if (params) {
4998 params[0] = group_->max_color_attachments();
4999 }
5000 return true;
5001 case GL_MAX_DRAW_BUFFERS_ARB:
5002 *num_written = 1;
5003 if (params) {
5004 params[0] = group_->max_draw_buffers();
5005 }
5006 return true;
[email protected]297ca1c2011-06-20 23:08:465007 case GL_ALPHA_BITS:
5008 *num_written = 1;
5009 if (params) {
5010 GLint v = 0;
marcheu1856f5d52015-04-04 01:42:535011 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:125012 Framebuffer* framebuffer =
5013 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
5014 if (framebuffer) {
5015 glGetFramebufferAttachmentParameterivEXT(
5016 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5017 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &v);
5018 } else {
5019 v = (back_buffer_color_format_ == GL_RGBA ? 8 : 0);
5020 }
5021 } else {
5022 glGetIntegerv(GL_ALPHA_BITS, &v);
5023 }
5024 params[0] =
5025 BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:465026 }
5027 return true;
5028 case GL_DEPTH_BITS:
5029 *num_written = 1;
5030 if (params) {
5031 GLint v = 0;
marcheu1856f5d52015-04-04 01:42:535032 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:125033 Framebuffer* framebuffer =
5034 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
5035 if (framebuffer) {
5036 glGetFramebufferAttachmentParameterivEXT(
5037 GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
5038 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &v);
5039 } else {
5040 v = (back_buffer_has_depth_ ? 24 : 0);
5041 }
5042 } else {
5043 glGetIntegerv(GL_DEPTH_BITS, &v);
5044 }
[email protected]297ca1c2011-06-20 23:08:465045 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
5046 }
5047 return true;
kbrc9f0e10c2015-03-31 19:49:125048 case GL_RED_BITS:
5049 case GL_GREEN_BITS:
5050 case GL_BLUE_BITS:
5051 *num_written = 1;
5052 if (params) {
5053 GLint v = 0;
marcheu1856f5d52015-04-04 01:42:535054 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:125055 Framebuffer* framebuffer =
5056 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
5057 if (framebuffer) {
5058 GLenum framebuffer_enum = 0;
5059 switch (pname) {
5060 case GL_RED_BITS:
5061 framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE;
5062 break;
5063 case GL_GREEN_BITS:
5064 framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
5065 break;
5066 case GL_BLUE_BITS:
5067 framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
5068 break;
5069 }
5070 glGetFramebufferAttachmentParameterivEXT(
5071 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, framebuffer_enum, &v);
5072 } else {
5073 v = 8;
5074 }
5075 } else {
5076 glGetIntegerv(pname, &v);
5077 }
5078 params[0] = v;
5079 }
5080 return true;
[email protected]297ca1c2011-06-20 23:08:465081 case GL_STENCIL_BITS:
5082 *num_written = 1;
5083 if (params) {
5084 GLint v = 0;
marcheu1856f5d52015-04-04 01:42:535085 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:125086 Framebuffer* framebuffer =
5087 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
5088 if (framebuffer) {
5089 glGetFramebufferAttachmentParameterivEXT(
5090 GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
5091 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &v);
5092 } else {
5093 v = (back_buffer_has_stencil_ ? 8 : 0);
5094 }
5095 } else {
5096 glGetIntegerv(GL_STENCIL_BITS, &v);
5097 }
[email protected]297ca1c2011-06-20 23:08:465098 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
5099 }
5100 return true;
[email protected]656dcaad2010-05-07 17:18:375101 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:115102 *num_written = validators_->compressed_texture_format.GetValues().size();
5103 if (params) {
5104 for (GLint ii = 0; ii < *num_written; ++ii) {
5105 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
5106 }
5107 }
[email protected]656dcaad2010-05-07 17:18:375108 return true;
[email protected]b273e432010-04-12 17:23:585109 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
5110 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:105111 if (params) {
[email protected]302ce6d2011-07-07 23:28:115112 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:105113 }
[email protected]b273e432010-04-12 17:23:585114 return true;
5115 case GL_NUM_SHADER_BINARY_FORMATS:
5116 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:105117 if (params) {
[email protected]302ce6d2011-07-07 23:28:115118 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:105119 }
[email protected]b273e432010-04-12 17:23:585120 return true;
5121 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:115122 *num_written = validators_->shader_binary_format.GetValues().size();
5123 if (params) {
5124 for (GLint ii = 0; ii < *num_written; ++ii) {
5125 params[ii] = validators_->shader_binary_format.GetValues()[ii];
5126 }
5127 }
5128 return true;
[email protected]b273e432010-04-12 17:23:585129 case GL_SHADER_COMPILER:
5130 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:105131 if (params) {
5132 *params = GL_TRUE;
5133 }
[email protected]b273e432010-04-12 17:23:585134 return true;
[email protected]6b8cf1a2010-05-06 16:13:585135 case GL_ARRAY_BUFFER_BINDING:
5136 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:105137 if (params) {
zmo4c0c3532015-05-22 20:04:485138 *params = GetClientId(
5139 buffer_manager(), state_.bound_array_buffer.get());
[email protected]6b8cf1a2010-05-06 16:13:585140 }
5141 return true;
5142 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
5143 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:105144 if (params) {
zmo4c0c3532015-05-22 20:04:485145 *params = GetClientId(
5146 buffer_manager(),
5147 state_.vertex_attrib_manager->element_array_buffer());
5148 }
5149 return true;
5150 case GL_COPY_READ_BUFFER_BINDING:
5151 *num_written = 1;
5152 if (params) {
5153 *params = GetClientId(
5154 buffer_manager(), state_.bound_copy_read_buffer.get());
5155 }
5156 return true;
5157 case GL_COPY_WRITE_BUFFER_BINDING:
5158 *num_written = 1;
5159 if (params) {
5160 *params = GetClientId(
5161 buffer_manager(), state_.bound_copy_write_buffer.get());
5162 }
5163 return true;
5164 case GL_PIXEL_PACK_BUFFER_BINDING:
5165 *num_written = 1;
5166 if (params) {
5167 *params = GetClientId(
5168 buffer_manager(), state_.bound_pixel_pack_buffer.get());
5169 }
5170 return true;
5171 case GL_PIXEL_UNPACK_BUFFER_BINDING:
5172 *num_written = 1;
5173 if (params) {
5174 *params = GetClientId(
5175 buffer_manager(), state_.bound_pixel_unpack_buffer.get());
5176 }
5177 return true;
5178 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
5179 *num_written = 1;
5180 if (params) {
5181 *params = GetClientId(
5182 buffer_manager(), state_.bound_transform_feedback_buffer.get());
5183 }
5184 return true;
5185 case GL_UNIFORM_BUFFER_BINDING:
5186 *num_written = 1;
5187 if (params) {
5188 *params = GetClientId(
5189 buffer_manager(), state_.bound_uniform_buffer.get());
[email protected]6b8cf1a2010-05-06 16:13:585190 }
5191 return true;
5192 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:305193 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:585194 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:105195 if (params) {
zmo4c0c3532015-05-22 20:04:485196 *params = GetClientId(
5197 framebuffer_manager(),
5198 GetFramebufferInfoForTarget(GL_FRAMEBUFFER));
[email protected]8e3e0662010-08-23 18:46:305199 }
5200 return true;
[email protected]ebfb73c2012-08-15 02:37:455201 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:305202 *num_written = 1;
5203 if (params) {
zmo4c0c3532015-05-22 20:04:485204 *params = GetClientId(
5205 framebuffer_manager(),
5206 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT));
[email protected]6b8cf1a2010-05-06 16:13:585207 }
5208 return true;
5209 case GL_RENDERBUFFER_BINDING:
5210 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:105211 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:355212 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205213 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5214 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:105215 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:105216 } else {
5217 *params = 0;
5218 }
[email protected]6b8cf1a2010-05-06 16:13:585219 }
5220 return true;
5221 case GL_CURRENT_PROGRAM:
5222 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:105223 if (params) {
zmo4c0c3532015-05-22 20:04:485224 *params = GetClientId(program_manager(), state_.current_program.get());
[email protected]6b8cf1a2010-05-06 16:13:585225 }
5226 return true;
[email protected]bf835842012-11-19 15:21:515227 case GL_VERTEX_ARRAY_BINDING_OES:
5228 *num_written = 1;
5229 if (params) {
[email protected]7cd76fd2013-06-02 21:11:115230 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:525231 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:515232 GLuint client_id = 0;
5233 vertex_array_manager_->GetClientId(
5234 state_.vertex_attrib_manager->service_id(), &client_id);
5235 *params = client_id;
5236 } else {
5237 *params = 0;
5238 }
5239 }
5240 return true;
[email protected]4e8a5b122010-05-08 22:00:105241 case GL_TEXTURE_BINDING_2D:
5242 *num_written = 1;
5243 if (params) {
[email protected]e259eb412012-10-13 05:47:245244 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:115245 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:105246 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:585247 } else {
5248 *params = 0;
5249 }
[email protected]6b8cf1a2010-05-06 16:13:585250 }
[email protected]4e8a5b122010-05-08 22:00:105251 return true;
5252 case GL_TEXTURE_BINDING_CUBE_MAP:
5253 *num_written = 1;
5254 if (params) {
[email protected]e259eb412012-10-13 05:47:245255 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:115256 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:105257 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:585258 } else {
5259 *params = 0;
5260 }
[email protected]6b8cf1a2010-05-06 16:13:585261 }
[email protected]4e8a5b122010-05-08 22:00:105262 return true;
[email protected]61eeb33f2011-07-26 15:30:315263 case GL_TEXTURE_BINDING_EXTERNAL_OES:
5264 *num_written = 1;
5265 if (params) {
[email protected]e259eb412012-10-13 05:47:245266 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:115267 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:105268 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:315269 } else {
5270 *params = 0;
5271 }
5272 }
5273 return true;
[email protected]e51bdf32011-11-23 22:21:465274 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
5275 *num_written = 1;
5276 if (params) {
[email protected]e259eb412012-10-13 05:47:245277 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:115278 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:105279 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:465280 } else {
5281 *params = 0;
5282 }
5283 }
5284 return true;
[email protected]6eda6822014-04-03 23:00:505285 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
5286 *num_written = 1;
5287 if (params) {
5288 params[0] = group_->bind_generates_resource() ? 1 : 0;
5289 }
5290 return true;
[email protected]b273e432010-04-12 17:23:585291 default:
[email protected]2f143d482013-03-14 18:04:495292 if (pname >= GL_DRAW_BUFFER0_ARB &&
5293 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
5294 *num_written = 1;
5295 if (params) {
5296 Framebuffer* framebuffer =
5297 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
5298 if (framebuffer) {
5299 params[0] = framebuffer->GetDrawBuffer(pname);
5300 } else { // backbuffer
5301 if (pname == GL_DRAW_BUFFER0_ARB)
5302 params[0] = group_->draw_buffer();
5303 else
5304 params[0] = GL_NONE;
5305 }
5306 }
5307 return true;
5308 }
[email protected]4e8a5b122010-05-08 22:00:105309 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:535310 return false;
[email protected]b273e432010-04-12 17:23:585311 }
5312}
5313
[email protected]4e8a5b122010-05-08 22:00:105314bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
5315 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:265316 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:535317 return true;
5318 }
[email protected]4e8a5b122010-05-08 22:00:105319 return GetHelper(pname, NULL, num_values);
5320}
5321
[email protected]7d3c36e2013-07-12 14:13:165322GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
5323 if (GL_MAX_SAMPLES == pname &&
5324 features().use_img_for_multisampled_render_to_texture) {
5325 return GL_MAX_SAMPLES_IMG;
5326 }
5327 return pname;
5328}
5329
[email protected]b273e432010-04-12 17:23:585330void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
5331 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:105332 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:535333 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:555334 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:265335 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:535336 GetHelper(pname, values.get(), &num_written);
5337 }
[email protected]b273e432010-04-12 17:23:585338 for (GLsizei ii = 0; ii < num_written; ++ii) {
5339 params[ii] = static_cast<GLboolean>(values[ii]);
5340 }
5341 } else {
[email protected]7d3c36e2013-07-12 14:13:165342 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:585343 glGetBooleanv(pname, params);
5344 }
5345}
5346
5347void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
5348 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:105349 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:265350 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:535351 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:555352 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:535353 GetHelper(pname, values.get(), &num_written);
5354 for (GLsizei ii = 0; ii < num_written; ++ii) {
5355 params[ii] = static_cast<GLfloat>(values[ii]);
5356 }
5357 } else {
[email protected]7d3c36e2013-07-12 14:13:165358 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:535359 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:585360 }
[email protected]b273e432010-04-12 17:23:585361 }
5362}
5363
zmo8ac3bab2015-04-18 02:30:585364void GLES2DecoderImpl::DoGetInteger64v(GLenum pname, GLint64* params) {
5365 DCHECK(params);
kbr9370c842015-05-22 02:36:295366 if (unsafe_es3_apis_enabled()) {
5367 switch (pname) {
5368 case GL_MAX_ELEMENT_INDEX: {
5369 if (feature_info_->gl_version_info().IsAtLeastGLES(3, 0) ||
5370 feature_info_->gl_version_info().IsAtLeastGL(4, 3)) {
5371 glGetInteger64v(GL_MAX_ELEMENT_INDEX, params);
5372 } else {
5373 // Assume that desktop GL implementations can generally support
5374 // 32-bit indices.
5375 if (params) {
5376 *params = std::numeric_limits<unsigned int>::max();
5377 }
5378 }
5379 return;
5380 }
5381 }
5382 }
zmo8ac3bab2015-04-18 02:30:585383 pname = AdjustGetPname(pname);
5384 glGetInteger64v(pname, params);
5385}
5386
[email protected]b273e432010-04-12 17:23:585387void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
5388 DCHECK(params);
5389 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:265390 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:535391 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:165392 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:585393 glGetIntegerv(pname, params);
5394 }
5395}
5396
[email protected]a0c3e972010-04-21 00:49:135397void GLES2DecoderImpl::DoGetProgramiv(
5398 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:425399 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
5400 if (!program) {
[email protected]a0c3e972010-04-21 00:49:135401 return;
5402 }
[email protected]df37b9932013-03-08 05:21:425403 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:135404}
5405
[email protected]17cfbe0e2013-03-07 01:26:085406void GLES2DecoderImpl::DoGetBufferParameteriv(
5407 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:135408 // Just delegate it. Some validation is actually done before this.
5409 buffer_manager()->ValidateAndDoGetBufferParameteriv(
5410 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:085411}
5412
[email protected]258a3313f2011-10-18 20:13:575413void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:425414 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:575415 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515416 LOCAL_SET_GL_ERROR(
5417 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:575418 return;
5419 }
[email protected]68dcb1f2012-04-07 00:14:565420 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515421 LOCAL_SET_GL_ERROR(
5422 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:565423 return;
5424 }
5425 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:515426 LOCAL_SET_GL_ERROR(
5427 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:565428 return;
5429 }
[email protected]df37b9932013-03-08 05:21:425430 Program* program = GetProgramInfoNotShader(
5431 program_id, "glBindAttribLocation");
5432 if (!program) {
[email protected]258a3313f2011-10-18 20:13:575433 return;
[email protected]558847a2010-03-24 07:02:545434 }
zmo460b593e2014-10-13 23:07:455435 // At this point, the program's shaders may not be translated yet,
5436 // therefore, we may not find the hashed attribute name.
5437 // glBindAttribLocation call with original name is useless.
5438 // So instead, we should simply cache the binding, and then call
5439 // Program::ExecuteBindAttribLocationCalls() right before link.
[email protected]df37b9932013-03-08 05:21:425440 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
zmo460b593e2014-10-13 23:07:455441 // TODO(zmo): Get rid of the following glBindAttribLocation call.
[email protected]df37b9932013-03-08 05:21:425442 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:575443}
5444
[email protected]558847a2010-03-24 07:02:545445error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:345446 uint32 immediate_data_size,
5447 const void* cmd_data) {
5448 const gles2::cmds::BindAttribLocationBucket& c =
5449 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:585450 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:545451 GLuint index = static_cast<GLuint>(c.index);
5452 Bucket* bucket = GetBucket(c.name_bucket_id);
5453 if (!bucket || bucket->size() == 0) {
5454 return error::kInvalidArguments;
5455 }
5456 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:185457 if (!bucket->GetAsString(&name_str)) {
5458 return error::kInvalidArguments;
5459 }
[email protected]258a3313f2011-10-18 20:13:575460 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:545461 return error::kNoError;
5462}
5463
[email protected]2be6abf32012-06-26 00:28:335464void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:425465 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:335466 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515467 LOCAL_SET_GL_ERROR(
5468 GL_INVALID_VALUE,
5469 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:335470 return;
5471 }
5472 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515473 LOCAL_SET_GL_ERROR(
5474 GL_INVALID_OPERATION,
5475 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:335476 return;
5477 }
5478 if (location < 0 || static_cast<uint32>(location) >=
5479 (group_->max_fragment_uniform_vectors() +
5480 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:515481 LOCAL_SET_GL_ERROR(
5482 GL_INVALID_VALUE,
5483 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335484 return;
5485 }
[email protected]df37b9932013-03-08 05:21:425486 Program* program = GetProgramInfoNotShader(
5487 program_id, "glBindUniformLocationCHROMIUM");
5488 if (!program) {
[email protected]2be6abf32012-06-26 00:28:335489 return;
5490 }
[email protected]df37b9932013-03-08 05:21:425491 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:515492 LOCAL_SET_GL_ERROR(
5493 GL_INVALID_VALUE,
5494 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335495 }
5496}
5497
[email protected]2be6abf32012-06-26 00:28:335498error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
5499 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:345500 const void* cmd_data) {
5501 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
5502 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
5503 cmd_data);
[email protected]2be6abf32012-06-26 00:28:335504 GLuint program = static_cast<GLuint>(c.program);
5505 GLint location = static_cast<GLint>(c.location);
5506 Bucket* bucket = GetBucket(c.name_bucket_id);
5507 if (!bucket || bucket->size() == 0) {
5508 return error::kInvalidArguments;
5509 }
5510 std::string name_str;
5511 if (!bucket->GetAsString(&name_str)) {
5512 return error::kInvalidArguments;
5513 }
5514 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
5515 return error::kNoError;
5516}
5517
vmiuracd108592014-09-08 14:36:345518error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
5519 const void* cmd_data) {
5520 const gles2::cmds::DeleteShader& c =
5521 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035522 GLuint client_id = c.shader;
5523 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425524 Shader* shader = GetShader(client_id);
5525 if (shader) {
5526 if (!shader->IsDeleted()) {
dyenc6a36cdd2015-02-25 05:24:315527 shader_manager()->Delete(shader);
[email protected]ca488e12010-12-13 20:06:145528 }
[email protected]ae51d192010-04-27 00:48:035529 } else {
[email protected]ab09b612013-03-11 22:11:515530 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:035531 }
[email protected]96449d2c2009-11-25 00:01:325532 }
[email protected]f7a64ee2010-02-01 22:24:145533 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325534}
5535
vmiuracd108592014-09-08 14:36:345536error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
5537 const void* cmd_data) {
5538 const gles2::cmds::DeleteProgram& c =
5539 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035540 GLuint client_id = c.program;
5541 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425542 Program* program = GetProgram(client_id);
5543 if (program) {
5544 if (!program->IsDeleted()) {
5545 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:145546 }
[email protected]ae51d192010-04-27 00:48:035547 } else {
[email protected]ab09b612013-03-11 22:11:515548 LOCAL_SET_GL_ERROR(
5549 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:035550 }
[email protected]96449d2c2009-11-25 00:01:325551 }
[email protected]f7a64ee2010-02-01 22:24:145552 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325553}
5554
[email protected]a7266a92012-06-28 02:11:085555error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:445556 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:205557 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:465558 ApplyDirtyState();
boliu2e7d8a7a2014-10-16 20:35:205559 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
sievers2384f2b2014-11-18 02:10:355560 if (workarounds().gl_clear_broken) {
5561 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround",
5562 GetErrorState());
5563 if (!BoundFramebufferHasDepthAttachment())
5564 mask &= ~GL_DEPTH_BUFFER_BIT;
5565 if (!BoundFramebufferHasStencilAttachment())
5566 mask &= ~GL_STENCIL_BUFFER_BIT;
5567 clear_framebuffer_blit_->ClearFramebuffer(
5568 this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red,
5569 state_.color_clear_green, state_.color_clear_blue,
5570 state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear);
5571 return error::kNoError;
5572 }
[email protected]3a03a8f2011-03-19 00:51:275573 glClear(mask);
5574 }
[email protected]a7266a92012-06-28 02:11:085575 return error::kNoError;
5576}
5577
[email protected]36cef8ce2010-03-16 07:34:455578void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5579 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035580 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065581 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5582 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515583 LOCAL_SET_GL_ERROR(
5584 GL_INVALID_OPERATION,
5585 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455586 return;
5587 }
[email protected]ae51d192010-04-27 00:48:035588 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275589 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035590 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275591 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5592 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515593 LOCAL_SET_GL_ERROR(
5594 GL_INVALID_OPERATION,
5595 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035596 return;
5597 }
[email protected]ee2a79c32013-03-10 03:50:275598 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035599 }
[email protected]ab09b612013-03-11 22:11:515600 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035601 glFramebufferRenderbufferEXT(
5602 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515603 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265604 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275605 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285606 }
[email protected]9d3b2e12013-10-02 01:04:345607 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445608 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465609 }
[email protected]81fc9d02013-03-14 23:53:325610 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285611}
5612
[email protected]3a2e7c7b2010-08-06 01:12:285613void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465614 if (SetCapabilityState(cap, false)) {
5615 glDisable(cap);
5616 }
[email protected]3a2e7c7b2010-08-06 01:12:285617}
5618
5619void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465620 if (SetCapabilityState(cap, true)) {
5621 glEnable(cap);
5622 }
[email protected]3a2e7c7b2010-08-06 01:12:285623}
5624
[email protected]88a61bf2012-10-27 13:00:425625void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5626 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5627 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5628 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285629}
5630
[email protected]b04e24c2013-01-08 18:35:255631void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425632 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5633 state_.sample_coverage_invert = (invert != 0);
5634 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285635}
5636
[email protected]0d6bfdc2011-11-02 01:32:205637// Assumes framebuffer is complete.
5638void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065639 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305640 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205641 // bind this to the DRAW point, clear then bind back to READ
5642 // TODO(gman): I don't think there is any guarantee that an FBO that
5643 // is complete on the READ attachment will be complete as a DRAW
5644 // attachment.
5645 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065646 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305647 }
[email protected]3a2e7c7b2010-08-06 01:12:285648 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425649 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465650 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205651 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465652 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065653 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5654 1.0f);
[email protected]454157e2014-05-03 02:49:455655 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285656 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535657 if (feature_info_->feature_flags().ext_draw_buffers)
5658 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285659 }
5660
[email protected]4d8f0dd2013-03-09 14:37:065661 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5662 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285663 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475664 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5665 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285666 clear_bits |= GL_STENCIL_BUFFER_BIT;
5667 }
5668
[email protected]4d8f0dd2013-03-09 14:37:065669 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5670 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285671 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455672 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285673 clear_bits |= GL_DEPTH_BUFFER_BIT;
5674 }
5675
[email protected]454157e2014-05-03 02:49:455676 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285677 glClear(clear_bits);
5678
brucedawson18249152014-10-31 23:02:325679 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]0e58af82014-08-08 14:02:535680 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425681 framebuffer->RestoreDrawBuffersAfterClear();
5682
[email protected]968351b2011-12-20 08:26:515683 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065684 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285685
[email protected]c007aa02010-09-02 22:22:405686 RestoreClearState();
5687
5688 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065689 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5690 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485691 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065692 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5693 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485694 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405695 }
5696}
5697
5698void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445699 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245700 glClearColor(
5701 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5702 state_.color_clear_alpha);
5703 glClearStencil(state_.stencil_clear);
5704 glClearDepth(state_.depth_clear);
reveman842a0982015-06-09 05:14:315705 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5706 state_.enable_flags.scissor_test);
5707 glScissor(state_.scissor_x, state_.scissor_y, state_.scissor_width,
5708 state_.scissor_height);
[email protected]36cef8ce2010-03-16 07:34:455709}
5710
5711GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355712 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305713 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205714 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455715 return GL_FRAMEBUFFER_COMPLETE;
5716 }
[email protected]0d6bfdc2011-11-02 01:32:205717 GLenum completeness = framebuffer->IsPossiblyComplete();
5718 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5719 return completeness;
5720 }
[email protected]73276522012-11-09 05:50:205721 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455722}
5723
5724void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035725 GLenum target, GLenum attachment, GLenum textarget,
5726 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165727 DoFramebufferTexture2DCommon(
5728 "glFramebufferTexture2D", target, attachment,
5729 textarget, client_texture_id, level, 0);
5730}
5731
5732void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5733 GLenum target, GLenum attachment, GLenum textarget,
5734 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165735 DoFramebufferTexture2DCommon(
5736 "glFramebufferTexture2DMultisample", target, attachment,
5737 textarget, client_texture_id, level, samples);
5738}
5739
5740void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5741 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5742 GLuint client_texture_id, GLint level, GLsizei samples) {
5743 if (samples > renderbuffer_manager()->max_samples()) {
5744 LOCAL_SET_GL_ERROR(
5745 GL_INVALID_VALUE,
5746 "glFramebufferTexture2DMultisample", "samples too large");
5747 return;
5748 }
[email protected]4d8f0dd2013-03-09 14:37:065749 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5750 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515751 LOCAL_SET_GL_ERROR(
5752 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165753 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455754 return;
5755 }
[email protected]ae51d192010-04-27 00:48:035756 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495757 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035758 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495759 texture_ref = GetTexture(client_texture_id);
5760 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515761 LOCAL_SET_GL_ERROR(
5762 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165763 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035764 return;
5765 }
[email protected]370eaf12013-05-18 09:19:495766 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035767 }
[email protected]0d6bfdc2011-11-02 01:32:205768
[email protected]80eb6b52012-01-19 00:14:415769 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515770 LOCAL_SET_GL_ERROR(
5771 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165772 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205773 return;
5774 }
5775
[email protected]91c94eb2013-10-22 10:32:545776 if (texture_ref)
5777 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5778
[email protected]7d3c36e2013-07-12 14:13:165779 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5780 if (0 == samples) {
5781 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5782 } else {
5783 if (features().use_img_for_multisampled_render_to_texture) {
5784 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5785 service_id, level, samples);
5786 } else {
5787 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5788 service_id, level, samples);
5789 }
5790 }
5791 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265792 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165793 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5794 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285795 }
[email protected]9d3b2e12013-10-02 01:04:345796 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445797 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465798 }
[email protected]91c94eb2013-10-22 10:32:545799
5800 if (texture_ref)
5801 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5802
[email protected]81fc9d02013-03-14 23:53:325803 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455804}
5805
zmo84c08202014-11-23 15:28:405806void GLES2DecoderImpl::DoFramebufferTextureLayer(
5807 GLenum target, GLenum attachment, GLuint client_texture_id,
5808 GLint level, GLint layer) {
5809 // TODO(zmo): Unsafe ES3 API, missing states update.
5810 GLuint service_id = 0;
5811 TextureRef* texture_ref = NULL;
5812 if (client_texture_id) {
5813 texture_ref = GetTexture(client_texture_id);
5814 if (!texture_ref) {
5815 LOCAL_SET_GL_ERROR(
5816 GL_INVALID_OPERATION,
5817 "glFramebufferTextureLayer", "unknown texture_ref");
5818 return;
5819 }
5820 service_id = texture_ref->service_id();
5821 }
5822 glFramebufferTextureLayer(target, attachment, service_id, level, layer);
5823}
5824
[email protected]36cef8ce2010-03-16 07:34:455825void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5826 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065827 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5828 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515829 LOCAL_SET_GL_ERROR(
5830 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205831 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455832 return;
5833 }
[email protected]74c1ec42010-08-12 01:55:575834 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105835 const Framebuffer::Attachment* attachment_object =
5836 framebuffer->GetAttachment(attachment);
5837 *params = attachment_object ? attachment_object->object_name() : 0;
5838 } else {
[email protected]7d3c36e2013-07-12 14:13:165839 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5840 features().use_img_for_multisampled_render_to_texture) {
5841 pname = GL_TEXTURE_SAMPLES_IMG;
5842 }
[email protected]62e65f02013-05-29 22:28:105843 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575844 }
[email protected]36cef8ce2010-03-16 07:34:455845}
5846
5847void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5848 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355849 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205850 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5851 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515852 LOCAL_SET_GL_ERROR(
5853 GL_INVALID_OPERATION,
5854 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455855 return;
5856 }
[email protected]8875a5f2014-06-27 08:33:475857
5858 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275859 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435860 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5861 *params = renderbuffer->internal_format();
5862 break;
5863 case GL_RENDERBUFFER_WIDTH:
5864 *params = renderbuffer->width();
5865 break;
5866 case GL_RENDERBUFFER_HEIGHT:
5867 *params = renderbuffer->height();
5868 break;
[email protected]7d3c36e2013-07-12 14:13:165869 case GL_RENDERBUFFER_SAMPLES_EXT:
5870 if (features().use_img_for_multisampled_render_to_texture) {
5871 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5872 params);
5873 } else {
5874 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5875 params);
5876 }
[email protected]ad84a3a2012-06-08 21:42:435877 default:
5878 glGetRenderbufferParameterivEXT(target, pname, params);
5879 break;
[email protected]b71f52c2010-06-18 22:20:205880 }
[email protected]36cef8ce2010-03-16 07:34:455881}
5882
[email protected]49cabed2013-11-13 18:15:185883void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305884 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5885 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5886 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445887 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165888
[email protected]49cabed2013-11-13 18:15:185889 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165890 return;
5891 }
5892
[email protected]454157e2014-05-03 02:49:455893 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
boliu2e7d8a7a2014-10-16 20:35:205894 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]f42f05b2013-11-15 21:46:185895 BlitFramebufferHelper(
5896 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455897 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5898 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185899}
5900
[email protected]8875a5f2014-06-27 08:33:475901void GLES2DecoderImpl::EnsureRenderbufferBound() {
5902 if (!state_.bound_renderbuffer_valid) {
5903 state_.bound_renderbuffer_valid = true;
5904 glBindRenderbufferEXT(GL_RENDERBUFFER,
5905 state_.bound_renderbuffer.get()
5906 ? state_.bound_renderbuffer->service_id()
5907 : 0);
5908 }
5909}
5910
[email protected]f42f05b2013-11-15 21:46:185911void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5912 const FeatureInfo* feature_info,
5913 GLenum target,
5914 GLsizei samples,
5915 GLenum internal_format,
5916 GLsizei width,
5917 GLsizei height) {
5918 // TODO(sievers): This could be resolved at the GL binding level, but the
5919 // binding process is currently a bit too 'brute force'.
zmo68fcdc62014-12-05 21:51:495920 if (feature_info->gl_version_info().is_angle) {
[email protected]f42f05b2013-11-15 21:46:185921 glRenderbufferStorageMultisampleANGLE(
5922 target, samples, internal_format, width, height);
5923 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5924 glRenderbufferStorageMultisample(
5925 target, samples, internal_format, width, height);
5926 } else {
5927 glRenderbufferStorageMultisampleEXT(
5928 target, samples, internal_format, width, height);
5929 }
5930}
5931
5932void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5933 GLint srcY0,
5934 GLint srcX1,
5935 GLint srcY1,
5936 GLint dstX0,
5937 GLint dstY0,
5938 GLint dstX1,
5939 GLint dstY1,
5940 GLbitfield mask,
5941 GLenum filter) {
5942 // TODO(sievers): This could be resolved at the GL binding level, but the
5943 // binding process is currently a bit too 'brute force'.
marcheu1856f5d52015-04-04 01:42:535944 if (feature_info_->gl_version_info().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245945 glBlitFramebufferANGLE(
5946 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185947 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5948 glBlitFramebuffer(
5949 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245950 } else {
5951 glBlitFramebufferEXT(
5952 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5953 }
[email protected]8e3e0662010-08-23 18:46:305954}
5955
[email protected]49cabed2013-11-13 18:15:185956bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5957 GLsizei samples,
5958 GLenum internalformat,
5959 GLsizei width,
5960 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535961 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515962 LOCAL_SET_GL_ERROR(
5963 GL_INVALID_VALUE,
5964 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185965 return false;
[email protected]84afefa2011-10-19 21:45:535966 }
5967
5968 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5969 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515970 LOCAL_SET_GL_ERROR(
5971 GL_INVALID_VALUE,
5972 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185973 return false;
[email protected]84afefa2011-10-19 21:45:535974 }
5975
[email protected]7989c9e2013-01-23 06:39:265976 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235977 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5978 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515979 LOCAL_SET_GL_ERROR(
5980 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205981 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185982 return false;
[email protected]8e3e0662010-08-23 18:46:305983 }
5984
[email protected]7989c9e2013-01-23 06:39:265985 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515986 LOCAL_SET_GL_ERROR(
5987 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205988 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185989 return false;
5990 }
5991
5992 return true;
5993}
5994
5995void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5996 GLenum target, GLsizei samples, GLenum internalformat,
5997 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185998 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5999 if (!renderbuffer) {
6000 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
6001 "glRenderbufferStorageMultisampleCHROMIUM",
6002 "no renderbuffer bound");
6003 return;
6004 }
6005
6006 if (!ValidateRenderbufferStorageMultisample(
6007 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:266008 return;
6009 }
6010
[email protected]8875a5f2014-06-27 08:33:476011 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:236012 GLenum impl_format =
6013 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
6014 internalformat);
[email protected]49cabed2013-11-13 18:15:186015 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
6016 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:186017 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:256018 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:186019 GLenum error =
6020 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:266021 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:106022 if (workarounds().validate_multisample_buffer_allocation) {
6023 if (!VerifyMultisampleRenderbufferIntegrity(
6024 renderbuffer->service_id(), impl_format)) {
6025 LOCAL_SET_GL_ERROR(
6026 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:186027 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:106028 return;
6029 }
6030 }
6031
[email protected]968351b2011-12-20 08:26:516032 // TODO(gman): If renderbuffers tracked which framebuffers they were
6033 // attached to we could just mark those framebuffers as not complete.
6034 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:206035 renderbuffer_manager()->SetInfo(
6036 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:266037 }
[email protected]8e3e0662010-08-23 18:46:306038}
6039
[email protected]49cabed2013-11-13 18:15:186040// This is the handler for multisampled_render_to_texture extensions.
6041void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
6042 GLenum target, GLsizei samples, GLenum internalformat,
6043 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:186044 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
6045 if (!renderbuffer) {
6046 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
6047 "glRenderbufferStorageMultisampleEXT",
6048 "no renderbuffer bound");
6049 return;
6050 }
6051
6052 if (!ValidateRenderbufferStorageMultisample(
6053 samples, internalformat, width, height)) {
6054 return;
6055 }
6056
[email protected]8875a5f2014-06-27 08:33:476057 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:186058 GLenum impl_format =
6059 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
6060 internalformat);
6061 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
6062 if (features().use_img_for_multisampled_render_to_texture) {
6063 glRenderbufferStorageMultisampleIMG(
6064 target, samples, impl_format, width, height);
6065 } else {
6066 glRenderbufferStorageMultisampleEXT(
6067 target, samples, impl_format, width, height);
6068 }
6069 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
6070 if (error == GL_NO_ERROR) {
6071 // TODO(gman): If renderbuffers tracked which framebuffers they were
6072 // attached to we could just mark those framebuffers as not complete.
6073 framebuffer_manager()->IncFramebufferStateChangeCount();
6074 renderbuffer_manager()->SetInfo(
6075 renderbuffer, samples, internalformat, width, height);
6076 }
6077}
6078
[email protected]4a4c18b2013-09-13 22:50:106079// This function validates the allocation of a multisampled renderbuffer
6080// by clearing it to a key color, blitting the contents to a texture, and
6081// reading back the color to ensure it matches the key.
6082bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
6083 GLuint renderbuffer, GLenum format) {
6084
6085 // Only validate color buffers.
6086 // These formats have been selected because they are very common or are known
6087 // to be used by the WebGL backbuffer. If problems are observed with other
6088 // color formats they can be added here.
dcastagna504d45c2015-04-06 19:30:396089 switch (format) {
[email protected]4a4c18b2013-09-13 22:50:106090 case GL_RGB:
6091 case GL_RGB8:
6092 case GL_RGBA:
6093 case GL_RGBA8:
6094 break;
6095 default:
6096 return true;
6097 }
6098
6099 GLint draw_framebuffer, read_framebuffer;
6100
6101 // Cache framebuffer and texture bindings.
6102 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
6103 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
6104
6105 if (!validation_texture_) {
6106 GLint bound_texture;
6107 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
6108
6109 // Create additional resources needed for the verification.
6110 glGenTextures(1, &validation_texture_);
6111 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
6112 glGenFramebuffersEXT(1, &validation_fbo_);
6113
6114 // Texture only needs to be 1x1.
6115 glBindTexture(GL_TEXTURE_2D, validation_texture_);
erikchene5cc32e2015-05-11 21:51:096116 // TODO(erikchen): When Chrome on Mac is linked against an OSX 10.9+ SDK, a
6117 // multisample will fail if the color format of the source and destination
6118 // do not match. Here, we assume that the source is GL_RGBA, and make the
6119 // destination GL_RGBA. http://crbug.com/484203
6120 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
[email protected]4a4c18b2013-09-13 22:50:106121 GL_UNSIGNED_BYTE, NULL);
6122
6123 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
6124 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
6125 GL_TEXTURE_2D, validation_texture_, 0);
6126
6127 glBindTexture(GL_TEXTURE_2D, bound_texture);
6128 }
6129
6130 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
6131 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
6132 GL_RENDERBUFFER, renderbuffer);
6133
6134 // Cache current state and reset it to the values we require.
6135 GLboolean scissor_enabled = false;
6136 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
6137 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:456138 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:106139
[email protected]454157e2014-05-03 02:49:456140 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:106141 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:456142 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:106143
6144 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6145 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
6146 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
6147
6148 // Clear the buffer to the desired key color.
6149 glClear(GL_COLOR_BUFFER_BIT);
6150
6151 // Blit from the multisample buffer to a standard texture.
6152 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
6153 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
6154
[email protected]f42f05b2013-11-15 21:46:186155 BlitFramebufferHelper(
6156 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:106157
6158 // Read a pixel from the buffer.
6159 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
6160
6161 unsigned char pixel[3] = {0, 0, 0};
6162 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
6163
6164 // Detach the renderbuffer.
6165 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
6166 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
6167 GL_RENDERBUFFER, 0);
6168
6169 // Restore cached state.
6170 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:456171 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:106172
[email protected]454157e2014-05-03 02:49:456173 state_.SetDeviceColorMask(
6174 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:106175 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
6176 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
6177 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
6178
6179 // Return true if the pixel matched the desired key color.
6180 return (pixel[0] == 0xFF &&
6181 pixel[1] == 0x00 &&
6182 pixel[2] == 0xFF);
6183}
6184
[email protected]36cef8ce2010-03-16 07:34:456185void GLES2DecoderImpl::DoRenderbufferStorage(
6186 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:356187 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:206188 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
6189 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:516190 LOCAL_SET_GL_ERROR(
6191 GL_INVALID_OPERATION,
6192 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:456193 return;
6194 }
[email protected]876f6fee2010-08-02 23:10:326195
[email protected]84afefa2011-10-19 21:45:536196 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
6197 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:516198 LOCAL_SET_GL_ERROR(
6199 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:536200 return;
6201 }
6202
[email protected]7989c9e2013-01-23 06:39:266203 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:236204 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
6205 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:516206 LOCAL_SET_GL_ERROR(
6207 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:266208 return;
6209 }
6210
6211 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:516212 LOCAL_SET_GL_ERROR(
6213 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:266214 return;
[email protected]b71f52c2010-06-18 22:20:206215 }
[email protected]876f6fee2010-08-02 23:10:326216
[email protected]8875a5f2014-06-27 08:33:476217 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:516218 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:266219 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:236220 target,
6221 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
6222 internalformat),
6223 width,
6224 height);
[email protected]ab09b612013-03-11 22:11:516225 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:266226 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:516227 // TODO(gman): If tetxures tracked which framebuffers they were attached to
6228 // we could just mark those framebuffers as not complete.
6229 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:206230 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:266231 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:266232 }
[email protected]36cef8ce2010-03-16 07:34:456233}
6234
[email protected]df37b9932013-03-08 05:21:426235void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:386236 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:426237 Program* program = GetProgramInfoNotShader(
6238 program_id, "glLinkProgram");
6239 if (!program) {
[email protected]a93bb842010-02-16 23:03:476240 return;
6241 }
[email protected]05afda12011-01-20 00:17:346242
[email protected]df37b9932013-03-08 05:21:426243 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]df37b9932013-03-08 05:21:426244 if (program->Link(shader_manager(),
[email protected]008401532014-02-07 00:10:506245 workarounds().count_all_in_varyings_packing ?
6246 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:116247 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:426248 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:186249 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:426250 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:186251 if (workarounds().clear_uniforms_before_first_program_use)
6252 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:546253 }
6254 }
vmiura8266ca72014-09-09 21:37:006255
6256 // LinkProgram can be very slow. Exit command processing to allow for
6257 // context preemption and GPU watchdog checks.
6258 ExitCommandProcessingEarly();
dcastagna504d45c2015-04-06 19:30:396259}
[email protected]07f54fcc2009-12-22 02:46:306260
zmobcb3fdd62014-12-11 00:49:036261void GLES2DecoderImpl::DoSamplerParameterfv(
6262 GLuint sampler, GLenum pname, const GLfloat* params) {
6263 DCHECK(params);
6264 glSamplerParameterf(sampler, pname, params[0]);
6265}
6266
6267void GLES2DecoderImpl::DoSamplerParameteriv(
6268 GLuint sampler, GLenum pname, const GLint* params) {
6269 DCHECK(params);
6270 glSamplerParameteri(sampler, pname, params[0]);
6271}
6272
[email protected]3916c97e2010-02-25 03:20:506273void GLES2DecoderImpl::DoTexParameterf(
6274 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:446275 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
6276 &state_, target);
[email protected]02965c22013-03-09 02:40:076277 if (!texture) {
[email protected]ab09b612013-03-11 22:11:516278 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:246279 return;
[email protected]07f54fcc2009-12-22 02:46:306280 }
[email protected]cbb22e42011-05-12 23:36:246281
[email protected]737191ee72014-03-09 08:02:426282 texture_manager()->SetParameterf(
6283 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:306284}
6285
[email protected]3916c97e2010-02-25 03:20:506286void GLES2DecoderImpl::DoTexParameteri(
6287 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:446288 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
6289 &state_, target);
[email protected]02965c22013-03-09 02:40:076290 if (!texture) {
[email protected]ab09b612013-03-11 22:11:516291 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:246292 return;
[email protected]3916c97e2010-02-25 03:20:506293 }
[email protected]cbb22e42011-05-12 23:36:246294
[email protected]737191ee72014-03-09 08:02:426295 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:506296 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:506297}
6298
6299void GLES2DecoderImpl::DoTexParameterfv(
6300 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:446301 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
6302 &state_, target);
[email protected]02965c22013-03-09 02:40:076303 if (!texture) {
[email protected]ab09b612013-03-11 22:11:516304 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:246305 return;
[email protected]3916c97e2010-02-25 03:20:506306 }
[email protected]cbb22e42011-05-12 23:36:246307
[email protected]737191ee72014-03-09 08:02:426308 texture_manager()->SetParameterf(
6309 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:506310}
6311
6312void GLES2DecoderImpl::DoTexParameteriv(
6313 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:446314 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
6315 &state_, target);
[email protected]02965c22013-03-09 02:40:076316 if (!texture) {
[email protected]ab09b612013-03-11 22:11:516317 LOCAL_SET_GL_ERROR(
6318 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:246319 return;
[email protected]3916c97e2010-02-25 03:20:506320 }
[email protected]cbb22e42011-05-12 23:36:246321
[email protected]737191ee72014-03-09 08:02:426322 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:506323 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:506324}
6325
orglofchcad5a6742014-11-07 19:51:126326bool GLES2DecoderImpl::CheckCurrentValuebuffer(const char* function_name) {
6327 if (!state_.bound_valuebuffer.get()) {
6328 // There is no valuebuffer bound
6329 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6330 "no valuebuffer in use");
6331 return false;
6332 }
6333 return true;
6334}
6335
6336bool GLES2DecoderImpl::CheckCurrentValuebufferForSubscription(
6337 GLenum subscription,
6338 const char* function_name) {
6339 if (!CheckCurrentValuebuffer(function_name)) {
6340 return false;
6341 }
6342 if (!state_.bound_valuebuffer.get()->IsSubscribed(subscription)) {
6343 // The valuebuffer is not subscribed to the target
6344 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6345 "valuebuffer is not subscribed");
6346 return false;
6347 }
6348 return true;
6349}
6350
6351bool GLES2DecoderImpl::CheckSubscriptionTarget(GLint location,
6352 GLenum subscription,
6353 const char* function_name) {
6354 if (!CheckCurrentProgramForUniform(location, function_name)) {
6355 return false;
6356 }
6357 GLint real_location = -1;
6358 GLint array_index = -1;
6359 const Program::UniformInfo* info =
6360 state_.current_program->GetUniformInfoByFakeLocation(
6361 location, &real_location, &array_index);
6362 if (!info) {
6363 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "unknown location");
6364 return false;
6365 }
6366 if ((ValuebufferManager::ApiTypeForSubscriptionTarget(subscription) &
6367 info->accepts_api_type) == 0) {
6368 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6369 "wrong type for subscription");
6370 return false;
6371 }
6372 return true;
6373}
6374
[email protected]939e7362010-05-13 20:49:106375bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:116376 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:436377 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:516378 LOCAL_SET_GL_ERROR(
6379 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:436380 return false;
[email protected]939e7362010-05-13 20:49:106381 }
[email protected]e259eb412012-10-13 05:47:246382 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:516383 LOCAL_SET_GL_ERROR(
6384 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:106385 return false;
6386 }
6387 return true;
6388}
6389
6390bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
6391 GLint location, const char* function_name) {
6392 if (!CheckCurrentProgram(function_name)) {
6393 return false;
6394 }
6395 return location != -1;
6396}
6397
zmof9a81360f2014-10-17 00:06:146398bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
6399 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
6400 if (!framebuffer)
6401 return false;
6402 const Framebuffer::Attachment* attachment =
6403 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
6404 if (!attachment)
6405 return false;
6406
6407 DCHECK(state_.current_program.get());
6408 const Program::SamplerIndices& sampler_indices =
6409 state_.current_program->sampler_indices();
6410 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
6411 const Program::UniformInfo* uniform_info =
6412 state_.current_program->GetUniformInfo(sampler_indices[ii]);
6413 DCHECK(uniform_info);
6414 if (uniform_info->type != GL_SAMPLER_2D)
6415 continue;
6416 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6417 GLuint texture_unit_index = uniform_info->texture_units[jj];
6418 if (texture_unit_index >= state_.texture_units.size())
6419 continue;
6420 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
6421 TextureRef* texture_ref =
6422 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
6423 if (attachment->IsTexture(texture_ref))
6424 return true;
6425 }
6426 }
6427 return false;
6428}
6429
orglofchcad5a6742014-11-07 19:51:126430bool GLES2DecoderImpl::CheckUniformForApiType(
6431 const Program::UniformInfo* info,
6432 const char* function_name,
6433 Program::UniformApiType api_type) {
6434 DCHECK(info);
6435 if ((api_type & info->accepts_api_type) == 0) {
6436 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6437 "wrong uniform function for type");
6438 return false;
6439 }
6440 return true;
6441}
6442
[email protected]43c2f1f2011-03-25 18:35:366443bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:136444 GLint fake_location,
6445 const char* function_name,
6446 Program::UniformApiType api_type,
6447 GLint* real_location,
6448 GLenum* type,
6449 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:366450 DCHECK(type);
6451 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:126452 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:526453
[email protected]1b0a6752012-02-22 03:44:126454 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:106455 return false;
6456 }
[email protected]43c2f1f2011-03-25 18:35:366457 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:356458 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:246459 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:126460 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:366461 if (!info) {
[email protected]ab09b612013-03-11 22:11:516462 LOCAL_SET_GL_ERROR(
6463 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:106464 return false;
6465 }
orglofchcad5a6742014-11-07 19:51:126466 if (!CheckUniformForApiType(info, function_name, api_type)) {
[email protected]476ccb72012-12-06 15:52:526467 return false;
6468 }
[email protected]43c2f1f2011-03-25 18:35:366469 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:516470 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436471 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:366472 return false;
6473 }
6474 *count = std::min(info->size - array_index, *count);
6475 if (*count <= 0) {
6476 return false;
6477 }
6478 *type = info->type;
[email protected]939e7362010-05-13 20:49:106479 return true;
6480}
6481
[email protected]1b0a6752012-02-22 03:44:126482void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
6483 GLenum type = 0;
6484 GLsizei count = 1;
6485 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136486 if (!PrepForSetUniformByLocation(fake_location,
6487 "glUniform1i",
6488 Program::kUniform1i,
6489 &real_location,
6490 &type,
6491 &count)) {
[email protected]3916c97e2010-02-25 03:20:506492 return;
6493 }
[email protected]e259eb412012-10-13 05:47:246494 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026495 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:516496 LOCAL_SET_GL_ERROR(
6497 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466498 return;
6499 }
[email protected]1b0a6752012-02-22 03:44:126500 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:506501}
6502
6503void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:126504 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:366505 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126506 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136507 if (!PrepForSetUniformByLocation(fake_location,
6508 "glUniform1iv",
6509 Program::kUniform1i,
6510 &real_location,
6511 &type,
6512 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366513 return;
6514 }
[email protected]74727112012-06-13 21:18:086515 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
6516 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:246517 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026518 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:516519 LOCAL_SET_GL_ERROR(
6520 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466521 return;
6522 }
[email protected]43c2f1f2011-03-25 18:35:366523 }
[email protected]1b0a6752012-02-22 03:44:126524 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:506525}
6526
[email protected]939e7362010-05-13 20:49:106527void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:126528 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366529 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126530 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136531 if (!PrepForSetUniformByLocation(fake_location,
6532 "glUniform1fv",
6533 Program::kUniform1f,
6534 &real_location,
6535 &type,
6536 &count)) {
[email protected]939e7362010-05-13 20:49:106537 return;
6538 }
6539 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:556540 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:106541 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:536542 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106543 }
[email protected]1b0a6752012-02-22 03:44:126544 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106545 } else {
[email protected]1b0a6752012-02-22 03:44:126546 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106547 }
6548}
6549
6550void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:126551 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366552 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126553 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136554 if (!PrepForSetUniformByLocation(fake_location,
6555 "glUniform2fv",
6556 Program::kUniform2f,
6557 &real_location,
6558 &type,
6559 &count)) {
[email protected]939e7362010-05-13 20:49:106560 return;
6561 }
6562 if (type == GL_BOOL_VEC2) {
6563 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:556564 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106565 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536566 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106567 }
[email protected]1b0a6752012-02-22 03:44:126568 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106569 } else {
[email protected]1b0a6752012-02-22 03:44:126570 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106571 }
6572}
6573
6574void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:126575 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366576 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126577 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136578 if (!PrepForSetUniformByLocation(fake_location,
6579 "glUniform3fv",
6580 Program::kUniform3f,
6581 &real_location,
6582 &type,
6583 &count)) {
[email protected]939e7362010-05-13 20:49:106584 return;
6585 }
6586 if (type == GL_BOOL_VEC3) {
6587 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:556588 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106589 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536590 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106591 }
[email protected]1b0a6752012-02-22 03:44:126592 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106593 } else {
[email protected]1b0a6752012-02-22 03:44:126594 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106595 }
6596}
6597
6598void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:126599 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366600 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126601 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136602 if (!PrepForSetUniformByLocation(fake_location,
6603 "glUniform4fv",
6604 Program::kUniform4f,
6605 &real_location,
6606 &type,
6607 &count)) {
[email protected]939e7362010-05-13 20:49:106608 return;
6609 }
6610 if (type == GL_BOOL_VEC4) {
6611 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:556612 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106613 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536614 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106615 }
[email protected]1b0a6752012-02-22 03:44:126616 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106617 } else {
[email protected]1b0a6752012-02-22 03:44:126618 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106619 }
6620}
6621
[email protected]43c2f1f2011-03-25 18:35:366622void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:126623 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366624 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126625 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136626 if (!PrepForSetUniformByLocation(fake_location,
6627 "glUniform2iv",
6628 Program::kUniform2i,
6629 &real_location,
6630 &type,
6631 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366632 return;
6633 }
[email protected]1b0a6752012-02-22 03:44:126634 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366635}
6636
6637void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:126638 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366639 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126640 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136641 if (!PrepForSetUniformByLocation(fake_location,
6642 "glUniform3iv",
6643 Program::kUniform3i,
6644 &real_location,
6645 &type,
6646 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366647 return;
6648 }
[email protected]1b0a6752012-02-22 03:44:126649 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366650}
6651
6652void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:126653 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366654 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126655 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136656 if (!PrepForSetUniformByLocation(fake_location,
6657 "glUniform4iv",
6658 Program::kUniform4i,
6659 &real_location,
6660 &type,
6661 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366662 return;
6663 }
[email protected]1b0a6752012-02-22 03:44:126664 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366665}
6666
6667void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126668 GLint fake_location, GLsizei count, GLboolean transpose,
6669 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366670 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126671 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136672 if (!PrepForSetUniformByLocation(fake_location,
6673 "glUniformMatrix2fv",
6674 Program::kUniformMatrix2f,
6675 &real_location,
6676 &type,
6677 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366678 return;
6679 }
[email protected]1b0a6752012-02-22 03:44:126680 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366681}
6682
6683void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126684 GLint fake_location, GLsizei count, GLboolean transpose,
6685 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366686 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126687 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136688 if (!PrepForSetUniformByLocation(fake_location,
6689 "glUniformMatrix3fv",
6690 Program::kUniformMatrix3f,
6691 &real_location,
6692 &type,
6693 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366694 return;
6695 }
[email protected]1b0a6752012-02-22 03:44:126696 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366697}
6698
6699void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126700 GLint fake_location, GLsizei count, GLboolean transpose,
6701 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366702 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126703 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136704 if (!PrepForSetUniformByLocation(fake_location,
6705 "glUniformMatrix4fv",
6706 Program::kUniformMatrix4f,
6707 &real_location,
6708 &type,
6709 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366710 return;
6711 }
[email protected]1b0a6752012-02-22 03:44:126712 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366713}
6714
[email protected]df37b9932013-03-08 05:21:426715void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036716 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426717 Program* program = NULL;
6718 if (program_id) {
6719 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6720 if (!program) {
[email protected]ae51d192010-04-27 00:48:036721 return;
6722 }
[email protected]df37b9932013-03-08 05:21:426723 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506724 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516725 LOCAL_SET_GL_ERROR(
6726 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506727 return;
6728 }
[email protected]df37b9932013-03-08 05:21:426729 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506730 }
[email protected]7cd76fd2013-06-02 21:11:116731 if (state_.current_program.get()) {
6732 program_manager()->UnuseProgram(shader_manager(),
6733 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146734 }
[email protected]df37b9932013-03-08 05:21:426735 state_.current_program = program;
6736 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546737 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116738 if (state_.current_program.get()) {
6739 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186740 if (workarounds().clear_uniforms_before_first_program_use)
6741 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146742 }
[email protected]3916c97e2010-02-25 03:20:506743}
6744
[email protected]ab09b612013-03-11 22:11:516745void GLES2DecoderImpl::RenderWarning(
6746 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326747 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016748}
6749
[email protected]ab09b612013-03-11 22:11:516750void GLES2DecoderImpl::PerformanceWarning(
6751 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506752 logger_.LogMessage(filename, line,
6753 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016754}
6755
[email protected]91c94eb2013-10-22 10:32:546756void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6757 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546758 // Image is already in use if texture is attached to a framebuffer.
6759 if (texture && !texture->IsAttachedToFramebuffer()) {
6760 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6761 if (image) {
6762 ScopedGLErrorSuppressor suppressor(
6763 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6764 GetErrorState());
6765 glBindTexture(textarget, texture->service_id());
6766 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026767 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546768 }
6769 }
6770}
6771
6772void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6773 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546774 // Image is still in use if texture is attached to a framebuffer.
6775 if (texture && !texture->IsAttachedToFramebuffer()) {
6776 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6777 if (image) {
6778 ScopedGLErrorSuppressor suppressor(
6779 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6780 GetErrorState());
6781 glBindTexture(textarget, texture->service_id());
6782 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026783 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546784 }
6785 }
6786}
6787
[email protected]e56131d22013-07-28 16:14:116788bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116789 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546790 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556791 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116792 return true;
[email protected]ef526492010-06-02 23:12:256793 }
[email protected]e2367b42013-05-31 03:37:216794
[email protected]ef526492010-06-02 23:12:256795 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356796 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246797 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506798 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356799 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246800 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506801 DCHECK(uniform_info);
6802 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6803 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026804 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246805 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546806 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366807 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546808 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6809 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256810 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506811 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6812 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546813 textarget,
[email protected]00f893d2010-08-24 18:55:496814 texture_manager()->black_texture_id(uniform_info->type));
dongseong.hwang7d87d722015-01-14 20:02:406815 if (!texture_ref) {
6816 LOCAL_RENDER_WARNING(
6817 std::string("there is no texture bound to the unit ") +
6818 base::IntToString(texture_unit_index));
6819 } else {
6820 LOCAL_RENDER_WARNING(
6821 std::string("texture bound to texture unit ") +
6822 base::IntToString(texture_unit_index) +
6823 " is not renderable. It maybe non-power-of-2 and have"
6824 " incompatible texture filtering.");
6825 }
[email protected]91c94eb2013-10-22 10:32:546826 continue;
[email protected]3916c97e2010-02-25 03:20:506827 }
[email protected]91c94eb2013-10-22 10:32:546828
[email protected]4e7b89202014-01-28 01:44:066829 if (textarget != GL_TEXTURE_CUBE_MAP) {
6830 Texture* texture = texture_ref->texture();
6831 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6832 if (image && !texture->IsAttachedToFramebuffer()) {
6833 ScopedGLErrorSuppressor suppressor(
6834 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6835 textures_set = true;
6836 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6837 image->WillUseTexImage();
6838 continue;
6839 }
[email protected]91c94eb2013-10-22 10:32:546840 }
[email protected]3916c97e2010-02-25 03:20:506841 }
6842 // else: should this be an error?
6843 }
6844 }
[email protected]e56131d22013-07-28 16:14:116845 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506846}
6847
[email protected]91c94eb2013-10-22 10:32:546848void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116849 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356850 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116851 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506852 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356853 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246854 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506855 DCHECK(uniform_info);
6856 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6857 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026858 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246859 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116860 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546861 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496862 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506863 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496864 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116865 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6866 ? texture_unit.bound_texture_2d.get()
6867 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506868 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496869 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546870 continue;
6871 }
6872
[email protected]4e7b89202014-01-28 01:44:066873 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6874 Texture* texture = texture_ref->texture();
6875 gfx::GLImage* image =
6876 texture->GetLevelImage(texture_unit.bind_target, 0);
6877 if (image && !texture->IsAttachedToFramebuffer()) {
6878 ScopedGLErrorSuppressor suppressor(
6879 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6880 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6881 image->DidUseTexImage();
6882 continue;
6883 }
[email protected]3916c97e2010-02-25 03:20:506884 }
6885 }
6886 }
6887 }
6888 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246889 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306890}
6891
[email protected]0d6bfdc2011-11-02 01:32:206892bool GLES2DecoderImpl::ClearUnclearedTextures() {
6893 // Only check if there are some uncleared textures.
6894 if (!texture_manager()->HaveUnsafeTextures()) {
6895 return true;
6896 }
6897
6898 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116899 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356900 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116901 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206902 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356903 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246904 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206905 DCHECK(uniform_info);
6906 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6907 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026908 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246909 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496910 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366911 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496912 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6913 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206914 return false;
6915 }
6916 }
6917 }
6918 }
6919 }
6920 }
6921 return true;
6922}
6923
[email protected]c6aef902012-02-14 03:31:426924bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106925 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6926 GLsizei primcount) {
6927 DCHECK(instanced || primcount == 1);
6928
[email protected]689fa1c52010-06-09 18:35:036929 // NOTE: We specifically do not check current_program->IsValid() because
6930 // it could never be invalid since glUseProgram would have failed. While
6931 // glLinkProgram could later mark the program as invalid the previous
6932 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116933 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506934 // The program does not exist.
6935 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516936 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506937 return false;
6938 }
[email protected]c6aef902012-02-14 03:31:426939
zmof9a81360f2014-10-17 00:06:146940 if (CheckDrawingFeedbackLoops()) {
6941 LOCAL_SET_GL_ERROR(
6942 GL_INVALID_OPERATION, function_name,
6943 "Source and destination textures of the draw are the same.");
6944 return false;
6945 }
6946
[email protected]7cd76fd2013-06-02 21:11:116947 return state_.vertex_attrib_manager
6948 ->ValidateBindings(function_name,
6949 this,
6950 feature_info_.get(),
6951 state_.current_program.get(),
6952 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106953 instanced,
[email protected]7cd76fd2013-06-02 21:11:116954 primcount);
[email protected]b1122982010-05-17 23:04:246955}
6956
[email protected]c13e1da62011-09-09 21:48:306957bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436958 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306959 DCHECK(simulated);
6960 *simulated = false;
6961
marcheu1856f5d52015-04-04 01:42:536962 if (feature_info_->gl_version_info().BehavesLikeGLES())
[email protected]c13e1da62011-09-09 21:48:306963 return true;
[email protected]876f6fee2010-08-02 23:10:326964
[email protected]ac77603c72013-03-08 13:52:066965 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356966 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246967 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246968 bool attrib_0_used =
6969 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066970 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306971 return true;
[email protected]b1122982010-05-17 23:04:246972 }
6973
[email protected]b1122982010-05-17 23:04:246974 // Make a buffer with a single repeated vec4 value enough to
6975 // simulate the constant value that is supposed to be here.
6976 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306977 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476978 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306979
6980 if (num_vertices == 0 ||
zmo5ee097e2015-05-14 19:13:526981 !SafeMultiplyUint32(num_vertices, sizeof(Vec4f), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306982 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516983 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306984 return false;
6985 }
6986
[email protected]ab09b612013-03-11 22:11:516987 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016988 "Attribute 0 is disabled. This has signficant performance penalty");
6989
[email protected]ab09b612013-03-11 22:11:516990 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306991 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6992
[email protected]8f0b86c2f2012-04-10 05:48:286993 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6994 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496995 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306996 GLenum error = glGetError();
6997 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516998 LOCAL_SET_GL_ERROR(
6999 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:307000 return false;
7001 }
[email protected]fc753442011-02-04 19:49:497002 }
[email protected]af6380962012-11-29 23:24:137003
7004 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:287005 if (new_buffer ||
7006 (attrib_0_used &&
zmo5ee097e2015-05-14 19:13:527007 (!attrib_0_buffer_matches_value_ || !value.Equal(attrib_0_value_)))){
7008 // TODO(zmo): This is not 100% correct because we might lose data when
7009 // casting to float type, but it is a corner case and once we migrate to
7010 // core profiles on desktop GL, it is no longer relevant.
7011 Vec4f fvalue(value);
7012 std::vector<Vec4f> temp(num_vertices, fvalue);
[email protected]fc753442011-02-04 19:49:497013 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
7014 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:137015 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:247016 attrib_0_size_ = size_needed;
7017 }
7018
7019 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
7020
[email protected]ac77603c72013-03-08 13:52:067021 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:427022 glVertexAttribDivisorANGLE(0, 0);
7023
[email protected]c13e1da62011-09-09 21:48:307024 *simulated = true;
[email protected]b1122982010-05-17 23:04:247025 return true;
[email protected]b1122982010-05-17 23:04:247026}
7027
[email protected]3fc38e22014-05-30 00:13:237028void GLES2DecoderImpl::RestoreStateForAttrib(
7029 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:067030 const VertexAttrib* attrib =
7031 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:237032 if (restore_array_binding) {
7033 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
7034 Buffer* buffer = attrib->buffer();
7035 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
7036 glVertexAttribPointer(
7037 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
7038 attrib->gl_stride(), ptr);
7039 }
[email protected]ac77603c72013-03-08 13:52:067040 if (attrib->divisor())
7041 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:247042 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:237043 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
7044 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:287045
[email protected]265f8992012-07-20 01:03:147046 // Never touch vertex attribute 0's state (in particular, never
7047 // disable it) when running on desktop GL because it will never be
7048 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:067049 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:147050 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:067051 if (attrib->enabled()) {
7052 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:147053 } else {
[email protected]ac77603c72013-03-08 13:52:067054 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:147055 }
[email protected]43410e92012-04-20 17:06:287056 }
[email protected]b1122982010-05-17 23:04:247057}
[email protected]07f54fcc2009-12-22 02:46:307058
[email protected]8fbedc02010-11-18 18:43:407059bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:437060 const char* function_name,
[email protected]c6aef902012-02-14 03:31:427061 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:407062 DCHECK(simulated);
7063 *simulated = false;
7064 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
7065 return true;
7066
[email protected]e259eb412012-10-13 05:47:247067 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:407068 return true;
7069 }
7070
[email protected]ab09b612013-03-11 22:11:517071 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:017072 "GL_FIXED attributes have a signficant performance penalty");
7073
[email protected]8fbedc02010-11-18 18:43:407074 // NOTE: we could be smart and try to check if a buffer is used
7075 // twice in 2 different attribs, find the overlapping parts and therefore
7076 // duplicate the minimum amount of data but this whole code path is not meant
7077 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
7078 // tests so we just add to the buffer attrib used.
7079
[email protected]c13e1da62011-09-09 21:48:307080 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:067081 const VertexAttribManager::VertexAttribList& enabled_attribs =
7082 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
7083 for (VertexAttribManager::VertexAttribList::const_iterator it =
7084 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
7085 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:357086 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:067087 state_.current_program->GetAttribInfoByLocation(attrib->index());
7088 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
7089 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:427090 GLuint num_vertices = max_accessed + 1;
7091 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:517092 LOCAL_SET_GL_ERROR(
7093 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:427094 return false;
7095 }
[email protected]8fbedc02010-11-18 18:43:407096 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:067097 attrib->CanAccess(max_accessed) &&
7098 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:477099 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:067100 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:477101 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:517102 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437103 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:407104 return false;
7105 }
7106 }
7107 }
7108
[email protected]3aad1a32012-09-07 20:54:477109 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
7110 uint32 size_needed = 0;
7111 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:307112 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:517113 LOCAL_SET_GL_ERROR(
7114 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:407115 return false;
7116 }
7117
[email protected]ab09b612013-03-11 22:11:517118 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:407119
7120 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:307121 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:407122 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:307123 GLenum error = glGetError();
7124 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:517125 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437126 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:307127 return false;
7128 }
[email protected]8fbedc02010-11-18 18:43:407129 }
7130
7131 // Copy the elements and convert to float
7132 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:067133 for (VertexAttribManager::VertexAttribList::const_iterator it =
7134 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
7135 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:357136 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:067137 state_.current_program->GetAttribInfoByLocation(attrib->index());
7138 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:427139 max_vertex_accessed);
7140 GLuint num_vertices = max_accessed + 1;
7141 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:517142 LOCAL_SET_GL_ERROR(
7143 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:427144 return false;
7145 }
[email protected]8fbedc02010-11-18 18:43:407146 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:067147 attrib->CanAccess(max_accessed) &&
7148 attrib->type() == GL_FIXED) {
penghuang5a3210b2014-10-29 18:24:367149 int num_elements = attrib->size() * num_vertices;
7150 const int src_size = num_elements * sizeof(int32);
7151 const int dst_size = num_elements * sizeof(float);
7152 scoped_ptr<float[]> data(new float[num_elements]);
[email protected]8fbedc02010-11-18 18:43:407153 const int32* src = reinterpret_cast<const int32 *>(
penghuang5a3210b2014-10-29 18:24:367154 attrib->buffer()->GetRange(attrib->offset(), src_size));
[email protected]8fbedc02010-11-18 18:43:407155 const int32* end = src + num_elements;
7156 float* dst = data.get();
7157 while (src != end) {
7158 *dst++ = static_cast<float>(*src++) / 65536.0f;
7159 }
penghuang5a3210b2014-10-29 18:24:367160 glBufferSubData(GL_ARRAY_BUFFER, offset, dst_size, data.get());
[email protected]8fbedc02010-11-18 18:43:407161 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:067162 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:407163 reinterpret_cast<GLvoid*>(offset));
penghuang5a3210b2014-10-29 18:24:367164 offset += dst_size;
[email protected]8fbedc02010-11-18 18:43:407165 }
7166 }
7167 *simulated = true;
7168 return true;
7169}
7170
7171void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
7172 // There's no need to call glVertexAttribPointer because we shadow all the
7173 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:247174 glBindBuffer(
7175 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:117176 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
7177 : 0);
[email protected]8fbedc02010-11-18 18:43:407178}
7179
[email protected]ad84a3a2012-06-08 21:42:437180error::Error GLES2DecoderImpl::DoDrawArrays(
7181 const char* function_name,
7182 bool instanced,
7183 GLenum mode,
7184 GLint first,
7185 GLsizei count,
7186 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:227187 error::Error error = WillAccessBoundFramebufferForDraw();
7188 if (error != error::kNoError)
7189 return error;
[email protected]38d139d2011-07-14 00:38:437190 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:517191 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:437192 return error::kNoError;
7193 }
7194 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:517195 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:437196 return error::kNoError;
7197 }
[email protected]c6aef902012-02-14 03:31:427198 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:517199 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:427200 return error::kNoError;
7201 }
[email protected]ad84a3a2012-06-08 21:42:437202 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:437203 return error::kNoError;
7204 }
7205 // We have to check this here because the prototype for glDrawArrays
7206 // is GLint not GLsizei.
7207 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:517208 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:437209 return error::kNoError;
7210 }
7211
[email protected]ac6904d62014-07-30 12:00:107212 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:517213 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:437214 return error::kNoError;
7215 }
7216
7217 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:107218 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:207219 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:517220 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:207221 return error::kNoError;
7222 }
[email protected]c13e1da62011-09-09 21:48:307223 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:437224 if (!SimulateAttrib0(
7225 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:307226 return error::kNoError;
7227 }
[email protected]38d139d2011-07-14 00:38:437228 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:437229 if (SimulateFixedAttribs(
7230 function_name, max_vertex_accessed, &simulated_fixed_attribs,
7231 primcount)) {
[email protected]e56131d22013-07-28 16:14:117232 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:437233 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:377234 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:427235 if (!instanced) {
7236 glDrawArrays(mode, first, count);
7237 } else {
7238 glDrawArraysInstancedANGLE(mode, first, count, primcount);
7239 }
[email protected]38d139d2011-07-14 00:38:437240 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:547241 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:437242 }
7243 if (simulated_fixed_attribs) {
7244 RestoreStateForSimulatedFixedAttribs();
7245 }
7246 }
7247 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:237248 // We don't have to restore attrib 0 generic data at the end of this
7249 // function even if it is simulated. This is because we will simulate
7250 // it in each draw call, and attrib 0 generic data queries use cached
7251 // values instead of passing down to the underlying driver.
7252 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:437253 }
[email protected]38d139d2011-07-14 00:38:437254 }
7255 return error::kNoError;
7256}
7257
vmiuracd108592014-09-08 14:36:347258error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
7259 const void* cmd_data) {
zmo640dc652015-04-28 00:53:387260 // TODO(zmo): crbug.com/481184
7261 // On Desktop GL with versions lower than 4.3, we need to emulate
7262 // GL_PRIMITIVE_RESTART_FIXED_INDEX using glPrimitiveRestartIndex().
vmiuracd108592014-09-08 14:36:347263 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:437264 return DoDrawArrays("glDrawArrays",
7265 false,
[email protected]c6aef902012-02-14 03:31:427266 static_cast<GLenum>(c.mode),
7267 static_cast<GLint>(c.first),
7268 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:107269 1);
[email protected]c6aef902012-02-14 03:31:427270}
7271
7272error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:347273 uint32 immediate_data_size,
7274 const void* cmd_data) {
7275 const gles2::cmds::DrawArraysInstancedANGLE& c =
7276 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157277 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517278 LOCAL_SET_GL_ERROR(
7279 GL_INVALID_OPERATION,
7280 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427281 return error::kNoError;
7282 }
[email protected]ad84a3a2012-06-08 21:42:437283 return DoDrawArrays("glDrawArraysIntancedANGLE",
7284 true,
[email protected]c6aef902012-02-14 03:31:427285 static_cast<GLenum>(c.mode),
7286 static_cast<GLint>(c.first),
7287 static_cast<GLsizei>(c.count),
7288 static_cast<GLsizei>(c.primcount));
7289}
7290
[email protected]ad84a3a2012-06-08 21:42:437291error::Error GLES2DecoderImpl::DoDrawElements(
7292 const char* function_name,
7293 bool instanced,
7294 GLenum mode,
7295 GLsizei count,
7296 GLenum type,
7297 int32 offset,
7298 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:227299 error::Error error = WillAccessBoundFramebufferForDraw();
7300 if (error != error::kNoError)
7301 return error;
[email protected]e259eb412012-10-13 05:47:247302 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:517303 LOCAL_SET_GL_ERROR(
7304 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:297305 return error::kNoError;
7306 }
7307
[email protected]8eee29c2010-04-29 03:38:297308 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:517309 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:297310 return error::kNoError;
7311 }
7312 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517313 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297314 return error::kNoError;
7315 }
[email protected]9438b012010-06-15 22:55:057316 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:517317 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:297318 return error::kNoError;
7319 }
[email protected]9438b012010-06-15 22:55:057320 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517321 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:297322 return error::kNoError;
7323 }
[email protected]c6aef902012-02-14 03:31:427324 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:517325 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:427326 return error::kNoError;
7327 }
[email protected]8eee29c2010-04-29 03:38:297328
[email protected]ad84a3a2012-06-08 21:42:437329 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:277330 return error::kNoError;
7331 }
7332
[email protected]ac6904d62014-07-30 12:00:107333 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:317334 return error::kNoError;
7335 }
7336
[email protected]8eee29c2010-04-29 03:38:297337 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:087338 Buffer* element_array_buffer =
7339 state_.vertex_attrib_manager->element_array_buffer();
7340
7341 if (!element_array_buffer->GetMaxValueForRange(
7342 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:517343 LOCAL_SET_GL_ERROR(
7344 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:297345 return error::kNoError;
7346 }
7347
[email protected]ac6904d62014-07-30 12:00:107348 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:207349 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:517350 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:207351 return error::kNoError;
7352 }
[email protected]c13e1da62011-09-09 21:48:307353 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:437354 if (!SimulateAttrib0(
7355 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:307356 return error::kNoError;
7357 }
[email protected]8fbedc02010-11-18 18:43:407358 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:437359 if (SimulateFixedAttribs(
7360 function_name, max_vertex_accessed, &simulated_fixed_attribs,
7361 primcount)) {
[email protected]e56131d22013-07-28 16:14:117362 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:467363 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:087364 // TODO(gman): Refactor to hide these details in BufferManager or
7365 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:407366 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:087367 bool used_client_side_array = false;
7368 if (element_array_buffer->IsClientSideArray()) {
7369 used_client_side_array = true;
7370 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
7371 indices = element_array_buffer->GetRange(offset, 0);
7372 }
7373
[email protected]00c2cf92014-03-14 00:08:377374 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:427375 if (!instanced) {
7376 glDrawElements(mode, count, type, indices);
7377 } else {
7378 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
7379 }
[email protected]17cfbe0e2013-03-07 01:26:087380
7381 if (used_client_side_array) {
7382 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
7383 element_array_buffer->service_id());
7384 }
7385
[email protected]8fbedc02010-11-18 18:43:407386 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:547387 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:407388 }
7389 if (simulated_fixed_attribs) {
7390 RestoreStateForSimulatedFixedAttribs();
7391 }
[email protected]ba3176a2009-12-16 18:19:467392 }
[email protected]b1122982010-05-17 23:04:247393 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:237394 // We don't have to restore attrib 0 generic data at the end of this
7395 // function even if it is simulated. This is because we will simulate
7396 // it in each draw call, and attrib 0 generic data queries use cached
7397 // values instead of passing down to the underlying driver.
7398 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:247399 }
[email protected]96449d2c2009-11-25 00:01:327400 }
[email protected]f7a64ee2010-02-01 22:24:147401 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327402}
7403
vmiuracd108592014-09-08 14:36:347404error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
7405 const void* cmd_data) {
zmo640dc652015-04-28 00:53:387406 // TODO(zmo): crbug.com/481184
7407 // On Desktop GL with versions lower than 4.3, we need to emulate
7408 // GL_PRIMITIVE_RESTART_FIXED_INDEX using glPrimitiveRestartIndex().
vmiuracd108592014-09-08 14:36:347409 const gles2::cmds::DrawElements& c =
7410 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:437411 return DoDrawElements("glDrawElements",
7412 false,
[email protected]c6aef902012-02-14 03:31:427413 static_cast<GLenum>(c.mode),
7414 static_cast<GLsizei>(c.count),
7415 static_cast<GLenum>(c.type),
7416 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:107417 1);
[email protected]c6aef902012-02-14 03:31:427418}
7419
7420error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:347421 uint32 immediate_data_size,
7422 const void* cmd_data) {
7423 const gles2::cmds::DrawElementsInstancedANGLE& c =
7424 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157425 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517426 LOCAL_SET_GL_ERROR(
7427 GL_INVALID_OPERATION,
7428 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427429 return error::kNoError;
7430 }
[email protected]ad84a3a2012-06-08 21:42:437431 return DoDrawElements("glDrawElementsInstancedANGLE",
7432 true,
[email protected]c6aef902012-02-14 03:31:427433 static_cast<GLenum>(c.mode),
7434 static_cast<GLsizei>(c.count),
7435 static_cast<GLenum>(c.type),
7436 static_cast<int32>(c.index_offset),
7437 static_cast<GLsizei>(c.primcount));
7438}
7439
[email protected]269200b12010-11-18 22:53:067440GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:237441 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
7442 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:077443 Buffer* buffer = GetBuffer(buffer_id);
7444 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:037445 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517446 LOCAL_SET_GL_ERROR(
7447 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:237448 } else {
[email protected]b10492f2013-03-08 05:24:077449 if (!buffer->GetMaxValueForRange(
7450 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:037451 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517452 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:067453 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437454 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:237455 }
7456 }
7457 return max_vertex_accessed;
7458}
7459
zmo1bb3d1d2015-01-21 20:29:437460void GLES2DecoderImpl::DoShaderSource(
7461 GLuint client_id, GLsizei count, const char** data, const GLint* length) {
7462 std::string str;
7463 for (GLsizei ii = 0; ii < count; ++ii) {
dyen7b0b4ba52015-02-04 21:38:067464 if (length && length[ii] > 0)
7465 str.append(data[ii], length[ii]);
7466 else
7467 str.append(data[ii]);
zmo1bb3d1d2015-01-21 20:29:437468 }
[email protected]df37b9932013-03-08 05:21:427469 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
7470 if (!shader) {
zmo1bb3d1d2015-01-21 20:29:437471 return;
[email protected]96449d2c2009-11-25 00:01:327472 }
[email protected]45bf5152010-02-12 00:11:317473 // Note: We don't actually call glShaderSource here. We wait until
dyen7b0b4ba52015-02-04 21:38:067474 // we actually compile the shader.
zmo576a0492014-09-13 01:12:327475 shader->set_source(str);
[email protected]558847a2010-03-24 07:02:547476}
7477
zmo38923562015-01-29 20:17:397478void GLES2DecoderImpl::DoTransformFeedbackVaryings(
7479 GLuint client_program_id, GLsizei count, const char* const* varyings,
7480 GLenum buffer_mode) {
7481 Program* program = GetProgramInfoNotShader(
7482 client_program_id, "glTransformFeedbackVaryings");
7483 if (!program) {
7484 return;
7485 }
bajones63ead732015-03-14 00:12:467486 program->TransformFeedbackVaryings(count, varyings, buffer_mode);
zmo38923562015-01-29 20:17:397487 glTransformFeedbackVaryings(
7488 program->service_id(), count, varyings, buffer_mode);
7489}
7490
[email protected]ae51d192010-04-27 00:48:037491void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:387492 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:427493 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
7494 if (!shader) {
[email protected]45bf5152010-02-12 00:11:317495 return;
7496 }
dyen0ff9e4402015-02-12 22:27:437497
7498 scoped_refptr<ShaderTranslatorInterface> translator;
[email protected]b1d2dcb2010-05-17 19:24:187499 if (use_shader_translator_) {
dyen0ff9e4402015-02-12 22:27:437500 translator = shader->shader_type() == GL_VERTEX_SHADER ?
7501 vertex_translator_ : fragment_translator_;
[email protected]de17df392010-04-23 21:09:417502 }
[email protected]de17df392010-04-23 21:09:417503
dyen0ff9e4402015-02-12 22:27:437504 const Shader::TranslatedShaderSourceType source_type =
7505 feature_info_->feature_flags().angle_translated_shader_source ?
7506 Shader::kANGLE : Shader::kGL;
7507 shader->RequestCompile(translator, source_type);
vmiura8266ca72014-09-09 21:37:007508}
[email protected]45bf5152010-02-12 00:11:317509
[email protected]ddd968b82010-03-02 00:44:297510void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:427511 GLuint shader_id, GLenum pname, GLint* params) {
7512 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
7513 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:297514 return;
7515 }
dyen0ff9e4402015-02-12 22:27:437516
7517 // Compile now for statuses that require it.
7518 switch (pname) {
7519 case GL_COMPILE_STATUS:
7520 case GL_INFO_LOG_LENGTH:
7521 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
7522 shader->DoCompile();
7523 break;
7524
7525 default:
7526 break;
7527 }
7528
[email protected]8f1ccdac2010-05-19 21:01:487529 switch (pname) {
7530 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:327531 *params = shader->source().size();
7532 if (*params)
7533 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:487534 return;
7535 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:327536 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:417537 return;
[email protected]8f1ccdac2010-05-19 21:01:487538 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:327539 *params = shader->log_info().size();
7540 if (*params)
7541 ++(*params);
[email protected]e5186162010-06-14 18:54:417542 return;
[email protected]d6a53e42011-10-05 00:09:367543 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:327544 *params = shader->translated_source().size();
7545 if (*params)
7546 ++(*params);
[email protected]d6a53e42011-10-05 00:09:367547 return;
[email protected]8f1ccdac2010-05-19 21:01:487548 default:
7549 break;
[email protected]ddd968b82010-03-02 00:44:297550 }
[email protected]df37b9932013-03-08 05:21:427551 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:297552}
7553
vmiuracd108592014-09-08 14:36:347554error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
7555 const void* cmd_data) {
7556 const gles2::cmds::GetShaderSource& c =
7557 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427558 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:037559 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7560 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427561 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:327562 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:297563 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:297564 return error::kNoError;
7565 }
zmo576a0492014-09-13 01:12:327566 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:037567 return error::kNoError;
7568}
7569
[email protected]d6a53e42011-10-05 00:09:367570error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
7571 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347572 const void* cmd_data) {
7573 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
7574 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
7575 cmd_data);
[email protected]df37b9932013-03-08 05:21:427576 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:367577 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7578 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427579 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:207580 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:427581 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:367582 bucket->SetSize(0);
7583 return error::kNoError;
7584 }
7585
dyen0ff9e4402015-02-12 22:27:437586 // Make sure translator has been utilized in compile.
7587 shader->DoCompile();
7588
zmo576a0492014-09-13 01:12:327589 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:367590 return error::kNoError;
7591}
7592
[email protected]ae51d192010-04-27 00:48:037593error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:347594 uint32 immediate_data_size,
7595 const void* cmd_data) {
7596 const gles2::cmds::GetProgramInfoLog& c =
7597 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427598 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:587599 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7600 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427601 Program* program = GetProgramInfoNotShader(
7602 program_id, "glGetProgramInfoLog");
7603 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:467604 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037605 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:317606 }
[email protected]df37b9932013-03-08 05:21:427607 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:037608 return error::kNoError;
7609}
7610
7611error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:347612 uint32 immediate_data_size,
7613 const void* cmd_data) {
7614 const gles2::cmds::GetShaderInfoLog& c =
7615 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427616 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:587617 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7618 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427619 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:327620 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:467621 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037622 return error::kNoError;
7623 }
dyen0ff9e4402015-02-12 22:27:437624
7625 // Shader must be compiled in order to get the info log.
7626 shader->DoCompile();
7627
zmo576a0492014-09-13 01:12:327628 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:037629 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327630}
7631
[email protected]d058bca2012-11-26 10:27:267632bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
7633 return state_.GetEnabled(cap);
7634}
7635
[email protected]1958e0e2010-04-22 05:17:157636bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:217637 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107638 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157639}
7640
7641bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357642 const Framebuffer* framebuffer =
7643 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107644 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157645}
7646
7647bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367648 // IsProgram is true for programs as soon as they are created, until they are
7649 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:357650 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:107651 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157652}
7653
7654bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357655 const Renderbuffer* renderbuffer =
7656 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107657 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157658}
7659
7660bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367661 // IsShader is true for shaders as soon as they are created, until they
7662 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:357663 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:107664 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157665}
7666
7667bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:497668 const TextureRef* texture_ref = GetTexture(client_id);
7669 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:037670}
7671
7672void GLES2DecoderImpl::DoAttachShader(
7673 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427674 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587675 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:427676 if (!program) {
[email protected]ae51d192010-04-27 00:48:037677 return;
[email protected]1958e0e2010-04-22 05:17:157678 }
[email protected]df37b9932013-03-08 05:21:427679 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
7680 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037681 return;
7682 }
[email protected]df37b9932013-03-08 05:21:427683 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517684 LOCAL_SET_GL_ERROR(
7685 GL_INVALID_OPERATION,
7686 "glAttachShader",
7687 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:317688 return;
7689 }
[email protected]df37b9932013-03-08 05:21:427690 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037691}
7692
7693void GLES2DecoderImpl::DoDetachShader(
7694 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427695 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587696 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427697 if (!program) {
[email protected]ae51d192010-04-27 00:48:037698 return;
7699 }
[email protected]df37b9932013-03-08 05:21:427700 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7701 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037702 return;
7703 }
[email protected]df37b9932013-03-08 05:21:427704 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517705 LOCAL_SET_GL_ERROR(
7706 GL_INVALID_OPERATION,
7707 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227708 return;
7709 }
[email protected]df37b9932013-03-08 05:21:427710 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037711}
7712
7713void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427714 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587715 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427716 if (!program) {
[email protected]ae51d192010-04-27 00:48:037717 return;
7718 }
[email protected]df37b9932013-03-08 05:21:427719 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157720}
7721
[email protected]ac77603c72013-03-08 13:52:067722void GLES2DecoderImpl::GetVertexAttribHelper(
7723 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247724 switch (pname) {
zmo5ee097e2015-05-14 19:13:527725 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
7726 {
[email protected]ac77603c72013-03-08 13:52:067727 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247728 if (buffer && !buffer->IsDeleted()) {
7729 GLuint client_id;
7730 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7731 *params = client_id;
7732 }
7733 break;
7734 }
7735 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067736 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247737 break;
7738 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067739 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247740 break;
7741 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067742 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247743 break;
7744 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067745 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247746 break;
7747 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067748 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247749 break;
zmo5ee097e2015-05-14 19:13:527750 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
[email protected]ac77603c72013-03-08 13:52:067751 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427752 break;
zmo5ee097e2015-05-14 19:13:527753 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
7754 *params = attrib->integer();
7755 break;
[email protected]ac77603c72013-03-08 13:52:067756 default:
7757 NOTREACHED();
7758 break;
7759 }
7760}
7761
[email protected]4c6f5462014-03-05 00:26:567762void GLES2DecoderImpl::DoGetTexParameterfv(
7763 GLenum target, GLenum pname, GLfloat* params) {
7764 InitTextureMaxAnisotropyIfNeeded(target, pname);
7765 glGetTexParameterfv(target, pname, params);
7766}
7767
7768void GLES2DecoderImpl::DoGetTexParameteriv(
7769 GLenum target, GLenum pname, GLint* params) {
7770 InitTextureMaxAnisotropyIfNeeded(target, pname);
7771 glGetTexParameteriv(target, pname, params);
7772}
7773
7774void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7775 GLenum target, GLenum pname) {
7776 if (!workarounds().init_texture_max_anisotropy)
7777 return;
7778 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7779 !validators_->texture_parameter.IsValid(pname)) {
7780 return;
7781 }
7782
7783 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7784 &state_, target);
7785 if (!texture_ref) {
7786 LOCAL_SET_GL_ERROR(
7787 GL_INVALID_OPERATION,
7788 "glGetTexParamter{fi}v", "unknown texture for target");
7789 return;
7790 }
7791 Texture* texture = texture_ref->texture();
7792 texture->InitTextureMaxAnisotropyIfNeeded(target);
7793}
7794
zmo5ee097e2015-05-14 19:13:527795template <typename T>
7796void GLES2DecoderImpl::DoGetVertexAttribImpl(
7797 GLuint index, GLenum pname, T* params) {
[email protected]ac77603c72013-03-08 13:52:067798 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7799 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517800 LOCAL_SET_GL_ERROR(
zmo5ee097e2015-05-14 19:13:527801 GL_INVALID_VALUE, "glGetVertexAttrib", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067802 return;
7803 }
7804 switch (pname) {
zmo5ee097e2015-05-14 19:13:527805 case GL_CURRENT_VERTEX_ATTRIB:
7806 state_.attrib_values[index].GetValues(params);
[email protected]ac77603c72013-03-08 13:52:067807 break;
[email protected]ac77603c72013-03-08 13:52:067808 default: {
7809 GLint value = 0;
7810 GetVertexAttribHelper(attrib, pname, &value);
zmo5ee097e2015-05-14 19:13:527811 *params = static_cast<T>(value);
[email protected]ac77603c72013-03-08 13:52:067812 break;
7813 }
7814 }
7815}
7816
zmo5ee097e2015-05-14 19:13:527817void GLES2DecoderImpl::DoGetVertexAttribfv(
7818 GLuint index, GLenum pname, GLfloat* params) {
7819 DoGetVertexAttribImpl<GLfloat>(index, pname, params);
7820}
7821
[email protected]ac77603c72013-03-08 13:52:067822void GLES2DecoderImpl::DoGetVertexAttribiv(
7823 GLuint index, GLenum pname, GLint* params) {
zmo5ee097e2015-05-14 19:13:527824 DoGetVertexAttribImpl<GLint>(index, pname, params);
7825}
7826
7827void GLES2DecoderImpl::DoGetVertexAttribIiv(
7828 GLuint index, GLenum pname, GLint* params) {
7829 DoGetVertexAttribImpl<GLint>(index, pname, params);
7830}
7831
7832void GLES2DecoderImpl::DoGetVertexAttribIuiv(
7833 GLuint index, GLenum pname, GLuint* params) {
7834 DoGetVertexAttribImpl<GLuint>(index, pname, params);
[email protected]b1122982010-05-17 23:04:247835}
7836
zmo143c51a2015-05-15 03:04:077837template <typename T>
[email protected]af6380962012-11-29 23:24:137838bool GLES2DecoderImpl::SetVertexAttribValue(
zmo143c51a2015-05-15 03:04:077839 const char* function_name, GLuint index, const T* value) {
[email protected]af6380962012-11-29 23:24:137840 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517841 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137842 return false;
[email protected]b1122982010-05-17 23:04:247843 }
zmo5ee097e2015-05-14 19:13:527844 state_.attrib_values[index].SetValues(value);
[email protected]af6380962012-11-29 23:24:137845 return true;
7846}
7847
7848void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7849 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7850 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7851 glVertexAttrib1f(index, v0);
7852 }
[email protected]b1122982010-05-17 23:04:247853}
7854
7855void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137856 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7857 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7858 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247859 }
[email protected]b1122982010-05-17 23:04:247860}
7861
7862void GLES2DecoderImpl::DoVertexAttrib3f(
7863 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137864 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7865 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7866 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247867 }
[email protected]b1122982010-05-17 23:04:247868}
7869
7870void GLES2DecoderImpl::DoVertexAttrib4f(
7871 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137872 GLfloat v[4] = { v0, v1, v2, v3, };
7873 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7874 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247875 }
[email protected]b1122982010-05-17 23:04:247876}
7877
7878void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137879 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7880 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7881 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247882 }
[email protected]b1122982010-05-17 23:04:247883}
7884
7885void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137886 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7887 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7888 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247889 }
[email protected]b1122982010-05-17 23:04:247890}
7891
7892void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137893 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7894 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7895 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247896 }
[email protected]b1122982010-05-17 23:04:247897}
7898
7899void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137900 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7901 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247902 }
[email protected]b1122982010-05-17 23:04:247903}
7904
zmo143c51a2015-05-15 03:04:077905void GLES2DecoderImpl::DoVertexAttribI4i(
7906 GLuint index, GLint v0, GLint v1, GLint v2, GLint v3) {
7907 GLint v[4] = { v0, v1, v2, v3 };
7908 if (SetVertexAttribValue("glVertexAttribI4i", index, v)) {
7909 glVertexAttribI4i(index, v0, v1, v2, v3);
7910 }
7911}
7912
7913void GLES2DecoderImpl::DoVertexAttribI4iv(GLuint index, const GLint* v) {
7914 if (SetVertexAttribValue("glVertexAttribI4iv", index, v)) {
7915 glVertexAttribI4iv(index, v);
7916 }
7917}
7918
7919void GLES2DecoderImpl::DoVertexAttribI4ui(
7920 GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {
7921 GLuint v[4] = { v0, v1, v2, v3 };
7922 if (SetVertexAttribValue("glVertexAttribI4ui", index, v)) {
7923 glVertexAttribI4ui(index, v0, v1, v2, v3);
7924 }
7925}
7926
7927void GLES2DecoderImpl::DoVertexAttribI4uiv(GLuint index, const GLuint* v) {
7928 if (SetVertexAttribValue("glVertexAttribI4uiv", index, v)) {
7929 glVertexAttribI4uiv(index, v);
7930 }
7931}
7932
zmo0c4b7cf2014-11-26 00:52:117933error::Error GLES2DecoderImpl::HandleVertexAttribIPointer(
7934 uint32 immediate_data_size,
7935 const void* cmd_data) {
zmo0c4b7cf2014-11-26 00:52:117936 if (!unsafe_es3_apis_enabled())
7937 return error::kUnknownCommand;
7938 const gles2::cmds::VertexAttribIPointer& c =
7939 *static_cast<const gles2::cmds::VertexAttribIPointer*>(cmd_data);
guanxian.li87543be32015-04-28 03:01:047940
7941 if (!state_.bound_array_buffer.get() ||
7942 state_.bound_array_buffer->IsDeleted()) {
7943 if (state_.vertex_attrib_manager.get() ==
7944 state_.default_vertex_attrib_manager.get()) {
7945 LOCAL_SET_GL_ERROR(
7946 GL_INVALID_VALUE, "glVertexAttribIPointer", "no array buffer bound");
7947 return error::kNoError;
7948 } else if (c.offset != 0) {
7949 LOCAL_SET_GL_ERROR(
7950 GL_INVALID_VALUE,
7951 "glVertexAttribIPointer", "client side arrays are not allowed");
7952 return error::kNoError;
7953 }
7954 }
7955
zmo0c4b7cf2014-11-26 00:52:117956 GLuint indx = c.indx;
7957 GLint size = c.size;
7958 GLenum type = c.type;
7959 GLsizei stride = c.stride;
7960 GLsizei offset = c.offset;
7961 const void* ptr = reinterpret_cast<const void*>(offset);
guanxian.li87543be32015-04-28 03:01:047962 if (!validators_->vertex_attrib_i_type.IsValid(type)) {
7963 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribIPointer", type, "type");
7964 return error::kNoError;
7965 }
7966 if (!validators_->vertex_attrib_size.IsValid(size)) {
7967 LOCAL_SET_GL_ERROR(
7968 GL_INVALID_VALUE, "glVertexAttribIPointer", "size GL_INVALID_VALUE");
7969 return error::kNoError;
7970 }
7971 if (indx >= group_->max_vertex_attribs()) {
7972 LOCAL_SET_GL_ERROR(
7973 GL_INVALID_VALUE, "glVertexAttribIPointer", "index out of range");
7974 return error::kNoError;
7975 }
7976 if (stride < 0) {
7977 LOCAL_SET_GL_ERROR(
7978 GL_INVALID_VALUE, "glVertexAttribIPointer", "stride < 0");
7979 return error::kNoError;
7980 }
7981 if (stride > 255) {
7982 LOCAL_SET_GL_ERROR(
7983 GL_INVALID_VALUE, "glVertexAttribIPointer", "stride > 255");
7984 return error::kNoError;
7985 }
7986 if (offset < 0) {
7987 LOCAL_SET_GL_ERROR(
7988 GL_INVALID_VALUE, "glVertexAttribIPointer", "offset < 0");
7989 return error::kNoError;
7990 }
7991 GLsizei component_size =
7992 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
7993 // component_size must be a power of two to use & as optimized modulo.
7994 DCHECK(GLES2Util::IsPOT(component_size));
7995 if (offset & (component_size - 1)) {
7996 LOCAL_SET_GL_ERROR(
7997 GL_INVALID_OPERATION,
7998 "glVertexAttribIPointer", "offset not valid for type");
7999 return error::kNoError;
8000 }
8001 if (stride & (component_size - 1)) {
8002 LOCAL_SET_GL_ERROR(
8003 GL_INVALID_OPERATION,
8004 "glVertexAttribIPointer", "stride not valid for type");
8005 return error::kNoError;
8006 }
8007 state_.vertex_attrib_manager
8008 ->SetAttribInfo(indx,
8009 state_.bound_array_buffer.get(),
8010 size,
8011 type,
8012 GL_FALSE,
8013 stride,
8014 stride != 0 ? stride : component_size * size,
zmo143c51a2015-05-15 03:04:078015 offset,
8016 GL_TRUE);
zmo0c4b7cf2014-11-26 00:52:118017 glVertexAttribIPointer(indx, size, type, stride, ptr);
8018 return error::kNoError;
8019}
8020
[email protected]f7a64ee2010-02-01 22:24:148021error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:348022 uint32 immediate_data_size,
8023 const void* cmd_data) {
8024 const gles2::cmds::VertexAttribPointer& c =
8025 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:468026
[email protected]7cd76fd2013-06-02 21:11:118027 if (!state_.bound_array_buffer.get() ||
8028 state_.bound_array_buffer->IsDeleted()) {
8029 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:528030 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:518031 LOCAL_SET_GL_ERROR(
8032 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:468033 return error::kNoError;
8034 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:518035 LOCAL_SET_GL_ERROR(
8036 GL_INVALID_VALUE,
8037 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:468038 return error::kNoError;
8039 }
[email protected]96449d2c2009-11-25 00:01:328040 }
[email protected]8eee29c2010-04-29 03:38:298041
8042 GLuint indx = c.indx;
8043 GLint size = c.size;
8044 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:328045 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:298046 GLsizei stride = c.stride;
8047 GLsizei offset = c.offset;
8048 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:058049 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518050 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:298051 return error::kNoError;
8052 }
[email protected]9438b012010-06-15 22:55:058053 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:518054 LOCAL_SET_GL_ERROR(
8055 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:298056 return error::kNoError;
8057 }
8058 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518059 LOCAL_SET_GL_ERROR(
8060 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:298061 return error::kNoError;
8062 }
8063 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:518064 LOCAL_SET_GL_ERROR(
8065 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:298066 return error::kNoError;
8067 }
8068 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:518069 LOCAL_SET_GL_ERROR(
8070 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:298071 return error::kNoError;
8072 }
8073 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:518074 LOCAL_SET_GL_ERROR(
8075 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:298076 return error::kNoError;
8077 }
8078 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:318079 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:128080 // component_size must be a power of two to use & as optimized modulo.
8081 DCHECK(GLES2Util::IsPOT(component_size));
8082 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:518083 LOCAL_SET_GL_ERROR(
8084 GL_INVALID_OPERATION,
8085 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:318086 return error::kNoError;
8087 }
[email protected]a07a23602014-08-05 11:36:128088 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:518089 LOCAL_SET_GL_ERROR(
8090 GL_INVALID_OPERATION,
8091 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:298092 return error::kNoError;
8093 }
[email protected]7cd76fd2013-06-02 21:11:118094 state_.vertex_attrib_manager
8095 ->SetAttribInfo(indx,
8096 state_.bound_array_buffer.get(),
8097 size,
8098 type,
8099 normalized,
8100 stride,
8101 stride != 0 ? stride : component_size * size,
zmo143c51a2015-05-15 03:04:078102 offset,
8103 GL_FALSE);
jmadill7cb0b8e72015-05-06 14:03:148104 // We support GL_FIXED natively on EGL/GLES2 implementations
8105 if (type != GL_FIXED || feature_info_->gl_version_info().is_es) {
[email protected]8fbedc02010-11-18 18:43:408106 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
8107 }
[email protected]f7a64ee2010-02-01 22:24:148108 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328109}
8110
[email protected]43410e92012-04-20 17:06:288111void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
8112 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:248113 state_.viewport_x = x;
8114 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:028115 state_.viewport_width = std::min(width, viewport_max_width_);
8116 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:288117 glViewport(x, y, width, height);
8118}
8119
[email protected]c6aef902012-02-14 03:31:428120error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:348121 uint32 immediate_data_size,
8122 const void* cmd_data) {
8123 const gles2::cmds::VertexAttribDivisorANGLE& c =
8124 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:158125 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:518126 LOCAL_SET_GL_ERROR(
8127 GL_INVALID_OPERATION,
8128 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:538129 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:428130 }
8131 GLuint index = c.index;
8132 GLuint divisor = c.divisor;
8133 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518134 LOCAL_SET_GL_ERROR(
8135 GL_INVALID_VALUE,
8136 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:428137 return error::kNoError;
8138 }
8139
[email protected]e259eb412012-10-13 05:47:248140 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:428141 index,
8142 divisor);
8143 glVertexAttribDivisorANGLE(index, divisor);
8144 return error::kNoError;
8145}
8146
[email protected]68586372013-12-11 01:27:598147template <typename pixel_data_type>
8148static void WriteAlphaData(
dcastagna504d45c2015-04-06 19:30:398149 void* pixels, uint32 row_count, uint32 channel_count,
[email protected]68586372013-12-11 01:27:598150 uint32 alpha_channel_index, uint32 unpadded_row_size,
8151 uint32 padded_row_size, pixel_data_type alpha_value) {
8152 DCHECK_GT(channel_count, 0U);
8153 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
8154 uint32 unpadded_row_size_in_elements =
8155 unpadded_row_size / sizeof(pixel_data_type);
8156 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
8157 uint32 padded_row_size_in_elements =
8158 padded_row_size / sizeof(pixel_data_type);
8159 pixel_data_type* dst =
8160 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
8161 for (uint32 yy = 0; yy < row_count; ++yy) {
8162 pixel_data_type* end = dst + unpadded_row_size_in_elements;
8163 for (pixel_data_type* d = dst; d < end; d += channel_count) {
8164 *d = alpha_value;
8165 }
8166 dst += padded_row_size_in_elements;
8167 }
8168}
8169
[email protected]5a36dc132013-07-23 23:17:558170void GLES2DecoderImpl::FinishReadPixels(
8171 const cmds::ReadPixels& c,
8172 GLuint buffer) {
8173 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
8174 GLsizei width = c.width;
8175 GLsizei height = c.height;
8176 GLenum format = c.format;
8177 GLenum type = c.type;
8178 typedef cmds::ReadPixels::Result Result;
8179 uint32 pixels_size;
8180 Result* result = NULL;
8181 if (c.result_shm_id != 0) {
8182 result = GetSharedMemoryAs<Result*>(
8183 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8184 if (!result) {
8185 if (buffer != 0) {
8186 glDeleteBuffersARB(1, &buffer);
8187 }
8188 return;
8189 }
8190 }
8191 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428192 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]5a36dc132013-07-23 23:17:558193 NULL, NULL);
8194 void* pixels = GetSharedMemoryAs<void*>(
8195 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
8196 if (!pixels) {
8197 if (buffer != 0) {
8198 glDeleteBuffersARB(1, &buffer);
8199 }
8200 return;
8201 }
8202
8203 if (buffer != 0) {
8204 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:338205 void* data;
8206 if (features().map_buffer_range) {
8207 data = glMapBufferRange(
8208 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
8209 } else {
8210 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
8211 }
miub70d78592014-11-15 03:53:478212 if (!data) {
8213 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer",
8214 "Unable to map memory for readback.");
8215 return;
8216 }
[email protected]5a36dc132013-07-23 23:17:558217 memcpy(pixels, data, pixels_size);
8218 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
8219 // have to restore the state.
8220 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
8221 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
8222 glDeleteBuffersARB(1, &buffer);
8223 }
8224
8225 if (result != NULL) {
8226 *result = true;
8227 }
8228
8229 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8230 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8231 if ((channels_exist & 0x0008) == 0 &&
8232 workarounds().clear_alpha_in_readpixels) {
8233 // Set the alpha to 255 because some drivers are buggy in this regard.
8234 uint32 temp_size;
8235
8236 uint32 unpadded_row_size;
8237 uint32 padded_row_size;
8238 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428239 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]5a36dc132013-07-23 23:17:558240 &unpadded_row_size, &padded_row_size)) {
8241 return;
8242 }
[email protected]68586372013-12-11 01:27:598243
8244 uint32 channel_count = 0;
8245 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:558246 switch (format) {
8247 case GL_RGBA:
8248 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:598249 channel_count = 4;
8250 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:558251 break;
[email protected]68586372013-12-11 01:27:598252 case GL_ALPHA:
8253 channel_count = 1;
8254 alpha_channel = 0;
8255 break;
8256 }
8257
8258 if (channel_count > 0) {
8259 switch (type) {
8260 case GL_UNSIGNED_BYTE:
8261 WriteAlphaData<uint8>(
8262 pixels, height, channel_count, alpha_channel, unpadded_row_size,
8263 padded_row_size, 0xFF);
8264 break;
8265 case GL_FLOAT:
8266 WriteAlphaData<float>(
8267 pixels, height, channel_count, alpha_channel, unpadded_row_size,
8268 padded_row_size, 1.0f);
8269 break;
8270 case GL_HALF_FLOAT:
8271 WriteAlphaData<uint16>(
8272 pixels, height, channel_count, alpha_channel, unpadded_row_size,
8273 padded_row_size, 0x3C00);
8274 break;
[email protected]5a36dc132013-07-23 23:17:558275 }
[email protected]5a36dc132013-07-23 23:17:558276 }
8277 }
8278}
8279
vmiuracd108592014-09-08 14:36:348280error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
8281 const void* cmd_data) {
8282 const gles2::cmds::ReadPixels& c =
8283 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:218284 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:228285 error::Error fbo_error = WillAccessBoundFramebufferForRead();
8286 if (fbo_error != error::kNoError)
8287 return fbo_error;
[email protected]612d2f82009-12-08 20:49:318288 GLint x = c.x;
8289 GLint y = c.y;
8290 GLsizei width = c.width;
8291 GLsizei height = c.height;
8292 GLenum format = c.format;
8293 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:328294 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:568295 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:518296 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:568297 return error::kNoError;
8298 }
[email protected]ed9f9cd2013-02-27 21:12:358299 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:188300 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348301 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428302 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:248303 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:188304 return error::kOutOfBounds;
8305 }
[email protected]612d2f82009-12-08 20:49:318306 void* pixels = GetSharedMemoryAs<void*>(
8307 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:108308 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148309 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:468310 }
[email protected]de43f082013-04-02 01:16:108311 Result* result = NULL;
8312 if (c.result_shm_id != 0) {
8313 result = GetSharedMemoryAs<Result*>(
8314 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8315 if (!result) {
8316 return error::kOutOfBounds;
8317 }
8318 }
[email protected]a51788e2010-02-24 21:54:258319
[email protected]9438b012010-06-15 22:55:058320 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518321 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:298322 return error::kNoError;
8323 }
[email protected]68586372013-12-11 01:27:598324 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518325 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:128326 return error::kNoError;
8327 }
[email protected]68586372013-12-11 01:27:598328 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
8329 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
8330 // format and type are acceptable enums but not guaranteed to be supported
8331 // for this framebuffer. Have to ask gl if they are valid.
8332 GLint preferred_format = 0;
8333 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
8334 GLint preferred_type = 0;
8335 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
8336 if (format != static_cast<GLenum>(preferred_format) ||
8337 type != static_cast<GLenum>(preferred_type)) {
8338 LOCAL_SET_GL_ERROR(
8339 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
8340 "with the current read framebuffer");
8341 return error::kNoError;
8342 }
8343 }
[email protected]57f223832010-03-19 01:57:568344 if (width == 0 || height == 0) {
8345 return error::kNoError;
8346 }
8347
[email protected]57f223832010-03-19 01:57:568348 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:308349 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:568350
[email protected]3aad1a32012-09-07 20:54:478351 int32 max_x;
8352 int32 max_y;
8353 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:518354 LOCAL_SET_GL_ERROR(
8355 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:148356 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:318357 }
[email protected]57f223832010-03-19 01:57:568358
[email protected]2ea5950d2014-07-09 18:20:348359 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
8360 return error::kNoError;
8361 }
8362
[email protected]0d6bfdc2011-11-02 01:32:208363 if (!CheckBoundFramebuffersValid("glReadPixels")) {
8364 return error::kNoError;
8365 }
8366
[email protected]caa13ed2014-02-17 11:29:208367 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:108368
8369 ScopedResolvedFrameBufferBinder binder(this, false, true);
8370
[email protected]d37231fa2010-04-09 21:16:028371 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:568372 // The user requested an out of range area. Get the results 1 line
8373 // at a time.
8374 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:348375 uint32 unpadded_row_size;
8376 uint32 padded_row_size;
8377 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428378 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:348379 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:518380 LOCAL_SET_GL_ERROR(
8381 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:568382 return error::kNoError;
8383 }
8384
8385 GLint dest_x_offset = std::max(-x, 0);
8386 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:348387 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428388 dest_x_offset, 1, 1, format, type, state_.pack_alignment,
8389 &dest_row_offset, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518390 LOCAL_SET_GL_ERROR(
8391 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:568392 return error::kNoError;
8393 }
8394
8395 // Copy each row into the larger dest rect.
8396 int8* dst = static_cast<int8*>(pixels);
8397 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:028398 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:568399 GLint read_width = read_end_x - read_x;
8400 for (GLint yy = 0; yy < height; ++yy) {
8401 GLint ry = y + yy;
8402
8403 // Clear the row.
8404 memset(dst, 0, unpadded_row_size);
8405
8406 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:028407 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:568408 glReadPixels(
8409 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
8410 }
8411 dst += padded_row_size;
8412 }
8413 } else {
[email protected]5a36dc132013-07-23 23:17:558414 if (async && features().use_async_readpixels) {
miu50cef602014-11-11 01:35:418415 GLuint buffer = 0;
[email protected]5a36dc132013-07-23 23:17:558416 glGenBuffersARB(1, &buffer);
8417 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
miub70d78592014-11-15 03:53:478418 // For ANGLE client version 2, GL_STREAM_READ is not available.
marcheu1856f5d52015-04-04 01:42:538419 const GLenum usage_hint = feature_info_->gl_version_info().is_angle ?
zmo68fcdc62014-12-05 21:51:498420 GL_STATIC_DRAW : GL_STREAM_READ;
miub70d78592014-11-15 03:53:478421 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint);
[email protected]5a36dc132013-07-23 23:17:558422 GLenum error = glGetError();
8423 if (error == GL_NO_ERROR) {
8424 glReadPixels(x, y, width, height, format, type, 0);
8425 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
8426 new FenceCallback()));
8427 WaitForReadPixels(base::Bind(
8428 &GLES2DecoderImpl::FinishReadPixels,
8429 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
8430 <GLES2DecoderImpl>(this),
8431 c, buffer));
8432 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
8433 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:598434 } else {
8435 // On error, unbind pack buffer and fall through to sync readpixels
8436 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
miu50cef602014-11-11 01:35:418437 glDeleteBuffersARB(1, &buffer);
[email protected]5a36dc132013-07-23 23:17:558438 }
8439 }
[email protected]57f223832010-03-19 01:57:568440 glReadPixels(x, y, width, height, format, type, pixels);
8441 }
[email protected]ab09b612013-03-11 22:11:518442 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:258443 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:108444 if (result != NULL) {
8445 *result = true;
8446 }
[email protected]5a36dc132013-07-23 23:17:558447 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:258448 }
[email protected]4848b9f82011-03-10 18:37:568449
[email protected]f7a64ee2010-02-01 22:24:148450 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328451}
8452
vmiuracd108592014-09-08 14:36:348453error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
8454 const void* cmd_data) {
8455 const gles2::cmds::PixelStorei& c =
8456 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198457 GLenum pname = c.pname;
8458 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:058459 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518460 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:128461 return error::kNoError;
8462 }
[email protected]222471d2011-11-30 18:06:398463 switch (pname) {
8464 case GL_PACK_ALIGNMENT:
8465 case GL_UNPACK_ALIGNMENT:
8466 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:518467 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:208468 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:398469 return error::kNoError;
8470 }
[email protected]164d6d52012-05-05 00:55:038471 break;
[email protected]222471d2011-11-30 18:06:398472 default:
8473 break;
[email protected]b9849abf2009-11-25 19:13:198474 }
8475 glPixelStorei(pname, param);
8476 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:438477 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:248478 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:438479 break;
8480 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:428481 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:438482 break;
8483 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:248484 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:438485 break;
8486 default:
8487 // Validation should have prevented us from getting here.
8488 NOTREACHED();
8489 break;
[email protected]b9849abf2009-11-25 19:13:198490 }
[email protected]f7a64ee2010-02-01 22:24:148491 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198492}
8493
[email protected]1c75a3702011-11-11 14:15:288494error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:348495 uint32 immediate_data_size,
8496 const void* cmd_data) {
8497 const gles2::cmds::PostSubBufferCHROMIUM& c =
8498 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:388499 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:278500 {
8501 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
8502 }
[email protected]b381ee32014-03-22 02:43:438503 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:518504 LOCAL_SET_GL_ERROR(
8505 GL_INVALID_OPERATION,
8506 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:288507 return error::kNoError;
8508 }
[email protected]8f9b8dd2013-09-12 18:05:138509 bool is_tracing;
8510 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
8511 &is_tracing);
8512 if (is_tracing) {
8513 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
8514 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
8515 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
8516 is_offscreen ? offscreen_size_ : surface_->GetSize());
8517 }
achaulkec8c2db2015-05-29 16:35:038518 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height) !=
8519 gfx::SwapResult::SWAP_FAILED) {
[email protected]1c75a3702011-11-11 14:15:288520 return error::kNoError;
[email protected]7794d512012-04-17 20:36:498521 } else {
8522 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:288523 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:498524 }
[email protected]1c75a3702011-11-11 14:15:288525}
8526
[email protected]957f0642014-04-09 16:50:018527error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
8528 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348529 const void* cmd_data) {
8530 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
8531 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:108532 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
8533 if (!ref) {
8534 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8535 "glScheduleOverlayPlaneCHROMIUM",
8536 "unknown texture");
8537 return error::kNoError;
8538 }
8539 gfx::GLImage* image =
8540 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
8541 if (!image) {
8542 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8543 "glScheduleOverlayPlaneCHROMIUM",
8544 "unsupported texture format");
8545 return error::kNoError;
8546 }
8547 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
8548 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
8549 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
8550 "glScheduleOverlayPlaneCHROMIUM",
8551 "invalid transform enum");
8552 return error::kNoError;
8553 }
8554 if (!surface_->ScheduleOverlayPlane(
8555 c.plane_z_order,
8556 transform,
8557 image,
8558 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
8559 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
8560 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8561 "glScheduleOverlayPlaneCHROMIUM",
8562 "failed to schedule overlay");
8563 }
[email protected]957f0642014-04-09 16:50:018564 return error::kNoError;
8565}
8566
[email protected]558847a2010-03-24 07:02:548567error::Error GLES2DecoderImpl::GetAttribLocationHelper(
8568 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8569 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578570 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518571 LOCAL_SET_GL_ERROR(
8572 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578573 return error::kNoError;
8574 }
[email protected]df37b9932013-03-08 05:21:428575 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:588576 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:428577 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148578 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198579 }
[email protected]df37b9932013-03-08 05:21:428580 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518581 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438582 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258583 return error::kNoError;
8584 }
[email protected]b9849abf2009-11-25 19:13:198585 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548586 location_shm_id, location_shm_offset, sizeof(GLint));
8587 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148588 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198589 }
[email protected]558847a2010-03-24 07:02:548590 // Require the client to init this incase the context is lost and we are no
8591 // longer executing commands.
8592 if (*location != -1) {
8593 return error::kGenericError;
8594 }
[email protected]df37b9932013-03-08 05:21:428595 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148596 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198597}
8598
[email protected]558847a2010-03-24 07:02:548599error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:348600 uint32 immediate_data_size,
8601 const void* cmd_data) {
8602 const gles2::cmds::GetAttribLocation& c =
8603 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548604 Bucket* bucket = GetBucket(c.name_bucket_id);
8605 if (!bucket) {
8606 return error::kInvalidArguments;
8607 }
8608 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188609 if (!bucket->GetAsString(&name_str)) {
8610 return error::kInvalidArguments;
8611 }
[email protected]558847a2010-03-24 07:02:548612 return GetAttribLocationHelper(
8613 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8614}
8615
8616error::Error GLES2DecoderImpl::GetUniformLocationHelper(
8617 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8618 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578619 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518620 LOCAL_SET_GL_ERROR(
8621 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578622 return error::kNoError;
8623 }
[email protected]df37b9932013-03-08 05:21:428624 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:208625 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:428626 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148627 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198628 }
[email protected]df37b9932013-03-08 05:21:428629 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518630 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438631 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258632 return error::kNoError;
8633 }
[email protected]b9849abf2009-11-25 19:13:198634 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548635 location_shm_id, location_shm_offset, sizeof(GLint));
8636 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148637 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198638 }
[email protected]558847a2010-03-24 07:02:548639 // Require the client to init this incase the context is lost an we are no
8640 // longer executing commands.
8641 if (*location != -1) {
8642 return error::kGenericError;
8643 }
[email protected]df37b9932013-03-08 05:21:428644 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148645 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198646}
8647
[email protected]f7a64ee2010-02-01 22:24:148648error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:348649 uint32 immediate_data_size,
8650 const void* cmd_data) {
8651 const gles2::cmds::GetUniformLocation& c =
8652 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548653 Bucket* bucket = GetBucket(c.name_bucket_id);
8654 if (!bucket) {
8655 return error::kInvalidArguments;
8656 }
8657 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188658 if (!bucket->GetAsString(&name_str)) {
8659 return error::kInvalidArguments;
8660 }
[email protected]558847a2010-03-24 07:02:548661 return GetUniformLocationHelper(
8662 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:198663}
8664
zmo155435a42015-02-13 05:06:538665error::Error GLES2DecoderImpl::HandleGetUniformIndices(
8666 uint32 immediate_data_size,
8667 const void* cmd_data) {
8668 if (!unsafe_es3_apis_enabled())
8669 return error::kUnknownCommand;
8670 const gles2::cmds::GetUniformIndices& c =
8671 *static_cast<const gles2::cmds::GetUniformIndices*>(cmd_data);
8672 Bucket* bucket = GetBucket(c.names_bucket_id);
8673 if (!bucket) {
8674 return error::kInvalidArguments;
8675 }
8676 GLsizei count = 0;
8677 std::vector<char*> names;
8678 std::vector<GLint> len;
8679 if (!bucket->GetAsStrings(&count, &names, &len) || count <= 0) {
8680 return error::kInvalidArguments;
8681 }
8682 typedef cmds::GetUniformIndices::Result Result;
8683 Result* result = GetSharedMemoryAs<Result*>(
8684 c.indices_shm_id, c.indices_shm_offset,
8685 Result::ComputeSize(static_cast<size_t>(count)));
8686 GLuint* indices = result ? result->GetData() : NULL;
8687 if (indices == NULL) {
8688 return error::kOutOfBounds;
8689 }
8690 // Check that the client initialized the result.
8691 if (result->size != 0) {
8692 return error::kInvalidArguments;
8693 }
8694 Program* program = GetProgramInfoNotShader(c.program, "glGetUniformIndices");
8695 if (!program) {
8696 return error::kNoError;
8697 }
8698 GLuint service_id = program->service_id();
8699 GLint link_status = GL_FALSE;
8700 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
8701 if (link_status != GL_TRUE) {
8702 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8703 "glGetUniformIndices", "program not linked");
8704 return error::kNoError;
8705 }
8706 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetUniformIndices");
8707 glGetUniformIndices(service_id, count, &names[0], indices);
8708 GLenum error = glGetError();
8709 if (error == GL_NO_ERROR) {
8710 result->SetNumResults(count);
8711 } else {
8712 LOCAL_SET_GL_ERROR(error, "GetUniformIndices", "");
8713 }
8714 return error::kNoError;
8715}
8716
zmo5393fb52015-01-27 01:50:488717error::Error GLES2DecoderImpl::GetFragDataLocationHelper(
8718 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8719 const std::string& name_str) {
8720 GLint* location = GetSharedMemoryAs<GLint*>(
8721 location_shm_id, location_shm_offset, sizeof(GLint));
8722 if (!location) {
8723 return error::kOutOfBounds;
8724 }
8725 // Require the client to init this incase the context is lost and we are no
8726 // longer executing commands.
8727 if (*location != -1) {
8728 return error::kGenericError;
8729 }
8730 Program* program = GetProgramInfoNotShader(
8731 client_id, "glGetFragDataLocation");
8732 if (!program) {
8733 return error::kNoError;
8734 }
8735 *location = glGetFragDataLocation(program->service_id(), name_str.c_str());
8736 return error::kNoError;
8737}
8738
8739error::Error GLES2DecoderImpl::HandleGetFragDataLocation(
8740 uint32 immediate_data_size,
8741 const void* cmd_data) {
8742 if (!unsafe_es3_apis_enabled())
8743 return error::kUnknownCommand;
8744 const gles2::cmds::GetFragDataLocation& c =
8745 *static_cast<const gles2::cmds::GetFragDataLocation*>(cmd_data);
8746 Bucket* bucket = GetBucket(c.name_bucket_id);
8747 if (!bucket) {
8748 return error::kInvalidArguments;
8749 }
8750 std::string name_str;
8751 if (!bucket->GetAsString(&name_str)) {
8752 return error::kInvalidArguments;
8753 }
8754 return GetFragDataLocationHelper(
8755 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8756}
8757
zmo4a16ff992015-02-05 22:18:418758error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex(
8759 uint32 immediate_data_size, const void* cmd_data) {
8760 if (!unsafe_es3_apis_enabled())
8761 return error::kUnknownCommand;
8762 const gles2::cmds::GetUniformBlockIndex& c =
8763 *static_cast<const gles2::cmds::GetUniformBlockIndex*>(cmd_data);
8764 Bucket* bucket = GetBucket(c.name_bucket_id);
8765 if (!bucket) {
8766 return error::kInvalidArguments;
8767 }
8768 std::string name_str;
8769 if (!bucket->GetAsString(&name_str)) {
8770 return error::kInvalidArguments;
8771 }
8772 GLuint* index = GetSharedMemoryAs<GLuint*>(
8773 c.index_shm_id, c.index_shm_offset, sizeof(GLuint));
8774 if (!index) {
8775 return error::kOutOfBounds;
8776 }
8777 // Require the client to init this in case the context is lost and we are no
8778 // longer executing commands.
8779 if (*index != GL_INVALID_INDEX) {
8780 return error::kGenericError;
8781 }
8782 Program* program = GetProgramInfoNotShader(
8783 c.program, "glGetUniformBlockIndex");
8784 if (!program) {
8785 return error::kNoError;
8786 }
8787 *index = glGetUniformBlockIndex(program->service_id(), name_str.c_str());
8788 return error::kNoError;
8789}
8790
vmiuracd108592014-09-08 14:36:348791error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
8792 const void* cmd_data) {
8793 const gles2::cmds::GetString& c =
8794 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:298795 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:058796 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:518797 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:298798 return error::kNoError;
8799 }
kbrc9f0e10c2015-03-31 19:49:128800
8801 const char* str = nullptr;
[email protected]f0d74742011-10-03 16:31:048802 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:158803 switch (name) {
8804 case GL_VERSION:
zmo539d22c2015-06-09 04:14:198805 if (unsafe_es3_apis_enabled())
8806 str = "OpenGL ES 3.0 Chromium";
8807 else
8808 str = "OpenGL ES 2.0 Chromium";
[email protected]1958e0e2010-04-22 05:17:158809 break;
8810 case GL_SHADING_LANGUAGE_VERSION:
zmo539d22c2015-06-09 04:14:198811 if (unsafe_es3_apis_enabled())
8812 str = "OpenGL ES GLSL ES 3.0 Chromium";
8813 else
8814 str = "OpenGL ES GLSL ES 1.0 Chromium";
[email protected]1958e0e2010-04-22 05:17:158815 break;
[email protected]32939602012-05-09 06:25:168816 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:168817 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:388818 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
8819 // They are used by WEBGL_debug_renderer_info.
zmo539d22c2015-06-09 04:14:198820 if (!IsWebGLContext())
[email protected]959e9072013-09-20 16:58:388821 str = "Chromium";
kbrc9f0e10c2015-03-31 19:49:128822 else
8823 str = reinterpret_cast<const char*>(glGetString(name));
[email protected]32939602012-05-09 06:25:168824 break;
[email protected]1958e0e2010-04-22 05:17:158825 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:048826 {
[email protected]70dc60932013-06-04 03:33:498827 // For WebGL contexts, strip out the OES derivatives and
8828 // EXT frag depth extensions if they have not been enabled.
zmo539d22c2015-06-09 04:14:198829 if (IsWebGLContext()) {
[email protected]f0d74742011-10-03 16:31:048830 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:498831 if (!derivatives_explicitly_enabled_) {
8832 size_t offset = extensions.find(kOESDerivativeExtension);
8833 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098834 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:498835 std::string());
8836 }
8837 }
8838 if (!frag_depth_explicitly_enabled_) {
8839 size_t offset = extensions.find(kEXTFragDepthExtension);
8840 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098841 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:498842 std::string());
8843 }
[email protected]f0d74742011-10-03 16:31:048844 }
[email protected]aff39ac82013-06-08 04:53:138845 if (!draw_buffers_explicitly_enabled_) {
8846 size_t offset = extensions.find(kEXTDrawBuffersExtension);
8847 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098848 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:138849 std::string());
8850 }
8851 }
[email protected]93c2fd82014-04-16 02:46:068852 if (!shader_texture_lod_explicitly_enabled_) {
8853 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
8854 if (std::string::npos != offset) {
8855 extensions.replace(offset,
8856 arraysize(kEXTShaderTextureLodExtension),
8857 std::string());
8858 }
8859 }
[email protected]f0d74742011-10-03 16:31:048860 } else {
[email protected]6f5fac9d12012-06-26 21:02:458861 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:048862 }
[email protected]b381ee32014-03-22 02:43:438863 if (supports_post_sub_buffer_)
8864 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:458865 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:048866 }
[email protected]1958e0e2010-04-22 05:17:158867 break;
8868 default:
kbrc9f0e10c2015-03-31 19:49:128869 str = reinterpret_cast<const char*>(glGetString(name));
[email protected]1958e0e2010-04-22 05:17:158870 break;
8871 }
[email protected]ddd968b82010-03-02 00:44:298872 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:158873 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:298874 return error::kNoError;
8875}
8876
vmiuracd108592014-09-08 14:36:348877error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
8878 const void* cmd_data) {
8879 const gles2::cmds::BufferData& c =
8880 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:118881 GLenum target = static_cast<GLenum>(c.target);
8882 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
8883 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8884 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8885 GLenum usage = static_cast<GLenum>(c.usage);
8886 const void* data = NULL;
8887 if (data_shm_id != 0 || data_shm_offset != 0) {
8888 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
8889 if (!data) {
8890 return error::kOutOfBounds;
8891 }
8892 }
[email protected]0fbba3732013-07-17 15:40:138893 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:148894 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198895}
8896
[email protected]0c86dbf2010-03-05 08:14:118897void GLES2DecoderImpl::DoBufferSubData(
8898 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:138899 // Just delegate it. Some validation is actually done before this.
8900 buffer_manager()->ValidateAndDoBufferSubData(
8901 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:198902}
8903
reveman7c4a13b2015-06-05 22:28:158904bool GLES2DecoderImpl::ClearLevel(Texture* texture,
8905 unsigned target,
8906 int level,
8907 unsigned format,
8908 unsigned type,
8909 int xoffset,
8910 int yoffset,
8911 int width,
8912 int height) {
[email protected]81375742012-06-08 00:04:008913 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:008914 if (feature_info_->feature_flags().angle_depth_texture &&
8915 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:008916 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
8917 // on depth formats.
8918 GLuint fb = 0;
8919 glGenFramebuffersEXT(1, &fb);
8920 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
8921
8922 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
8923 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
8924 GL_DEPTH_ATTACHMENT;
8925
boliu45dc77a2015-02-25 23:26:318926 glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, attachment, target,
8927 texture->service_id(), level);
[email protected]81375742012-06-08 00:04:008928 // ANGLE promises a depth only attachment ok.
8929 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8930 GL_FRAMEBUFFER_COMPLETE) {
8931 return false;
8932 }
8933 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:478934 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8935 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008936 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458937 state_.SetDeviceDepthMask(GL_TRUE);
reveman7c4a13b2015-06-05 22:28:158938 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
8939 glScissor(xoffset, yoffset, width, height);
[email protected]81375742012-06-08 00:04:008940 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8941
8942 RestoreClearState();
8943
8944 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358945 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008946 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8947 GLuint fb_service_id =
8948 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8949 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8950 return true;
8951 }
8952
[email protected]45d15a62012-04-18 14:33:178953 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8954
8955 uint32 size;
8956 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348957 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428958 width, height, 1, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178959 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208960 return false;
8961 }
[email protected]45d15a62012-04-18 14:33:178962
[email protected]a5d3dad2012-05-26 04:34:448963 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8964
[email protected]45d15a62012-04-18 14:33:178965 int tile_height;
8966
8967 if (size > kMaxZeroSize) {
8968 if (kMaxZeroSize < padded_row_size) {
8969 // That'd be an awfully large texture.
8970 return false;
8971 }
8972 // We should never have a large total size with a zero row size.
8973 DCHECK_GT(padded_row_size, 0U);
8974 tile_height = kMaxZeroSize / padded_row_size;
8975 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428976 width, tile_height, 1, format, type, state_.unpack_alignment, &size,
[email protected]e259eb412012-10-13 05:47:248977 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178978 return false;
8979 }
[email protected]4502e6492011-12-14 19:39:158980 } else {
[email protected]45d15a62012-04-18 14:33:178981 tile_height = height;
8982 }
8983
8984 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558985 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178986 memset(zero.get(), 0, size);
boliu45dc77a2015-02-25 23:26:318987 glBindTexture(texture->target(), texture->service_id());
[email protected]45d15a62012-04-18 14:33:178988
8989 GLint y = 0;
8990 while (y < height) {
8991 GLint h = y + tile_height > height ? height - y : tile_height;
reveman7c4a13b2015-06-05 22:28:158992 glTexSubImage2D(target, level, xoffset, yoffset + y, width, h, format, type,
8993 zero.get());
[email protected]45d15a62012-04-18 14:33:178994 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158995 }
boliu45dc77a2015-02-25 23:26:318996 TextureRef* bound_texture =
8997 texture_manager()->GetTextureInfoForTarget(&state_, texture->target());
8998 glBindTexture(texture->target(),
8999 bound_texture ? bound_texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:209000 return true;
9001}
9002
[email protected]ad84a3a2012-06-08 21:42:439003namespace {
9004
9005const int kS3TCBlockWidth = 4;
9006const int kS3TCBlockHeight = 4;
9007const int kS3TCDXT1BlockSize = 8;
9008const int kS3TCDXT3AndDXT5BlockSize = 16;
zmoea06a6f2015-04-30 01:15:469009const int kEACAndETC2BlockSize = 4;
[email protected]ad84a3a2012-06-08 21:42:439010
9011bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:519012 return (size == 1) ||
9013 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:439014}
9015
[email protected]8aec81ec2014-04-29 01:04:519016bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:129017 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:519018}
9019
[email protected]ad84a3a2012-06-08 21:42:439020} // anonymous namespace.
9021
christiank83120092015-06-17 11:40:109022bool GLES2DecoderImpl::GetCompressedTexSizeInBytes(
zmoea06a6f2015-04-30 01:15:469023 const char* function_name, GLsizei width, GLsizei height, GLsizei depth,
christiank83120092015-06-17 11:40:109024 GLenum format, GLsizei* size_in_bytes) {
zmoea06a6f2015-04-30 01:15:469025 base::CheckedNumeric<GLsizei> bytes_required(0);
[email protected]ad84a3a2012-06-08 21:42:439026
9027 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:519028 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:439029 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:519030 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
zmoea06a6f2015-04-30 01:15:469031 case GL_ETC1_RGB8_OES:
9032 bytes_required =
9033 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
9034 bytes_required *=
9035 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
9036 bytes_required *= kS3TCDXT1BlockSize;
9037 break;
[email protected]8aec81ec2014-04-29 01:04:519038 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
9039 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:439040 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
zmoea06a6f2015-04-30 01:15:469041 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
9042 bytes_required =
9043 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
9044 bytes_required *=
9045 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
9046 bytes_required *= kS3TCDXT3AndDXT5BlockSize;
9047 break;
[email protected]8aec81ec2014-04-29 01:04:519048 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
zmoea06a6f2015-04-30 01:15:469049 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
9050 bytes_required = std::max(width, 8);
9051 bytes_required *= std::max(height, 8);
9052 bytes_required *= 4;
9053 bytes_required += 7;
9054 bytes_required /= 8;
9055 break;
[email protected]8aec81ec2014-04-29 01:04:519056 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
zmoea06a6f2015-04-30 01:15:469057 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
9058 bytes_required = std::max(width, 16);
9059 bytes_required *= std::max(height, 8);
9060 bytes_required *= 2;
9061 bytes_required += 7;
9062 bytes_required /= 8;
9063 break;
9064
9065 // ES3 formats.
9066 case GL_COMPRESSED_R11_EAC:
9067 case GL_COMPRESSED_SIGNED_R11_EAC:
9068 case GL_COMPRESSED_RGB8_ETC2:
9069 case GL_COMPRESSED_SRGB8_ETC2:
9070 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
9071 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
9072 bytes_required =
9073 (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
9074 bytes_required *=
9075 (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
9076 bytes_required *= 8;
9077 bytes_required *= depth;
9078 break;
9079 case GL_COMPRESSED_RG11_EAC:
9080 case GL_COMPRESSED_SIGNED_RG11_EAC:
9081 case GL_COMPRESSED_RGBA8_ETC2_EAC:
9082 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
9083 bytes_required =
9084 (width + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
9085 bytes_required *=
9086 (height + kEACAndETC2BlockSize - 1) / kEACAndETC2BlockSize;
9087 bytes_required *= 16;
9088 bytes_required *= depth;
9089 break;
[email protected]ad84a3a2012-06-08 21:42:439090 default:
[email protected]ab09b612013-03-11 22:11:519091 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:439092 return false;
9093 }
9094
christiank83120092015-06-17 11:40:109095 if (!bytes_required.IsValid()) {
9096 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid size");
9097 return false;
9098 }
9099
9100 *size_in_bytes = bytes_required.ValueOrDefault(0);
9101 return true;
9102}
9103
9104bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
9105 const char* function_name, GLsizei width, GLsizei height, GLsizei depth,
9106 GLenum format, GLsizei size) {
9107 GLsizei bytes_required = 0;
9108 if (!GetCompressedTexSizeInBytes(
9109 function_name, width, height, depth, format, &bytes_required)) {
9110 return false;
9111 }
9112
9113 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:519114 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439115 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
9116 return false;
9117 }
9118
9119 return true;
9120}
9121
9122bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
zmoea06a6f2015-04-30 01:15:469123 const char* function_name, GLenum target, GLint level,
9124 GLsizei width, GLsizei height, GLsizei depth, GLenum format) {
[email protected]ad84a3a2012-06-08 21:42:439125 switch (format) {
9126 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
9127 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
9128 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
zmoea06a6f2015-04-30 01:15:469129 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
9130 DCHECK_EQ(1, depth); // 2D formats.
[email protected]ad84a3a2012-06-08 21:42:439131 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:519132 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439133 GL_INVALID_OPERATION, function_name,
9134 "width or height invalid for level");
9135 return false;
9136 }
9137 return true;
[email protected]8aec81ec2014-04-29 01:04:519138 case GL_ATC_RGB_AMD:
9139 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
9140 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
zmoea06a6f2015-04-30 01:15:469141 case GL_ETC1_RGB8_OES:
9142 DCHECK_EQ(1, depth); // 2D formats.
[email protected]2d3765b2012-10-03 00:31:079143 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:519144 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:079145 GL_INVALID_OPERATION, function_name,
9146 "width or height invalid for level");
9147 return false;
9148 }
9149 return true;
[email protected]8aec81ec2014-04-29 01:04:519150 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
9151 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
9152 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
zmoea06a6f2015-04-30 01:15:469153 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
9154 DCHECK_EQ(1, depth); // 2D formats.
[email protected]8aec81ec2014-04-29 01:04:519155 if (!IsValidPVRTCSize(level, width) ||
9156 !IsValidPVRTCSize(level, height)) {
9157 LOCAL_SET_GL_ERROR(
9158 GL_INVALID_OPERATION, function_name,
9159 "width or height invalid for level");
9160 return false;
9161 }
9162 return true;
zmoea06a6f2015-04-30 01:15:469163
9164 // ES3 formats.
9165 case GL_COMPRESSED_R11_EAC:
9166 case GL_COMPRESSED_SIGNED_R11_EAC:
9167 case GL_COMPRESSED_RG11_EAC:
9168 case GL_COMPRESSED_SIGNED_RG11_EAC:
9169 case GL_COMPRESSED_RGB8_ETC2:
9170 case GL_COMPRESSED_SRGB8_ETC2:
9171 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
9172 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
9173 case GL_COMPRESSED_RGBA8_ETC2_EAC:
9174 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
9175 if (width <= 0 || height <= 0 || depth <= 0) {
9176 LOCAL_SET_GL_ERROR(
9177 GL_INVALID_OPERATION, function_name,
9178 "width, height, or depth invalid");
9179 return false;
9180 }
bajones69efbed2015-05-08 19:40:209181 if (target == GL_TEXTURE_3D) {
zmoea06a6f2015-04-30 01:15:469182 LOCAL_SET_GL_ERROR(
9183 GL_INVALID_OPERATION, function_name,
9184 "target invalid for format");
9185 return false;
9186 }
9187 return true;
[email protected]ad84a3a2012-06-08 21:42:439188 default:
9189 return false;
9190 }
9191}
9192
9193bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
9194 const char* function_name,
zmo9a7b17e2015-05-06 00:22:339195 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
9196 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:359197 Texture* texture) {
zmo9a7b17e2015-05-06 00:22:339198 if (xoffset < 0 || yoffset < 0 || zoffset < 0) {
[email protected]ab09b612013-03-11 22:11:519199 LOCAL_SET_GL_ERROR(
zmo9a7b17e2015-05-06 00:22:339200 GL_INVALID_VALUE, function_name, "x/y/z offset < 0");
[email protected]ad84a3a2012-06-08 21:42:439201 return false;
9202 }
9203
9204 switch (format) {
9205 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
9206 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
9207 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
9208 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
9209 const int kBlockWidth = 4;
9210 const int kBlockHeight = 4;
9211 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:519212 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439213 GL_INVALID_OPERATION, function_name,
9214 "xoffset or yoffset not multiple of 4");
9215 return false;
9216 }
9217 GLsizei tex_width = 0;
9218 GLsizei tex_height = 0;
zmo9a7b17e2015-05-06 00:22:339219 if (!texture->GetLevelSize(target, level,
9220 &tex_width, &tex_height, nullptr) ||
[email protected]ad84a3a2012-06-08 21:42:439221 width - xoffset > tex_width ||
9222 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:519223 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439224 GL_INVALID_OPERATION, function_name, "dimensions out of range");
9225 return false;
9226 }
9227 return ValidateCompressedTexDimensions(
zmoea06a6f2015-04-30 01:15:469228 function_name, target, level, width, height, 1, format);
[email protected]ad84a3a2012-06-08 21:42:439229 }
[email protected]8aec81ec2014-04-29 01:04:519230 case GL_ATC_RGB_AMD:
9231 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
9232 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
9233 LOCAL_SET_GL_ERROR(
9234 GL_INVALID_OPERATION, function_name,
9235 "not supported for ATC textures");
9236 return false;
9237 }
[email protected]2d3765b2012-10-03 00:31:079238 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:519239 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:079240 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:209241 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:079242 return false;
9243 }
[email protected]8aec81ec2014-04-29 01:04:519244 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
9245 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
9246 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
9247 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
9248 if ((xoffset != 0) || (yoffset != 0)) {
9249 LOCAL_SET_GL_ERROR(
9250 GL_INVALID_OPERATION, function_name,
9251 "xoffset and yoffset must be zero");
9252 return false;
9253 }
9254 GLsizei tex_width = 0;
9255 GLsizei tex_height = 0;
zmo9a7b17e2015-05-06 00:22:339256 if (!texture->GetLevelSize(target, level,
9257 &tex_width, &tex_height, nullptr) ||
[email protected]8aec81ec2014-04-29 01:04:519258 width != tex_width ||
9259 height != tex_height) {
9260 LOCAL_SET_GL_ERROR(
9261 GL_INVALID_OPERATION, function_name,
9262 "dimensions must match existing texture level dimensions");
9263 return false;
9264 }
9265 return ValidateCompressedTexDimensions(
zmoea06a6f2015-04-30 01:15:469266 function_name, target, level, width, height, 1, format);
[email protected]8aec81ec2014-04-29 01:04:519267 }
zmo9a7b17e2015-05-06 00:22:339268
9269 // ES3 formats
9270 case GL_COMPRESSED_R11_EAC:
9271 case GL_COMPRESSED_SIGNED_R11_EAC:
9272 case GL_COMPRESSED_RG11_EAC:
9273 case GL_COMPRESSED_SIGNED_RG11_EAC:
9274 case GL_COMPRESSED_RGB8_ETC2:
9275 case GL_COMPRESSED_SRGB8_ETC2:
9276 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
9277 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
9278 case GL_COMPRESSED_RGBA8_ETC2_EAC:
9279 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
9280 {
9281 const int kBlockSize = 4;
9282 GLsizei tex_width, tex_height;
bajones69efbed2015-05-08 19:40:209283 if (target == GL_TEXTURE_3D ||
zmo9a7b17e2015-05-06 00:22:339284 !texture->GetLevelSize(target, level,
9285 &tex_width, &tex_height, nullptr) ||
9286 (xoffset % kBlockSize) || (yoffset % kBlockSize) ||
9287 ((width % kBlockSize) && xoffset + width != tex_width) ||
9288 ((height % kBlockSize) && yoffset + height != tex_height)) {
9289 LOCAL_SET_GL_ERROR(
9290 GL_INVALID_OPERATION, function_name,
9291 "dimensions must match existing texture level dimensions");
9292 return false;
9293 }
9294 return true;
9295 }
[email protected]ad84a3a2012-06-08 21:42:439296 default:
9297 return false;
9298 }
9299}
9300
[email protected]a93bb842010-02-16 23:03:479301error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
9302 GLenum target,
9303 GLint level,
9304 GLenum internal_format,
9305 GLsizei width,
9306 GLsizei height,
9307 GLint border,
9308 GLsizei image_size,
9309 const void* data) {
[email protected]9438b012010-06-15 22:55:059310 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:519311 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9312 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:299313 return error::kNoError;
9314 }
[email protected]9438b012010-06-15 22:55:059315 if (!validators_->compressed_texture_format.IsValid(
9316 internal_format)) {
[email protected]ab09b612013-03-11 22:11:519317 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539318 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:479319 return error::kNoError;
9320 }
[email protected]80eb6b52012-01-19 00:14:419321 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:479322 border != 0) {
[email protected]ab09b612013-03-11 22:11:519323 LOCAL_SET_GL_ERROR(
9324 GL_INVALID_VALUE,
9325 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:479326 return error::kNoError;
9327 }
[email protected]c986af502013-08-14 01:04:449328 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9329 &state_, target);
[email protected]370eaf12013-05-18 09:19:499330 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519331 LOCAL_SET_GL_ERROR(
9332 GL_INVALID_VALUE,
9333 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:479334 return error::kNoError;
9335 }
[email protected]370eaf12013-05-18 09:19:499336 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079337 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519338 LOCAL_SET_GL_ERROR(
9339 GL_INVALID_OPERATION,
9340 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:439341 return error::kNoError;
9342 }
9343
zmoea06a6f2015-04-30 01:15:469344 if (!ValidateCompressedTexDimensions("glCompressedTexImage2D", target, level,
9345 width, height, 1, internal_format) ||
9346 !ValidateCompressedTexFuncData("glCompressedTexImage2D", width, height,
9347 1, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:179348 return error::kNoError;
9349 }
[email protected]968351b2011-12-20 08:26:519350
[email protected]7989c9e2013-01-23 06:39:269351 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:519352 LOCAL_SET_GL_ERROR(
9353 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:269354 return error::kNoError;
9355 }
9356
[email protected]02965c22013-03-09 02:40:079357 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:449358 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:519359 }
9360
[email protected]40d90a22013-04-09 03:39:559361 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:479362 if (!data) {
9363 zero.reset(new int8[image_size]);
9364 memset(zero.get(), 0, image_size);
9365 data = zero.get();
9366 }
[email protected]ab09b612013-03-11 22:11:519367 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:479368 glCompressedTexImage2D(
9369 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:519370 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:439371 if (error == GL_NO_ERROR) {
reveman7c4a13b2015-06-05 22:28:159372 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format,
9373 width, height, 1, border, 0, 0,
9374 gfx::Rect(width, height));
[email protected]cadde4a2010-07-31 17:10:439375 }
vmiura8266ca72014-09-09 21:37:009376
9377 // This may be a slow command. Exit command processing to allow for
9378 // context preemption and GPU watchdog checks.
9379 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:479380 return error::kNoError;
9381}
9382
[email protected]f7a64ee2010-02-01 22:24:149383error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:349384 uint32 immediate_data_size,
9385 const void* cmd_data) {
9386 const gles2::cmds::CompressedTexImage2D& c =
9387 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:199388 GLenum target = static_cast<GLenum>(c.target);
9389 GLint level = static_cast<GLint>(c.level);
9390 GLenum internal_format = static_cast<GLenum>(c.internalformat);
9391 GLsizei width = static_cast<GLsizei>(c.width);
9392 GLsizei height = static_cast<GLsizei>(c.height);
9393 GLint border = static_cast<GLint>(c.border);
9394 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
9395 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
9396 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
9397 const void* data = NULL;
9398 if (data_shm_id != 0 || data_shm_offset != 0) {
9399 data = GetSharedMemoryAs<const void*>(
9400 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:469401 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:149402 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:199403 }
9404 }
[email protected]a93bb842010-02-16 23:03:479405 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:199406 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:199407}
9408
[email protected]b6140d02010-05-17 14:47:169409error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:349410 uint32 immediate_data_size,
9411 const void* cmd_data) {
9412 const gles2::cmds::CompressedTexImage2DBucket& c =
9413 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:169414 GLenum target = static_cast<GLenum>(c.target);
9415 GLint level = static_cast<GLint>(c.level);
9416 GLenum internal_format = static_cast<GLenum>(c.internalformat);
9417 GLsizei width = static_cast<GLsizei>(c.width);
9418 GLsizei height = static_cast<GLsizei>(c.height);
9419 GLint border = static_cast<GLint>(c.border);
9420 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289421 if (!bucket) {
9422 return error::kInvalidArguments;
9423 }
9424 uint32 data_size = bucket->size();
9425 GLsizei imageSize = data_size;
9426 const void* data = bucket->GetData(0, data_size);
9427 if (!data) {
9428 return error::kInvalidArguments;
9429 }
[email protected]b6140d02010-05-17 14:47:169430 return DoCompressedTexImage2D(
9431 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:289432 imageSize, data);
[email protected]b6140d02010-05-17 14:47:169433}
9434
9435error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
9436 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:349437 const void* cmd_data) {
9438 const gles2::cmds::CompressedTexSubImage2DBucket& c =
9439 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:169440 GLenum target = static_cast<GLenum>(c.target);
9441 GLint level = static_cast<GLint>(c.level);
9442 GLint xoffset = static_cast<GLint>(c.xoffset);
9443 GLint yoffset = static_cast<GLint>(c.yoffset);
9444 GLsizei width = static_cast<GLsizei>(c.width);
9445 GLsizei height = static_cast<GLsizei>(c.height);
9446 GLenum format = static_cast<GLenum>(c.format);
9447 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289448 if (!bucket) {
9449 return error::kInvalidArguments;
9450 }
[email protected]b6140d02010-05-17 14:47:169451 uint32 data_size = bucket->size();
9452 GLsizei imageSize = data_size;
9453 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:289454 if (!data) {
9455 return error::kInvalidArguments;
9456 }
[email protected]9438b012010-06-15 22:55:059457 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:519458 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:539459 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:169460 return error::kNoError;
9461 }
[email protected]9438b012010-06-15 22:55:059462 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:519463 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9464 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:059465 return error::kNoError;
9466 }
[email protected]b6140d02010-05-17 14:47:169467 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:519468 LOCAL_SET_GL_ERROR(
9469 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:169470 return error::kNoError;
9471 }
9472 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:519473 LOCAL_SET_GL_ERROR(
9474 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:169475 return error::kNoError;
9476 }
9477 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:519478 LOCAL_SET_GL_ERROR(
9479 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:169480 return error::kNoError;
9481 }
[email protected]cadde4a2010-07-31 17:10:439482 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:169483 target, level, xoffset, yoffset, width, height, format, imageSize, data);
9484 return error::kNoError;
9485}
9486
zmoea06a6f2015-04-30 01:15:469487error::Error GLES2DecoderImpl::DoCompressedTexImage3D(
9488 GLenum target,
9489 GLint level,
9490 GLenum internal_format,
9491 GLsizei width,
9492 GLsizei height,
9493 GLsizei depth,
9494 GLint border,
9495 GLsizei image_size,
9496 const void* data) {
9497 if (!validators_->texture_3_d_target.IsValid(target)) {
9498 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9499 "glCompressedTexImage3D", target, "target");
9500 return error::kNoError;
9501 }
9502 if (!validators_->compressed_texture_format.IsValid(
9503 internal_format)) {
9504 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9505 "glCompressedTexImage3D", internal_format, "internal_format");
9506 return error::kNoError;
9507 }
9508 if (!texture_manager()->ValidForTarget(target, level, width, height, depth) ||
9509 border != 0) {
9510 LOCAL_SET_GL_ERROR(
9511 GL_INVALID_VALUE,
9512 "glCompressedTexImage3D", "dimensions out of range");
9513 return error::kNoError;
9514 }
9515 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9516 &state_, target);
9517 if (!texture_ref) {
9518 LOCAL_SET_GL_ERROR(
9519 GL_INVALID_VALUE,
9520 "glCompressedTexImage3D", "unknown texture target");
9521 return error::kNoError;
9522 }
9523 Texture* texture = texture_ref->texture();
9524 if (texture->IsImmutable()) {
9525 LOCAL_SET_GL_ERROR(
9526 GL_INVALID_OPERATION,
9527 "glCompressedTexImage3D", "texture is immutable");
9528 return error::kNoError;
9529 }
9530
9531 if (!ValidateCompressedTexDimensions("glCompressedTexImage3D", target, level,
9532 width, height, depth, internal_format) ||
9533 !ValidateCompressedTexFuncData("glCompressedTexImage3D", width, height,
9534 depth, internal_format, image_size)) {
9535 return error::kNoError;
9536 }
9537
9538 if (!EnsureGPUMemoryAvailable(image_size)) {
9539 LOCAL_SET_GL_ERROR(
9540 GL_OUT_OF_MEMORY, "glCompressedTexImage3D", "out of memory");
9541 return error::kNoError;
9542 }
9543
9544 if (texture->IsAttachedToFramebuffer()) {
9545 framebuffer_state_.clear_state_dirty = true;
9546 }
9547
9548 scoped_ptr<int8[]> zero;
9549 if (!data) {
9550 zero.reset(new int8[image_size]);
9551 memset(zero.get(), 0, image_size);
9552 data = zero.get();
9553 }
9554 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D");
9555 glCompressedTexImage3D(target, level, internal_format, width, height, depth,
9556 border, image_size, data);
9557 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D");
9558 if (error == GL_NO_ERROR) {
reveman7c4a13b2015-06-05 22:28:159559 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format,
9560 width, height, depth, border, 0, 0,
9561 gfx::Rect(width, height));
zmoea06a6f2015-04-30 01:15:469562 }
9563
9564 // This may be a slow command. Exit command processing to allow for
9565 // context preemption and GPU watchdog checks.
9566 ExitCommandProcessingEarly();
9567 return error::kNoError;
9568}
9569
9570error::Error GLES2DecoderImpl::HandleCompressedTexImage3D(
9571 uint32 immediate_data_size, const void* cmd_data) {
9572 if (!unsafe_es3_apis_enabled())
9573 return error::kUnknownCommand;
9574
9575 const gles2::cmds::CompressedTexImage3D& c =
9576 *static_cast<const gles2::cmds::CompressedTexImage3D*>(cmd_data);
9577 GLenum target = static_cast<GLenum>(c.target);
9578 GLint level = static_cast<GLint>(c.level);
9579 GLenum internal_format = static_cast<GLenum>(c.internalformat);
9580 GLsizei width = static_cast<GLsizei>(c.width);
9581 GLsizei height = static_cast<GLsizei>(c.height);
9582 GLsizei depth = static_cast<GLsizei>(c.depth);
9583 GLint border = static_cast<GLint>(c.border);
9584 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
9585 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
9586 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
9587 const void* data = NULL;
9588 if (data_shm_id != 0 || data_shm_offset != 0) {
9589 data = GetSharedMemoryAs<const void*>(
9590 data_shm_id, data_shm_offset, image_size);
9591 if (!data) {
9592 return error::kOutOfBounds;
9593 }
9594 }
9595 return DoCompressedTexImage3D(target, level, internal_format, width, height,
9596 depth, border, image_size, data);
9597}
9598
9599error::Error GLES2DecoderImpl::HandleCompressedTexImage3DBucket(
9600 uint32 immediate_data_size, const void* cmd_data) {
9601 if (!unsafe_es3_apis_enabled())
9602 return error::kUnknownCommand;
9603
9604 const gles2::cmds::CompressedTexImage3DBucket& c =
9605 *static_cast<const gles2::cmds::CompressedTexImage3DBucket*>(cmd_data);
9606 GLenum target = static_cast<GLenum>(c.target);
9607 GLint level = static_cast<GLint>(c.level);
9608 GLenum internal_format = static_cast<GLenum>(c.internalformat);
9609 GLsizei width = static_cast<GLsizei>(c.width);
9610 GLsizei height = static_cast<GLsizei>(c.height);
9611 GLsizei depth = static_cast<GLsizei>(c.depth);
9612 GLint border = static_cast<GLint>(c.border);
9613 Bucket* bucket = GetBucket(c.bucket_id);
9614 if (!bucket) {
9615 return error::kInvalidArguments;
9616 }
9617 uint32 data_size = bucket->size();
9618 GLsizei imageSize = data_size;
9619 const void* data = bucket->GetData(0, data_size);
9620 if (!data) {
9621 return error::kInvalidArguments;
9622 }
9623 return DoCompressedTexImage3D(target, level, internal_format, width, height,
9624 depth, border, imageSize, data);
9625}
9626
zmo9a7b17e2015-05-06 00:22:339627void GLES2DecoderImpl::DoCompressedTexSubImage3D(
9628 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
9629 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
9630 GLsizei image_size, const void* data) {
9631 if (!validators_->texture_3_d_target.IsValid(target)) {
9632 LOCAL_SET_GL_ERROR(
9633 GL_INVALID_ENUM, "glCompressedTexSubImage3D", "target");
9634 return;
9635 }
9636 if (!validators_->compressed_texture_format.IsValid(format)) {
9637 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9638 "glCompressedTexSubImage3D", format, "format");
9639 return;
9640 }
9641 if (width < 0 || height < 0 || depth < 0) {
9642 LOCAL_SET_GL_ERROR(
9643 GL_INVALID_VALUE, "glCompressedTexSubImage3D", "size < 0");
9644 return;
9645 }
9646 if (image_size < 0) {
9647 LOCAL_SET_GL_ERROR(
9648 GL_INVALID_VALUE, "glCompressedTexSubImage3D", "imageSize < 0");
9649 return;
9650 }
9651 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9652 &state_, target);
9653 if (!texture_ref) {
9654 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D",
9655 "unknown texture for target");
9656 return;
9657 }
9658 Texture* texture = texture_ref->texture();
9659 GLenum type = 0, internal_format = 0;
9660 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
9661 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D",
9662 "level does not exist");
9663 return;
9664 }
9665 if (internal_format != format) {
9666 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D",
9667 "format does not match internal format");
9668 return;
9669 }
9670 if (!texture->ValidForTexture(target, level, xoffset, yoffset, zoffset,
9671 width, height, depth, type)) {
9672 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedTexSubImage3D",
9673 "bad dimensions");
9674 return;
9675 }
9676 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage3D",
9677 width, height, depth, format,
9678 image_size) ||
9679 !ValidateCompressedTexSubDimensions("glCompressedTexSubImage3D",
9680 target, level, xoffset, yoffset,
9681 zoffset, width, height, depth,
9682 format, texture)) {
9683 return;
9684 }
9685
9686 // Note: There is no need to deal with texture cleared tracking here
9687 // because the validation above means you can only get here if the level
9688 // is already a matching compressed format and in that case
9689 // CompressedTexImage3D already cleared the texture.
9690 glCompressedTexSubImage3D(
9691 target, level, xoffset, yoffset, zoffset, width, height, depth, format,
9692 image_size, data);
9693
9694 // This may be a slow command. Exit command processing to allow for
9695 // context preemption and GPU watchdog checks.
9696 ExitCommandProcessingEarly();
9697}
9698
9699error::Error GLES2DecoderImpl::HandleCompressedTexSubImage3DBucket(
9700 uint32 immediate_data_size, const void* cmd_data) {
9701 if (!unsafe_es3_apis_enabled())
9702 return error::kUnknownCommand;
9703 const gles2::cmds::CompressedTexSubImage3DBucket& c =
9704 *static_cast<const gles2::cmds::CompressedTexSubImage3DBucket*>(cmd_data);
9705 GLenum target = static_cast<GLenum>(c.target);
9706 GLint level = static_cast<GLint>(c.level);
9707 GLint xoffset = static_cast<GLint>(c.xoffset);
9708 GLint yoffset = static_cast<GLint>(c.yoffset);
9709 GLint zoffset = static_cast<GLint>(c.zoffset);
9710 GLsizei width = static_cast<GLsizei>(c.width);
9711 GLsizei height = static_cast<GLsizei>(c.height);
9712 GLsizei depth = static_cast<GLsizei>(c.depth);
9713 GLenum format = static_cast<GLenum>(c.format);
9714 Bucket* bucket = GetBucket(c.bucket_id);
9715 if (!bucket) {
9716 return error::kInvalidArguments;
9717 }
9718 uint32 data_size = bucket->size();
9719 GLsizei image_size = data_size;
9720 const void* data = bucket->GetData(0, data_size);
9721 if (!data) {
9722 return error::kInvalidArguments;
9723 }
9724 DoCompressedTexSubImage3D(
9725 target, level, xoffset, yoffset, zoffset, width, height, depth, format,
9726 image_size, data);
9727 return error::kNoError;
9728}
9729
vmiuracd108592014-09-08 14:36:349730error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
9731 const void* cmd_data) {
9732 const gles2::cmds::TexImage2D& c =
9733 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139734 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
9735 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:449736 // Set as failed for now, but if it successed, this will be set to not failed.
zmo54f23712015-05-28 19:28:499737 texture_state_.tex_image_failed = true;
[email protected]b9849abf2009-11-25 19:13:199738 GLenum target = static_cast<GLenum>(c.target);
9739 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:449740 // TODO(kloveless): Change TexImage2D command to use unsigned integer
9741 // for internalformat.
9742 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:199743 GLsizei width = static_cast<GLsizei>(c.width);
9744 GLsizei height = static_cast<GLsizei>(c.height);
9745 GLint border = static_cast<GLint>(c.border);
9746 GLenum format = static_cast<GLenum>(c.format);
9747 GLenum type = static_cast<GLenum>(c.type);
9748 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
9749 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:189750 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:349751 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429752 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
9753 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:189754 return error::kOutOfBounds;
9755 }
[email protected]b9849abf2009-11-25 19:13:199756 const void* pixels = NULL;
9757 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
9758 pixels = GetSharedMemoryAs<const void*>(
9759 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:469760 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:149761 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:199762 }
9763 }
[email protected]f598f422012-12-07 08:30:039764
bajones6b0124f42015-04-07 23:14:429765 // For testing only. Allows us to stress the ability to respond to OOM errors.
9766 if (workarounds().simulate_out_of_memory_on_large_textures &&
9767 (width * height >= 4096 * 4096)) {
9768 LOCAL_SET_GL_ERROR(
9769 GL_OUT_OF_MEMORY,
9770 "glTexImage2D", "synthetic out of memory");
9771 return error::kNoError;
9772 }
9773
zmode7b4382015-05-21 21:23:009774 TextureManager::DoTexImageArguments args = {
9775 target, level, internal_format, width, height, 1, border, format, type,
zmo54f23712015-05-28 19:28:499776 pixels, pixels_size, TextureManager::DoTexImageArguments::kTexImage2D };
9777 texture_manager()->ValidateAndDoTexImage(
9778 &texture_state_, &state_, &framebuffer_state_, "glTexImage2D", args);
vmiura8266ca72014-09-09 21:37:009779
9780 // This may be a slow command. Exit command processing to allow for
9781 // context preemption and GPU watchdog checks.
9782 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039783 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:199784}
9785
zmobcadd6592015-01-08 20:13:429786error::Error GLES2DecoderImpl::HandleTexImage3D(uint32 immediate_data_size,
9787 const void* cmd_data) {
zmobcadd6592015-01-08 20:13:429788 if (!unsafe_es3_apis_enabled())
9789 return error::kUnknownCommand;
9790
9791 const gles2::cmds::TexImage3D& c =
9792 *static_cast<const gles2::cmds::TexImage3D*>(cmd_data);
9793 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage3D",
9794 "widthXheight", c.width * c.height, "depth", c.depth);
zmo54f23712015-05-28 19:28:499795 // Set as failed for now, but if it successed, this will be set to not failed.
9796 texture_state_.tex_image_failed = true;
zmobcadd6592015-01-08 20:13:429797 GLenum target = static_cast<GLenum>(c.target);
9798 GLint level = static_cast<GLint>(c.level);
9799 GLenum internal_format = static_cast<GLenum>(c.internalformat);
9800 GLsizei width = static_cast<GLsizei>(c.width);
9801 GLsizei height = static_cast<GLsizei>(c.height);
9802 GLsizei depth = static_cast<GLsizei>(c.depth);
9803 GLint border = static_cast<GLint>(c.border);
9804 GLenum format = static_cast<GLenum>(c.format);
9805 GLenum type = static_cast<GLenum>(c.type);
9806 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
9807 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
9808 uint32 pixels_size;
9809 if (!GLES2Util::ComputeImageDataSizes(
9810 width, height, depth, format, type, state_.unpack_alignment, &pixels_size,
9811 NULL, NULL)) {
9812 return error::kOutOfBounds;
9813 }
9814 const void* pixels = NULL;
9815 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
9816 pixels = GetSharedMemoryAs<const void*>(
9817 pixels_shm_id, pixels_shm_offset, pixels_size);
9818 if (!pixels) {
9819 return error::kOutOfBounds;
9820 }
9821 }
9822
zmo54f23712015-05-28 19:28:499823 // For testing only. Allows us to stress the ability to respond to OOM errors.
9824 if (workarounds().simulate_out_of_memory_on_large_textures &&
9825 (width * height * depth >= 4096 * 4096)) {
9826 LOCAL_SET_GL_ERROR(
9827 GL_OUT_OF_MEMORY,
9828 "glTexImage3D", "synthetic out of memory");
9829 return error::kNoError;
9830 }
9831
zmode7b4382015-05-21 21:23:009832 TextureManager::DoTexImageArguments args = {
9833 target, level, internal_format, width, height, depth, border, format, type,
zmo54f23712015-05-28 19:28:499834 pixels, pixels_size, TextureManager::DoTexImageArguments::kTexImage3D };
9835 texture_manager()->ValidateAndDoTexImage(
9836 &texture_state_, &state_, &framebuffer_state_, "glTexImage3D", args);
zmobcadd6592015-01-08 20:13:429837
9838 // This may be a slow command. Exit command processing to allow for
9839 // context preemption and GPU watchdog checks.
9840 ExitCommandProcessingEarly();
9841 return error::kNoError;
9842}
9843
[email protected]cadde4a2010-07-31 17:10:439844void GLES2DecoderImpl::DoCompressedTexSubImage2D(
9845 GLenum target,
9846 GLint level,
9847 GLint xoffset,
9848 GLint yoffset,
9849 GLsizei width,
9850 GLsizei height,
9851 GLenum format,
9852 GLsizei image_size,
9853 const void * data) {
[email protected]c986af502013-08-14 01:04:449854 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9855 &state_, target);
[email protected]370eaf12013-05-18 09:19:499856 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519857 LOCAL_SET_GL_ERROR(
9858 GL_INVALID_OPERATION,
9859 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439860 return;
9861 }
[email protected]370eaf12013-05-18 09:19:499862 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:439863 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:529864 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079865 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519866 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:529867 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439868 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:529869 return;
9870 }
9871 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:519872 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:529873 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439874 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:529875 return;
9876 }
zmo9a7b17e2015-05-06 00:22:339877 if (!texture->ValidForTexture(target, level, xoffset, yoffset, 0, width,
9878 height, 1, type)) {
[email protected]ab09b612013-03-11 22:11:519879 LOCAL_SET_GL_ERROR(
9880 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:439881 return;
9882 }
[email protected]ad84a3a2012-06-08 21:42:439883
zmoea06a6f2015-04-30 01:15:469884 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage2D",
9885 width, height, 1, format, image_size) ||
zmo9a7b17e2015-05-06 00:22:339886 !ValidateCompressedTexSubDimensions("glCompressedTexSubImage2D",
9887 target, level, xoffset, yoffset, 0,
9888 width, height, 1, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:439889 return;
9890 }
9891
9892
[email protected]0d6bfdc2011-11-02 01:32:209893 // Note: There is no need to deal with texture cleared tracking here
9894 // because the validation above means you can only get here if the level
9895 // is already a matching compressed format and in that case
9896 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:439897 glCompressedTexSubImage2D(
9898 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:009899
9900 // This may be a slow command. Exit command processing to allow for
9901 // context preemption and GPU watchdog checks.
9902 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439903}
9904
[email protected]6e288612010-12-21 20:45:039905static void Clip(
9906 GLint start, GLint range, GLint sourceRange,
9907 GLint* out_start, GLint* out_range) {
9908 DCHECK(out_start);
9909 DCHECK(out_range);
9910 if (start < 0) {
9911 range += start;
9912 start = 0;
9913 }
9914 GLint end = start + range;
9915 if (end > sourceRange) {
9916 range -= end - sourceRange;
9917 }
9918 *out_start = start;
9919 *out_range = range;
9920}
9921
[email protected]cadde4a2010-07-31 17:10:439922void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:449923 GLenum target,
9924 GLint level,
9925 GLenum internal_format,
9926 GLint x,
9927 GLint y,
9928 GLsizei width,
9929 GLsizei height,
9930 GLint border) {
[email protected]09e17272012-11-30 10:30:449931 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449932 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9933 &state_, target);
[email protected]370eaf12013-05-18 09:19:499934 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519935 LOCAL_SET_GL_ERROR(
9936 GL_INVALID_OPERATION,
9937 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439938 return;
9939 }
[email protected]370eaf12013-05-18 09:19:499940 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079941 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519942 LOCAL_SET_GL_ERROR(
9943 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:539944 return;
[email protected]97dc7cbe2011-12-06 17:26:179945 }
[email protected]80eb6b52012-01-19 00:14:419946 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:189947 border != 0) {
[email protected]ab09b612013-03-11 22:11:519948 LOCAL_SET_GL_ERROR(
9949 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:189950 return;
9951 }
[email protected]17a961192014-02-14 15:20:529952 if (!texture_manager()->ValidateFormatAndTypeCombination(
9953 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
9954 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:009955 return;
9956 }
[email protected]f5719fb2010-08-04 18:27:189957
[email protected]9edc6b22010-12-23 02:00:269958 // Check we have compatible formats.
9959 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9960 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9961 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
9962
9963 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519964 LOCAL_SET_GL_ERROR(
9965 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269966 return;
9967 }
9968
[email protected]81375742012-06-08 00:04:009969 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519970 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009971 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:269972 "glCopyTexImage2D", "can not be used with depth or stencil textures");
9973 return;
9974 }
9975
9976 uint32 estimated_size = 0;
9977 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429978 width, height, 1, internal_format, GL_UNSIGNED_BYTE,
9979 state_.unpack_alignment, &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519980 LOCAL_SET_GL_ERROR(
9981 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269982 return;
9983 }
9984
9985 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519986 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:009987 return;
9988 }
9989
[email protected]2ea5950d2014-07-09 18:20:349990 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
9991 return;
9992 }
9993
zmo383512cf2014-10-14 00:11:009994 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9995 LOCAL_SET_GL_ERROR(
9996 GL_INVALID_OPERATION,
9997 "glCopyTexImage2D", "source and destination textures are the same");
9998 return;
9999 }
10000
[email protected]a0b78dc2011-11-11 10:43:1010001 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
10002 return;
10003 }
10004
[email protected]ab09b612013-03-11 22:11:5110005 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:2710006 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:0310007 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:2610008
[email protected]02965c22013-03-09 02:40:0710009 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4410010 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:4610011 }
10012
[email protected]9edc6b22010-12-23 02:00:2610013 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:0310014 GLint copyX = 0;
10015 GLint copyY = 0;
10016 GLint copyWidth = 0;
10017 GLint copyHeight = 0;
10018 Clip(x, width, size.width(), &copyX, &copyWidth);
10019 Clip(y, height, size.height(), &copyY, &copyHeight);
10020
10021 if (copyX != x ||
10022 copyY != y ||
10023 copyWidth != width ||
10024 copyHeight != height) {
reveman7c4a13b2015-06-05 22:28:1510025 // some part was clipped so clear the rect.
10026 uint32 pixels_size = 0;
10027 if (!GLES2Util::ComputeImageDataSizes(
10028 width, height, 1, internal_format, GL_UNSIGNED_BYTE,
10029 state_.unpack_alignment, &pixels_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:5110030 LOCAL_SET_GL_ERROR(
10031 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:0310032 return;
10033 }
reveman7c4a13b2015-06-05 22:28:1510034 scoped_ptr<char[]> zero(new char[pixels_size]);
10035 memset(zero.get(), 0, pixels_size);
10036 ScopedModifyPixels modify(texture_ref);
10037 glTexImage2D(target, level, internal_format, width, height, border,
10038 internal_format, GL_UNSIGNED_BYTE, zero.get());
[email protected]6e288612010-12-21 20:45:0310039 if (copyHeight > 0 && copyWidth > 0) {
10040 GLint dx = copyX - x;
10041 GLint dy = copyY - y;
10042 GLint destX = dx;
10043 GLint destY = dy;
10044 glCopyTexSubImage2D(target, level,
10045 destX, destY, copyX, copyY,
10046 copyWidth, copyHeight);
10047 }
10048 } else {
[email protected]00c2cf92014-03-14 00:08:3710049 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:0310050 glCopyTexImage2D(target, level, internal_format,
10051 copyX, copyY, copyWidth, copyHeight, border);
10052 }
[email protected]ab09b612013-03-11 22:11:5110053 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:4310054 if (error == GL_NO_ERROR) {
reveman7c4a13b2015-06-05 22:28:1510055 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format,
10056 width, height, 1, border, internal_format,
10057 GL_UNSIGNED_BYTE, gfx::Rect(width, height));
[email protected]cadde4a2010-07-31 17:10:4310058 }
vmiura8266ca72014-09-09 21:37:0010059
10060 // This may be a slow command. Exit command processing to allow for
10061 // context preemption and GPU watchdog checks.
10062 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:4310063}
10064
10065void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:4410066 GLenum target,
10067 GLint level,
10068 GLint xoffset,
10069 GLint yoffset,
10070 GLint x,
10071 GLint y,
10072 GLsizei width,
10073 GLsizei height) {
[email protected]09e17272012-11-30 10:30:4410074 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:4410075 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10076 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910077 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110078 LOCAL_SET_GL_ERROR(
10079 GL_INVALID_OPERATION,
10080 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:4310081 return;
10082 }
[email protected]370eaf12013-05-18 09:19:4910083 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:4310084 GLenum type = 0;
10085 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:0710086 if (!texture->GetLevelType(target, level, &type, &format) ||
10087 !texture->ValidForTexture(
zmo9a7b17e2015-05-06 00:22:3310088 target, level, xoffset, yoffset, 0, width, height, 1, type)) {
[email protected]ab09b612013-03-11 22:11:5110089 LOCAL_SET_GL_ERROR(
10090 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:4310091 return;
10092 }
[email protected]85a4ac22013-05-31 01:58:4710093 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110094 LOCAL_SET_GL_ERROR(
10095 GL_INVALID_OPERATION,
10096 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:5910097 return;
10098 }
[email protected]9edc6b22010-12-23 02:00:2610099
10100 // Check we have compatible formats.
10101 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
10102 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
10103 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
10104
[email protected]2d3765b2012-10-03 00:31:0710105 if (!channels_needed ||
10106 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:5110107 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310108 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:2610109 return;
10110 }
10111
[email protected]81375742012-06-08 00:04:0010112 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:5110113 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:0010114 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310115 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:0010116 return;
10117 }
10118
[email protected]2ea5950d2014-07-09 18:20:3410119 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
10120 return;
10121 }
10122
zmo383512cf2014-10-14 00:11:0010123 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
10124 LOCAL_SET_GL_ERROR(
10125 GL_INVALID_OPERATION,
10126 "glCopyTexSubImage2D", "source and destination textures are the same");
10127 return;
10128 }
10129
[email protected]a0b78dc2011-11-11 10:43:1010130 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
10131 return;
10132 }
10133
[email protected]de26b3c2011-08-03 21:54:2710134 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:0310135 gfx::Size size = GetBoundReadFrameBufferSize();
10136 GLint copyX = 0;
10137 GLint copyY = 0;
10138 GLint copyWidth = 0;
10139 GLint copyHeight = 0;
10140 Clip(x, width, size.width(), &copyX, &copyWidth);
10141 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:2010142
dongseong.hwang351519f2015-01-21 14:33:5910143 if (xoffset != 0 || yoffset != 0 || width != size.width() ||
10144 height != size.height()) {
reveman7c4a13b2015-06-05 22:28:1510145 gfx::Rect cleared_rect;
10146 if (CombineAdjacentRects(texture->GetLevelClearedRect(target, level),
10147 gfx::Rect(xoffset, yoffset, width, height),
10148 &cleared_rect)) {
10149 DCHECK_GE(cleared_rect.size().GetArea(),
10150 texture->GetLevelClearedRect(target, level).size().GetArea());
10151 texture_manager()->SetLevelClearedRect(texture_ref, target, level,
10152 cleared_rect);
10153 } else {
10154 // Otherwise clear part of texture level that is not already cleared.
10155 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
10156 level)) {
10157 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D",
10158 "dimensions too big");
10159 return;
10160 }
dongseong.hwang351519f2015-01-21 14:33:5910161 }
10162 } else {
10163 // Write all pixels in below.
10164 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]0d6bfdc2011-11-02 01:32:2010165 }
10166
[email protected]6e288612010-12-21 20:45:0310167 if (copyX != x ||
10168 copyY != y ||
10169 copyWidth != width ||
10170 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:2010171 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:0310172 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:3410173 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4210174 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:2410175 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:5110176 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310177 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:0310178 return;
10179 }
[email protected]40d90a22013-04-09 03:39:5510180 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:0310181 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:3710182 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:0310183 glTexSubImage2D(
10184 target, level, xoffset, yoffset, width, height,
10185 format, type, zero.get());
10186 }
[email protected]0d6bfdc2011-11-02 01:32:2010187
[email protected]6e288612010-12-21 20:45:0310188 if (copyHeight > 0 && copyWidth > 0) {
10189 GLint dx = copyX - x;
10190 GLint dy = copyY - y;
10191 GLint destX = xoffset + dx;
10192 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:3710193 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:0310194 glCopyTexSubImage2D(target, level,
10195 destX, destY, copyX, copyY,
10196 copyWidth, copyHeight);
10197 }
vmiura8266ca72014-09-09 21:37:0010198
10199 // This may be a slow command. Exit command processing to allow for
10200 // context preemption and GPU watchdog checks.
10201 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:4310202}
10203
[email protected]f598f422012-12-07 08:30:0310204bool GLES2DecoderImpl::ValidateTexSubImage2D(
10205 error::Error* error,
10206 const char* function_name,
10207 GLenum target,
10208 GLint level,
10209 GLint xoffset,
10210 GLint yoffset,
10211 GLsizei width,
10212 GLsizei height,
10213 GLenum format,
10214 GLenum type,
10215 const void * data) {
10216 (*error) = error::kNoError;
10217 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:5110218 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:0310219 return false;
10220 }
10221 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:5110222 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:0310223 return false;
10224 }
10225 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:5110226 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:0310227 return false;
10228 }
[email protected]c986af502013-08-14 01:04:4410229 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10230 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910231 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110232 LOCAL_SET_GL_ERROR(
10233 GL_INVALID_OPERATION,
10234 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:0310235 return false;
[email protected]cadde4a2010-07-31 17:10:4310236 }
[email protected]370eaf12013-05-18 09:19:4910237 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:5210238 GLenum current_type = 0;
10239 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:0710240 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:5110241 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:0310242 GL_INVALID_OPERATION, function_name, "level does not exist.");
10243 return false;
[email protected]df6cf1ad2011-01-29 01:20:5210244 }
[email protected]17a961192014-02-14 15:20:5210245 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
10246 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:0310247 return false;
[email protected]df6cf1ad2011-01-29 01:20:5210248 }
10249 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:5110250 LOCAL_SET_GL_ERROR(
10251 GL_INVALID_OPERATION,
10252 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:0310253 return false;
[email protected]df6cf1ad2011-01-29 01:20:5210254 }
[email protected]85a4ac22013-05-31 01:58:4710255 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110256 LOCAL_SET_GL_ERROR(
10257 GL_INVALID_OPERATION,
10258 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:5910259 return false;
10260 }
[email protected]02965c22013-03-09 02:40:0710261 if (!texture->ValidForTexture(
zmo9a7b17e2015-05-06 00:22:3310262 target, level, xoffset, yoffset, 0, width, height, 1, type)) {
[email protected]ab09b612013-03-11 22:11:5110263 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:0310264 return false;
[email protected]cadde4a2010-07-31 17:10:4310265 }
[email protected]81375742012-06-08 00:04:0010266 if ((GLES2Util::GetChannelsForFormat(format) &
10267 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:5110268 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:0010269 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:0310270 function_name, "can not supply data for depth or stencil textures");
10271 return false;
[email protected]81375742012-06-08 00:04:0010272 }
[email protected]f598f422012-12-07 08:30:0310273 if (data == NULL) {
10274 (*error) = error::kOutOfBounds;
10275 return false;
10276 }
10277 return true;
10278}
[email protected]81375742012-06-08 00:04:0010279
[email protected]f598f422012-12-07 08:30:0310280error::Error GLES2DecoderImpl::DoTexSubImage2D(
10281 GLenum target,
10282 GLint level,
10283 GLint xoffset,
10284 GLint yoffset,
10285 GLsizei width,
10286 GLsizei height,
10287 GLenum format,
10288 GLenum type,
10289 const void * data) {
10290 error::Error error = error::kNoError;
10291 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
10292 xoffset, yoffset, width, height, format, type, data)) {
10293 return error;
10294 }
[email protected]c986af502013-08-14 01:04:4410295 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10296 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910297 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:1510298 GLsizei tex_width = 0;
10299 GLsizei tex_height = 0;
zmo9a7b17e2015-05-06 00:22:3310300 bool ok = texture->GetLevelSize(
10301 target, level, &tex_width, &tex_height, nullptr);
[email protected]4502e6492011-12-14 19:39:1510302 DCHECK(ok);
10303 if (xoffset != 0 || yoffset != 0 ||
10304 width != tex_width || height != tex_height) {
reveman7c4a13b2015-06-05 22:28:1510305 gfx::Rect cleared_rect;
10306 if (CombineAdjacentRects(texture->GetLevelClearedRect(target, level),
10307 gfx::Rect(xoffset, yoffset, width, height),
10308 &cleared_rect)) {
10309 DCHECK_GE(cleared_rect.size().GetArea(),
10310 texture->GetLevelClearedRect(target, level).size().GetArea());
10311 texture_manager()->SetLevelClearedRect(texture_ref, target, level,
10312 cleared_rect);
10313 } else {
10314 // Otherwise clear part of texture level that is not already cleared.
10315 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
10316 level)) {
10317 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glTexSubImage2D",
10318 "dimensions too big");
10319 return error::kNoError;
10320 }
[email protected]473c01ccb2011-06-07 01:33:3010321 }
[email protected]c986af502013-08-14 01:04:4410322 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:1510323 glTexSubImage2D(
10324 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:0310325 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:2010326 }
[email protected]4502e6492011-12-14 19:39:1510327
zmo54f23712015-05-28 19:28:4910328 if (!texture_state_.texsubimage_faster_than_teximage &&
boliu45dc77a2015-02-25 23:26:3110329 !texture->IsImmutable() &&
10330 !texture->HasImages()) {
[email protected]c986af502013-08-14 01:04:4410331 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:2510332 GLenum internal_format;
10333 GLenum tex_type;
10334 texture->GetLevelType(target, level, &tex_type, &internal_format);
10335 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
10336 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:3810337 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:2510338 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:1510339 } else {
[email protected]c986af502013-08-14 01:04:4410340 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:1510341 glTexSubImage2D(
10342 target, level, xoffset, yoffset, width, height, format, type, data);
10343 }
[email protected]370eaf12013-05-18 09:19:4910344 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:0010345
10346 // This may be a slow command. Exit command processing to allow for
10347 // context preemption and GPU watchdog checks.
10348 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:0310349 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:4310350}
10351
vmiuracd108592014-09-08 14:36:3410352error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
10353 const void* cmd_data) {
10354 const gles2::cmds::TexSubImage2D& c =
10355 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:1310356 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
10357 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:0010358 GLboolean internal = static_cast<GLboolean>(c.internal);
zmo54f23712015-05-28 19:28:4910359 if (internal == GL_TRUE && texture_state_.tex_image_failed)
[email protected]b493ee622011-04-13 23:52:0010360 return error::kNoError;
10361
10362 GLenum target = static_cast<GLenum>(c.target);
10363 GLint level = static_cast<GLint>(c.level);
10364 GLint xoffset = static_cast<GLint>(c.xoffset);
10365 GLint yoffset = static_cast<GLint>(c.yoffset);
10366 GLsizei width = static_cast<GLsizei>(c.width);
10367 GLsizei height = static_cast<GLsizei>(c.height);
10368 GLenum format = static_cast<GLenum>(c.format);
10369 GLenum type = static_cast<GLenum>(c.type);
10370 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:3410371 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4210372 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]e259eb412012-10-13 05:47:2410373 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:0010374 return error::kOutOfBounds;
10375 }
10376 const void* pixels = GetSharedMemoryAs<const void*>(
10377 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:0310378 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:0010379 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:0010380}
10381
zmode7b4382015-05-21 21:23:0010382error::Error GLES2DecoderImpl::DoTexSubImage3D(
10383 GLenum target,
10384 GLint level,
10385 GLint xoffset,
10386 GLint yoffset,
10387 GLint zoffset,
10388 GLsizei width,
10389 GLsizei height,
10390 GLsizei depth,
10391 GLenum format,
10392 GLenum type,
10393 const void * data) {
10394 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10395 &state_, target);
10396 if (!texture_ref) {
10397 LOCAL_SET_GL_ERROR(
10398 GL_INVALID_ENUM, "glTexSubImage3D", "invalid target");
10399 }
10400
10401 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexSubImage3D");
10402 ScopedTextureUploadTimer timer(&texture_state_);
10403 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
10404 depth, format, type, data);
10405 GLenum error = LOCAL_PEEK_GL_ERROR("glTexSubImage3D");
10406 if (error == GL_NO_ERROR) {
10407 // TODO(zmo): This is not 100% correct because only part of the level
10408 // image is cleared.
10409 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
10410 }
10411
10412 // This may be a slow command. Exit command processing to allow for
10413 // context preemption and GPU watchdog checks.
10414 ExitCommandProcessingEarly();
10415 return error::kNoError;
10416}
10417
zmobcadd6592015-01-08 20:13:4210418error::Error GLES2DecoderImpl::HandleTexSubImage3D(uint32 immediate_data_size,
10419 const void* cmd_data) {
zmobcadd6592015-01-08 20:13:4210420 if (!unsafe_es3_apis_enabled())
10421 return error::kUnknownCommand;
10422
10423 const gles2::cmds::TexSubImage3D& c =
10424 *static_cast<const gles2::cmds::TexSubImage3D*>(cmd_data);
10425 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage3D",
10426 "widthXheight", c.width * c.height, "depth", c.depth);
zmo54f23712015-05-28 19:28:4910427 GLboolean internal = static_cast<GLboolean>(c.internal);
10428 if (internal == GL_TRUE && texture_state_.tex_image_failed)
10429 return error::kNoError;
10430
zmobcadd6592015-01-08 20:13:4210431 GLenum target = static_cast<GLenum>(c.target);
10432 GLint level = static_cast<GLint>(c.level);
10433 GLint xoffset = static_cast<GLint>(c.xoffset);
10434 GLint yoffset = static_cast<GLint>(c.yoffset);
10435 GLint zoffset = static_cast<GLint>(c.zoffset);
10436 GLsizei width = static_cast<GLsizei>(c.width);
10437 GLsizei height = static_cast<GLsizei>(c.height);
10438 GLsizei depth = static_cast<GLsizei>(c.depth);
10439 GLenum format = static_cast<GLenum>(c.format);
10440 GLenum type = static_cast<GLenum>(c.type);
10441 uint32 data_size;
10442 if (!GLES2Util::ComputeImageDataSizes(
10443 width, height, depth, format, type, state_.unpack_alignment, &data_size,
10444 NULL, NULL)) {
10445 return error::kOutOfBounds;
10446 }
10447 const void* pixels = GetSharedMemoryAs<const void*>(
10448 c.pixels_shm_id, c.pixels_shm_offset, data_size);
zmode7b4382015-05-21 21:23:0010449 return DoTexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
10450 height, depth, format, type, pixels);
zmobcadd6592015-01-08 20:13:4210451}
10452
[email protected]f7a64ee2010-02-01 22:24:1410453error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:3410454 uint32 immediate_data_size,
10455 const void* cmd_data) {
10456 const gles2::cmds::GetVertexAttribPointerv& c =
10457 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:3610458 GLuint index = static_cast<GLuint>(c.index);
10459 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:3510460 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:2510461 Result* result = GetSharedMemoryAs<Result*>(
10462 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:3610463 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:1410464 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:3610465 }
[email protected]07d0cc82010-02-17 04:51:4010466 // Check that the client initialized the result.
10467 if (result->size != 0) {
10468 return error::kInvalidArguments;
10469 }
[email protected]9438b012010-06-15 22:55:0510470 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:5110471 LOCAL_SET_GL_ERROR_INVALID_ENUM(
10472 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:1410473 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:3610474 }
[email protected]3916c97e2010-02-25 03:20:5010475 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:5110476 LOCAL_SET_GL_ERROR(
10477 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:1410478 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:3610479 }
[email protected]0bfd9882010-02-05 23:02:2510480 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:0810481 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:3510482 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:1410483 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:3210484}
10485
zmoc9ea7b82015-05-08 03:44:4410486template <class T>
vmiura181c74002015-03-20 01:32:5110487bool GLES2DecoderImpl::GetUniformSetup(GLuint program_id,
10488 GLint fake_location,
10489 uint32 shm_id,
10490 uint32 shm_offset,
10491 error::Error* error,
10492 GLint* real_location,
10493 GLuint* service_id,
zmoc9ea7b82015-05-08 03:44:4410494 SizedResult<T>** result_pointer,
vmiura181c74002015-03-20 01:32:5110495 GLenum* result_type,
10496 GLsizei* result_size) {
[email protected]939e7362010-05-13 20:49:1010497 DCHECK(error);
10498 DCHECK(service_id);
10499 DCHECK(result_pointer);
10500 DCHECK(result_type);
zmoc9ea7b82015-05-08 03:44:4410501 DCHECK(result_size);
[email protected]1b0a6752012-02-22 03:44:1210502 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:3710503 *error = error::kNoError;
10504 // Make sure we have enough room for the result on failure.
zmoc9ea7b82015-05-08 03:44:4410505 SizedResult<T>* result;
10506 result = GetSharedMemoryAs<SizedResult<T>*>(
10507 shm_id, shm_offset, SizedResult<T>::ComputeSize(0));
[email protected]0bfd9882010-02-05 23:02:2510508 if (!result) {
[email protected]f7b85372010-02-03 01:11:3710509 *error = error::kOutOfBounds;
10510 return false;
10511 }
[email protected]0bfd9882010-02-05 23:02:2510512 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:3710513 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:2510514 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:4210515 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
10516 if (!program) {
[email protected]ae51d192010-04-27 00:48:0310517 return false;
10518 }
[email protected]df37b9932013-03-08 05:21:4210519 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:3710520 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:5110521 LOCAL_SET_GL_ERROR(
10522 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:3710523 return false;
10524 }
[email protected]df37b9932013-03-08 05:21:4210525 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:3610526 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:3510527 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:4210528 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:1210529 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:3610530 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:3710531 // No such location.
[email protected]ab09b612013-03-11 22:11:5110532 LOCAL_SET_GL_ERROR(
10533 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:3710534 return false;
10535 }
[email protected]43c2f1f2011-03-25 18:35:3610536 GLenum type = uniform_info->type;
zmoc9ea7b82015-05-08 03:44:4410537 uint32 num_elements = GLES2Util::GetElementCountForUniformType(type);
10538 if (num_elements == 0) {
[email protected]ab09b612013-03-11 22:11:5110539 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:3710540 return false;
10541 }
zmoc9ea7b82015-05-08 03:44:4410542 result = GetSharedMemoryAs<SizedResult<T>*>(
10543 shm_id, shm_offset, SizedResult<T>::ComputeSize(num_elements));
[email protected]0bfd9882010-02-05 23:02:2510544 if (!result) {
[email protected]f7b85372010-02-03 01:11:3710545 *error = error::kOutOfBounds;
10546 return false;
10547 }
zmoc9ea7b82015-05-08 03:44:4410548 result->SetNumResults(num_elements);
10549 *result_size = num_elements * sizeof(T);
[email protected]939e7362010-05-13 20:49:1010550 *result_type = type;
[email protected]f7b85372010-02-03 01:11:3710551 return true;
10552}
10553
vmiuracd108592014-09-08 14:36:3410554error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
10555 const void* cmd_data) {
10556 const gles2::cmds::GetUniformiv& c =
10557 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:3710558 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:3310559 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:3710560 GLuint service_id;
[email protected]939e7362010-05-13 20:49:1010561 GLenum result_type;
vmiura181c74002015-03-20 01:32:5110562 GLsizei result_size;
[email protected]1b0a6752012-02-22 03:44:1210563 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:3710564 Error error;
zmoc9ea7b82015-05-08 03:44:4410565 cmds::GetUniformiv::Result* result;
10566 if (GetUniformSetup<GLint>(program, fake_location, c.params_shm_id,
10567 c.params_shm_offset, &error, &real_location,
10568 &service_id, &result, &result_type,
10569 &result_size)) {
[email protected]0bfd9882010-02-05 23:02:2510570 glGetUniformiv(
zmoc9ea7b82015-05-08 03:44:4410571 service_id, real_location, result->GetData());
10572 }
10573 return error;
10574}
10575
10576error::Error GLES2DecoderImpl::HandleGetUniformuiv(uint32 immediate_data_size,
10577 const void* cmd_data) {
10578 if (!unsafe_es3_apis_enabled())
10579 return error::kUnknownCommand;
10580
10581 const gles2::cmds::GetUniformuiv& c =
10582 *static_cast<const gles2::cmds::GetUniformuiv*>(cmd_data);
10583 GLuint program = c.program;
10584 GLint fake_location = c.location;
10585 GLuint service_id;
10586 GLenum result_type;
10587 GLsizei result_size;
10588 GLint real_location = -1;
10589 Error error;
10590 cmds::GetUniformuiv::Result* result;
10591 if (GetUniformSetup<GLuint>(program, fake_location, c.params_shm_id,
10592 c.params_shm_offset, &error, &real_location,
10593 &service_id, &result, &result_type,
10594 &result_size)) {
10595 glGetUniformuiv(
10596 service_id, real_location, result->GetData());
[email protected]f7b85372010-02-03 01:11:3710597 }
10598 return error;
[email protected]96449d2c2009-11-25 00:01:3210599}
10600
vmiuracd108592014-09-08 14:36:3410601error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
10602 const void* cmd_data) {
10603 const gles2::cmds::GetUniformfv& c =
10604 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:3710605 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:3310606 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:3710607 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:1210608 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:3710609 Error error;
zmoc9ea7b82015-05-08 03:44:4410610 cmds::GetUniformfv::Result* result;
[email protected]939e7362010-05-13 20:49:1010611 GLenum result_type;
vmiura181c74002015-03-20 01:32:5110612 GLsizei result_size;
zmoc9ea7b82015-05-08 03:44:4410613 if (GetUniformSetup<GLfloat>(program, fake_location, c.params_shm_id,
10614 c.params_shm_offset, &error, &real_location,
10615 &service_id, &result, &result_type,
10616 &result_size)) {
[email protected]939e7362010-05-13 20:49:1010617 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
10618 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
zmoc9ea7b82015-05-08 03:44:4410619 GLsizei num_values = result_size / sizeof(GLfloat);
[email protected]40d90a22013-04-09 03:39:5510620 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:1210621 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:1010622 GLfloat* dst = result->GetData();
10623 for (GLsizei ii = 0; ii < num_values; ++ii) {
10624 dst[ii] = (temp[ii] != 0);
10625 }
10626 } else {
[email protected]1b0a6752012-02-22 03:44:1210627 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:1010628 }
[email protected]f7b85372010-02-03 01:11:3710629 }
10630 return error;
[email protected]96449d2c2009-11-25 00:01:3210631}
10632
[email protected]f7a64ee2010-02-01 22:24:1410633error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:3410634 uint32 immediate_data_size,
10635 const void* cmd_data) {
10636 const gles2::cmds::GetShaderPrecisionFormat& c =
10637 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:2510638 GLenum shader_type = static_cast<GLenum>(c.shadertype);
10639 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:3510640 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:2510641 Result* result = GetSharedMemoryAs<Result*>(
10642 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10643 if (!result) {
10644 return error::kOutOfBounds;
10645 }
[email protected]07d0cc82010-02-17 04:51:4010646 // Check that the client initialized the result.
10647 if (result->success != 0) {
10648 return error::kInvalidArguments;
10649 }
[email protected]9438b012010-06-15 22:55:0510650 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:5110651 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:5310652 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:2910653 return error::kNoError;
10654 }
[email protected]9438b012010-06-15 22:55:0510655 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:5110656 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:5310657 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:2910658 return error::kNoError;
10659 }
10660
10661 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:4010662
[email protected]46c86752013-05-21 05:08:3910663 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:4010664 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:2110665 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:4010666
10667 result->min_range = range[0];
10668 result->max_range = range[1];
10669 result->precision = precision;
10670
[email protected]f7a64ee2010-02-01 22:24:1410671 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:3210672}
10673
[email protected]f7a64ee2010-02-01 22:24:1410674error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:3410675 uint32 immediate_data_size,
10676 const void* cmd_data) {
10677 const gles2::cmds::GetAttachedShaders& c =
10678 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:2510679 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:4210680 GLuint program_id = static_cast<GLuint>(c.program);
10681 Program* program = GetProgramInfoNotShader(
10682 program_id, "glGetAttachedShaders");
10683 if (!program) {
[email protected]0bfd9882010-02-05 23:02:2510684 return error::kNoError;
10685 }
[email protected]ed9f9cd2013-02-27 21:12:3510686 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:2510687 uint32 max_count = Result::ComputeMaxResults(result_size);
10688 Result* result = GetSharedMemoryAs<Result*>(
10689 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
10690 if (!result) {
10691 return error::kOutOfBounds;
10692 }
[email protected]07d0cc82010-02-17 04:51:4010693 // Check that the client initialized the result.
10694 if (result->size != 0) {
10695 return error::kInvalidArguments;
10696 }
[email protected]0bfd9882010-02-05 23:02:2510697 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:0310698 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:4210699 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:2510700 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:0310701 if (!shader_manager()->GetClientId(result->GetData()[ii],
10702 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:2510703 NOTREACHED();
10704 return error::kGenericError;
10705 }
10706 }
10707 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:1410708 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:3210709}
10710
[email protected]f7a64ee2010-02-01 22:24:1410711error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:3410712 uint32 immediate_data_size,
10713 const void* cmd_data) {
10714 const gles2::cmds::GetActiveUniform& c =
10715 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:4210716 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:2510717 GLuint index = c.index;
10718 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:3510719 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:2510720 Result* result = GetSharedMemoryAs<Result*>(
10721 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10722 if (!result) {
10723 return error::kOutOfBounds;
10724 }
[email protected]07d0cc82010-02-17 04:51:4010725 // Check that the client initialized the result.
10726 if (result->success != 0) {
10727 return error::kInvalidArguments;
10728 }
[email protected]df37b9932013-03-08 05:21:4210729 Program* program = GetProgramInfoNotShader(
10730 program_id, "glGetActiveUniform");
10731 if (!program) {
[email protected]0bfd9882010-02-05 23:02:2510732 return error::kNoError;
10733 }
[email protected]ed9f9cd2013-02-27 21:12:3510734 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:4210735 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:2510736 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:5110737 LOCAL_SET_GL_ERROR(
10738 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:2510739 return error::kNoError;
10740 }
10741 result->success = 1; // true.
10742 result->size = uniform_info->size;
10743 result->type = uniform_info->type;
10744 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:2910745 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:1410746 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:3210747}
10748
zmoa2b555d2015-02-06 23:50:3910749error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockiv(
10750 uint32 immediate_data_size, const void* cmd_data) {
10751 if (!unsafe_es3_apis_enabled())
10752 return error::kUnknownCommand;
10753 const gles2::cmds::GetActiveUniformBlockiv& c =
10754 *static_cast<const gles2::cmds::GetActiveUniformBlockiv*>(cmd_data);
10755 GLuint program_id = c.program;
10756 GLuint index = static_cast<GLuint>(c.index);
10757 GLenum pname = static_cast<GLenum>(c.pname);
10758 Program* program = GetProgramInfoNotShader(
zmo8fab00c2015-02-07 02:45:0510759 program_id, "glGetActiveUniformBlockiv");
zmoa2b555d2015-02-06 23:50:3910760 if (!program) {
10761 return error::kNoError;
10762 }
10763 GLuint service_id = program->service_id();
10764 GLint link_status = GL_FALSE;
10765 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10766 if (link_status != GL_TRUE) {
10767 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10768 "glGetActiveActiveUniformBlockiv", "program not linked");
10769 return error::kNoError;
10770 }
10771 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformBlockiv");
10772 GLsizei num_values = 1;
10773 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
10774 GLint num = 0;
10775 glGetActiveUniformBlockiv(
10776 service_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &num);
10777 GLenum error = glGetError();
10778 if (error != GL_NO_ERROR) {
10779 // Assume this will the same error if calling with pname.
10780 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
10781 return error::kNoError;
10782 }
10783 num_values = static_cast<GLsizei>(num);
10784 }
10785 typedef cmds::GetActiveUniformBlockiv::Result Result;
10786 Result* result = GetSharedMemoryAs<Result*>(
10787 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
10788 GLint* params = result ? result->GetData() : NULL;
10789 if (params == NULL) {
10790 return error::kOutOfBounds;
10791 }
10792 // Check that the client initialized the result.
10793 if (result->size != 0) {
10794 return error::kInvalidArguments;
10795 }
10796 glGetActiveUniformBlockiv(service_id, index, pname, params);
10797 GLenum error = glGetError();
10798 if (error == GL_NO_ERROR) {
10799 result->SetNumResults(num_values);
10800 } else {
10801 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
10802 }
10803 return error::kNoError;
10804}
10805
zmo4a16ff992015-02-05 22:18:4110806error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockName(
10807 uint32 immediate_data_size, const void* cmd_data) {
10808 if (!unsafe_es3_apis_enabled())
10809 return error::kUnknownCommand;
10810 const gles2::cmds::GetActiveUniformBlockName& c =
10811 *static_cast<const gles2::cmds::GetActiveUniformBlockName*>(cmd_data);
10812 GLuint program_id = c.program;
10813 GLuint index = c.index;
10814 uint32 name_bucket_id = c.name_bucket_id;
10815 typedef cmds::GetActiveUniformBlockName::Result Result;
10816 Result* result = GetSharedMemoryAs<Result*>(
10817 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10818 if (!result) {
10819 return error::kOutOfBounds;
10820 }
10821 // Check that the client initialized the result.
10822 if (*result != 0) {
10823 return error::kInvalidArguments;
10824 }
10825 Program* program = GetProgramInfoNotShader(
10826 program_id, "glGetActiveUniformBlockName");
10827 if (!program) {
10828 return error::kNoError;
10829 }
10830 GLuint service_id = program->service_id();
10831 GLint link_status = GL_FALSE;
10832 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10833 if (link_status != GL_TRUE) {
10834 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10835 "glGetActiveActiveUniformBlockName", "program not linked");
10836 return error::kNoError;
10837 }
10838 GLint max_length = 0;
10839 glGetProgramiv(
10840 service_id, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_length);
10841 // Increase one so &buffer[0] is always valid.
10842 GLsizei buf_size = static_cast<GLsizei>(max_length) + 1;
10843 std::vector<char> buffer(buf_size);
10844 GLsizei length = 0;
10845 glGetActiveUniformBlockName(
10846 service_id, index, buf_size, &length, &buffer[0]);
10847 if (length == 0) {
10848 *result = 0;
10849 return error::kNoError;
10850 }
10851 *result = 1;
10852 Bucket* bucket = CreateBucket(name_bucket_id);
10853 DCHECK_GT(buf_size, length);
10854 DCHECK_EQ(0, buffer[length]);
10855 bucket->SetFromString(&buffer[0]);
10856 return error::kNoError;
10857}
10858
zmoc7e7e13f2015-02-17 22:07:0710859error::Error GLES2DecoderImpl::HandleGetActiveUniformsiv(
10860 uint32 immediate_data_size, const void* cmd_data) {
10861 if (!unsafe_es3_apis_enabled())
10862 return error::kUnknownCommand;
10863 const gles2::cmds::GetActiveUniformsiv& c =
10864 *static_cast<const gles2::cmds::GetActiveUniformsiv*>(cmd_data);
10865 GLuint program_id = c.program;
10866 GLenum pname = static_cast<GLenum>(c.pname);
10867 Bucket* bucket = GetBucket(c.indices_bucket_id);
10868 if (!bucket) {
10869 return error::kInvalidArguments;
10870 }
10871 GLsizei count = static_cast<GLsizei>(bucket->size() / sizeof(GLuint));
10872 const GLuint* indices = bucket->GetDataAs<const GLuint*>(0, bucket->size());
10873 typedef cmds::GetActiveUniformsiv::Result Result;
10874 Result* result = GetSharedMemoryAs<Result*>(
10875 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(count));
10876 GLint* params = result ? result->GetData() : NULL;
10877 if (params == NULL) {
10878 return error::kOutOfBounds;
10879 }
10880 // Check that the client initialized the result.
10881 if (result->size != 0) {
10882 return error::kInvalidArguments;
10883 }
10884 Program* program = GetProgramInfoNotShader(
10885 program_id, "glGetActiveUniformsiv");
10886 if (!program) {
10887 return error::kNoError;
10888 }
10889 GLuint service_id = program->service_id();
10890 GLint link_status = GL_FALSE;
10891 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10892 if (link_status != GL_TRUE) {
10893 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10894 "glGetActiveUniformsiv", "program not linked");
10895 return error::kNoError;
10896 }
10897 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformsiv");
10898 glGetActiveUniformsiv(service_id, count, indices, pname, params);
10899 GLenum error = glGetError();
10900 if (error == GL_NO_ERROR) {
10901 result->SetNumResults(count);
10902 } else {
10903 LOCAL_SET_GL_ERROR(error, "GetActiveUniformsiv", "");
10904 }
10905 return error::kNoError;
10906}
10907
vmiuracd108592014-09-08 14:36:3410908error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
10909 const void* cmd_data) {
10910 const gles2::cmds::GetActiveAttrib& c =
10911 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:4210912 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:2510913 GLuint index = c.index;
10914 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:3510915 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:2510916 Result* result = GetSharedMemoryAs<Result*>(
10917 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10918 if (!result) {
10919 return error::kOutOfBounds;
10920 }
[email protected]07d0cc82010-02-17 04:51:4010921 // Check that the client initialized the result.
10922 if (result->success != 0) {
10923 return error::kInvalidArguments;
10924 }
[email protected]df37b9932013-03-08 05:21:4210925 Program* program = GetProgramInfoNotShader(
10926 program_id, "glGetActiveAttrib");
10927 if (!program) {
[email protected]0bfd9882010-02-05 23:02:2510928 return error::kNoError;
10929 }
[email protected]ed9f9cd2013-02-27 21:12:3510930 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:4210931 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:2510932 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:5110933 LOCAL_SET_GL_ERROR(
10934 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:2510935 return error::kNoError;
10936 }
10937 result->success = 1; // true.
10938 result->size = attrib_info->size;
10939 result->type = attrib_info->type;
10940 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:2910941 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:1410942 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:3210943}
10944
vmiuracd108592014-09-08 14:36:3410945error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
10946 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:5810947#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:5110948 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:5810949 return error::kNoError;
10950#else
10951 GLsizei n = static_cast<GLsizei>(c.n);
10952 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:5110953 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:5810954 return error::kNoError;
10955 }
10956 GLsizei length = static_cast<GLsizei>(c.length);
10957 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:5110958 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:5810959 return error::kNoError;
10960 }
10961 uint32 data_size;
10962 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
10963 return error::kOutOfBounds;
10964 }
10965 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
10966 c.shaders_shm_id, c.shaders_shm_offset, data_size);
10967 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
10968 const void* binary = GetSharedMemoryAs<const void*>(
10969 c.binary_shm_id, c.binary_shm_offset, length);
10970 if (shaders == NULL || binary == NULL) {
10971 return error::kOutOfBounds;
10972 }
[email protected]0782b14b2014-05-24 13:04:1610973 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:5810974 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:4210975 Shader* shader = GetShader(shaders[ii]);
10976 if (!shader) {
[email protected]ab09b612013-03-11 22:11:5110977 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:5810978 return error::kNoError;
10979 }
[email protected]df37b9932013-03-08 05:21:4210980 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:5810981 }
10982 // TODO(gman): call glShaderBinary
10983 return error::kNoError;
10984#endif
10985}
10986
[email protected]6d792ee12013-05-15 00:40:5610987void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:4910988 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:0810989
[email protected]64ace852011-05-19 21:49:4910990 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:4210991 // TRACE_EVENT for gpu tests:
10992 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:4210993 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:4210994 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
10995 "width", (is_offscreen ? offscreen_size_.width() :
10996 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:5610997 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:4910998 "offscreen", is_offscreen,
10999 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:1511000 {
[email protected]a36ed4832014-04-24 16:40:2711001 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:1511002 }
11003
dyenb547eff62015-01-17 00:14:5611004 ScopedGPUTrace scoped_gpu_trace(gpu_tracer_.get(), kTraceDecoder,
11005 "gpu_toplevel", "SwapBuffer");
11006
[email protected]8f9b8dd2013-09-12 18:05:1311007 bool is_tracing;
11008 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
11009 &is_tracing);
11010 if (is_tracing) {
11011 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
11012 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
11013 is_offscreen ? offscreen_size_ : surface_->GetSize());
11014 }
11015
[email protected]6217d392010-03-25 22:08:3511016 // If offscreen then don't actually SwapBuffers to the display. Just copy
11017 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:4911018 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:3111019 TRACE_EVENT2("gpu", "Offscreen",
11020 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:5311021 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
11022 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
11023 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
11024 // fix this.
[email protected]62e155e2012-10-23 22:43:1511025 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:5311026 offscreen_saved_frame_buffer_->Create();
11027 glFinish();
11028 }
11029
11030 // Allocate the offscreen saved color texture.
11031 DCHECK(offscreen_saved_color_format_);
11032 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:0911033 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:5311034
11035 offscreen_saved_frame_buffer_->AttachRenderTexture(
11036 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:0511037 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
11038 if (offscreen_saved_frame_buffer_->CheckStatus() !=
11039 GL_FRAMEBUFFER_COMPLETE) {
11040 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
11041 << "because offscreen saved FBO was incomplete.";
sieversfbaa5dc2015-04-28 00:45:3111042 MarkContextLost(error::kUnknown);
11043 group_->LoseContexts(error::kUnknown);
[email protected]6d792ee12013-05-15 00:40:5611044 return;
[email protected]f0cfe752013-01-14 01:09:0511045 }
[email protected]1fb8c482011-08-31 01:01:5311046
[email protected]f0cfe752013-01-14 01:09:0511047 // Clear the offscreen color texture.
11048 // TODO(piman): Is this still necessary?
11049 {
11050 ScopedFrameBufferBinder binder(this,
11051 offscreen_saved_frame_buffer_->id());
11052 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:4511053 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
11054 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:0511055 glClear(GL_COLOR_BUFFER_BIT);
11056 RestoreClearState();
11057 }
[email protected]1fb8c482011-08-31 01:01:5311058 }
11059
11060 UpdateParentTextureInfo();
11061 }
11062
[email protected]f0cfe752013-01-14 01:09:0511063 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:5611064 return;
[email protected]ab09b612013-03-11 22:11:5111065 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011066 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:3511067
[email protected]34ff8b0c2010-10-01 20:06:0211068 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:1311069 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:2711070 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:4811071 } else {
[email protected]069944672012-04-25 20:52:2311072 ScopedFrameBufferBinder binder(this,
11073 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:1311074
[email protected]069944672012-04-25 20:52:2311075 if (offscreen_target_buffer_preserved_) {
11076 // Copy the target frame buffer to the saved offscreen texture.
11077 offscreen_saved_color_texture_->Copy(
11078 offscreen_saved_color_texture_->size(),
11079 offscreen_saved_color_format_);
11080 } else {
11081 // Flip the textures in the parent context via the texture manager.
11082 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:4911083 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:2311084 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:5611085
[email protected]069944672012-04-25 20:52:2311086 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
11087 offscreen_target_frame_buffer_->AttachRenderTexture(
11088 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:4811089 }
[email protected]069944672012-04-25 20:52:2311090
11091 // Ensure the side effects of the copy are visible to the parent
11092 // context. There is no need to do this for ANGLE because it uses a
11093 // single D3D device for all contexts.
marcheu1856f5d52015-04-04 01:42:5311094 if (!feature_info_->gl_version_info().is_angle)
[email protected]069944672012-04-25 20:52:2311095 glFlush();
[email protected]0c8c9d22010-06-25 17:36:3911096 }
[email protected]6217d392010-03-25 22:08:3511097 } else {
achaulkec8c2db2015-05-29 16:35:0311098 if (surface_->SwapBuffers() == gfx::SwapResult::SWAP_FAILED) {
[email protected]d0498742010-09-20 20:27:0111099 LOG(ERROR) << "Context lost because SwapBuffers failed.";
sieversfbaa5dc2015-04-28 00:45:3111100 if (!CheckResetStatus()) {
11101 MarkContextLost(error::kUnknown);
11102 group_->LoseContexts(error::kUnknown);
11103 }
[email protected]d0498742010-09-20 20:27:0111104 }
[email protected]6217d392010-03-25 22:08:3511105 }
vmiura8266ca72014-09-09 21:37:0011106
11107 // This may be a slow command. Exit command processing to allow for
11108 // context preemption and GPU watchdog checks.
11109 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:3511110}
11111
dcastagna504d45c2015-04-06 19:30:3911112void GLES2DecoderImpl::DoSwapInterval(int interval) {
bajones2345c1f2014-12-09 04:45:5111113 context_->SetSwapInterval(interval);
11114}
11115
[email protected]d4239852011-08-12 04:51:2211116error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:3411117 uint32 immediate_data_size,
11118 const void* cmd_data) {
11119 const gles2::cmds::EnableFeatureCHROMIUM& c =
11120 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:1811121 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2811122 if (!bucket || bucket->size() == 0) {
11123 return error::kInvalidArguments;
11124 }
[email protected]ed9f9cd2013-02-27 21:12:3511125 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:1811126 Result* result = GetSharedMemoryAs<Result*>(
11127 c.result_shm_id, c.result_shm_offset, sizeof(*result));
11128 if (!result) {
11129 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:1011130 }
[email protected]b1d2dcb2010-05-17 19:24:1811131 // Check that the client initialized the result.
11132 if (*result != 0) {
11133 return error::kInvalidArguments;
11134 }
11135 std::string feature_str;
11136 if (!bucket->GetAsString(&feature_str)) {
11137 return error::kInvalidArguments;
11138 }
11139
11140 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:2211141 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:1811142 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:2211143 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
penghuang0140c182015-01-12 23:20:1211144 buffer_manager()->set_allow_fixed_attribs(true);
[email protected]8fbedc02010-11-18 18:43:4011145 // TODO(gman): decide how to remove the need for this const_cast.
11146 // I could make validators_ non const but that seems bad as this is the only
11147 // place it is needed. I could make some special friend class of validators
11148 // just to allow this to set them. That seems silly. I could refactor this
11149 // code to use the extension mechanism or the initialization attributes to
11150 // turn this feature on. Given that the only real point of this is to make
11151 // the conformance tests pass and given that there is lots of real work that
11152 // needs to be done it seems like refactoring for one to one of those
11153 // methods is a very low priority.
11154 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]b1d2dcb2010-05-17 19:24:1811155 } else {
11156 return error::kNoError;
11157 }
11158
11159 *result = 1; // true.
11160 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:1011161}
11162
[email protected]c2f8c8402010-12-06 18:07:2411163error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
11164 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:3411165 const void* cmd_data) {
11166 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
11167 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
11168 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2411169 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:3511170 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:1911171 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:2411172 bucket->SetFromString(info->extensions().c_str());
11173 return error::kNoError;
11174}
11175
11176error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:3411177 uint32 immediate_data_size,
11178 const void* cmd_data) {
11179 const gles2::cmds::RequestExtensionCHROMIUM& c =
11180 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2411181 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2811182 if (!bucket || bucket->size() == 0) {
11183 return error::kInvalidArguments;
11184 }
[email protected]c2f8c8402010-12-06 18:07:2411185 std::string feature_str;
11186 if (!bucket->GetAsString(&feature_str)) {
11187 return error::kInvalidArguments;
11188 }
11189
[email protected]4b7eba92013-01-08 02:23:5611190 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:4911191 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:1311192 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:0611193 bool desire_shader_texture_lod = false;
zmo539d22c2015-06-09 04:14:1911194 if (IsWebGLContext()) {
[email protected]4b7eba92013-01-08 02:23:5611195 desire_standard_derivatives =
11196 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:4911197 desire_frag_depth =
11198 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:1311199 desire_draw_buffers =
11200 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:0611201 desire_shader_texture_lod =
11202 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:0411203 }
11204
zmo539d22c2015-06-09 04:14:1911205 if (desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:1311206 desire_frag_depth != frag_depth_explicitly_enabled_ ||
zmo539d22c2015-06-09 04:14:1911207 desire_draw_buffers != draw_buffers_explicitly_enabled_ ||
11208 desire_shader_texture_lod != shader_texture_lod_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:4911209 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
11210 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:1311211 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:0611212 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:2411213 InitializeShaderTranslator();
11214 }
11215
[email protected]302ce6d2011-07-07 23:28:1111216 UpdateCapabilities();
11217
[email protected]c2f8c8402010-12-06 18:07:2411218 return error::kNoError;
11219}
11220
[email protected]2318d342011-07-11 22:27:4211221error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:3411222 uint32 immediate_data_size,
11223 const void* cmd_data) {
11224 const gles2::cmds::GetProgramInfoCHROMIUM& c =
11225 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:4211226 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:4211227 uint32 bucket_id = c.bucket_id;
11228 Bucket* bucket = CreateBucket(bucket_id);
11229 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:4211230 Program* program = NULL;
11231 program = GetProgram(program_id);
11232 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:4611233 return error::kNoError;
[email protected]2318d342011-07-11 22:27:4211234 }
[email protected]df37b9932013-03-08 05:21:4211235 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:4211236 return error::kNoError;
11237}
11238
zmo4a16ff992015-02-05 22:18:4111239error::Error GLES2DecoderImpl::HandleGetUniformBlocksCHROMIUM(
11240 uint32 immediate_data_size, const void* cmd_data) {
11241 if (!unsafe_es3_apis_enabled())
11242 return error::kUnknownCommand;
11243 const gles2::cmds::GetUniformBlocksCHROMIUM& c =
11244 *static_cast<const gles2::cmds::GetUniformBlocksCHROMIUM*>(cmd_data);
11245 GLuint program_id = static_cast<GLuint>(c.program);
11246 uint32 bucket_id = c.bucket_id;
11247 Bucket* bucket = CreateBucket(bucket_id);
11248 bucket->SetSize(sizeof(UniformBlocksHeader)); // in case we fail.
11249 Program* program = NULL;
11250 program = GetProgram(program_id);
11251 if (!program || !program->IsValid()) {
11252 return error::kNoError;
11253 }
11254 program->GetUniformBlocks(bucket);
11255 return error::kNoError;
11256}
11257
zmoc7e7e13f2015-02-17 22:07:0711258error::Error GLES2DecoderImpl::HandleGetUniformsES3CHROMIUM(
11259 uint32 immediate_data_size, const void* cmd_data) {
11260 if (!unsafe_es3_apis_enabled())
11261 return error::kUnknownCommand;
11262 const gles2::cmds::GetUniformsES3CHROMIUM& c =
11263 *static_cast<const gles2::cmds::GetUniformsES3CHROMIUM*>(cmd_data);
11264 GLuint program_id = static_cast<GLuint>(c.program);
11265 uint32 bucket_id = c.bucket_id;
11266 Bucket* bucket = CreateBucket(bucket_id);
11267 bucket->SetSize(sizeof(UniformsES3Header)); // in case we fail.
11268 Program* program = NULL;
11269 program = GetProgram(program_id);
11270 if (!program || !program->IsValid()) {
11271 return error::kNoError;
11272 }
11273 program->GetUniformsES3(bucket);
11274 return error::kNoError;
11275}
11276
zmo10842492015-02-12 00:44:1611277error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVarying(
11278 uint32 immediate_data_size,
11279 const void* cmd_data) {
11280 if (!unsafe_es3_apis_enabled())
11281 return error::kUnknownCommand;
11282 const gles2::cmds::GetTransformFeedbackVarying& c =
11283 *static_cast<const gles2::cmds::GetTransformFeedbackVarying*>(cmd_data);
11284 GLuint program_id = c.program;
11285 GLuint index = c.index;
11286 uint32 name_bucket_id = c.name_bucket_id;
11287 typedef cmds::GetTransformFeedbackVarying::Result Result;
11288 Result* result = GetSharedMemoryAs<Result*>(
11289 c.result_shm_id, c.result_shm_offset, sizeof(*result));
11290 if (!result) {
11291 return error::kOutOfBounds;
11292 }
11293 // Check that the client initialized the result.
11294 if (result->success != 0) {
11295 return error::kInvalidArguments;
11296 }
11297 Program* program = GetProgramInfoNotShader(
11298 program_id, "glGetTransformFeedbackVarying");
11299 if (!program) {
11300 return error::kNoError;
11301 }
11302 GLuint service_id = program->service_id();
11303 GLint link_status = GL_FALSE;
11304 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
11305 if (link_status != GL_TRUE) {
11306 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11307 "glGetTransformFeedbackVarying", "program not linked");
11308 return error::kNoError;
11309 }
11310 GLint max_length = 0;
11311 glGetProgramiv(
11312 service_id, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_length);
11313 max_length = std::max(1, max_length);
11314 std::vector<char> buffer(max_length);
11315 GLsizei length = 0;
11316 GLsizei size = 0;
11317 GLenum type = 0;
11318 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetTransformFeedbackVarying");
11319 glGetTransformFeedbackVarying(
11320 service_id, index, max_length, &length, &size, &type, &buffer[0]);
11321 GLenum error = glGetError();
11322 if (error != GL_NO_ERROR) {
11323 LOCAL_SET_GL_ERROR(error, "glGetTransformFeedbackVarying", "");
11324 return error::kNoError;
11325 }
11326 result->success = 1; // true.
11327 result->size = static_cast<int32_t>(size);
11328 result->type = static_cast<uint32_t>(type);
11329 Bucket* bucket = CreateBucket(name_bucket_id);
11330 DCHECK(length >= 0 && length < max_length);
11331 buffer[length] = '\0'; // Just to be safe.
11332 bucket->SetFromString(&buffer[0]);
11333 return error::kNoError;
11334}
11335
11336error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVaryingsCHROMIUM(
11337 uint32 immediate_data_size, const void* cmd_data) {
11338 if (!unsafe_es3_apis_enabled())
11339 return error::kUnknownCommand;
11340 const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM& c =
11341 *static_cast<const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM*>(
11342 cmd_data);
11343 GLuint program_id = static_cast<GLuint>(c.program);
11344 uint32 bucket_id = c.bucket_id;
11345 Bucket* bucket = CreateBucket(bucket_id);
11346 bucket->SetSize(sizeof(TransformFeedbackVaryingsHeader)); // in case we fail.
11347 Program* program = NULL;
11348 program = GetProgram(program_id);
11349 if (!program || !program->IsValid()) {
11350 return error::kNoError;
11351 }
11352 program->GetTransformFeedbackVaryings(bucket);
11353 return error::kNoError;
11354}
11355
[email protected]38d139d2011-07-14 00:38:4311356error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
sieversfbaa5dc2015-04-28 00:45:3111357 return context_lost_reason_;
11358}
11359
11360error::ContextLostReason GLES2DecoderImpl::GetContextLostReasonFromResetStatus(
11361 GLenum reset_status) const {
11362 switch (reset_status) {
[email protected]ad84a3a2012-06-08 21:42:4311363 case GL_NO_ERROR:
11364 // TODO(kbr): improve the precision of the error code in this case.
11365 // Consider delegating to context for error code if MakeCurrent fails.
11366 return error::kUnknown;
11367 case GL_GUILTY_CONTEXT_RESET_ARB:
11368 return error::kGuilty;
11369 case GL_INNOCENT_CONTEXT_RESET_ARB:
11370 return error::kInnocent;
11371 case GL_UNKNOWN_CONTEXT_RESET_ARB:
11372 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:4311373 }
11374
11375 NOTREACHED();
11376 return error::kUnknown;
11377}
11378
sieversfbaa5dc2015-04-28 00:45:3111379bool GLES2DecoderImpl::WasContextLost() const {
11380 return context_was_lost_;
11381}
11382
11383bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() const {
11384 return WasContextLost() && reset_by_robustness_extension_;
11385}
11386
11387void GLES2DecoderImpl::MarkContextLost(error::ContextLostReason reason) {
11388 // Only lose the context once.
11389 if (WasContextLost())
11390 return;
11391
11392 // Don't make GL calls in here, the context might not be current.
11393 context_lost_reason_ = reason;
11394 current_decoder_error_ = error::kLostContext;
11395 context_was_lost_ = true;
jbauman7a059312014-10-16 19:30:5411396}
11397
sieversfbaa5dc2015-04-28 00:45:3111398bool GLES2DecoderImpl::CheckResetStatus() {
11399 DCHECK(!WasContextLost());
11400 DCHECK(context_->IsCurrent(NULL));
11401
dongseong.hwange1cb2aa2015-02-11 09:33:3311402 if (IsRobustnessSupported()) {
oetuaho37cc50e2014-10-31 11:19:2011403 // If the reason for the call was a GL error, we can try to determine the
11404 // reset status more accurately.
11405 GLenum driver_status = glGetGraphicsResetStatusARB();
sieversfbaa5dc2015-04-28 00:45:3111406 if (driver_status == GL_NO_ERROR)
11407 return false;
oetuaho37cc50e2014-10-31 11:19:2011408
sieversfbaa5dc2015-04-28 00:45:3111409 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
11410 << " context lost via ARB/EXT_robustness. Reset status = "
11411 << GLES2Util::GetStringEnum(driver_status);
11412
11413 // Don't pretend we know which client was responsible.
11414 if (workarounds().use_virtualized_gl_contexts)
11415 driver_status = GL_UNKNOWN_CONTEXT_RESET_ARB;
11416
11417 switch (driver_status) {
11418 case GL_GUILTY_CONTEXT_RESET_ARB:
11419 MarkContextLost(error::kGuilty);
11420 break;
11421 case GL_INNOCENT_CONTEXT_RESET_ARB:
11422 MarkContextLost(error::kInnocent);
11423 break;
11424 case GL_UNKNOWN_CONTEXT_RESET_ARB:
11425 MarkContextLost(error::kUnknown);
11426 break;
11427 default:
11428 NOTREACHED();
11429 return false;
11430 }
11431 reset_by_robustness_extension_ = true;
11432 return true;
11433 }
11434 return false;
[email protected]c4485aad62012-12-17 10:19:0911435}
11436
[email protected]b096d032013-03-08 03:08:0111437error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3411438 uint32 immediate_data_size,
11439 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:0111440 return error::kUnknownCommand;
11441}
11442
[email protected]840a7e462013-02-27 01:29:5111443error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3411444 uint32 immediate_data_size,
11445 const void* cmd_data) {
11446 const gles2::cmds::WaitSyncPointCHROMIUM& c =
11447 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
sievers173a20d2014-10-22 18:19:3211448 uint32 sync_point = c.sync_point;
[email protected]840a7e462013-02-27 01:29:5111449 if (wait_sync_point_callback_.is_null())
11450 return error::kNoError;
11451
sievers173a20d2014-10-22 18:19:3211452 return wait_sync_point_callback_.Run(sync_point) ?
[email protected]840a7e462013-02-27 01:29:5111453 error::kNoError : error::kDeferCommandUntilLater;
11454}
11455
[email protected]5dfc457b2013-12-13 11:13:0711456error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:3411457 uint32 immediate_data_size,
11458 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:0711459 if (surface_->DeferDraws())
11460 return error::kDeferCommandUntilLater;
11461 if (!surface_->SetBackbufferAllocation(false))
11462 return error::kLostContext;
11463 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
11464 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
11465 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
11466 return error::kNoError;
11467}
11468
[email protected]882ba1e22012-03-08 19:02:5311469bool GLES2DecoderImpl::GenQueriesEXTHelper(
11470 GLsizei n, const GLuint* client_ids) {
11471 for (GLsizei ii = 0; ii < n; ++ii) {
11472 if (query_manager_->GetQuery(client_ids[ii])) {
11473 return false;
11474 }
11475 }
[email protected]4eea7e62014-04-22 21:14:4311476 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:5311477 return true;
11478}
11479
11480void GLES2DecoderImpl::DeleteQueriesEXTHelper(
11481 GLsizei n, const GLuint* client_ids) {
11482 for (GLsizei ii = 0; ii < n; ++ii) {
11483 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
11484 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:1311485 ContextState::QueryMap::iterator it =
11486 state_.current_queries.find(query->target());
11487 if (it != state_.current_queries.end())
11488 state_.current_queries.erase(it);
11489
[email protected]c45f1972012-03-14 07:27:3611490 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:5311491 }
[email protected]4eea7e62014-04-22 21:14:4311492 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:5311493 }
11494}
11495
revemancc241eb2014-11-11 03:30:3711496bool GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
[email protected]22e3f552012-03-13 01:54:1911497 if (query_manager_.get() == NULL) {
11498 return false;
11499 }
revemancc241eb2014-11-11 03:30:3711500 if (!query_manager_->ProcessPendingQueries(did_finish)) {
[email protected]22e3f552012-03-13 01:54:1911501 current_decoder_error_ = error::kOutOfBounds;
11502 }
11503 return query_manager_->HavePendingQueries();
11504}
11505
[email protected]5a36dc132013-07-23 23:17:5511506// Note that if there are no pending readpixels right now,
11507// this function will call the callback immediately.
11508void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
11509 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
11510 pending_readpixel_fences_.back()->callbacks.push_back(callback);
11511 } else {
11512 callback.Run();
11513 }
11514}
11515
11516void GLES2DecoderImpl::ProcessPendingReadPixels() {
11517 while (!pending_readpixel_fences_.empty() &&
11518 pending_readpixel_fences_.front()->fence->HasCompleted()) {
11519 std::vector<base::Closure> callbacks =
11520 pending_readpixel_fences_.front()->callbacks;
11521 pending_readpixel_fences_.pop();
11522 for (size_t i = 0; i < callbacks.size(); i++) {
11523 callbacks[i].Run();
11524 }
11525 }
11526}
11527
[email protected]2b1767cf2013-03-16 09:25:0511528bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5511529 return !pending_readpixel_fences_.empty() ||
11530 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0511531}
11532
11533void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5511534 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:4811535 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:0511536 return;
[email protected]b68b100752013-06-05 08:34:4811537 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0511538 ProcessFinishedAsyncTransfers();
11539}
11540
vmiuracd108592014-09-08 14:36:3411541error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
11542 const void* cmd_data) {
11543 const gles2::cmds::BeginQueryEXT& c =
11544 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5311545 GLenum target = static_cast<GLenum>(c.target);
11546 GLuint client_id = static_cast<GLuint>(c.id);
11547 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
11548 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11549
[email protected]c45f1972012-03-14 07:27:3611550 switch (target) {
11551 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:5511552 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:3111553 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
11554 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:0011555 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:3611556 break;
[email protected]6a25ae422014-04-17 23:48:2711557 case GL_COMMANDS_COMPLETED_CHROMIUM:
11558 if (!features().chromium_sync_query) {
11559 LOCAL_SET_GL_ERROR(
11560 GL_INVALID_OPERATION, "glBeginQueryEXT",
11561 "not enabled for commands completed queries");
11562 return error::kNoError;
11563 }
11564 break;
[email protected]c45f1972012-03-14 07:27:3611565 default:
[email protected]62e155e2012-10-23 22:43:1511566 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:5111567 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:0011568 GL_INVALID_OPERATION, "glBeginQueryEXT",
11569 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:3611570 return error::kNoError;
11571 }
11572 break;
[email protected]882ba1e22012-03-08 19:02:5311573 }
11574
[email protected]8ebd46c2014-01-08 12:06:1311575 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5111576 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311577 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:5311578 return error::kNoError;
11579 }
11580
11581 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:5111582 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:5311583 return error::kNoError;
11584 }
11585
11586 QueryManager::Query* query = query_manager_->GetQuery(client_id);
11587 if (!query) {
[email protected]4eea7e62014-04-22 21:14:4311588 if (!query_manager_->IsValidQuery(client_id)) {
11589 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11590 "glBeginQueryEXT",
11591 "id not made by glGenQueriesEXT");
11592 return error::kNoError;
11593 }
[email protected]c45f1972012-03-14 07:27:3611594 query = query_manager_->CreateQuery(
11595 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:5311596 }
11597
[email protected]c45f1972012-03-14 07:27:3611598 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:5111599 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311600 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:5311601 return error::kNoError;
11602 } else if (query->shm_id() != sync_shm_id ||
11603 query->shm_offset() != sync_shm_offset) {
11604 DLOG(ERROR) << "Shared memory used by query not the same as before";
11605 return error::kInvalidArguments;
11606 }
11607
[email protected]c45f1972012-03-14 07:27:3611608 if (!query_manager_->BeginQuery(query)) {
11609 return error::kOutOfBounds;
11610 }
[email protected]882ba1e22012-03-08 19:02:5311611
[email protected]8ebd46c2014-01-08 12:06:1311612 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:5311613 return error::kNoError;
11614}
11615
vmiuracd108592014-09-08 14:36:3411616error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
11617 const void* cmd_data) {
11618 const gles2::cmds::EndQueryEXT& c =
11619 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5311620 GLenum target = static_cast<GLenum>(c.target);
11621 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:1311622 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:5311623
[email protected]8ebd46c2014-01-08 12:06:1311624 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5111625 LOCAL_SET_GL_ERROR(
11626 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:5311627 return error::kNoError;
11628 }
[email protected]882ba1e22012-03-08 19:02:5311629
[email protected]8ebd46c2014-01-08 12:06:1311630 QueryManager::Query* query = it->second.get();
11631 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:3611632 return error::kOutOfBounds;
11633 }
11634
[email protected]fe8d73c2013-02-16 22:37:3211635 query_manager_->ProcessPendingTransferQueries();
11636
[email protected]8ebd46c2014-01-08 12:06:1311637 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:5311638 return error::kNoError;
11639}
11640
[email protected]944b62f32012-09-27 02:20:4611641bool GLES2DecoderImpl::GenVertexArraysOESHelper(
11642 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4611643 for (GLsizei ii = 0; ii < n; ++ii) {
11644 if (GetVertexAttribManager(client_ids[ii])) {
11645 return false;
11646 }
11647 }
[email protected]ab4fd7282012-10-12 16:25:5711648
[email protected]62e155e2012-10-23 22:43:1511649 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5711650 // Emulated VAO
11651 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4811652 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:5711653 }
11654 } else {
[email protected]40d90a22013-04-09 03:39:5511655 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:5711656
11657 glGenVertexArraysOES(n, service_ids.get());
11658 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4811659 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:5711660 }
[email protected]944b62f32012-09-27 02:20:4611661 }
[email protected]ab4fd7282012-10-12 16:25:5711662
[email protected]944b62f32012-09-27 02:20:4611663 return true;
11664}
11665
11666void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
11667 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4611668 for (GLsizei ii = 0; ii < n; ++ii) {
11669 VertexAttribManager* vao =
11670 GetVertexAttribManager(client_ids[ii]);
11671 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:1111672 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:1111673 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:4611674 }
11675 RemoveVertexAttribManager(client_ids[ii]);
11676 }
11677 }
11678}
11679
11680void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4611681 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:4611682 if (client_id != 0) {
11683 vao = GetVertexAttribManager(client_id);
11684 if (!vao) {
11685 // Unlike most Bind* methods, the spec explicitly states that VertexArray
11686 // only allows names that have been previously generated. As such, we do
11687 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:5111688 LOCAL_SET_GL_ERROR(
11689 GL_INVALID_OPERATION,
11690 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:4611691 current_decoder_error_ = error::kNoError;
11692 return;
[email protected]944b62f32012-09-27 02:20:4611693 }
[email protected]944b62f32012-09-27 02:20:4611694 } else {
[email protected]81f20a622014-04-18 01:54:5211695 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4611696 }
11697
[email protected]ab4fd7282012-10-12 16:25:5711698 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1111699 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2411700 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1511701 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5711702 EmulateVertexArrayState();
11703 } else {
[email protected]da364812014-05-09 21:39:4811704 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5711705 glBindVertexArrayOES(service_id);
11706 }
11707 }
11708}
11709
11710// Used when OES_vertex_array_object isn't natively supported
11711void GLES2DecoderImpl::EmulateVertexArrayState() {
11712 // Setup the Vertex attribute state
11713 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2311714 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5711715 }
11716
11717 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2111718 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2411719 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5711720 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
11721 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4611722}
11723
11724bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4611725 const VertexAttribManager* vao =
11726 GetVertexAttribManager(client_id);
11727 return vao && vao->IsValid() && !vao->IsDeleted();
11728}
11729
[email protected]e51bdf32011-11-23 22:21:4611730#if defined(OS_MACOSX)
11731void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
11732 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
11733 texture_id);
11734 if (it != texture_to_io_surface_map_.end()) {
11735 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5311736 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4611737 CFRelease(surface);
11738 texture_to_io_surface_map_.erase(it);
11739 }
11740}
11741#endif
11742
11743void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
11744 GLenum target, GLsizei width, GLsizei height,
11745 GLuint io_surface_id, GLuint plane) {
11746#if defined(OS_MACOSX)
11747 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5111748 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311749 GL_INVALID_OPERATION,
11750 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4611751 return;
11752 }
11753
[email protected]e51bdf32011-11-23 22:21:4611754 if (target != GL_TEXTURE_RECTANGLE_ARB) {
11755 // This might be supported in the future, and if we could require
11756 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
11757 // could delete a lot of code. For now, perform strict validation so we
11758 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5111759 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4611760 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4311761 "glTexImageIOSurface2DCHROMIUM",
11762 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4611763 return;
11764 }
11765
[email protected]09d50362012-10-18 20:54:3711766 // Default target might be conceptually valid, but disallow it to avoid
11767 // accidents.
[email protected]c986af502013-08-14 01:04:4411768 TextureRef* texture_ref =
11769 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911770 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111771 LOCAL_SET_GL_ERROR(
11772 GL_INVALID_OPERATION,
11773 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4611774 return;
11775 }
[email protected]e51bdf32011-11-23 22:21:4611776
11777 // Look up the new IOSurface. Note that because of asynchrony
11778 // between processes this might fail; during live resizing the
11779 // plugin process might allocate and release an IOSurface before
11780 // this process gets a chance to look it up. Hold on to any old
11781 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5311782 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4611783 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5111784 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311785 GL_INVALID_OPERATION,
11786 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4611787 return;
11788 }
11789
11790 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4911791 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4611792
11793 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
11794 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4911795 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4611796
11797 CGLContextObj context =
11798 static_cast<CGLContextObj>(context_->GetHandle());
11799
[email protected]c3a6b4a2014-06-04 09:25:5311800 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4611801 context,
11802 target,
11803 GL_RGBA,
11804 width,
11805 height,
11806 GL_BGRA,
11807 GL_UNSIGNED_INT_8_8_8_8_REV,
11808 surface,
11809 plane);
11810
11811 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5111812 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4611813 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4311814 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4611815 return;
11816 }
11817
11818 texture_manager()->SetLevelInfo(
reveman7c4a13b2015-06-05 22:28:1511819 texture_ref, target, 0, GL_RGBA, width, height, 1, 0, GL_BGRA,
11820 GL_UNSIGNED_INT_8_8_8_8_REV, gfx::Rect(width, height));
[email protected]e51bdf32011-11-23 22:21:4611821
11822#else
[email protected]ab09b612013-03-11 22:11:5111823 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4311824 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4611825#endif
11826}
11827
[email protected]97dc7cbe2011-12-06 17:26:1711828static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
11829 switch (internalformat) {
11830 case GL_RGB565:
11831 return GL_RGB;
11832 case GL_RGBA4:
11833 return GL_RGBA;
11834 case GL_RGB5_A1:
11835 return GL_RGBA;
11836 case GL_RGB8_OES:
11837 return GL_RGB;
11838 case GL_RGBA8_OES:
11839 return GL_RGBA;
11840 case GL_LUMINANCE8_ALPHA8_EXT:
11841 return GL_LUMINANCE_ALPHA;
11842 case GL_LUMINANCE8_EXT:
11843 return GL_LUMINANCE;
11844 case GL_ALPHA8_EXT:
11845 return GL_ALPHA;
11846 case GL_RGBA32F_EXT:
11847 return GL_RGBA;
11848 case GL_RGB32F_EXT:
11849 return GL_RGB;
11850 case GL_ALPHA32F_EXT:
11851 return GL_ALPHA;
11852 case GL_LUMINANCE32F_EXT:
11853 return GL_LUMINANCE;
11854 case GL_LUMINANCE_ALPHA32F_EXT:
11855 return GL_LUMINANCE_ALPHA;
11856 case GL_RGBA16F_EXT:
11857 return GL_RGBA;
11858 case GL_RGB16F_EXT:
11859 return GL_RGB;
11860 case GL_ALPHA16F_EXT:
11861 return GL_ALPHA;
11862 case GL_LUMINANCE16F_EXT:
11863 return GL_LUMINANCE;
11864 case GL_LUMINANCE_ALPHA16F_EXT:
11865 return GL_LUMINANCE_ALPHA;
11866 case GL_BGRA8_EXT:
11867 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5911868 case GL_SRGB8_ALPHA8_EXT:
11869 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1711870 default:
11871 return GL_NONE;
11872 }
11873}
11874
dongseong.hwang46305b12015-03-05 18:28:0411875bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUM(
11876 const char* function_name,
11877 GLenum target,
11878 TextureRef* source_texture_ref,
11879 TextureRef* dest_texture_ref,
11880 GLenum dest_internal_format) {
[email protected]370eaf12013-05-18 09:19:4911881 if (!source_texture_ref || !dest_texture_ref) {
dongseong.hwang46305b12015-03-05 18:28:0411882 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown texture id");
11883 return false;
[email protected]43410e92012-04-20 17:06:2811884 }
11885
11886 if (GL_TEXTURE_2D != target) {
dongseong.hwang46305b12015-03-05 18:28:0411887 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
11888 "invalid texture target");
11889 return false;
[email protected]43410e92012-04-20 17:06:2811890 }
11891
[email protected]370eaf12013-05-18 09:19:4911892 Texture* source_texture = source_texture_ref->texture();
11893 Texture* dest_texture = dest_texture_ref->texture();
dongseong.hwang46305b12015-03-05 18:28:0411894 if (source_texture == dest_texture) {
11895 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11896 "source and destination textures are the same");
11897 return false;
11898 }
11899
[email protected]02965c22013-03-09 02:40:0711900 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2511901 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3411902 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
11903 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
dongseong.hwang46305b12015-03-05 18:28:0411904 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
[email protected]3ecc1052013-09-26 08:59:0011905 "invalid texture target binding");
dongseong.hwang46305b12015-03-05 18:28:0411906 return false;
[email protected]0a1e9ad2012-05-04 21:13:0311907 }
11908
dongseong.hwang46305b12015-03-05 18:28:0411909 GLenum source_type = 0;
11910 GLenum source_internal_format = 0;
11911 source_texture->GetLevelType(source_texture->target(), 0, &source_type,
11912 &source_internal_format);
[email protected]43410e92012-04-20 17:06:2811913
dongseong.hwang46305b12015-03-05 18:28:0411914 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
11915 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
11916 // renderable on some platforms.
11917 bool valid_dest_format = dest_internal_format == GL_RGB ||
11918 dest_internal_format == GL_RGBA ||
11919 dest_internal_format == GL_BGRA_EXT;
11920 bool valid_source_format = source_internal_format == GL_ALPHA ||
11921 source_internal_format == GL_RGB ||
11922 source_internal_format == GL_RGBA ||
11923 source_internal_format == GL_LUMINANCE ||
11924 source_internal_format == GL_LUMINANCE_ALPHA ||
11925 source_internal_format == GL_BGRA_EXT;
11926 if (!valid_source_format || !valid_dest_format) {
11927 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11928 "invalid internal format");
11929 return false;
11930 }
11931 return true;
11932}
11933
christiank83120092015-06-17 11:40:1011934bool GLES2DecoderImpl::ValidateCompressedCopyTextureCHROMIUM(
11935 const char* function_name,
11936 GLenum target,
11937 TextureRef* source_texture_ref,
11938 TextureRef* dest_texture_ref) {
11939 if (!source_texture_ref || !dest_texture_ref) {
11940 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown texture id");
11941 return false;
11942 }
11943
11944 if (GL_TEXTURE_2D != target) {
11945 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
11946 "invalid texture target");
11947 return false;
11948 }
11949
11950 Texture* source_texture = source_texture_ref->texture();
11951 Texture* dest_texture = dest_texture_ref->texture();
11952 if (source_texture == dest_texture) {
11953 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11954 "source and destination textures are the same");
11955 return false;
11956 }
11957
11958 if (dest_texture->target() != GL_TEXTURE_2D ||
11959 (source_texture->target() != GL_TEXTURE_2D &&
11960 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
11961 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
11962 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
11963 "invalid texture target binding");
11964 return false;
11965 }
11966
11967 GLenum source_type = 0;
11968 GLenum source_internal_format = 0;
11969 source_texture->GetLevelType(source_texture->target(), 0, &source_type,
11970 &source_internal_format);
11971
11972 bool valid_format =
11973 source_internal_format == GL_ATC_RGB_AMD ||
11974 source_internal_format == GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD ||
11975 source_internal_format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
11976 source_internal_format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ||
11977 source_internal_format == GL_ETC1_RGB8_OES;
11978
11979 if (!valid_format) {
11980 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11981 "invalid internal format");
11982 return false;
11983 }
11984
11985 return true;
11986}
11987
zmodbea74da2015-06-23 20:41:5111988void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
11989 GLenum target,
11990 GLuint source_id,
11991 GLuint dest_id,
11992 GLenum internal_format,
11993 GLenum dest_type,
11994 GLboolean unpack_flip_y,
11995 GLboolean unpack_premultiply_alpha,
11996 GLboolean unpack_unmultiply_alpha) {
dongseong.hwang46305b12015-03-05 18:28:0411997 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
11998
11999 TextureRef* source_texture_ref = GetTexture(source_id);
12000 TextureRef* dest_texture_ref = GetTexture(dest_id);
12001 Texture* source_texture = source_texture_ref->texture();
12002 Texture* dest_texture = dest_texture_ref->texture();
12003 int source_width = 0;
12004 int source_height = 0;
[email protected]3e0dfd72014-02-21 06:28:4112005 gfx::GLImage* image =
12006 source_texture->GetLevelImage(source_texture->target(), 0);
12007 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5512008 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5612009 source_width = size.width();
12010 source_height = size.height();
12011 if (source_width <= 0 || source_height <= 0) {
12012 LOCAL_SET_GL_ERROR(
12013 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5512014 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5612015 return;
12016 }
[email protected]3ecc1052013-09-26 08:59:0012017 } else {
zmo9a7b17e2015-05-06 00:22:3312018 if (!source_texture->GetLevelSize(source_texture->target(), 0,
12019 &source_width, &source_height, nullptr)) {
[email protected]3ecc1052013-09-26 08:59:0012020 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
12021 "glCopyTextureChromium",
12022 "source texture has no level 0");
12023 return;
12024 }
12025
12026 // Check that this type of texture is allowed.
dongseong.hwang46305b12015-03-05 18:28:0412027 if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
12028 source_width, source_height, 1)) {
[email protected]3ecc1052013-09-26 08:59:0012029 LOCAL_SET_GL_ERROR(
12030 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
12031 return;
12032 }
[email protected]377976552013-05-14 23:32:5612033 }
12034
[email protected]a6e3d282014-08-22 22:20:4412035 GLenum source_type = 0;
12036 GLenum source_internal_format = 0;
12037 source_texture->GetLevelType(
12038 source_texture->target(), 0, &source_type, &source_internal_format);
12039
dongseong.hwang46305b12015-03-05 18:28:0412040 if (dest_texture->IsImmutable()) {
12041 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyTextureCHROMIUM",
12042 "texture is immutable");
12043 return;
12044 }
12045
12046 if (!ValidateCopyTextureCHROMIUM("glCopyTextureCHROMIUM", target,
12047 source_texture_ref, dest_texture_ref,
12048 internal_format)) {
12049 return;
12050 }
12051
12052 // Clear the source texture if necessary.
12053 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
12054 source_texture->target(), 0)) {
12055 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM",
12056 "dimensions too big");
[email protected]a6e3d282014-08-22 22:20:4412057 return;
12058 }
12059
[email protected]cf6b8f62012-05-25 21:43:3712060 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
12061 // needed because it takes 10s of milliseconds to initialize.
12062 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5112063 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3712064 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2712065 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3712066 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5112067 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3712068 return;
12069 }
12070
[email protected]efc87712014-07-09 00:22:4712071 GLenum dest_type_previous = dest_type;
12072 GLenum dest_internal_format = internal_format;
dongseong.hwang46305b12015-03-05 18:28:0412073 int dest_width = 0;
12074 int dest_height = 0;
zmo9a7b17e2015-05-06 00:22:3312075 bool dest_level_defined = dest_texture->GetLevelSize(
12076 GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr);
[email protected]43410e92012-04-20 17:06:2812077
[email protected]0a1e9ad2012-05-04 21:13:0312078 if (dest_level_defined) {
dongseong.hwang46305b12015-03-05 18:28:0412079 dest_texture->GetLevelType(GL_TEXTURE_2D, 0, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0712080 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0312081 }
12082
12083 // Resize the destination texture to the dimensions of the source texture.
12084 if (!dest_level_defined || dest_width != source_width ||
12085 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5412086 dest_internal_format != internal_format ||
12087 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2812088 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5112089 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0712090 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
dongseong.hwang46305b12015-03-05 18:28:0412091 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, source_width, source_height,
12092 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5112093 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0312094 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0212095 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2812096 return;
[email protected]0a1e9ad2012-05-04 21:13:0312097 }
[email protected]43410e92012-04-20 17:06:2812098
12099 texture_manager()->SetLevelInfo(
dongseong.hwang46305b12015-03-05 18:28:0412100 dest_texture_ref, GL_TEXTURE_2D, 0, internal_format, source_width,
reveman7c4a13b2015-06-05 22:28:1512101 source_height, 1, 0, internal_format, dest_type,
12102 gfx::Rect(source_width, source_height));
[email protected]f7024712012-05-15 21:30:2512103 } else {
dongseong.hwang46305b12015-03-05 18:28:0412104 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0,
12105 true);
[email protected]43410e92012-04-20 17:06:2812106 }
12107
[email protected]00c2cf92014-03-14 00:08:3712108 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5412109
revemanb6643fb02015-05-26 06:05:3412110 // Try using GLImage::CopyTexSubImage when possible.
revemance8fbe82014-09-05 02:19:5212111 bool unpack_premultiply_alpha_change =
zmodbea74da2015-06-23 20:41:5112112 (unpack_premultiply_alpha ^ unpack_unmultiply_alpha) != 0;
12113 if (image && !unpack_flip_y && !unpack_premultiply_alpha_change) {
revemance8fbe82014-09-05 02:19:5212114 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
reveman6b683f22015-05-22 02:38:3212115 if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(0, 0),
12116 gfx::Rect(0, 0, source_width, source_height))) {
revemance8fbe82014-09-05 02:19:5212117 return;
reveman6b683f22015-05-22 02:38:3212118 }
revemance8fbe82014-09-05 02:19:5212119 }
12120
12121 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
12122
[email protected]5394a4102013-04-18 05:41:3712123 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
12124 // before presenting.
12125 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
12126 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
dongseong.hwang46305b12015-03-05 18:28:0412127 // instead of using kIdentityMatrix crbug.com/226218.
[email protected]5394a4102013-04-18 05:41:3712128 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
dongseong.hwang46305b12015-03-05 18:28:0412129 this, source_texture->target(), source_texture->service_id(),
zmodbea74da2015-06-23 20:41:5112130 dest_texture->service_id(), source_width, source_height,
12131 unpack_flip_y == GL_TRUE,
12132 unpack_premultiply_alpha == GL_TRUE,
12133 unpack_unmultiply_alpha == GL_TRUE,
dongseong.hwang46305b12015-03-05 18:28:0412134 kIdentityMatrix);
[email protected]5394a4102013-04-18 05:41:3712135 } else {
dongseong.hwang46305b12015-03-05 18:28:0412136 copy_texture_CHROMIUM_->DoCopyTexture(
12137 this, source_texture->target(), source_texture->service_id(),
12138 source_internal_format, dest_texture->service_id(), internal_format,
zmodbea74da2015-06-23 20:41:5112139 source_width, source_height,
12140 unpack_flip_y == GL_TRUE,
12141 unpack_premultiply_alpha == GL_TRUE,
12142 unpack_unmultiply_alpha == GL_TRUE);
dongseong.hwang46305b12015-03-05 18:28:0412143 }
12144
12145 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
12146}
12147
zmodbea74da2015-06-23 20:41:5112148void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(
12149 GLenum target,
12150 GLuint source_id,
12151 GLuint dest_id,
12152 GLint xoffset,
12153 GLint yoffset,
12154 GLint x,
12155 GLint y,
12156 GLsizei width,
12157 GLsizei height,
12158 GLboolean unpack_flip_y,
12159 GLboolean unpack_premultiply_alpha,
12160 GLboolean unpack_unmultiply_alpha) {
dongseong.hwang46305b12015-03-05 18:28:0412161 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopySubTextureCHROMIUM");
12162
12163 TextureRef* source_texture_ref = GetTexture(source_id);
12164 TextureRef* dest_texture_ref = GetTexture(dest_id);
12165 Texture* source_texture = source_texture_ref->texture();
12166 Texture* dest_texture = dest_texture_ref->texture();
12167 int source_width = 0;
12168 int source_height = 0;
12169 gfx::GLImage* image =
12170 source_texture->GetLevelImage(source_texture->target(), 0);
12171 if (image) {
12172 gfx::Size size = image->GetSize();
12173 source_width = size.width();
12174 source_height = size.height();
12175 if (source_width <= 0 || source_height <= 0) {
12176 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
12177 "invalid image size");
12178 return;
12179 }
12180 } else {
12181 if (!source_texture->GetLevelSize(source_texture->target(), 0,
zmo9a7b17e2015-05-06 00:22:3312182 &source_width, &source_height, nullptr)) {
dongseong.hwang46305b12015-03-05 18:28:0412183 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
12184 "source texture has no level 0");
12185 return;
12186 }
12187
12188 // Check that this type of texture is allowed.
12189 if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
12190 source_width, source_height, 1)) {
12191 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
12192 "source texture bad dimensions");
12193 return;
12194 }
12195 }
12196
12197 GLenum source_type = 0;
12198 GLenum source_internal_format = 0;
12199 source_texture->GetLevelType(source_texture->target(), 0, &source_type,
12200 &source_internal_format);
revemanb6643fb02015-05-26 06:05:3412201 if (!source_texture->ValidForTexture(source_texture->target(), 0, x, y, 0,
12202 width, height, 1, source_type)) {
12203 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
12204 "source texture bad dimensions.");
12205 return;
12206 }
12207
dongseong.hwang46305b12015-03-05 18:28:0412208 GLenum dest_type = 0;
12209 GLenum dest_internal_format = 0;
12210 bool dest_level_defined = dest_texture->GetLevelType(
12211 dest_texture->target(), 0, &dest_type, &dest_internal_format);
12212 if (!dest_level_defined) {
12213 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopySubTextureCHROMIUM",
12214 "destination texture is not defined");
12215 return;
12216 }
12217 if (!dest_texture->ValidForTexture(dest_texture->target(), 0, xoffset,
revemanb6643fb02015-05-26 06:05:3412218 yoffset, 0, width, height, 1, dest_type)) {
dongseong.hwang46305b12015-03-05 18:28:0412219 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
12220 "destination texture bad dimensions.");
12221 return;
12222 }
12223
12224 if (!ValidateCopyTextureCHROMIUM("glCopySubTextureCHROMIUM", target,
12225 source_texture_ref, dest_texture_ref,
12226 dest_internal_format)) {
12227 return;
12228 }
12229
12230 // Clear the source texture if necessary.
12231 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
12232 source_texture->target(), 0)) {
12233 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM",
12234 "source texture dimensions too big");
12235 return;
12236 }
12237
12238 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
12239 // needed because it takes 10s of milliseconds to initialize.
12240 if (!copy_texture_CHROMIUM_.get()) {
12241 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopySubTextureCHROMIUM");
12242 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
12243 copy_texture_CHROMIUM_->Initialize(this);
12244 RestoreCurrentFramebufferBindings();
12245 if (LOCAL_PEEK_GL_ERROR("glCopySubTextureCHROMIUM") != GL_NO_ERROR)
12246 return;
12247 }
12248
12249 int dest_width = 0;
12250 int dest_height = 0;
zmo9a7b17e2015-05-06 00:22:3312251 bool ok = dest_texture->GetLevelSize(
12252 GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr);
dongseong.hwang46305b12015-03-05 18:28:0412253 DCHECK(ok);
revemanb6643fb02015-05-26 06:05:3412254 if (xoffset != 0 || yoffset != 0 || width != dest_width ||
12255 height != dest_height) {
reveman7c4a13b2015-06-05 22:28:1512256 gfx::Rect cleared_rect;
12257 if (CombineAdjacentRects(dest_texture->GetLevelClearedRect(target, 0),
12258 gfx::Rect(xoffset, yoffset, width, height),
12259 &cleared_rect)) {
12260 DCHECK_GE(cleared_rect.size().GetArea(),
12261 dest_texture->GetLevelClearedRect(target, 0).size().GetArea());
12262 texture_manager()->SetLevelClearedRect(dest_texture_ref, target, 0,
12263 cleared_rect);
12264 } else {
12265 // Otherwise clear part of texture level that is not already cleared.
12266 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target,
12267 0)) {
12268 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM",
12269 "destination texture dimensions too big");
12270 return;
12271 }
dongseong.hwang46305b12015-03-05 18:28:0412272 }
12273 } else {
12274 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0,
12275 true);
12276 }
12277
12278 ScopedModifyPixels modify(dest_texture_ref);
12279
12280 // Try using GLImage::CopyTexSubImage when possible.
12281 bool unpack_premultiply_alpha_change =
zmodbea74da2015-06-23 20:41:5112282 (unpack_premultiply_alpha ^ unpack_unmultiply_alpha) != 0;
12283 if (image && !unpack_flip_y && !unpack_premultiply_alpha_change) {
dongseong.hwang46305b12015-03-05 18:28:0412284 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
reveman6b683f22015-05-22 02:38:3212285 if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(xoffset, yoffset),
revemand41b0e1f2015-05-26 13:05:1912286 gfx::Rect(x, y, width, height))) {
dongseong.hwang46305b12015-03-05 18:28:0412287 return;
reveman6b683f22015-05-22 02:38:3212288 }
dongseong.hwang46305b12015-03-05 18:28:0412289 }
12290
12291 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
12292
revemanb6643fb02015-05-26 06:05:3412293 // TODO(hkuang): get the StreamTexture transform matrix in GPU process.
12294 // crbug.com/226218.
12295 copy_texture_CHROMIUM_->DoCopySubTexture(
12296 this, source_texture->target(), source_texture->service_id(),
12297 source_internal_format, dest_texture->service_id(), dest_internal_format,
12298 xoffset, yoffset, x, y, width, height, dest_width, dest_height,
zmodbea74da2015-06-23 20:41:5112299 source_width, source_height,
12300 unpack_flip_y == GL_TRUE,
12301 unpack_premultiply_alpha == GL_TRUE,
12302 unpack_unmultiply_alpha == GL_TRUE);
[email protected]91c94eb2013-10-22 10:32:5412303
12304 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2812305}
12306
christiank83120092015-06-17 11:40:1012307void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLenum target,
12308 GLuint source_id,
12309 GLuint dest_id) {
12310 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM");
12311
12312 TextureRef* source_texture_ref = GetTexture(source_id);
12313 TextureRef* dest_texture_ref = GetTexture(dest_id);
12314 Texture* source_texture = source_texture_ref->texture();
12315 Texture* dest_texture = dest_texture_ref->texture();
12316 int source_width = 0;
12317 int source_height = 0;
12318 gfx::GLImage* image =
12319 source_texture->GetLevelImage(source_texture->target(), 0);
12320 if (image) {
12321 gfx::Size size = image->GetSize();
12322 source_width = size.width();
12323 source_height = size.height();
12324 if (source_width <= 0 || source_height <= 0) {
12325 LOCAL_SET_GL_ERROR(
12326 GL_INVALID_VALUE,
12327 "glCompressedCopyTextureCHROMIUM", "invalid image size");
12328 return;
12329 }
12330 } else {
12331 if (!source_texture->GetLevelSize(source_texture->target(), 0,
12332 &source_width, &source_height, nullptr)) {
12333 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
12334 "glCompressedCopyTextureCHROMIUM",
12335 "source texture has no level 0");
12336 return;
12337 }
12338
12339 // Check that this type of texture is allowed.
12340 if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
12341 source_width, source_height, 1)) {
12342 LOCAL_SET_GL_ERROR(
12343 GL_INVALID_VALUE, "glCompressedCopyTextureCHROMIUM",
12344 "Bad dimensions");
12345 return;
12346 }
12347 }
12348
12349 GLenum source_type = 0;
12350 GLenum source_internal_format = 0;
12351 source_texture->GetLevelType(
12352 source_texture->target(), 0, &source_type, &source_internal_format);
12353
12354 if (dest_texture->IsImmutable()) {
12355 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
12356 "glCompressedCopyTextureCHROMIUM",
12357 "texture is immutable");
12358 return;
12359 }
12360
christiank83120092015-06-17 11:40:1012361 if (!ValidateCompressedCopyTextureCHROMIUM(
12362 "glCompressedCopyTextureCHROMIUM",
12363 target,
12364 source_texture_ref, dest_texture_ref)) {
12365 return;
12366 }
12367
12368 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
12369 // needed because it takes 10s of milliseconds to initialize.
12370 if (!copy_texture_CHROMIUM_.get()) {
12371 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
12372 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
12373 copy_texture_CHROMIUM_->Initialize(this);
12374 RestoreCurrentFramebufferBindings();
12375 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
12376 return;
12377 }
12378
12379 // Clear the source texture if necessary.
12380 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
12381 source_texture->target(), 0)) {
12382 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCompressedCopyTextureCHROMIUM",
12383 "dimensions too big");
12384 return;
12385 }
12386
12387 ScopedTextureBinder binder(
12388 &state_, dest_texture->service_id(), GL_TEXTURE_2D);
12389
12390 ScopedModifyPixels modify(dest_texture_ref);
12391
12392 // Try using GLImage::CopyTexImage when possible.
12393 if (image) {
12394 GLenum dest_type = 0;
12395 GLenum dest_internal_format = 0;
12396 int dest_width = 0;
12397 int dest_height = 0;
12398 bool dest_level_defined = dest_texture->GetLevelSize(
12399 GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr);
12400
12401 if (dest_level_defined) {
12402 dest_texture->GetLevelType(GL_TEXTURE_2D, 0, &dest_type,
12403 &dest_internal_format);
12404 }
12405
12406 // Resize the destination texture to the dimensions of the source texture.
12407 if (!dest_level_defined || dest_width != source_width ||
12408 dest_height != source_height ||
12409 dest_internal_format != source_internal_format) {
12410 GLsizei source_size = 0;
12411
12412 bool did_get_size = GetCompressedTexSizeInBytes(
12413 "glCompressedCopyTextureCHROMIUM", source_width, source_height,
12414 1, source_internal_format, &source_size);
12415 DCHECK(did_get_size);
12416
12417 // Ensure that the glCompressedTexImage2D succeeds.
12418 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM");
12419 glCompressedTexImage2D(GL_TEXTURE_2D, 0, source_internal_format,
12420 source_width, source_height, 0, source_size,
12421 NULL);
12422 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedCopyTextureCHROMIUM");
12423 if (error != GL_NO_ERROR) {
12424 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
12425 return;
12426 }
12427
12428 texture_manager()->SetLevelInfo(
12429 dest_texture_ref, GL_TEXTURE_2D, 0, source_internal_format,
12430 source_width, source_height, 1, 0, source_internal_format,
12431 source_type, gfx::Rect(source_width, source_height));
12432 } else {
12433 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0,
12434 true);
12435 }
12436
12437 if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(0, 0),
12438 gfx::Rect(0, 0, source_width, source_height))) {
12439 return;
12440 }
12441 }
12442
12443 TRACE_EVENT0(
12444 "gpu",
12445 "GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM, fallback");
12446
12447 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
12448
12449 // As a fallback, copy into a non-compressed GL_RGBA texture.
12450 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM");
12451 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, source_width, source_height,
12452 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
12453 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedCopyTextureCHROMIUM");
12454 if (error != GL_NO_ERROR) {
12455 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
12456 return;
12457 }
12458
12459 texture_manager()->SetLevelInfo(
12460 dest_texture_ref, GL_TEXTURE_2D, 0, GL_RGBA, source_width,
12461 source_height, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
12462 gfx::Rect(source_width, source_height));
12463
12464 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
12465 // before presenting.
12466 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
12467 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
12468 // instead of using kIdentityMatrix crbug.com/226218.
12469 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
12470 this, source_texture->target(), source_texture->service_id(),
12471 dest_texture->service_id(), source_width, source_height,
zmodbea74da2015-06-23 20:41:5112472 false, false, false, kIdentityMatrix);
christiank83120092015-06-17 11:40:1012473 } else {
12474 copy_texture_CHROMIUM_->DoCopyTexture(
12475 this, source_texture->target(), source_texture->service_id(),
12476 source_internal_format, dest_texture->service_id(), GL_RGBA,
zmodbea74da2015-06-23 20:41:5112477 source_width, source_height, false, false, false);
christiank83120092015-06-17 11:40:1012478 }
12479
12480 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
12481}
12482
[email protected]97dc7cbe2011-12-06 17:26:1712483static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
12484 switch (internalformat) {
12485 case GL_RGB565:
12486 return GL_UNSIGNED_SHORT_5_6_5;
12487 case GL_RGBA4:
12488 return GL_UNSIGNED_SHORT_4_4_4_4;
12489 case GL_RGB5_A1:
12490 return GL_UNSIGNED_SHORT_5_5_5_1;
12491 case GL_RGB8_OES:
12492 return GL_UNSIGNED_BYTE;
12493 case GL_RGBA8_OES:
12494 return GL_UNSIGNED_BYTE;
12495 case GL_LUMINANCE8_ALPHA8_EXT:
12496 return GL_UNSIGNED_BYTE;
12497 case GL_LUMINANCE8_EXT:
12498 return GL_UNSIGNED_BYTE;
12499 case GL_ALPHA8_EXT:
12500 return GL_UNSIGNED_BYTE;
12501 case GL_RGBA32F_EXT:
12502 return GL_FLOAT;
12503 case GL_RGB32F_EXT:
12504 return GL_FLOAT;
12505 case GL_ALPHA32F_EXT:
12506 return GL_FLOAT;
12507 case GL_LUMINANCE32F_EXT:
12508 return GL_FLOAT;
12509 case GL_LUMINANCE_ALPHA32F_EXT:
12510 return GL_FLOAT;
12511 case GL_RGBA16F_EXT:
12512 return GL_HALF_FLOAT_OES;
12513 case GL_RGB16F_EXT:
12514 return GL_HALF_FLOAT_OES;
12515 case GL_ALPHA16F_EXT:
12516 return GL_HALF_FLOAT_OES;
12517 case GL_LUMINANCE16F_EXT:
12518 return GL_HALF_FLOAT_OES;
12519 case GL_LUMINANCE_ALPHA16F_EXT:
12520 return GL_HALF_FLOAT_OES;
12521 case GL_BGRA8_EXT:
12522 return GL_UNSIGNED_BYTE;
12523 default:
12524 return GL_NONE;
12525 }
12526}
12527
12528void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4412529 GLenum target,
12530 GLint levels,
12531 GLenum internal_format,
12532 GLsizei width,
12533 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1312534 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
12535 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4112536 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0012537 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5112538 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4312539 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1712540 return;
12541 }
[email protected]c986af502013-08-14 01:04:4412542 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
12543 &state_, target);
[email protected]370eaf12013-05-18 09:19:4912544 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5112545 LOCAL_SET_GL_ERROR(
12546 GL_INVALID_OPERATION,
12547 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1712548 return;
12549 }
[email protected]370eaf12013-05-18 09:19:4912550 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0712551 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4412552 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1712553 }
[email protected]02965c22013-03-09 02:40:0712554 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5112555 LOCAL_SET_GL_ERROR(
12556 GL_INVALID_OPERATION,
12557 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1712558 return;
12559 }
[email protected]7989c9e2013-01-23 06:39:2612560
12561 GLenum format = ExtractFormatFromStorageFormat(internal_format);
12562 GLenum type = ExtractTypeFromStorageFormat(internal_format);
12563
12564 {
12565 GLsizei level_width = width;
12566 GLsizei level_height = height;
12567 uint32 estimated_size = 0;
12568 for (int ii = 0; ii < levels; ++ii) {
12569 uint32 level_size = 0;
12570 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4212571 level_width, level_height, 1, format, type, state_.unpack_alignment,
[email protected]7989c9e2013-01-23 06:39:2612572 &estimated_size, NULL, NULL) ||
12573 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5112574 LOCAL_SET_GL_ERROR(
12575 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2612576 return;
12577 }
12578 level_width = std::max(1, level_width >> 1);
12579 level_height = std::max(1, level_height >> 1);
12580 }
12581 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5112582 LOCAL_SET_GL_ERROR(
12583 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2612584 return;
12585 }
12586 }
12587
[email protected]ab09b612013-03-11 22:11:5112588 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3812589 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5112590 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1712591 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1512592 GLsizei level_width = width;
12593 GLsizei level_height = height;
12594 for (int ii = 0; ii < levels; ++ii) {
reveman7c4a13b2015-06-05 22:28:1512595 texture_manager()->SetLevelInfo(texture_ref, target, ii, format,
12596 level_width, level_height, 1, 0, format,
12597 type, gfx::Rect());
[email protected]4502e6492011-12-14 19:39:1512598 level_width = std::max(1, level_width >> 1);
12599 level_height = std::max(1, level_height >> 1);
12600 }
[email protected]02965c22013-03-09 02:40:0712601 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1712602 }
[email protected]97dc7cbe2011-12-06 17:26:1712603}
[email protected]e51bdf32011-11-23 22:21:4612604
[email protected]78b514b2012-05-01 21:50:5912605error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3412606 uint32 immediate_data_size,
12607 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3512608 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5912609}
12610
12611void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3712612 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0212613 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3212614 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3712615 "mailbox[0]", static_cast<unsigned char>(data[0]));
12616
[email protected]43f253da2014-06-10 17:51:2212617 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
12618 &state_, target);
12619 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
12620}
12621
12622void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
12623 GLenum target, const GLbyte* data) {
12624 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
12625 "context", logger_.GetLogPrefix(),
12626 "mailbox[0]", static_cast<unsigned char>(data[0]));
12627
12628 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
12629 target, data);
12630}
12631
12632void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
12633 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3712634 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2212635 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3712636 "mailbox that was not generated by "
12637 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0212638
[email protected]370eaf12013-05-18 09:19:4912639 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5112640 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2212641 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5912642 return;
12643 }
12644
[email protected]62e65f02013-05-29 22:28:1012645 Texture* produced = texture_manager()->Produce(texture_ref);
12646 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5112647 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2212648 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
12649 return;
12650 }
12651
12652 if (produced->target() != target) {
12653 LOCAL_SET_GL_ERROR(
12654 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5912655 return;
12656 }
12657
sievers8b373ec52014-10-24 23:04:0612658 group_->mailbox_manager()->ProduceTexture(mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5912659}
12660
12661void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3712662 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0212663 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3212664 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3712665 "mailbox[0]", static_cast<unsigned char>(data[0]));
12666 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
12667 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
12668 "mailbox that was not generated by "
12669 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0212670
[email protected]62e65f02013-05-29 22:28:1012671 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4412672 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1112673 if (!texture_ref.get()) {
12674 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
12675 "glConsumeTextureCHROMIUM",
12676 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5912677 return;
12678 }
[email protected]62e65f02013-05-29 22:28:1012679 GLuint client_id = texture_ref->client_id();
12680 if (!client_id) {
12681 LOCAL_SET_GL_ERROR(
12682 GL_INVALID_OPERATION,
12683 "glConsumeTextureCHROMIUM", "unknown texture for target");
12684 return;
12685 }
sievers8b373ec52014-10-24 23:04:0612686 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]62e65f02013-05-29 22:28:1012687 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5112688 LOCAL_SET_GL_ERROR(
12689 GL_INVALID_OPERATION,
12690 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5912691 return;
12692 }
[email protected]62e65f02013-05-29 22:28:1012693 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5112694 LOCAL_SET_GL_ERROR(
12695 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1012696 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5912697 return;
12698 }
[email protected]62e65f02013-05-29 22:28:1012699
12700 DeleteTexturesHelper(1, &client_id);
12701 texture_ref = texture_manager()->Consume(client_id, texture);
12702 glBindTexture(target, texture_ref->service_id());
12703
12704 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
12705 unit.bind_target = target;
12706 switch (target) {
12707 case GL_TEXTURE_2D:
12708 unit.bound_texture_2d = texture_ref;
12709 break;
12710 case GL_TEXTURE_CUBE_MAP:
12711 unit.bound_texture_cube_map = texture_ref;
12712 break;
12713 case GL_TEXTURE_EXTERNAL_OES:
12714 unit.bound_texture_external_oes = texture_ref;
12715 break;
12716 case GL_TEXTURE_RECTANGLE_ARB:
12717 unit.bound_texture_rectangle_arb = texture_ref;
12718 break;
12719 default:
12720 NOTREACHED(); // Validation should prevent us getting here.
12721 break;
12722 }
[email protected]78b514b2012-05-01 21:50:5912723}
12724
bajonesd8388be02015-04-04 00:15:4312725void GLES2DecoderImpl::EnsureTextureForClientId(
12726 GLenum target,
12727 GLuint client_id) {
12728 TextureRef* texture_ref = GetTexture(client_id);
12729 if (!texture_ref) {
12730 GLuint service_id;
12731 glGenTextures(1, &service_id);
12732 DCHECK_NE(0u, service_id);
12733 texture_ref = CreateTexture(client_id, service_id);
12734 texture_manager()->SetTarget(texture_ref, target);
12735 glBindTexture(target, service_id);
12736 RestoreCurrentTextureBindings(&state_, target);
12737 }
12738}
12739
12740// If CreateAndConsumeTexture fails we still need to ensure that the client_id
12741// provided is associated with a service_id/TextureRef for consistency, even if
12742// the resulting texture is incomplete.
[email protected]43f253da2014-06-10 17:51:2212743error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
12744 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3412745 const void* cmd_data) {
12746 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
12747 *static_cast<
12748 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
12749 cmd_data);
[email protected]43f253da2014-06-10 17:51:2212750 GLenum target = static_cast<GLenum>(c.target);
12751 uint32_t data_size;
12752 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
12753 return error::kOutOfBounds;
12754 }
12755 if (data_size > immediate_data_size) {
12756 return error::kOutOfBounds;
12757 }
12758 const GLbyte* mailbox =
12759 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
12760 if (!validators_->texture_bind_target.IsValid(target)) {
12761 LOCAL_SET_GL_ERROR_INVALID_ENUM(
12762 "glCreateAndConsumeTextureCHROMIUM", target, "target");
12763 return error::kNoError;
12764 }
12765 if (mailbox == NULL) {
12766 return error::kOutOfBounds;
12767 }
12768 uint32_t client_id = c.client_id;
12769 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
12770 return error::kNoError;
12771}
12772
12773void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
12774 const GLbyte* data, GLuint client_id) {
12775 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
12776 "context", logger_.GetLogPrefix(),
12777 "mailbox[0]", static_cast<unsigned char>(data[0]));
12778 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
12779 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
12780 "passed a mailbox that was not "
12781 "generated by GenMailboxCHROMIUM.";
12782
12783 TextureRef* texture_ref = GetTexture(client_id);
12784 if (texture_ref) {
bajonesd8388be02015-04-04 00:15:4312785 // No need to call EnsureTextureForClientId here, the client_id already has
12786 // an associated texture.
[email protected]43f253da2014-06-10 17:51:2212787 LOCAL_SET_GL_ERROR(
12788 GL_INVALID_OPERATION,
12789 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
12790 return;
12791 }
sievers8b373ec52014-10-24 23:04:0612792 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]43f253da2014-06-10 17:51:2212793 if (!texture) {
bajonesd8388be02015-04-04 00:15:4312794 EnsureTextureForClientId(target, client_id);
[email protected]43f253da2014-06-10 17:51:2212795 LOCAL_SET_GL_ERROR(
12796 GL_INVALID_OPERATION,
12797 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
12798 return;
12799 }
bajonesd8388be02015-04-04 00:15:4312800
[email protected]43f253da2014-06-10 17:51:2212801 if (texture->target() != target) {
bajonesd8388be02015-04-04 00:15:4312802 EnsureTextureForClientId(target, client_id);
[email protected]43f253da2014-06-10 17:51:2212803 LOCAL_SET_GL_ERROR(
12804 GL_INVALID_OPERATION,
12805 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
12806 return;
12807 }
12808
[email protected]43f253da2014-06-10 17:51:2212809 texture_ref = texture_manager()->Consume(client_id, texture);
12810}
12811
orglofchcad5a6742014-11-07 19:51:1212812bool GLES2DecoderImpl::DoIsValuebufferCHROMIUM(GLuint client_id) {
12813 const Valuebuffer* valuebuffer = GetValuebuffer(client_id);
12814 return valuebuffer && valuebuffer->IsValid();
12815}
12816
12817void GLES2DecoderImpl::DoBindValueBufferCHROMIUM(GLenum target,
12818 GLuint client_id) {
12819 Valuebuffer* valuebuffer = NULL;
12820 if (client_id != 0) {
12821 valuebuffer = GetValuebuffer(client_id);
12822 if (!valuebuffer) {
12823 if (!group_->bind_generates_resource()) {
12824 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindValuebufferCHROMIUM",
12825 "id not generated by glBindValuebufferCHROMIUM");
12826 return;
12827 }
12828
12829 // It's a new id so make a valuebuffer for it.
12830 CreateValuebuffer(client_id);
12831 valuebuffer = GetValuebuffer(client_id);
12832 }
12833 valuebuffer->MarkAsValid();
12834 }
12835 state_.bound_valuebuffer = valuebuffer;
12836}
12837
12838void GLES2DecoderImpl::DoSubscribeValueCHROMIUM(GLenum target,
12839 GLenum subscription) {
12840 if (!CheckCurrentValuebuffer("glSubscribeValueCHROMIUM")) {
12841 return;
12842 }
12843 state_.bound_valuebuffer.get()->AddSubscription(subscription);
12844}
12845
12846void GLES2DecoderImpl::DoPopulateSubscribedValuesCHROMIUM(GLenum target) {
12847 if (!CheckCurrentValuebuffer("glPopulateSubscribedValuesCHROMIUM")) {
12848 return;
12849 }
12850 valuebuffer_manager()->UpdateValuebufferState(state_.bound_valuebuffer.get());
12851}
12852
12853void GLES2DecoderImpl::DoUniformValueBufferCHROMIUM(GLint location,
12854 GLenum target,
12855 GLenum subscription) {
12856 if (!CheckCurrentValuebufferForSubscription(
12857 subscription, "glPopulateSubscribedValuesCHROMIUM")) {
12858 return;
12859 }
12860 if (!CheckSubscriptionTarget(location, subscription,
12861 "glPopulateSubscribedValuesCHROMIUM")) {
12862 return;
12863 }
12864 const ValueState* state =
12865 state_.bound_valuebuffer.get()->GetState(subscription);
12866 if (state) {
12867 switch (subscription) {
12868 case GL_MOUSE_POSITION_CHROMIUM:
12869 DoUniform2iv(location, 1, state->int_value);
12870 break;
12871 default:
12872 NOTREACHED() << "Unhandled uniform subscription target "
12873 << subscription;
12874 break;
12875 }
12876 }
12877}
12878
[email protected]d2a0e1a2012-08-12 02:25:0112879void GLES2DecoderImpl::DoInsertEventMarkerEXT(
12880 GLsizei length, const GLchar* marker) {
12881 if (!marker) {
12882 marker = "";
12883 }
12884 debug_marker_manager_.SetMarker(
12885 length ? std::string(marker, length) : std::string(marker));
12886}
12887
12888void GLES2DecoderImpl::DoPushGroupMarkerEXT(
12889 GLsizei length, const GLchar* marker) {
12890 if (!marker) {
12891 marker = "";
12892 }
[email protected]cac16542014-01-15 17:53:5112893 std::string name = length ? std::string(marker, length) : std::string(marker);
12894 debug_marker_manager_.PushGroup(name);
dyen4bb43282015-01-08 01:09:5612895 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_group_marker"), name,
12896 kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0112897}
12898
12899void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
12900 debug_marker_manager_.PopGroup();
dyen4bb43282015-01-08 01:09:5612901 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0112902}
12903
[email protected]09d50362012-10-18 20:54:3712904void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
12905 GLenum target, GLint image_id) {
12906 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3712907
[email protected]bc26e8d2014-01-29 00:40:3012908 if (target == GL_TEXTURE_CUBE_MAP) {
12909 LOCAL_SET_GL_ERROR(
12910 GL_INVALID_ENUM,
12911 "glBindTexImage2DCHROMIUM", "invalid target");
12912 return;
12913 }
12914
[email protected]09d50362012-10-18 20:54:3712915 // Default target might be conceptually valid, but disallow it to avoid
12916 // accidents.
[email protected]c986af502013-08-14 01:04:4412917 TextureRef* texture_ref =
12918 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4912919 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5112920 LOCAL_SET_GL_ERROR(
12921 GL_INVALID_OPERATION,
12922 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3712923 return;
12924 }
12925
12926 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
12927 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5112928 LOCAL_SET_GL_ERROR(
12929 GL_INVALID_OPERATION,
12930 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3712931 return;
12932 }
12933
[email protected]b8160812013-04-09 00:41:0412934 {
12935 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3012936 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2612937 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0412938 LOCAL_SET_GL_ERROR(
12939 GL_INVALID_OPERATION,
12940 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
12941 return;
12942 }
[email protected]09d50362012-10-18 20:54:3712943 }
12944
12945 gfx::Size size = gl_image->GetSize();
12946 texture_manager()->SetLevelInfo(
reveman7c4a13b2015-06-05 22:28:1512947 texture_ref, target, 0, gl_image->GetInternalFormat(), size.width(),
12948 size.height(), 1, 0, gl_image->GetInternalFormat(), GL_UNSIGNED_BYTE,
12949 gfx::Rect(size));
[email protected]370eaf12013-05-18 09:19:4912950 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3712951}
12952
12953void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
12954 GLenum target, GLint image_id) {
12955 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3712956
12957 // Default target might be conceptually valid, but disallow it to avoid
12958 // accidents.
[email protected]c986af502013-08-14 01:04:4412959 TextureRef* texture_ref =
12960 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4912961 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5112962 LOCAL_SET_GL_ERROR(
12963 GL_INVALID_OPERATION,
12964 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3712965 return;
12966 }
12967
12968 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
12969 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5112970 LOCAL_SET_GL_ERROR(
12971 GL_INVALID_OPERATION,
12972 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3712973 return;
12974 }
12975
12976 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4912977 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3712978 return;
12979
[email protected]b8160812013-04-09 00:41:0412980 {
12981 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3012982 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2612983 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0412984 }
[email protected]09d50362012-10-18 20:54:3712985
12986 texture_manager()->SetLevelInfo(
christiank55ddebb2015-05-18 08:56:3212987 texture_ref, target, 0, gl_image->GetInternalFormat(), 0, 0, 1, 0,
reveman7c4a13b2015-06-05 22:28:1512988 gl_image->GetInternalFormat(), GL_UNSIGNED_BYTE, gfx::Rect());
[email protected]09d50362012-10-18 20:54:3712989}
[email protected]d2a0e1a2012-08-12 02:25:0112990
[email protected]94307712012-11-16 23:26:1112991error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3412992 uint32 immediate_data_size,
12993 const void* cmd_data) {
12994 const gles2::cmds::TraceBeginCHROMIUM& c =
12995 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
dyencb86f2f2014-12-09 18:35:4112996 Bucket* category_bucket = GetBucket(c.category_bucket_id);
12997 Bucket* name_bucket = GetBucket(c.name_bucket_id);
12998 if (!category_bucket || category_bucket->size() == 0 ||
12999 !name_bucket || name_bucket->size() == 0) {
[email protected]94307712012-11-16 23:26:1113000 return error::kInvalidArguments;
13001 }
dyencb86f2f2014-12-09 18:35:4113002
13003 std::string category_name;
13004 std::string trace_name;
13005 if (!category_bucket->GetAsString(&category_name) ||
13006 !name_bucket->GetAsString(&trace_name)) {
[email protected]94307712012-11-16 23:26:1113007 return error::kInvalidArguments;
13008 }
dyencb86f2f2014-12-09 18:35:4113009
dyencb86f2f2014-12-09 18:35:4113010 if (!gpu_tracer_->Begin(category_name, trace_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5113011 LOCAL_SET_GL_ERROR(
13012 GL_INVALID_OPERATION,
13013 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1413014 return error::kNoError;
13015 }
[email protected]94307712012-11-16 23:26:1113016 return error::kNoError;
13017}
13018
13019void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
dyen4bb43282015-01-08 01:09:5613020 if (!gpu_tracer_->End(kTraceCHROMIUM)) {
13021 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
13022 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1113023 return;
13024 }
[email protected]94307712012-11-16 23:26:1113025}
13026
[email protected]2f143d482013-03-14 18:04:4913027void GLES2DecoderImpl::DoDrawBuffersEXT(
13028 GLsizei count, const GLenum* bufs) {
13029 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
13030 LOCAL_SET_GL_ERROR(
13031 GL_INVALID_VALUE,
13032 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
13033 return;
13034 }
13035
13036 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
13037 if (framebuffer) {
13038 for (GLsizei i = 0; i < count; ++i) {
13039 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
13040 bufs[i] != GL_NONE) {
13041 LOCAL_SET_GL_ERROR(
13042 GL_INVALID_OPERATION,
13043 "glDrawBuffersEXT",
13044 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
13045 return;
13046 }
13047 }
13048 glDrawBuffersARB(count, bufs);
13049 framebuffer->SetDrawBuffers(count, bufs);
13050 } else { // backbuffer
13051 if (count > 1 ||
13052 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
13053 LOCAL_SET_GL_ERROR(
13054 GL_INVALID_OPERATION,
13055 "glDrawBuffersEXT",
13056 "more than one buffer or bufs not GL_NONE or GL_BACK");
13057 return;
13058 }
13059 GLenum mapped_buf = bufs[0];
13060 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
13061 bufs[0] == GL_BACK) {
13062 mapped_buf = GL_COLOR_ATTACHMENT0;
13063 }
13064 glDrawBuffersARB(count, &mapped_buf);
13065 group_->set_draw_buffer(bufs[0]);
13066 }
13067}
13068
[email protected]a6a09f852014-05-23 13:05:0313069void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
sieversfbaa5dc2015-04-28 00:45:3113070 MarkContextLost(GetContextLostReasonFromResetStatus(current));
13071 group_->LoseContexts(GetContextLostReasonFromResetStatus(other));
13072 reset_by_robustness_extension_ = true;
[email protected]a6a09f852014-05-23 13:05:0313073}
13074
kkinnunen337d59632014-08-26 10:19:5713075void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
13076 const GLfloat* matrix) {
13077 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
13078 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
13079 if (!features().chromium_path_rendering) {
13080 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
13081 "glMatrixLoadfCHROMIUM",
13082 "function not available");
13083 return;
13084 }
13085
13086 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
13087 ? state_.projection_matrix
13088 : state_.modelview_matrix;
13089 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
13090 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
13091 // since the values of the _NV and _CHROMIUM tokens match.
13092 glMatrixLoadfEXT(matrix_mode, matrix);
13093}
13094
13095void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
13096 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
13097 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
13098
13099 if (!features().chromium_path_rendering) {
13100 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
13101 "glMatrixLoadIdentityCHROMIUM",
13102 "function not available");
13103 return;
13104 }
13105
kkinnunen337d59632014-08-26 10:19:5713106 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
13107 ? state_.projection_matrix
13108 : state_.modelview_matrix;
13109 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
13110 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
13111 // since the values of the _NV and _CHROMIUM tokens match.
13112 glMatrixLoadIdentityEXT(matrix_mode);
13113}
13114
[email protected]32145a92012-12-17 09:01:5913115bool GLES2DecoderImpl::ValidateAsyncTransfer(
13116 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4713117 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5913118 GLenum target,
13119 GLint level,
13120 const void * data) {
13121 // We only support async uploads to 2D textures for now.
13122 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5113123 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5913124 return false;
13125 }
13126 // We only support uploads to level zero for now.
13127 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5113128 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5913129 return false;
13130 }
13131 // A transfer buffer must be bound, even for asyncTexImage2D.
13132 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5113133 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5913134 return false;
13135 }
13136 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4713137 if (!texture_ref ||
13138 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5113139 LOCAL_SET_GL_ERROR(
13140 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5913141 function_name, "transfer already in progress");
13142 return false;
13143 }
13144 return true;
13145}
13146
[email protected]e3c4a9ab2014-03-31 09:07:0213147base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
13148 uint32 async_upload_token,
13149 uint32 sync_data_shm_id,
13150 uint32 sync_data_shm_offset) {
13151 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2513152 if (!buffer.get() ||
13153 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0213154 return base::Closure();
13155
13156 AsyncMemoryParams mem_params(buffer,
13157 sync_data_shm_offset,
13158 sizeof(AsyncUploadSync));
13159
13160 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
13161 new AsyncUploadTokenCompletionObserver(async_upload_token));
13162
13163 return base::Bind(
13164 &AsyncPixelTransferManager::AsyncNotifyCompletion,
13165 base::Unretained(GetAsyncPixelTransferManager()),
13166 mem_params,
13167 observer);
13168}
13169
[email protected]69023942012-11-30 19:57:1613170error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3413171 uint32 immediate_data_size,
13172 const void* cmd_data) {
13173 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
13174 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1613175 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1613176 GLenum target = static_cast<GLenum>(c.target);
13177 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4413178 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1613179 GLsizei width = static_cast<GLsizei>(c.width);
13180 GLsizei height = static_cast<GLsizei>(c.height);
13181 GLint border = static_cast<GLint>(c.border);
13182 GLenum format = static_cast<GLenum>(c.format);
13183 GLenum type = static_cast<GLenum>(c.type);
13184 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
13185 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
13186 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0213187 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
13188 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
13189 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
13190
13191 base::ScopedClosureRunner scoped_completion_callback;
13192 if (async_upload_token) {
13193 base::Closure completion_closure =
13194 AsyncUploadTokenCompletionClosure(async_upload_token,
13195 sync_data_shm_id,
13196 sync_data_shm_offset);
13197 if (completion_closure.is_null())
13198 return error::kInvalidArguments;
13199
13200 scoped_completion_callback.Reset(completion_closure);
13201 }
[email protected]32145a92012-12-17 09:01:5913202
13203 // TODO(epenner): Move this and copies of this memory validation
13204 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1613205 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4213206 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
13207 NULL, NULL)) {
[email protected]69023942012-11-30 19:57:1613208 return error::kOutOfBounds;
13209 }
13210 const void* pixels = NULL;
13211 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
13212 pixels = GetSharedMemoryAs<const void*>(
13213 pixels_shm_id, pixels_shm_offset, pixels_size);
13214 if (!pixels) {
13215 return error::kOutOfBounds;
13216 }
13217 }
13218
zmode7b4382015-05-21 21:23:0013219 TextureManager::DoTexImageArguments args = {
13220 target, level, internal_format, width, height, 1, border, format, type,
zmo54f23712015-05-28 19:28:4913221 pixels, pixels_size, TextureManager::DoTexImageArguments::kTexImage2D };
[email protected]c986af502013-08-14 01:04:4413222 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5913223 // All the normal glTexSubImage2D validation.
zmo54f23712015-05-28 19:28:4913224 if (!texture_manager()->ValidateTexImage(
[email protected]c986af502013-08-14 01:04:4413225 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5913226 return error::kNoError;
13227 }
13228
13229 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4913230 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5913231 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4713232 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5913233 return error::kNoError;
13234
13235 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0713236 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5113237 LOCAL_SET_GL_ERROR(
13238 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5913239 "glAsyncTexImage2DCHROMIUM", "already defined");
13240 return error::kNoError;
13241 }
13242
[email protected]7989c9e2013-01-23 06:39:2613243 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5113244 LOCAL_SET_GL_ERROR(
13245 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2613246 return error::kNoError;
13247 }
13248
[email protected]5b3a8e02013-03-13 05:36:4413249 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3813250 AsyncTexImage2DParams tex_params = {
13251 target, level, static_cast<GLenum>(internal_format),
13252 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1213253 AsyncMemoryParams mem_params(
13254 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5913255
[email protected]5b3a8e02013-03-13 05:36:4413256 // Set up the async state if needed, and make the texture
13257 // immutable so the async state stays valid. The level info
13258 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1813259 AsyncPixelTransferDelegate* delegate =
13260 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
13261 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4413262 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5913263
[email protected]896425e2013-06-12 17:27:1813264 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4413265 tex_params,
13266 mem_params,
13267 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4913268 // The callback is only invoked if the transfer delegate still
13269 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4413270 // ownership that both of these pointers are valid.
13271 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4913272 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4413273 tex_params));
[email protected]f598f422012-12-07 08:30:0313274 return error::kNoError;
[email protected]69023942012-11-30 19:57:1613275}
13276
13277error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3413278 uint32 immediate_data_size,
13279 const void* cmd_data) {
13280 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
13281 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1613282 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1613283 GLenum target = static_cast<GLenum>(c.target);
13284 GLint level = static_cast<GLint>(c.level);
13285 GLint xoffset = static_cast<GLint>(c.xoffset);
13286 GLint yoffset = static_cast<GLint>(c.yoffset);
13287 GLsizei width = static_cast<GLsizei>(c.width);
13288 GLsizei height = static_cast<GLsizei>(c.height);
13289 GLenum format = static_cast<GLenum>(c.format);
13290 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0213291 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
13292 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
13293 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
13294
13295 base::ScopedClosureRunner scoped_completion_callback;
13296 if (async_upload_token) {
13297 base::Closure completion_closure =
13298 AsyncUploadTokenCompletionClosure(async_upload_token,
13299 sync_data_shm_id,
13300 sync_data_shm_offset);
13301 if (completion_closure.is_null())
13302 return error::kInvalidArguments;
13303
13304 scoped_completion_callback.Reset(completion_closure);
13305 }
[email protected]32145a92012-12-17 09:01:5913306
13307 // TODO(epenner): Move this and copies of this memory validation
13308 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1613309 uint32 data_size;
13310 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4213311 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]69023942012-11-30 19:57:1613312 NULL, NULL)) {
13313 return error::kOutOfBounds;
13314 }
13315 const void* pixels = GetSharedMemoryAs<const void*>(
13316 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5913317
13318 // All the normal glTexSubImage2D validation.
13319 error::Error error = error::kNoError;
13320 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
13321 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
13322 return error;
[email protected]69023942012-11-30 19:57:1613323 }
13324
[email protected]32145a92012-12-17 09:01:5913325 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4413326 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
13327 &state_, target);
[email protected]370eaf12013-05-18 09:19:4913328 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5913329 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4713330 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5913331 return error::kNoError;
13332
13333 // Guarantee async textures are always 'cleared' as follows:
13334 // - AsyncTexImage2D can not redefine an existing texture
13335 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
13336 // - AsyncTexSubImage2D clears synchronously if not already cleared.
13337 // - Textures become immutable after an async call.
13338 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0713339 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4913340 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
13341 target, level)) {
[email protected]ab09b612013-03-11 22:11:5113342 LOCAL_SET_GL_ERROR(
13343 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2513344 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5913345 return error::kNoError;
13346 }
13347 }
13348
[email protected]5b3a8e02013-03-13 05:36:4413349 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0313350 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5913351 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1213352 AsyncMemoryParams mem_params(
13353 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1813354 AsyncPixelTransferDelegate* delegate =
13355 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
13356 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4413357 // TODO(epenner): We may want to enforce exclusive use
13358 // of async APIs in which case this should become an error,
13359 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0313360 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4413361 0, 0, 0, 0, 0, 0};
zmo9a7b17e2015-05-06 00:22:3313362 texture->GetLevelSize(
13363 target, level, &define_params.width, &define_params.height, nullptr);
13364 texture->GetLevelType(
13365 target, level, &define_params.type, &define_params.internal_format);
[email protected]5b3a8e02013-03-13 05:36:4413366 // Set up the async state if needed, and make the texture
13367 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1813368 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4713369 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4413370 texture->SetImmutable(true);
13371 }
13372
[email protected]896425e2013-06-12 17:27:1813373 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5913374 return error::kNoError;
[email protected]69023942012-11-30 19:57:1613375}
13376
[email protected]a00c1f742013-03-05 17:02:1613377error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3413378 uint32 immediate_data_size,
13379 const void* cmd_data) {
13380 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
13381 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1613382 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
13383 GLenum target = static_cast<GLenum>(c.target);
13384
13385 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5113386 LOCAL_SET_GL_ERROR(
13387 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1613388 return error::kNoError;
13389 }
[email protected]c986af502013-08-14 01:04:4413390 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
13391 &state_, target);
[email protected]370eaf12013-05-18 09:19:4913392 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5113393 LOCAL_SET_GL_ERROR(
13394 GL_INVALID_OPERATION,
13395 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1613396 return error::kNoError;
13397 }
[email protected]896425e2013-06-12 17:27:1813398 AsyncPixelTransferDelegate* delegate =
13399 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
13400 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4913401 LOCAL_SET_GL_ERROR(
13402 GL_INVALID_OPERATION,
13403 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
13404 return error::kNoError;
13405 }
[email protected]896425e2013-06-12 17:27:1813406 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0913407 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1613408 return error::kNoError;
13409}
13410
[email protected]e3c4a9ab2014-03-31 09:07:0213411error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3413412 uint32 immediate_data_size,
13413 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0213414 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
13415
13416 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
13417 ProcessFinishedAsyncTransfers();
13418 return error::kNoError;
13419}
13420
zmo8fab00c2015-02-07 02:45:0513421error::Error GLES2DecoderImpl::HandleUniformBlockBinding(
13422 uint32_t immediate_data_size, const void* cmd_data) {
13423 if (!unsafe_es3_apis_enabled())
13424 return error::kUnknownCommand;
13425 const gles2::cmds::UniformBlockBinding& c =
13426 *static_cast<const gles2::cmds::UniformBlockBinding*>(cmd_data);
13427 GLuint client_id = c.program;
13428 GLuint index = static_cast<GLuint>(c.index);
13429 GLuint binding = static_cast<GLuint>(c.binding);
13430 Program* program = GetProgramInfoNotShader(
13431 client_id, "glUniformBlockBinding");
13432 if (!program) {
13433 return error::kNoError;
13434 }
13435 GLuint service_id = program->service_id();
13436 glUniformBlockBinding(service_id, index, binding);
13437 return error::kNoError;
13438}
13439
zmo3366957e2015-02-18 23:40:0713440error::Error GLES2DecoderImpl::HandleClientWaitSync(
13441 uint32_t immediate_data_size, const void* cmd_data) {
13442 if (!unsafe_es3_apis_enabled())
13443 return error::kUnknownCommand;
13444 const gles2::cmds::ClientWaitSync& c =
13445 *static_cast<const gles2::cmds::ClientWaitSync*>(cmd_data);
13446 GLuint sync = static_cast<GLuint>(c.sync);
13447 GLbitfield flags = static_cast<GLbitfield>(c.flags);
13448 GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1);
13449 typedef cmds::ClientWaitSync::Result Result;
13450 Result* result_dst = GetSharedMemoryAs<Result*>(
13451 c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
13452 if (!result_dst) {
13453 return error::kOutOfBounds;
13454 }
13455 if (*result_dst != GL_WAIT_FAILED) {
13456 return error::kInvalidArguments;
13457 }
13458 GLsync service_sync = 0;
13459 if (!group_->GetSyncServiceId(sync, &service_sync)) {
13460 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "ClientWaitSync", "invalid sync");
13461 return error::kNoError;
13462 }
13463 *result_dst = glClientWaitSync(service_sync, flags, timeout);
13464 return error::kNoError;
13465}
13466
zmo41e40582015-02-19 02:13:3013467error::Error GLES2DecoderImpl::HandleWaitSync(
13468 uint32_t immediate_data_size, const void* cmd_data) {
13469 if (!unsafe_es3_apis_enabled())
13470 return error::kUnknownCommand;
13471 const gles2::cmds::WaitSync& c =
13472 *static_cast<const gles2::cmds::WaitSync*>(cmd_data);
13473 GLuint sync = static_cast<GLuint>(c.sync);
13474 GLbitfield flags = static_cast<GLbitfield>(c.flags);
13475 GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1);
13476 GLsync service_sync = 0;
13477 if (!group_->GetSyncServiceId(sync, &service_sync)) {
13478 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "WaitSync", "invalid sync");
13479 return error::kNoError;
13480 }
13481 glWaitSync(service_sync, flags, timeout);
13482 return error::kNoError;
13483}
13484
zmo335fe5412015-06-05 22:23:4313485error::Error GLES2DecoderImpl::HandleGetInternalformativ(
13486 uint32_t immediate_data_size, const void* cmd_data) {
13487 if (!unsafe_es3_apis_enabled())
13488 return error::kUnknownCommand;
13489 const gles2::cmds::GetInternalformativ& c =
13490 *static_cast<const gles2::cmds::GetInternalformativ*>(cmd_data);
13491 GLenum target = static_cast<GLenum>(c.target);
13492 GLenum format = static_cast<GLenum>(c.format);
13493 GLenum pname = static_cast<GLenum>(c.pname);
13494 if (!validators_->render_buffer_target.IsValid(target)) {
13495 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetInternalformativ", target, "target");
13496 return error::kNoError;
13497 }
13498 if (!validators_->render_buffer_format.IsValid(format)) {
13499 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetInternalformativ", format, "format");
13500 return error::kNoError;
13501 }
13502 if (!validators_->internal_format_parameter.IsValid(pname)) {
13503 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetInternalformativ", pname, "pname");
13504 return error::kNoError;
13505 }
13506 typedef cmds::GetInternalformativ::Result Result;
13507 GLsizei num_values = 0;
13508 switch (pname) {
13509 case GL_NUM_SAMPLE_COUNTS:
13510 num_values = 1;
13511 break;
13512 case GL_SAMPLES:
13513 {
13514 GLint value = 0;
13515 glGetInternalformativ(target, format, GL_NUM_SAMPLE_COUNTS, 1, &value);
13516 num_values = static_cast<GLsizei>(value);
13517 }
13518 break;
13519 default:
13520 NOTREACHED();
13521 break;
13522 }
13523 Result* result = GetSharedMemoryAs<Result*>(
13524 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
13525 GLint* params = result ? result->GetData() : NULL;
13526 if (params == NULL) {
13527 return error::kOutOfBounds;
13528 }
13529 // Check that the client initialized the result.
13530 if (result->size != 0) {
13531 return error::kInvalidArguments;
13532 }
13533 glGetInternalformativ(target, format, pname, num_values, params);
13534 result->SetNumResults(num_values);
13535 return error::kNoError;
13536}
13537
zmoa06b9882015-03-10 20:50:3413538error::Error GLES2DecoderImpl::HandleMapBufferRange(
13539 uint32_t immediate_data_size, const void* cmd_data) {
13540 if (!unsafe_es3_apis_enabled()) {
13541 return error::kUnknownCommand;
13542 }
13543 const gles2::cmds::MapBufferRange& c =
13544 *static_cast<const gles2::cmds::MapBufferRange*>(cmd_data);
13545 GLenum target = static_cast<GLenum>(c.target);
13546 GLbitfield access = static_cast<GLbitfield>(c.access);
13547 GLintptr offset = static_cast<GLintptr>(c.offset);
13548 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
13549
13550 typedef cmds::MapBufferRange::Result Result;
13551 Result* result = GetSharedMemoryAs<Result*>(
13552 c.result_shm_id, c.result_shm_offset, sizeof(*result));
13553 if (!result) {
13554 return error::kOutOfBounds;
13555 }
13556 if (*result != 0) {
13557 *result = 0;
13558 return error::kInvalidArguments;
13559 }
13560 int8_t* mem =
13561 GetSharedMemoryAs<int8_t*>(c.data_shm_id, c.data_shm_offset, size);
13562 if (!mem) {
13563 return error::kOutOfBounds;
13564 }
13565
13566 GLbitfield mask = GL_MAP_INVALIDATE_BUFFER_BIT;
13567 if ((access & mask) == mask) {
13568 // TODO(zmo): To be on the safe side, always map
13569 // GL_MAP_INVALIDATE_BUFFER_BIT to GL_MAP_INVALIDATE_RANGE_BIT.
13570 access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT);
13571 access = (access | GL_MAP_INVALIDATE_RANGE_BIT);
13572 }
13573 // TODO(zmo): Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of
13574 // undefined behaviors.
13575 mask = GL_MAP_READ_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
13576 if ((access & mask) == mask) {
13577 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "MapBufferRange",
13578 "incompatible access bits");
13579 return error::kNoError;
13580 }
13581 access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT);
13582 if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT &&
13583 (access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) {
13584 access = (access | GL_MAP_READ_BIT);
13585 }
13586 void* ptr = glMapBufferRange(target, offset, size, access);
13587 if (ptr == nullptr) {
13588 return error::kNoError;
13589 }
13590 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
13591 DCHECK(buffer);
zmo2a09dc052015-03-12 00:48:2513592 buffer->SetMappedRange(offset, size, access, ptr,
13593 GetSharedMemoryBuffer(c.data_shm_id));
zmoa06b9882015-03-10 20:50:3413594 if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) {
13595 memcpy(mem, ptr, size);
13596 }
13597 *result = 1;
13598 return error::kNoError;
13599}
13600
zmo2a09dc052015-03-12 00:48:2513601error::Error GLES2DecoderImpl::HandleUnmapBuffer(
13602 uint32_t immediate_data_size, const void* cmd_data) {
13603 if (!unsafe_es3_apis_enabled()) {
13604 return error::kUnknownCommand;
13605 }
13606 const gles2::cmds::UnmapBuffer& c =
13607 *static_cast<const gles2::cmds::UnmapBuffer*>(cmd_data);
13608 GLenum target = static_cast<GLenum>(c.target);
13609
13610 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
13611 if (!buffer) {
13612 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", "no buffer bound");
13613 return error::kNoError;
13614 }
13615 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange();
13616 if (!mapped_range) {
13617 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer",
13618 "buffer is unmapped");
13619 return error::kNoError;
13620 }
13621 if ((mapped_range->access & GL_MAP_WRITE_BIT) == 0 ||
13622 (mapped_range->access & GL_MAP_FLUSH_EXPLICIT_BIT) ==
13623 GL_MAP_FLUSH_EXPLICIT_BIT) {
13624 // If we don't need to write back, or explict flush is required, no copying
13625 // back is needed.
13626 } else {
13627 void* mem = mapped_range->GetShmPointer();
13628 if (!mem) {
13629 return error::kOutOfBounds;
13630 }
13631 DCHECK(mapped_range->pointer);
13632 memcpy(mapped_range->pointer, mem, mapped_range->size);
13633 }
13634 buffer->RemoveMappedRange();
13635 GLboolean rt = glUnmapBuffer(target);
13636 if (rt == GL_FALSE) {
13637 // At this point, we have already done the necessary validation, so
13638 // GL_FALSE indicates data corruption.
13639 // TODO(zmo): We could redo the map / copy data / unmap to recover, but
13640 // the second unmap could still return GL_FALSE. For now, we simply lose
13641 // the contexts in the share group.
13642 LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE";
sieversfbaa5dc2015-04-28 00:45:3113643 // Need to lose current context before broadcasting!
13644 MarkContextLost(error::kGuilty);
13645 group_->LoseContexts(error::kInnocent);
zmo2a09dc052015-03-12 00:48:2513646 return error::kLostContext;
13647 }
13648 return error::kNoError;
13649}
13650
[email protected]91c94eb2013-10-22 10:32:5413651void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
13652 TextureRef* texture_ref) {
13653 Texture* texture = texture_ref->texture();
13654 DoDidUseTexImageIfNeeded(texture, texture->target());
13655}
13656
sieversfbaa5dc2015-04-28 00:45:3113657// Note that GL_LOST_CONTEXT is specific to GLES.
13658// For desktop GL we have to query the reset status proactively.
oetuaho37cc50e2014-10-31 11:19:2013659void GLES2DecoderImpl::OnContextLostError() {
sieversfbaa5dc2015-04-28 00:45:3113660 if (!WasContextLost()) {
13661 // Need to lose current context before broadcasting!
13662 CheckResetStatus();
13663 group_->LoseContexts(error::kUnknown);
13664 reset_by_robustness_extension_ = true;
13665 }
oetuaho37cc50e2014-10-31 11:19:2013666}
13667
[email protected]828a3932014-04-02 14:43:1313668void GLES2DecoderImpl::OnOutOfMemoryError() {
sieversfbaa5dc2015-04-28 00:45:3113669 if (lose_context_when_out_of_memory_ && !WasContextLost()) {
13670 error::ContextLostReason other = error::kOutOfMemory;
13671 if (CheckResetStatus()) {
13672 other = error::kUnknown;
13673 } else {
13674 // Need to lose current context before broadcasting!
13675 MarkContextLost(error::kOutOfMemory);
13676 }
13677 group_->LoseContexts(other);
[email protected]828a3932014-04-02 14:43:1313678 }
13679}
13680
[email protected]96449d2c2009-11-25 00:01:3213681// Include the auto-generated part of this file. We split this because it means
13682// we can easily edit the non-auto generated parts right here in this file
13683// instead of having to edit some template or the code generator.
13684#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
13685
13686} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2513687} // namespace gpu