blob: f76c085eb35b97d269bc5549fb29b0996e1b7a48 [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>
[email protected]f39f4b3f2010-05-12 17:04:0810#include <list>
[email protected]96449d2c2009-11-25 00:01:3211#include <map>
[email protected]94307712012-11-16 23:26:1112#include <stack>
[email protected]f39f4b3f2010-05-12 17:04:0813#include <string>
14#include <vector>
[email protected]5a6db6c2010-04-22 18:32:0615
[email protected]00eb49a2010-08-12 20:46:5716#include "base/at_exit.h"
[email protected]9d37f062011-11-22 01:24:5217#include "base/bind.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]5aa95ac2014-08-14 15:20:5620#include "base/float_util.h"
[email protected]3b63f8f42011-03-28 01:54:1521#include "base/memory/scoped_ptr.h"
[email protected]e3c4a9ab2014-03-31 09:07:0222#include "base/numerics/safe_math.h"
[email protected]f4390962013-06-11 07:29:2223#include "base/strings/string_number_conversions.h"
[email protected]6d668892013-12-04 21:37:1224#include "base/strings/string_split.h"
primiano05dadf012015-01-28 13:10:3225#include "base/trace_event/trace_event.h"
26#include "base/trace_event/trace_event_synthetic_delay.h"
[email protected]d37231fa2010-04-09 21:16:0227#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3228#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2229#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3230#include "gpu/command_buffer/common/gles2_cmd_format.h"
31#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1032#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5133#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2234#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
35#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5036#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3237#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5038#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2439#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5040#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1141#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5842#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3243#include "gpu/command_buffer/service/gl_utils.h"
sievers2384f2b2014-11-18 02:10:3544#include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h"
[email protected]43410e92012-04-20 17:06:2845#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4646#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1347#include "gpu/command_buffer/service/gpu_state_tracer.h"
[email protected]e844ae22012-01-14 03:36:2648#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1449#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3750#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5951#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2552#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4753#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5354#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5855#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4756#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4557#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0458#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]a93bb842010-02-16 23:03:4759#include "gpu/command_buffer/service/texture_manager.h"
orglofchcad5a6742014-11-07 19:51:1260#include "gpu/command_buffer/service/valuebuffer_manager.h"
[email protected]944b62f32012-09-27 02:20:4661#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2262#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]6896d7f2014-04-28 20:24:1563#include "third_party/smhasher/src/City.h"
[email protected]5a36dc132013-07-23 23:17:5564#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3765#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2766#include "ui/gl/gl_implementation.h"
67#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2768
[email protected]e51bdf32011-11-23 22:21:4669#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:5370#include <IOSurface/IOSurfaceAPI.h>
71// Note that this must be included after gl_bindings.h to avoid conflicts.
72#include <OpenGL/CGLIOSurface.h>
[email protected]e51bdf32011-11-23 22:21:4673#endif
[email protected]de17df392010-04-23 21:09:4174
[email protected]6eb775352013-08-27 05:57:1675#if defined(OS_WIN)
76#include "base/win/win_util.h"
77#endif
78
[email protected]a7a27ace2009-12-12 00:11:2579namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3280namespace gles2 {
81
[email protected]f0d74742011-10-03 16:31:0482namespace {
[email protected]693ca512012-11-13 18:09:1383
dongseong.hwang46305b12015-03-05 18:28:0484const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
85const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
86const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
87const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
88
89const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
90 0.0f, 1.0f, 0.0f, 0.0f,
91 0.0f, 0.0f, 1.0f, 0.0f,
92 0.0f, 0.0f, 0.0f, 1.0f};
[email protected]693ca512012-11-13 18:09:1393
[email protected]448e459e2013-06-12 17:00:4194static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
95 GLint rangeMax,
96 GLint precision) {
97 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
98}
99
[email protected]8dc1bf92013-03-12 03:58:21100static void GetShaderPrecisionFormatImpl(GLenum shader_type,
101 GLenum precision_type,
102 GLint *range, GLint *precision) {
103 switch (precision_type) {
104 case GL_LOW_INT:
105 case GL_MEDIUM_INT:
106 case GL_HIGH_INT:
107 // These values are for a 32-bit twos-complement integer format.
108 range[0] = 31;
109 range[1] = 30;
110 *precision = 0;
111 break;
112 case GL_LOW_FLOAT:
113 case GL_MEDIUM_FLOAT:
114 case GL_HIGH_FLOAT:
115 // These values are for an IEEE single-precision floating-point format.
116 range[0] = 127;
117 range[1] = 127;
118 *precision = 23;
119 break;
120 default:
121 NOTREACHED();
122 break;
123 }
124
[email protected]8af4d5e2013-03-15 23:55:33125 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
126 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21127 // This function is sometimes defined even though it's really just
128 // a stub, so we need to set range and precision as if it weren't
129 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44130 // On Mac OS with some GPUs, calling this generates a
131 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
132 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21133 glGetShaderPrecisionFormat(shader_type, precision_type,
134 range, precision);
[email protected]448e459e2013-06-12 17:00:41135
136 // TODO(brianderson): Make the following official workarounds.
137
138 // Some drivers have bugs where they report the ranges as a negative number.
139 // Taking the absolute value here shouldn't hurt because negative numbers
140 // aren't expected anyway.
141 range[0] = abs(range[0]);
142 range[1] = abs(range[1]);
143
144 // If the driver reports a precision for highp float that isn't actually
145 // highp, don't pretend like it's supported because shader compilation will
146 // fail anyway.
147 if (precision_type == GL_HIGH_FLOAT &&
148 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
149 range[0] = 0;
150 range[1] = 0;
151 *precision = 0;
152 }
[email protected]8dc1bf92013-03-12 03:58:21153 }
154}
155
[email protected]d286ebbc2014-07-03 17:19:10156static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
157 switch (plane_transform) {
158 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
159 return gfx::OVERLAY_TRANSFORM_NONE;
160 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
161 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
162 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
163 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
164 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
165 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
166 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
167 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
168 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
169 return gfx::OVERLAY_TRANSFORM_ROTATE_270;
170 default:
171 return gfx::OVERLAY_TRANSFORM_INVALID;
172 }
173}
174
[email protected]b04e24c2013-01-08 18:35:25175} // namespace
[email protected]f0d74742011-10-03 16:31:04176
[email protected]6217d392010-03-25 22:08:35177class GLES2DecoderImpl;
178
[email protected]ab09b612013-03-11 22:11:51179// Local versions of the SET_GL_ERROR macros
180#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50181 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51182#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50183 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
184 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51185#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50186 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
187 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51188#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50189 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
190 function_name)
[email protected]ab09b612013-03-11 22:11:51191#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50192 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51193#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50194 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51195#define LOCAL_PERFORMANCE_WARNING(msg) \
196 PerformanceWarning(__FILE__, __LINE__, msg)
197#define LOCAL_RENDER_WARNING(msg) \
198 RenderWarning(__FILE__, __LINE__, msg)
199
[email protected]07f54fcc2009-12-22 02:46:30200// Check that certain assumptions the code makes are true. There are places in
201// the code where shared memory is passed direclty to GL. Example, glUniformiv,
202// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
203// a few others) are 32bits. If they are not 32bits the code will have to change
204// to call those GL functions with service side memory and then copy the results
205// to shared memory, converting the sizes.
mostynb7f032092014-12-20 00:36:44206static_assert(sizeof(GLint) == sizeof(uint32), // NOLINT
207 "GLint should be the same size as uint32");
208static_assert(sizeof(GLsizei) == sizeof(uint32), // NOLINT
209 "GLsizei should be the same size as uint32");
210static_assert(sizeof(GLfloat) == sizeof(float), // NOLINT
211 "GLfloat should be the same size as float");
[email protected]07f54fcc2009-12-22 02:46:30212
[email protected]43f28f832010-02-03 02:28:48213// TODO(kbr): the use of this anonymous namespace core dumps the
214// linker on Mac OS X 10.6 when the symbol ordering file is used
215// namespace {
[email protected]96449d2c2009-11-25 00:01:32216
217// Returns the address of the first byte after a struct.
218template <typename T>
219const void* AddressAfterStruct(const T& pod) {
220 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
221}
222
[email protected]07f54fcc2009-12-22 02:46:30223// Returns the address of the frst byte after the struct or NULL if size >
224// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32225template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30226RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
227 uint32 size,
228 uint32 immediate_data_size) {
229 return (size <= immediate_data_size) ?
230 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
231 NULL;
[email protected]96449d2c2009-11-25 00:01:32232}
233
[email protected]07f54fcc2009-12-22 02:46:30234// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18235bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32236 GLuint count,
237 size_t size,
[email protected]a76b0052010-03-05 00:33:18238 unsigned int elements_per_unit,
239 uint32* dst) {
240 uint32 value;
241 if (!SafeMultiplyUint32(count, size, &value)) {
242 return false;
243 }
244 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
245 return false;
246 }
247 *dst = value;
248 return true;
[email protected]96449d2c2009-11-25 00:01:32249}
250
[email protected]258a3313f2011-10-18 20:13:57251// Return true if a character belongs to the ASCII subset as defined in
252// GLSL ES 1.0 spec section 3.1.
253static bool CharacterIsValidForGLES(unsigned char c) {
254 // Printing characters are valid except " $ ` @ \ ' DEL.
255 if (c >= 32 && c <= 126 &&
256 c != '"' &&
257 c != '$' &&
258 c != '`' &&
259 c != '@' &&
260 c != '\\' &&
261 c != '\'') {
262 return true;
263 }
264 // Horizontal tab, line feed, vertical tab, form feed, carriage return
265 // are also valid.
266 if (c >= 9 && c <= 13) {
267 return true;
268 }
269
270 return false;
271}
272
273static bool StringIsValidForGLES(const char* str) {
274 for (; *str; ++str) {
275 if (!CharacterIsValidForGLES(*str)) {
276 return false;
277 }
278 }
279 return true;
280}
281
[email protected]6217d392010-03-25 22:08:35282// This class prevents any GL errors that occur when it is in scope from
283// being reported to the client.
284class ScopedGLErrorSuppressor {
285 public:
[email protected]ab09b612013-03-11 22:11:51286 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30287 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35288 ~ScopedGLErrorSuppressor();
289 private:
[email protected]ab09b612013-03-11 22:11:51290 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30291 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35292 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
293};
294
[email protected]2b10c02d2014-01-29 16:43:02295// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35296// object goes out of scope. Also temporarily switches to using active texture
297// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02298class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35299 public:
[email protected]00c2cf92014-03-14 00:08:37300 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02301 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35302
303 private:
[email protected]ce296892013-10-24 22:04:36304 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02305 GLenum target_;
306 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35307};
308
309// Temporarily changes a decoder's bound render buffer and restore it when this
310// object goes out of scope.
311class ScopedRenderBufferBinder {
312 public:
[email protected]00c2cf92014-03-14 00:08:37313 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35314 ~ScopedRenderBufferBinder();
315
316 private:
[email protected]18e785a2013-10-09 03:29:41317 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35318 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
319};
320
321// Temporarily changes a decoder's bound frame buffer and restore it when this
322// object goes out of scope.
323class ScopedFrameBufferBinder {
324 public:
[email protected]00c2cf92014-03-14 00:08:37325 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35326 ~ScopedFrameBufferBinder();
327
328 private:
329 GLES2DecoderImpl* decoder_;
330 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
331};
332
[email protected]34ff8b0c2010-10-01 20:06:02333// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52334// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27335// if it is bound or enforce_internal_framebuffer is true. If internal is
336// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02337class ScopedResolvedFrameBufferBinder {
338 public:
[email protected]00c2cf92014-03-14 00:08:37339 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
340 bool enforce_internal_framebuffer,
341 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02342 ~ScopedResolvedFrameBufferBinder();
343
344 private:
345 GLES2DecoderImpl* decoder_;
346 bool resolve_and_bind_;
347 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
348};
349
[email protected]00c2cf92014-03-14 00:08:37350class ScopedModifyPixels {
351 public:
352 explicit ScopedModifyPixels(TextureRef* ref);
353 ~ScopedModifyPixels();
354
355 private:
356 TextureRef* ref_;
357};
358
359ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
360 if (ref_)
361 ref_->texture()->OnWillModifyPixels();
362}
363
364ScopedModifyPixels::~ScopedModifyPixels() {
365 if (ref_)
366 ref_->texture()->OnDidModifyPixels();
367}
368
369class ScopedRenderTo {
370 public:
371 explicit ScopedRenderTo(Framebuffer* framebuffer);
372 ~ScopedRenderTo();
373
374 private:
375 const Framebuffer* framebuffer_;
376};
377
378ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
379 : framebuffer_(framebuffer) {
380 if (framebuffer)
381 framebuffer_->OnWillRenderTo();
382}
383
384ScopedRenderTo::~ScopedRenderTo() {
385 if (framebuffer_)
386 framebuffer_->OnDidRenderTo();
387}
388
[email protected]6217d392010-03-25 22:08:35389// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35390class BackTexture {
[email protected]6217d392010-03-25 22:08:35391 public:
[email protected]ce296892013-10-24 22:04:36392 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35393 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35394
395 // Create a new render texture.
396 void Create();
397
398 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09399 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35400
401 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58402 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35403
404 // Destroy the render texture. This must be explicitly called before
405 // destroying this object.
406 void Destroy();
407
[email protected]97872062010-11-03 19:07:05408 // Invalidate the texture. This can be used when a context is lost and it is
409 // not possible to make it current in order to free the resource.
410 void Invalidate();
411
[email protected]6217d392010-03-25 22:08:35412 GLuint id() const {
413 return id_;
414 }
415
[email protected]d37231fa2010-04-09 21:16:02416 gfx::Size size() const {
417 return size_;
418 }
419
[email protected]6217d392010-03-25 22:08:35420 private:
[email protected]ff6493f2012-07-31 19:52:25421 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36422 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48423 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35424 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02425 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35426 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35427};
428
429// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35430class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35431 public:
[email protected]d5a28e452013-10-10 01:01:40432 explicit BackRenderbuffer(
433 RenderbufferManager* renderbuffer_manager,
434 MemoryTracker* memory_tracker,
435 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35436 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35437
438 // Create a new render buffer.
439 void Create();
440
441 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18442 bool AllocateStorage(const FeatureInfo* feature_info,
443 const gfx::Size& size,
444 GLenum format,
445 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35446
447 // Destroy the render buffer. This must be explicitly called before destroying
448 // this object.
449 void Destroy();
450
[email protected]97872062010-11-03 19:07:05451 // Invalidate the render buffer. This can be used when a context is lost and
452 // it is 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
459 private:
[email protected]d5a28e452013-10-10 01:01:40460 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25461 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40462 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48463 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35464 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35465 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35466};
467
468// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35469class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35470 public:
[email protected]ed9f9cd2013-02-27 21:12:35471 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
472 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35473
474 // Create a new frame buffer.
475 void Create();
476
477 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35478 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35479
[email protected]b9363b22010-06-09 22:06:15480 // Attach a render buffer to a frame buffer. Note that this unbinds any
481 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35482 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35483
[email protected]6217d392010-03-25 22:08:35484 // Destroy the frame buffer. This must be explicitly called before destroying
485 // this object.
486 void Destroy();
487
[email protected]97872062010-11-03 19:07:05488 // Invalidate the frame buffer. This can be used when a context is lost and it
489 // is not possible to make it current in order to free the resource.
490 void Invalidate();
491
[email protected]6217d392010-03-25 22:08:35492 // See glCheckFramebufferStatusEXT.
493 GLenum CheckStatus();
494
495 GLuint id() const {
496 return id_;
497 }
498
499 private:
500 GLES2DecoderImpl* decoder_;
501 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35502 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35503};
[email protected]34ff8b0c2010-10-01 20:06:02504
[email protected]5a36dc132013-07-23 23:17:55505struct FenceCallback {
506 explicit FenceCallback()
507 : fence(gfx::GLFence::Create()) {
508 DCHECK(fence);
509 }
[email protected]5a36dc132013-07-23 23:17:55510 std::vector<base::Closure> callbacks;
511 scoped_ptr<gfx::GLFence> fence;
512};
513
[email protected]e3c4a9ab2014-03-31 09:07:02514class AsyncUploadTokenCompletionObserver
515 : public AsyncPixelTransferCompletionObserver {
516 public:
517 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
518 : async_upload_token_(async_upload_token) {
519 }
520
dcheng1f4d1d72014-10-21 16:21:58521 void DidComplete(const AsyncMemoryParams& mem_params) override {
dcheng6ef3c5552014-08-30 05:34:19522 DCHECK(mem_params.buffer().get());
[email protected]e3c4a9ab2014-03-31 09:07:02523 void* data = mem_params.GetDataAddress();
524 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
525 sync->SetAsyncUploadToken(async_upload_token_);
526 }
527
528 private:
dcheng1f4d1d72014-10-21 16:21:58529 ~AsyncUploadTokenCompletionObserver() override {}
[email protected]e3c4a9ab2014-03-31 09:07:02530
531 uint32 async_upload_token_;
532
533 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
534};
535
[email protected]43f28f832010-02-03 02:28:48536// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32537
[email protected]efc87712014-07-09 00:22:47538// static
539const unsigned int GLES2Decoder::kDefaultStencilMask =
540 static_cast<unsigned int>(-1);
541
[email protected]ddb1e5a2010-12-13 20:10:45542bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
543 uint32* service_texture_id) {
544 return false;
545}
546
[email protected]a3ded6d2010-10-19 06:44:39547GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06548 : initialized_(false),
549 debug_(false),
zmo84c08202014-11-23 15:28:40550 log_commands_(false),
551 unsafe_es3_apis_enabled_(false) {
[email protected]96449d2c2009-11-25 00:01:32552}
553
[email protected]3916c97e2010-02-25 03:20:50554GLES2Decoder::~GLES2Decoder() {
555}
556
[email protected]cac16542014-01-15 17:53:51557void GLES2Decoder::BeginDecoding() {}
558
559void GLES2Decoder::EndDecoding() {}
560
[email protected]f39f4b3f2010-05-12 17:04:08561// This class implements GLES2Decoder so we don't have to expose all the GLES2
562// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54563class GLES2DecoderImpl : public GLES2Decoder,
[email protected]828a3932014-04-02 14:43:13564 public FramebufferManager::TextureDetachObserver,
565 public ErrorStateClient {
[email protected]f39f4b3f2010-05-12 17:04:08566 public:
[email protected]aa7666122011-09-02 19:45:52567 explicit GLES2DecoderImpl(ContextGroup* group);
dcheng1f4d1d72014-10-21 16:21:58568 ~GLES2DecoderImpl() override;
[email protected]f39f4b3f2010-05-12 17:04:08569
[email protected]96449d2c2009-11-25 00:01:32570 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58571 Error DoCommand(unsigned int command,
572 unsigned int arg_count,
573 const void* args) override;
[email protected]96449d2c2009-11-25 00:01:32574
dcheng1f4d1d72014-10-21 16:21:58575 error::Error DoCommands(unsigned int num_commands,
576 const void* buffer,
577 int num_entries,
578 int* entries_processed) override;
vmiura8266ca72014-09-09 21:37:00579
vmiura1c2b1de2014-09-19 19:03:24580 template <bool DebugImpl>
581 error::Error DoCommandsImpl(unsigned int num_commands,
582 const void* buffer,
583 int num_entries,
584 int* entries_processed);
585
[email protected]96449d2c2009-11-25 00:01:32586 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58587 const char* GetCommandName(unsigned int command_id) const override;
[email protected]96449d2c2009-11-25 00:01:32588
589 // Overridden from GLES2Decoder.
dcheng1f4d1d72014-10-21 16:21:58590 bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
591 const scoped_refptr<gfx::GLContext>& context,
592 bool offscreen,
dongseong.hwang4c04a162015-03-04 07:27:33593 const gfx::Size& offscreen_size,
dcheng1f4d1d72014-10-21 16:21:58594 const DisallowedFeatures& disallowed_features,
595 const std::vector<int32>& attribs) override;
596 void Destroy(bool have_context) override;
597 void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
598 void ProduceFrontBuffer(const Mailbox& mailbox) override;
599 bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
[email protected]9a5afa432011-07-22 18:16:39600 void UpdateParentTextureInfo();
dcheng1f4d1d72014-10-21 16:21:58601 bool MakeCurrent() override;
602 GLES2Util* GetGLES2Util() override { return &util_; }
603 gfx::GLContext* GetGLContext() override { return context_.get(); }
604 ContextGroup* GetContextGroup() override { return group_.get(); }
605 Capabilities GetCapabilities() override;
606 void RestoreState(const ContextState* prev_state) override;
[email protected]29a4d902013-02-26 20:18:06607
dcheng1f4d1d72014-10-21 16:21:58608 void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); }
609 void RestoreAllTextureUnitBindings(
mohan.reddy5e1b8952014-10-08 01:38:17610 const ContextState* prev_state) const override {
[email protected]5baa86bc2014-01-16 04:33:16611 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55612 }
dcheng1f4d1d72014-10-21 16:21:58613 void RestoreActiveTextureUnitBinding(unsigned int target) const override {
[email protected]4b2d2b262014-03-21 22:05:27614 state_.RestoreActiveTextureUnitBinding(target);
615 }
dcheng1f4d1d72014-10-21 16:21:58616 void RestoreBufferBindings() const override {
[email protected]29a4d902013-02-26 20:18:06617 state_.RestoreBufferBindings();
618 }
dcheng1f4d1d72014-10-21 16:21:58619 void RestoreGlobalState() const override { state_.RestoreGlobalState(NULL); }
620 void RestoreProgramBindings() const override {
[email protected]29a4d902013-02-26 20:18:06621 state_.RestoreProgramBindings();
622 }
dcheng1f4d1d72014-10-21 16:21:58623 void RestoreTextureUnitBindings(unsigned unit) const override {
[email protected]5baa86bc2014-01-16 04:33:16624 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06625 }
dcheng1f4d1d72014-10-21 16:21:58626 void RestoreFramebufferBindings() const override;
627 void RestoreRenderbufferBindings() override;
628 void RestoreTextureState(unsigned service_id) const override;
[email protected]29a4d902013-02-26 20:18:06629
dcheng1f4d1d72014-10-21 16:21:58630 void ClearAllAttributes() const override;
631 void RestoreAllAttributes() const override;
[email protected]cd2ef752014-02-12 23:16:03632
dcheng1f4d1d72014-10-21 16:21:58633 QueryManager* GetQueryManager() override { return query_manager_.get(); }
634 VertexArrayManager* GetVertexArrayManager() override {
[email protected]944b62f32012-09-27 02:20:46635 return vertex_array_manager_.get();
636 }
dcheng1f4d1d72014-10-21 16:21:58637 ImageManager* GetImageManager() override { return image_manager_.get(); }
orglofch33edd842014-12-03 05:32:15638
639 ValuebufferManager* GetValuebufferManager() override {
640 return valuebuffer_manager();
641 }
642
revemancc241eb2014-11-11 03:30:37643 bool ProcessPendingQueries(bool did_finish) override;
orglofch33edd842014-12-03 05:32:15644
dcheng1f4d1d72014-10-21 16:21:58645 bool HasMoreIdleWork() override;
646 void PerformIdleWork() override;
[email protected]43f28f832010-02-03 02:28:48647
dcheng1f4d1d72014-10-21 16:21:58648 void WaitForReadPixels(base::Closure callback) override;
[email protected]5a36dc132013-07-23 23:17:55649
dcheng1f4d1d72014-10-21 16:21:58650 void SetResizeCallback(
mohan.reddy5e1b8952014-10-08 01:38:17651 const base::Callback<void(gfx::Size, float)>& callback) override;
[email protected]22f320a2011-08-30 01:17:00652
dcheng1f4d1d72014-10-21 16:21:58653 Logger* GetLogger() override;
[email protected]cac16542014-01-15 17:53:51654
dcheng1f4d1d72014-10-21 16:21:58655 void BeginDecoding() override;
656 void EndDecoding() override;
[email protected]cac16542014-01-15 17:53:51657
dcheng1f4d1d72014-10-21 16:21:58658 ErrorState* GetErrorState() override;
659 const ContextState* GetContextState() override { return &state_; }
[email protected]1d82e822013-04-10 21:32:32660
dcheng1f4d1d72014-10-21 16:21:58661 void SetShaderCacheCallback(const ShaderCacheCallback& callback) override;
662 void SetWaitSyncPointCallback(const WaitSyncPointCallback& callback) override;
[email protected]22f320a2011-08-30 01:17:00663
dcheng1f4d1d72014-10-21 16:21:58664 AsyncPixelTransferManager* GetAsyncPixelTransferManager() override;
665 void ResetAsyncPixelTransferManagerForTest() override;
666 void SetAsyncPixelTransferManagerForTest(
mohan.reddy5e1b8952014-10-08 01:38:17667 AsyncPixelTransferManager* manager) override;
dcheng1f4d1d72014-10-21 16:21:58668 void SetIgnoreCachedStateForTest(bool ignore) override;
[email protected]69a8701e2013-03-07 21:31:09669 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59670
dcheng1f4d1d72014-10-21 16:21:58671 bool GetServiceTextureId(uint32 client_texture_id,
672 uint32* service_texture_id) override;
[email protected]43f28f832010-02-03 02:28:48673
dcheng1f4d1d72014-10-21 16:21:58674 uint32 GetTextureUploadCount() override;
675 base::TimeDelta GetTotalTextureUploadTime() override;
676 base::TimeDelta GetTotalProcessingCommandsTime() override;
677 void AddProcessingCommandsTime(base::TimeDelta) override;
[email protected]63b465922012-09-06 02:04:52678
[email protected]8e3e0662010-08-23 18:46:30679 // Restores the current state to the user's settings.
680 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30681
[email protected]297ca1c2011-06-20 23:08:46682 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
683 void ApplyDirtyState();
684
685 // These check the state of the currently bound framebuffer or the
686 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54687 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
688 // check with all attached and enabled color attachments.
689 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46690 bool BoundFramebufferHasDepthAttachment();
691 bool BoundFramebufferHasStencilAttachment();
692
dcheng1f4d1d72014-10-21 16:21:58693 error::ContextLostReason GetContextLostReason() override;
[email protected]38d139d2011-07-14 00:38:43694
[email protected]91c94eb2013-10-22 10:32:54695 // Overridden from FramebufferManager::TextureDetachObserver:
dcheng1f4d1d72014-10-21 16:21:58696 void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) override;
[email protected]91c94eb2013-10-22 10:32:54697
[email protected]828a3932014-04-02 14:43:13698 // Overriden from ErrorStateClient.
oetuaho37cc50e2014-10-31 11:19:20699 void OnContextLostError() override;
dcheng1f4d1d72014-10-21 16:21:58700 void OnOutOfMemoryError() override;
[email protected]828a3932014-04-02 14:43:13701
[email protected]8875a5f2014-06-27 08:33:47702 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
703 void EnsureRenderbufferBound();
704
[email protected]f42f05b2013-11-15 21:46:18705 // Helpers to facilitate calling into compatible extensions.
706 static void RenderbufferStorageMultisampleHelper(
707 const FeatureInfo* feature_info,
708 GLenum target,
709 GLsizei samples,
710 GLenum internal_format,
711 GLsizei width,
712 GLsizei height);
713
714 void BlitFramebufferHelper(GLint srcX0,
715 GLint srcY0,
716 GLint srcX1,
717 GLint srcY1,
718 GLint dstX0,
719 GLint dstY0,
720 GLint dstX1,
721 GLint dstY1,
722 GLbitfield mask,
723 GLenum filter);
[email protected]345ba902013-11-14 21:39:00724
[email protected]96449d2c2009-11-25 00:01:32725 private:
[email protected]70d34263c2013-01-09 00:27:45726 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02727 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35728 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35729
[email protected]c2f8c8402010-12-06 18:07:24730 // Initialize or re-initialize the shader translator.
731 bool InitializeShaderTranslator();
732
[email protected]302ce6d2011-07-07 23:28:11733 void UpdateCapabilities();
734
[email protected]ae51d192010-04-27 00:48:03735 // Helpers for the glGen and glDelete functions.
736 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
737 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
738 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
739 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
740 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
741 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
742 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
743 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
orglofchcad5a6742014-11-07 19:51:12744 bool GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
745 void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53746 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
747 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46748 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
749 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47750
[email protected]e3c4a9ab2014-03-31 09:07:02751 // Helper for async upload token completion notification callback.
752 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
753 uint32 sync_data_shm_id,
754 uint32 sync_data_shm_offset);
755
756
757
[email protected]70d34263c2013-01-09 00:27:45758 // Workarounds
759 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51760 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45761
[email protected]3916c97e2010-02-25 03:20:50762 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50763 BufferManager* buffer_manager() {
764 return group_->buffer_manager();
765 }
766
[email protected]a25fa872010-03-25 02:57:58767 RenderbufferManager* renderbuffer_manager() {
768 return group_->renderbuffer_manager();
769 }
770
771 FramebufferManager* framebuffer_manager() {
772 return group_->framebuffer_manager();
773 }
774
orglofchcad5a6742014-11-07 19:51:12775 ValuebufferManager* valuebuffer_manager() {
776 return group_->valuebuffer_manager();
777 }
778
[email protected]3916c97e2010-02-25 03:20:50779 ProgramManager* program_manager() {
780 return group_->program_manager();
781 }
782
783 ShaderManager* shader_manager() {
784 return group_->shader_manager();
785 }
786
[email protected]03cef9b2014-04-03 15:58:14787 ShaderTranslatorCache* shader_translator_cache() {
788 return group_->shader_translator_cache();
789 }
790
[email protected]29a4d902013-02-26 20:18:06791 const TextureManager* texture_manager() const {
792 return group_->texture_manager();
793 }
794
[email protected]3916c97e2010-02-25 03:20:50795 TextureManager* texture_manager() {
796 return group_->texture_manager();
797 }
798
[email protected]78b514b2012-05-01 21:50:59799 MailboxManager* mailbox_manager() {
800 return group_->mailbox_manager();
801 }
802
[email protected]b63f1d62014-07-18 15:40:59803 ImageManager* image_manager() { return image_manager_.get(); }
[email protected]09d50362012-10-18 20:54:37804
[email protected]944b62f32012-09-27 02:20:46805 VertexArrayManager* vertex_array_manager() {
806 return vertex_array_manager_.get();
807 }
808
[email protected]7989c9e2013-01-23 06:39:26809 MemoryTracker* memory_tracker() {
810 return group_->memory_tracker();
811 }
812
813 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
814 MemoryTracker* tracker = memory_tracker();
815 if (tracker) {
816 return tracker->EnsureGPUMemoryAvailable(estimated_size);
817 }
818 return true;
819 }
820
[email protected]34ff8b0c2010-10-01 20:06:02821 bool IsOffscreenBufferMultisampled() const {
822 return offscreen_target_samples_ > 1;
823 }
824
[email protected]ed9f9cd2013-02-27 21:12:35825 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49826 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03827 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35828 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47829 }
830
831 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49832 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07833 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47834 }
835
836 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35837 void RemoveTexture(GLuint client_id) {
838 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50839 }
[email protected]a93bb842010-02-16 23:03:47840
[email protected]d37231fa2010-04-09 21:16:02841 // Get the size (in pixels) of the currently bound frame buffer (either FBO
842 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30843 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02844
[email protected]9edc6b22010-12-23 02:00:26845 // Get the format of the currently bound frame buffer (either FBO or regular
846 // back buffer)
[email protected]68586372013-12-11 01:27:59847 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26848 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46849 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26850
[email protected]a93bb842010-02-16 23:03:47851 // Wrapper for CompressedTexImage2D commands.
852 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37853 GLenum target,
854 GLint level,
855 GLenum internal_format,
856 GLsizei width,
857 GLsizei height,
858 GLint border,
859 GLsizei image_size,
860 const void* data);
[email protected]a93bb842010-02-16 23:03:47861
[email protected]cadde4a2010-07-31 17:10:43862 // Wrapper for CompressedTexSubImage2D.
863 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37864 GLenum target,
865 GLint level,
866 GLint xoffset,
867 GLint yoffset,
868 GLsizei width,
869 GLsizei height,
870 GLenum format,
871 GLsizei imageSize,
872 const void * data);
[email protected]cadde4a2010-07-31 17:10:43873
874 // Wrapper for CopyTexImage2D.
875 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37876 GLenum target,
877 GLint level,
878 GLenum internal_format,
879 GLint x,
880 GLint y,
881 GLsizei width,
882 GLsizei height,
883 GLint border);
[email protected]cadde4a2010-07-31 17:10:43884
[email protected]6d792ee12013-05-15 00:40:56885 // Wrapper for SwapBuffers.
886 void DoSwapBuffers();
887
bajones2345c1f2014-12-09 04:45:51888 // Wrapper for SwapInterval.
889 void DoSwapInterval(int interval);
890
[email protected]cadde4a2010-07-31 17:10:43891 // Wrapper for CopyTexSubImage2D.
892 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37893 GLenum target,
894 GLint level,
895 GLint xoffset,
896 GLint yoffset,
897 GLint x,
898 GLint y,
899 GLsizei width,
900 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43901
[email protected]f598f422012-12-07 08:30:03902 // Validation for TexSubImage2D.
903 bool ValidateTexSubImage2D(
904 error::Error* error,
905 const char* function_name,
906 GLenum target,
907 GLint level,
908 GLint xoffset,
909 GLint yoffset,
910 GLsizei width,
911 GLsizei height,
912 GLenum format,
913 GLenum type,
914 const void * data);
915
[email protected]cadde4a2010-07-31 17:10:43916 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03917 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37918 GLenum target,
919 GLint level,
920 GLint xoffset,
921 GLint yoffset,
922 GLsizei width,
923 GLsizei height,
924 GLenum format,
925 GLenum type,
926 const void * data);
[email protected]cadde4a2010-07-31 17:10:43927
[email protected]32145a92012-12-17 09:01:59928 // Extra validation for async tex(Sub)Image2D.
929 bool ValidateAsyncTransfer(
930 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47931 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59932 GLenum target,
933 GLint level,
934 const void * data);
935
[email protected]e51bdf32011-11-23 22:21:46936 // Wrapper for TexImageIOSurface2DCHROMIUM.
937 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37938 GLenum target,
939 GLsizei width,
940 GLsizei height,
941 GLuint io_surface_id,
942 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46943
dongseong.hwang46305b12015-03-05 18:28:04944 void DoCopyTextureCHROMIUM(GLenum target,
945 GLuint source_id,
946 GLuint dest_id,
947 GLenum internal_format,
948 GLenum dest_type);
949
950 void DoCopySubTextureCHROMIUM(GLenum target,
951 GLuint source_id,
952 GLuint dest_id,
953 GLint xoffset,
954 GLint yoffset);
[email protected]43410e92012-04-20 17:06:28955
[email protected]97dc7cbe2011-12-06 17:26:17956 // Wrapper for TexStorage2DEXT.
957 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37958 GLenum target,
959 GLint levels,
960 GLenum internal_format,
961 GLsizei width,
962 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17963
[email protected]78b514b2012-05-01 21:50:59964 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22965 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
966 const GLbyte* key);
967 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
968 GLenum target, const GLbyte* data);
969
[email protected]78b514b2012-05-01 21:50:59970 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22971 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
972 GLuint client_id);
[email protected]78b514b2012-05-01 21:50:59973
orglofchcad5a6742014-11-07 19:51:12974 bool DoIsValuebufferCHROMIUM(GLuint client_id);
975 void DoBindValueBufferCHROMIUM(GLenum target, GLuint valuebuffer);
976 void DoSubscribeValueCHROMIUM(GLenum target, GLenum subscription);
977 void DoPopulateSubscribedValuesCHROMIUM(GLenum target);
978 void DoUniformValueBufferCHROMIUM(GLint location,
979 GLenum target,
980 GLenum subscription);
981
[email protected]09d50362012-10-18 20:54:37982 void DoBindTexImage2DCHROMIUM(
983 GLenum target,
984 GLint image_id);
985 void DoReleaseTexImage2DCHROMIUM(
986 GLenum target,
987 GLint image_id);
988
[email protected]94307712012-11-16 23:26:11989 void DoTraceEndCHROMIUM(void);
990
[email protected]2f143d482013-03-14 18:04:49991 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
992
[email protected]a6a09f852014-05-23 13:05:03993 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
994
kkinnunen337d59632014-08-26 10:19:57995 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
996 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
997
[email protected]ed9f9cd2013-02-27 21:12:35998 // Creates a Program for the given program.
999 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:571000 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:351001 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471002 }
1003
[email protected]07f54fcc2009-12-22 02:46:301004 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351005 Program* GetProgram(GLuint client_id) {
1006 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:461007 }
[email protected]07f54fcc2009-12-22 02:46:301008
[email protected]cae20172012-12-07 00:06:191009#if defined(NDEBUG)
1010 void LogClientServiceMapping(
1011 const char* /* function_name */,
1012 GLuint /* client_id */,
1013 GLuint /* service_id */) {
1014 }
1015 template<typename T>
1016 void LogClientServiceForInfo(
1017 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
1018 }
1019#else
1020 void LogClientServiceMapping(
1021 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:261022 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:471023 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
1024 << ": client_id = " << client_id
1025 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:261026 }
[email protected]cae20172012-12-07 00:06:191027 }
1028 template<typename T>
1029 void LogClientServiceForInfo(
1030 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:261031 if (info) {
[email protected]cae20172012-12-07 00:06:191032 LogClientServiceMapping(function_name, client_id, info->service_id());
1033 }
1034 }
1035#endif
1036
[email protected]6b8cf1a2010-05-06 16:13:581037 // Gets the program info for the given program. If it's not a program
1038 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:351039 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:581040 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421041 Program* program = GetProgram(client_id);
1042 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351043 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511044 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431045 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581046 } else {
[email protected]ab09b612013-03-11 22:11:511047 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581048 }
1049 }
[email protected]df37b9932013-03-08 05:21:421050 LogClientServiceForInfo(program, client_id, function_name);
1051 return program;
[email protected]6b8cf1a2010-05-06 16:13:581052 }
1053
1054
[email protected]ed9f9cd2013-02-27 21:12:351055 // Creates a Shader for the given shader.
1056 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571057 GLuint client_id,
1058 GLuint service_id,
1059 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351060 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571061 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311062 }
1063
1064 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351065 Shader* GetShader(GLuint client_id) {
1066 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311067 }
1068
[email protected]6b8cf1a2010-05-06 16:13:581069 // Gets the shader info for the given shader. If it's not a shader generates a
1070 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351071 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581072 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421073 Shader* shader = GetShader(client_id);
1074 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351075 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511076 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431077 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581078 } else {
[email protected]ab09b612013-03-11 22:11:511079 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431080 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581081 }
1082 }
[email protected]df37b9932013-03-08 05:21:421083 LogClientServiceForInfo(shader, client_id, function_name);
1084 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581085 }
1086
[email protected]a93bb842010-02-16 23:03:471087 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351088 void CreateBuffer(GLuint client_id, GLuint service_id) {
1089 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471090 }
1091
[email protected]07f54fcc2009-12-22 02:46:301092 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211093 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071094 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1095 return buffer;
[email protected]1d32bc82010-01-13 22:06:461096 }
[email protected]07f54fcc2009-12-22 02:46:301097
[email protected]a93bb842010-02-16 23:03:471098 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1099 // on glDeleteBuffers so we can make sure the user does not try to render
1100 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351101 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471102
[email protected]a25fa872010-03-25 02:57:581103 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351104 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1105 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581106 }
1107
1108 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061109 Framebuffer* GetFramebuffer(GLuint client_id) {
1110 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581111 }
1112
1113 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351114 void RemoveFramebuffer(GLuint client_id) {
1115 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581116 }
1117
1118 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351119 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1120 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031121 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581122 }
1123
1124 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271125 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1126 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581127 }
1128
1129 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351130 void RemoveRenderbuffer(GLuint client_id) {
1131 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581132 }
1133
orglofchcad5a6742014-11-07 19:51:121134 // Creates a valuebuffer info for the given valuebuffer.
1135 void CreateValuebuffer(GLuint client_id) {
1136 return valuebuffer_manager()->CreateValuebuffer(client_id);
1137 }
1138
1139 // Gets the valuebuffer info for a given valuebuffer.
1140 Valuebuffer* GetValuebuffer(GLuint client_id) {
1141 return valuebuffer_manager()->GetValuebuffer(client_id);
1142 }
1143
1144 // Removes the valuebuffer info for the given valuebuffer.
1145 void RemoveValuebuffer(GLuint client_id) {
1146 valuebuffer_manager()->RemoveValuebuffer(client_id);
1147 }
1148
[email protected]944b62f32012-09-27 02:20:461149 // Gets the vertex attrib manager for the given vertex array.
1150 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1151 VertexAttribManager* info =
1152 vertex_array_manager()->GetVertexAttribManager(client_id);
1153 return info;
1154 }
1155
1156 // Removes the vertex attrib manager for the given vertex array.
1157 void RemoveVertexAttribManager(GLuint client_id) {
1158 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1159 }
1160
1161 // Creates a vertex attrib manager for the given vertex array.
[email protected]da364812014-05-09 21:39:481162 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1163 GLuint client_id,
1164 GLuint service_id,
1165 bool client_visible) {
1166 return vertex_array_manager()->CreateVertexAttribManager(
1167 client_id, service_id, group_->max_vertex_attribs(), client_visible);
[email protected]944b62f32012-09-27 02:20:461168 }
1169
[email protected]258a3313f2011-10-18 20:13:571170 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331171 void DoBindUniformLocationCHROMIUM(
1172 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571173
[email protected]558847a2010-03-24 07:02:541174 error::Error GetAttribLocationHelper(
zmo4a16ff992015-02-05 22:18:411175 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1176 const std::string& name_str);
[email protected]558847a2010-03-24 07:02:541177
1178 error::Error GetUniformLocationHelper(
zmo4a16ff992015-02-05 22:18:411179 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1180 const std::string& name_str);
[email protected]558847a2010-03-24 07:02:541181
zmo5393fb52015-01-27 01:50:481182 error::Error GetFragDataLocationHelper(
zmo4a16ff992015-02-05 22:18:411183 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1184 const std::string& name_str);
zmo5393fb52015-01-27 01:50:481185
zmo1bb3d1d2015-01-21 20:29:431186 // Wrapper for glShaderSource.
1187 void DoShaderSource(
1188 GLuint client_id, GLsizei count, const char** data, const GLint* length);
[email protected]07f54fcc2009-12-22 02:46:301189
zmo38923562015-01-29 20:17:391190 // Wrapper for glTransformFeedbackVaryings.
1191 void DoTransformFeedbackVaryings(
1192 GLuint client_program_id, GLsizei count, const char* const* varyings,
1193 GLenum buffer_mode);
1194
[email protected]0d6bfdc2011-11-02 01:32:201195 // Clear any textures used by the current program.
1196 bool ClearUnclearedTextures();
1197
[email protected]0d6bfdc2011-11-02 01:32:201198 // Clears any uncleared attachments attached to the given frame buffer.
1199 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061200 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281201
[email protected]0d6bfdc2011-11-02 01:32:201202 // overridden from GLES2Decoder
boliu45dc77a2015-02-25 23:26:311203 bool ClearLevel(Texture* texture,
dcheng1f4d1d72014-10-21 16:21:581204 unsigned target,
1205 int level,
1206 unsigned internal_format,
1207 unsigned format,
1208 unsigned type,
1209 int width,
1210 int height,
1211 bool is_texture_immutable) override;
[email protected]0d6bfdc2011-11-02 01:32:201212
[email protected]c007aa02010-09-02 22:22:401213 // Restore all GL state that affects clearing.
1214 void RestoreClearState();
1215
[email protected]3a2e7c7b2010-08-06 01:12:281216 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461217 // Returns: true if glEnable/glDisable should actually be called.
1218 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281219
[email protected]0d6bfdc2011-11-02 01:32:201220 // Check that the currently bound framebuffers are valid.
1221 // Generates GL error if not.
1222 bool CheckBoundFramebuffersValid(const char* func_name);
1223
[email protected]2ea5950d2014-07-09 18:20:341224 // Check that the currently bound read framebuffer has a color image
1225 // attached. Generates GL error if not.
1226 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1227
zmo383512cf2014-10-14 00:11:001228 // Check that the currently bound read framebuffer's color image
1229 // isn't the target texture of the glCopyTex{Sub}Image2D.
1230 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
1231
[email protected]0d6bfdc2011-11-02 01:32:201232 // Check if a framebuffer meets our requirements.
1233 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351234 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201235 GLenum target,
1236 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271237
orglofchcad5a6742014-11-07 19:51:121238 // Check if the current valuebuffer exists and is valid. If not generates
1239 // the appropriate GL error. Returns true if the current valuebuffer is in
1240 // a usable state.
1241 bool CheckCurrentValuebuffer(const char* function_name);
1242
1243 // Check if the current valuebuffer exists and is valiud and that the
1244 // value buffer is actually subscribed to the given subscription
1245 bool CheckCurrentValuebufferForSubscription(GLenum subscription,
1246 const char* function_name);
1247
1248 // Check if the location can be used for the given subscription target. If not
1249 // generates the appropriate GL error. Returns true if the location is usable
1250 bool CheckSubscriptionTarget(GLint location,
1251 GLenum subscription,
1252 const char* function_name);
1253
[email protected]939e7362010-05-13 20:49:101254 // Checks if the current program exists and is valid. If not generates the
1255 // appropriate GL error. Returns true if the current program is in a usable
1256 // state.
1257 bool CheckCurrentProgram(const char* function_name);
1258
1259 // Checks if the current program exists and is valid and that location is not
1260 // -1. If the current program is not valid generates the appropriate GL
1261 // error. Returns true if the current program is in a usable state and
1262 // location is not -1.
1263 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1264
zmof9a81360f2014-10-17 00:06:141265 // Checks if the current program samples a texture that is also the color
1266 // image of the current bound framebuffer, i.e., the source and destination
1267 // of the draw operation are the same.
1268 bool CheckDrawingFeedbackLoops();
1269
orglofchcad5a6742014-11-07 19:51:121270 // Checks if |api_type| is valid for the given uniform
1271 // If the api type is not valid generates the appropriate GL
1272 // error. Returns true if |api_type| is valid for the uniform
1273 bool CheckUniformForApiType(const Program::UniformInfo* info,
1274 const char* function_name,
1275 Program::UniformApiType api_type);
1276
[email protected]939e7362010-05-13 20:49:101277 // Gets the type of a uniform for a location in the current program. Sets GL
1278 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361279 // program is valid and the location exists. Adjusts count so it
1280 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131281 bool PrepForSetUniformByLocation(GLint fake_location,
1282 const char* function_name,
1283 Program::UniformApiType api_type,
1284 GLint* real_location,
1285 GLenum* type,
1286 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101287
[email protected]b177ae22011-11-01 03:29:111288 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021289 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111290
[email protected]b273e432010-04-12 17:23:581291 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1292 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1293
[email protected]ac77603c72013-03-08 13:52:061294 // Helper for glGetVertexAttrib
1295 void GetVertexAttribHelper(
1296 const VertexAttrib* attrib, GLenum pname, GLint* param);
1297
[email protected]3916c97e2010-02-25 03:20:501298 // Wrapper for glActiveTexture
1299 void DoActiveTexture(GLenum texture_unit);
1300
[email protected]ae51d192010-04-27 00:48:031301 // Wrapper for glAttachShader
1302 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1303
[email protected]96449d2c2009-11-25 00:01:321304 // Wrapper for glBindBuffer since we need to track the current targets.
1305 void DoBindBuffer(GLenum target, GLuint buffer);
1306
[email protected]86093972010-03-11 00:13:561307 // Wrapper for glBindFramebuffer since we need to track the current targets.
1308 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1309
1310 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1311 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1312
[email protected]a93bb842010-02-16 23:03:471313 // Wrapper for glBindTexture since we need to track the current targets.
1314 void DoBindTexture(GLenum target, GLuint texture);
1315
[email protected]944b62f32012-09-27 02:20:461316 // Wrapper for glBindVertexArrayOES
1317 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571318 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461319
[email protected]49cabed2013-11-13 18:15:181320 // Wrapper for glBlitFramebufferCHROMIUM.
1321 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301322 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1323 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1324 GLbitfield mask, GLenum filter);
1325
[email protected]36cef8ce2010-03-16 07:34:451326 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111327 void DoBufferSubData(
1328 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1329
[email protected]36cef8ce2010-03-16 07:34:451330 // Wrapper for glCheckFramebufferStatus
1331 GLenum DoCheckFramebufferStatus(GLenum target);
1332
[email protected]3a03a8f2011-03-19 00:51:271333 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081334 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271335
[email protected]88a61bf2012-10-27 13:00:421336 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421337 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251338 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281339
[email protected]45bf5152010-02-12 00:11:311340 // Wrapper for glCompileShader.
1341 void DoCompileShader(GLuint shader);
1342
[email protected]ae51d192010-04-27 00:48:031343 // Wrapper for glDetachShader
1344 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1345
[email protected]3a2e7c7b2010-08-06 01:12:281346 // Wrapper for glDisable
1347 void DoDisable(GLenum cap);
1348
[email protected]07f54fcc2009-12-22 02:46:301349 // Wrapper for glDisableVertexAttribArray.
1350 void DoDisableVertexAttribArray(GLuint index);
1351
[email protected]60f22d32012-12-12 00:31:581352 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1353 // attachments.
1354 void DoDiscardFramebufferEXT(GLenum target,
1355 GLsizei numAttachments,
1356 const GLenum* attachments);
1357
[email protected]3a2e7c7b2010-08-06 01:12:281358 // Wrapper for glEnable
1359 void DoEnable(GLenum cap);
1360
[email protected]07f54fcc2009-12-22 02:46:301361 // Wrapper for glEnableVertexAttribArray.
1362 void DoEnableVertexAttribArray(GLuint index);
1363
[email protected]882ba1e22012-03-08 19:02:531364 // Wrapper for glFinish.
1365 void DoFinish();
1366
1367 // Wrapper for glFlush.
1368 void DoFlush();
1369
[email protected]36cef8ce2010-03-16 07:34:451370 // Wrapper for glFramebufferRenderbufffer.
1371 void DoFramebufferRenderbuffer(
1372 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1373 GLuint renderbuffer);
1374
1375 // Wrapper for glFramebufferTexture2D.
1376 void DoFramebufferTexture2D(
1377 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1378 GLint level);
1379
[email protected]7d3c36e2013-07-12 14:13:161380 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1381 void DoFramebufferTexture2DMultisample(
1382 GLenum target, GLenum attachment, GLenum textarget,
1383 GLuint texture, GLint level, GLsizei samples);
1384
1385 // Common implementation for both DoFramebufferTexture2D wrappers.
1386 void DoFramebufferTexture2DCommon(const char* name,
1387 GLenum target, GLenum attachment, GLenum textarget,
1388 GLuint texture, GLint level, GLsizei samples);
1389
zmo84c08202014-11-23 15:28:401390 // Wrapper for glFramebufferTextureLayer.
1391 void DoFramebufferTextureLayer(
1392 GLenum target, GLenum attachment, GLuint texture, GLint level,
1393 GLint layer);
1394
[email protected]a93bb842010-02-16 23:03:471395 // Wrapper for glGenerateMipmap
1396 void DoGenerateMipmap(GLenum target);
1397
[email protected]7d3c36e2013-07-12 14:13:161398 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1399 // to account for different pname values defined in different extension
1400 // variants.
1401 GLenum AdjustGetPname(GLenum pname);
1402
[email protected]b273e432010-04-12 17:23:581403 // Wrapper for DoGetBooleanv.
1404 void DoGetBooleanv(GLenum pname, GLboolean* params);
1405
1406 // Wrapper for DoGetFloatv.
1407 void DoGetFloatv(GLenum pname, GLfloat* params);
1408
[email protected]36cef8ce2010-03-16 07:34:451409 // Wrapper for glGetFramebufferAttachmentParameteriv.
1410 void DoGetFramebufferAttachmentParameteriv(
1411 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1412
[email protected]a0c3e972010-04-21 00:49:131413 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581414 void DoGetIntegerv(GLenum pname, GLint* params);
1415
[email protected]29a9eb52010-04-13 09:04:231416 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061417 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231418 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1419
[email protected]17cfbe0e2013-03-07 01:26:081420 // Wrapper for glGetBufferParameteriv.
1421 void DoGetBufferParameteriv(
1422 GLenum target, GLenum pname, GLint* params);
1423
[email protected]a0c3e972010-04-21 00:49:131424 // Wrapper for glGetProgramiv.
1425 void DoGetProgramiv(
1426 GLuint program_id, GLenum pname, GLint* params);
1427
[email protected]36cef8ce2010-03-16 07:34:451428 // Wrapper for glRenderbufferParameteriv.
1429 void DoGetRenderbufferParameteriv(
1430 GLenum target, GLenum pname, GLint* params);
1431
[email protected]ddd968b82010-03-02 00:44:291432 // Wrapper for glGetShaderiv
1433 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1434
[email protected]4c6f5462014-03-05 00:26:561435 // Wrappers for glGetTexParameter.
1436 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1437 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1438 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1439
[email protected]b1122982010-05-17 23:04:241440 // Wrappers for glGetVertexAttrib.
1441 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1442 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1443
[email protected]1958e0e2010-04-22 05:17:151444 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241445 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151446 bool DoIsBuffer(GLuint client_id);
1447 bool DoIsFramebuffer(GLuint client_id);
1448 bool DoIsProgram(GLuint client_id);
1449 bool DoIsRenderbuffer(GLuint client_id);
1450 bool DoIsShader(GLuint client_id);
1451 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461452 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151453
[email protected]07f54fcc2009-12-22 02:46:301454 // Wrapper for glLinkProgram
1455 void DoLinkProgram(GLuint program);
1456
[email protected]36cef8ce2010-03-16 07:34:451457 // Wrapper for glRenderbufferStorage.
1458 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031459 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451460
[email protected]49cabed2013-11-13 18:15:181461 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1462 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301463 GLenum target, GLsizei samples, GLenum internalformat,
1464 GLsizei width, GLsizei height);
1465
[email protected]49cabed2013-11-13 18:15:181466 // Handler for glRenderbufferStorageMultisampleEXT
1467 // (multisampled_render_to_texture).
1468 void DoRenderbufferStorageMultisampleEXT(
1469 GLenum target, GLsizei samples, GLenum internalformat,
1470 GLsizei width, GLsizei height);
1471
1472 // Common validation for multisample extensions.
1473 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1474 GLenum internalformat,
1475 GLsizei width,
1476 GLsizei height);
1477
[email protected]4a4c18b2013-09-13 22:50:101478 // Verifies that the currently bound multisample renderbuffer is valid
1479 // Very slow! Only done on platforms with driver bugs that return invalid
1480 // buffers under memory pressure
1481 bool VerifyMultisampleRenderbufferIntegrity(
1482 GLuint renderbuffer, GLenum format);
1483
[email protected]b273e432010-04-12 17:23:581484 // Wrapper for glReleaseShaderCompiler.
1485 void DoReleaseShaderCompiler() { }
1486
zmobcb3fdd62014-12-11 00:49:031487 // Wrappers for glSamplerParameter*v functions.
1488 void DoSamplerParameterfv(
1489 GLuint sampler, GLenum pname, const GLfloat* params);
1490 void DoSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* params);
1491
[email protected]3916c97e2010-02-25 03:20:501492 // Wrappers for glTexParameter functions.
1493 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1494 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1495 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1496 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1497
1498 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1499 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121500 void DoUniform1i(GLint fake_location, GLint v0);
1501 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1502 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1503 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1504 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101505
1506 // Wrappers for glUniformfv because some drivers don't correctly accept
1507 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121508 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1509 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1510 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1511 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501512
[email protected]43c2f1f2011-03-25 18:35:361513 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121514 GLint fake_location, GLsizei count, GLboolean transpose,
1515 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361516 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121517 GLint fake_location, GLsizei count, GLboolean transpose,
1518 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361519 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121520 GLint fake_location, GLsizei count, GLboolean transpose,
1521 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361522
[email protected]af6380962012-11-29 23:24:131523 bool SetVertexAttribValue(
1524 const char* function_name, GLuint index, const GLfloat* value);
1525
[email protected]b1122982010-05-17 23:04:241526 // Wrappers for glVertexAttrib??
1527 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1528 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1529 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1530 void DoVertexAttrib4f(
1531 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1532 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1533 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1534 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1535 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1536
[email protected]43410e92012-04-20 17:06:281537 // Wrapper for glViewport
1538 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1539
[email protected]07f54fcc2009-12-22 02:46:301540 // Wrapper for glUseProgram
1541 void DoUseProgram(GLuint program);
1542
[email protected]ae51d192010-04-27 00:48:031543 // Wrapper for glValidateProgram.
1544 void DoValidateProgram(GLuint program_client_id);
1545
[email protected]d2a0e1a2012-08-12 02:25:011546 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1547 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1548 void DoPopGroupMarkerEXT(void);
1549
[email protected]4e8a5b122010-05-08 22:00:101550 // Gets the number of values that will be returned by glGetXXX. Returns
1551 // false if pname is unknown.
1552 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1553
[email protected]07f54fcc2009-12-22 02:46:301554 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431555 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101556 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1557 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301558
[email protected]c13e1da62011-09-09 21:48:301559 // Returns true if successful, simulated will be true if attrib0 was
1560 // simulated.
[email protected]c6aef902012-02-14 03:31:421561 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431562 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231563 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241564
[email protected]91c94eb2013-10-22 10:32:541565 // If an image is bound to texture, this will call Will/DidUseTexImage
1566 // if needed.
1567 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1568 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1569
1570 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111571 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541572 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501573
[email protected]8fbedc02010-11-18 18:43:401574 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421575 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431576 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421577 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401578 void RestoreStateForSimulatedFixedAttribs();
1579
[email protected]c6aef902012-02-14 03:31:421580 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101581 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421582 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431583 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421584 bool instanced, GLenum mode, GLint first, GLsizei count,
1585 GLsizei primcount);
1586 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431587 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421588 bool instanced, GLenum mode, GLsizei count, GLenum type,
1589 int32 offset, GLsizei primcount);
1590
[email protected]61eeb33f2011-07-26 15:30:311591 GLenum GetBindTargetForSamplerType(GLenum type) {
1592 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461593 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1594 switch (type) {
1595 case GL_SAMPLER_2D:
1596 return GL_TEXTURE_2D;
1597 case GL_SAMPLER_CUBE:
1598 return GL_TEXTURE_CUBE_MAP;
1599 case GL_SAMPLER_EXTERNAL_OES:
1600 return GL_TEXTURE_EXTERNAL_OES;
1601 case GL_SAMPLER_2D_RECT_ARB:
1602 return GL_TEXTURE_RECTANGLE_ARB;
1603 }
1604
1605 NOTREACHED();
1606 return 0;
[email protected]61eeb33f2011-07-26 15:30:311607 }
1608
[email protected]8e3e0662010-08-23 18:46:301609 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061610 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1611 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301612 switch (target) {
1613 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451614 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341615 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301616 break;
[email protected]ebfb73c2012-08-15 02:37:451617 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341618 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301619 break;
1620 default:
1621 NOTREACHED();
1622 break;
1623 }
[email protected]4d8f0dd2013-03-09 14:37:061624 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301625 }
1626
[email protected]ed9f9cd2013-02-27 21:12:351627 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201628 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271629 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201630 switch (target) {
1631 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111632 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201633 break;
1634 default:
1635 NOTREACHED();
1636 break;
1637 }
[email protected]ee2a79c32013-03-10 03:50:271638 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201639 }
1640
[email protected]f7b85372010-02-03 01:11:371641 // Validates the program and location for a glGetUniform call and returns
1642 // a SizeResult setup to receive the result. Returns true if glGetUniform
1643 // should be called.
1644 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121645 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371646 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121647 error::Error* error, GLint* real_location, GLuint* service_id,
1648 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371649
jbauman7a059312014-10-16 19:30:541650 void MaybeExitOnContextLost();
dcheng1f4d1d72014-10-21 16:21:581651 bool WasContextLost() override;
1652 bool WasContextLostByRobustnessExtension() override;
1653 void LoseContext(uint32 reset_status) override;
[email protected]38d139d2011-07-14 00:38:431654
[email protected]e51bdf32011-11-23 22:21:461655#if defined(OS_MACOSX)
1656 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1657#endif
1658
[email protected]ad84a3a2012-06-08 21:42:431659 bool ValidateCompressedTexDimensions(
1660 const char* function_name,
1661 GLint level, GLsizei width, GLsizei height, GLenum format);
1662 bool ValidateCompressedTexFuncData(
1663 const char* function_name,
1664 GLsizei width, GLsizei height, GLenum format, size_t size);
1665 bool ValidateCompressedTexSubDimensions(
1666 const char* function_name,
1667 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1668 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351669 Texture* texture);
dongseong.hwang46305b12015-03-05 18:28:041670 bool ValidateCopyTextureCHROMIUM(const char* function_name,
1671 GLenum target,
1672 TextureRef* source_texture_ref,
1673 TextureRef* dest_texture_ref,
1674 GLenum dest_internal_format);
[email protected]ad84a3a2012-06-08 21:42:431675
[email protected]ab09b612013-03-11 22:11:511676 void RenderWarning(const char* filename, int line, const std::string& msg);
1677 void PerformanceWarning(
1678 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011679
[email protected]62e155e2012-10-23 22:43:151680 const FeatureInfo::FeatureFlags& features() const {
1681 return feature_info_->feature_flags();
1682 }
1683
1684 const FeatureInfo::Workarounds& workarounds() const {
1685 return feature_info_->workarounds();
1686 }
1687
[email protected]a7266a92012-06-28 02:11:081688 bool ShouldDeferDraws() {
1689 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341690 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081691 surface_->DeferDraws();
1692 }
1693
[email protected]09e17272012-11-30 10:30:441694 bool ShouldDeferReads() {
1695 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341696 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441697 surface_->DeferDraws();
1698 }
1699
dongseong.hwange1cb2aa2015-02-11 09:33:331700 bool IsRobustnessSupported() {
1701 return has_robustness_extension_ &&
1702 context_->WasAllocatedUsingRobustnessExtension();
1703 }
1704
[email protected]c76fe672013-12-13 23:30:221705 error::Error WillAccessBoundFramebufferForDraw() {
1706 if (ShouldDeferDraws())
1707 return error::kDeferCommandUntilLater;
1708 if (!offscreen_target_frame_buffer_.get() &&
1709 !framebuffer_state_.bound_draw_framebuffer.get() &&
1710 !surface_->SetBackbufferAllocation(true))
1711 return error::kLostContext;
1712 return error::kNoError;
1713 }
1714
1715 error::Error WillAccessBoundFramebufferForRead() {
1716 if (ShouldDeferReads())
1717 return error::kDeferCommandUntilLater;
1718 if (!offscreen_target_frame_buffer_.get() &&
1719 !framebuffer_state_.bound_read_framebuffer.get() &&
1720 !surface_->SetBackbufferAllocation(true))
1721 return error::kLostContext;
1722 return error::kNoError;
1723 }
1724
vmiura8266ca72014-09-09 21:37:001725 // Set remaining commands to process to 0 to force DoCommands to return
1726 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1727 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1728
[email protected]5a36dc132013-07-23 23:17:551729 void ProcessPendingReadPixels();
1730 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1731
[email protected]96449d2c2009-11-25 00:01:321732 // Generate a member function prototype for each command in an automated and
1733 // typesafe way.
vmiuracd108592014-09-08 14:36:341734#define GLES2_CMD_OP(name) \
1735 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321736
1737 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1738
1739 #undef GLES2_CMD_OP
1740
[email protected]2f2d7042010-04-14 21:45:581741 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381742 scoped_refptr<gfx::GLSurface> surface_;
1743 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021744
[email protected]a3ded6d2010-10-19 06:44:391745 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351746 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391747
[email protected]1d82e822013-04-10 21:32:321748 DebugMarkerManager debug_marker_manager_;
1749 Logger logger_;
1750
[email protected]e259eb412012-10-13 05:47:241751 // All the state for this context.
1752 ContextState state_;
1753
[email protected]34ff8b0c2010-10-01 20:06:021754 // Current width and height of the offscreen frame buffer.
1755 gfx::Size offscreen_size_;
1756
[email protected]96449d2c2009-11-25 00:01:321757 // Util to help with GL.
1758 GLES2Util util_;
1759
[email protected]43410e92012-04-20 17:06:281760 // unpack flip y as last set by glPixelStorei
1761 bool unpack_flip_y_;
1762
[email protected]6c75c712012-06-19 15:43:171763 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281764 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171765 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281766
[email protected]b1122982010-05-17 23:04:241767 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1768 GLuint attrib_0_buffer_id_;
1769
1770 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131771 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241772
[email protected]fc753442011-02-04 19:49:491773 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1774 bool attrib_0_buffer_matches_value_;
1775
[email protected]b1122982010-05-17 23:04:241776 // The size of attrib 0.
1777 GLsizei attrib_0_size_;
1778
[email protected]8fbedc02010-11-18 18:43:401779 // The buffer used to simulate GL_FIXED attribs.
1780 GLuint fixed_attrib_buffer_id_;
1781
1782 // The size of fiixed attrib buffer.
1783 GLsizei fixed_attrib_buffer_size_;
1784
[email protected]b9363b22010-06-09 22:06:151785 // The offscreen frame buffer that the client renders to. With EGL, the
1786 // depth and stencil buffers are separate. With regular GL there is a single
1787 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1788 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351789 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1790 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1791 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1792 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1793 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021794 GLenum offscreen_target_color_format_;
1795 GLenum offscreen_target_depth_format_;
1796 GLenum offscreen_target_stencil_format_;
1797 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561798 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351799
[email protected]de26b3c2011-08-03 21:54:271800 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351801 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1802 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491803 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351804 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271805
1806 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351807 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1808 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051809 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351810
[email protected]882ba1e22012-03-08 19:02:531811 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531812
[email protected]944b62f32012-09-27 02:20:461813 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1814
[email protected]b63f1d62014-07-18 15:40:591815 scoped_ptr<ImageManager> image_manager_;
1816
[email protected]729c0b42013-05-26 02:05:071817 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001818
[email protected]840a7e462013-02-27 01:29:511819 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481820
[email protected]e3932abb2013-03-13 00:01:371821 ShaderCacheCallback shader_cache_callback_;
1822
[email protected]85a4ac22013-05-31 01:58:471823 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421824
[email protected]32fe9aa2011-01-21 23:47:131825 // The format of the back buffer_
1826 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461827 bool back_buffer_has_depth_;
1828 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131829
achaulkcf5316f2014-09-26 19:28:421830 bool surfaceless_;
1831
[email protected]60f22d32012-12-12 00:31:581832 // Backbuffer attachments that are currently undefined.
1833 uint32 backbuffer_needs_clear_bits_;
1834
[email protected]a6a09f852014-05-23 13:05:031835 // The current decoder error communicates the decoder error through command
1836 // processing functions that do not return the error value. Should be set only
1837 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561838 error::Error current_decoder_error_;
1839
[email protected]b1d2dcb2010-05-17 19:24:181840 bool use_shader_translator_;
dyen0ff9e4402015-02-12 22:27:431841 scoped_refptr<ShaderTranslatorInterface> vertex_translator_;
1842 scoped_refptr<ShaderTranslatorInterface> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181843
[email protected]e82fb792011-09-22 00:33:291844 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411845
[email protected]915a59a12010-09-30 21:29:111846 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051847 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351848 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051849
[email protected]65225772011-05-12 21:10:241850 int frame_number_;
1851
vmiura8266ca72014-09-09 21:37:001852 // Number of commands remaining to be processed in DoCommands().
1853 int commands_to_process_;
1854
[email protected]706b69f2012-07-27 04:59:301855 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431856 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221857 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431858 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431859
[email protected]f0d74742011-10-03 16:31:041860 // These flags are used to override the state of the shared feature_info_
1861 // member. Because the same FeatureInfo instance may be shared among many
1862 // contexts, the assumptions on the availablity of extensions in WebGL
1863 // contexts may be broken. These flags override the shared state to preserve
1864 // WebGL semantics.
1865 bool force_webgl_glsl_validation_;
1866 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491867 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131868 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061869 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041870
[email protected]062c38b2012-01-18 03:25:101871 bool compile_shader_always_succeeds_;
1872
[email protected]828a3932014-04-02 14:43:131873 // An optional behaviour to lose the context and group when OOM.
1874 bool lose_context_when_out_of_memory_;
1875
[email protected]cae20172012-12-07 00:06:191876 // Log extra info.
1877 bool service_logging_;
1878
[email protected]e51bdf32011-11-23 22:21:461879#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531880 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461881 TextureToIOSurfaceMap texture_to_io_surface_map_;
1882#endif
1883
[email protected]43410e92012-04-20 17:06:281884 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
sievers2384f2b2014-11-18 02:10:351885 scoped_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_;
[email protected]43410e92012-04-20 17:06:281886
[email protected]1868a342012-11-07 15:56:021887 // Cached values of the currently assigned viewport dimensions.
1888 GLsizei viewport_max_width_;
1889 GLsizei viewport_max_height_;
1890
[email protected]63b465922012-09-06 02:04:521891 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521892 base::TimeDelta total_processing_commands_time_;
1893
[email protected]c986af502013-08-14 01:04:441894 // States related to each manager.
1895 DecoderTextureState texture_state_;
1896 DecoderFramebufferState framebuffer_state_;
1897
[email protected]fb97b662013-02-20 23:02:141898 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131899 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:241900 const unsigned char* cb_command_trace_category_;
dyencb86f2f2014-12-09 18:35:411901 const unsigned char* gpu_decoder_category_;
[email protected]cac16542014-01-15 17:53:511902 int gpu_trace_level_;
1903 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:241904 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:111905
[email protected]5a36dc132013-07-23 23:17:551906 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1907
[email protected]4a4c18b2013-09-13 22:50:101908 // Used to validate multisample renderbuffers if needed
1909 GLuint validation_texture_;
1910 GLuint validation_fbo_multisample_;
1911 GLuint validation_fbo_;
1912
vmiuracd108592014-09-08 14:36:341913 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1914 uint32 immediate_data_size,
1915 const void* data);
1916
1917 // A struct to hold info about each command.
1918 struct CommandInfo {
1919 CmdHandler cmd_handler;
1920 uint8 arg_flags; // How to handle the arguments for this command
1921 uint8 cmd_flags; // How to handle this command
1922 uint16 arg_count; // How many arguments are expected for this command.
1923 };
1924
1925 // A table of CommandInfo for all the commands.
1926 static const CommandInfo command_info[kNumCommands - kStartPoint];
1927
[email protected]96449d2c2009-11-25 00:01:321928 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1929};
1930
vmiuracd108592014-09-08 14:36:341931const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1932#define GLES2_CMD_OP(name) \
1933 { \
1934 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
1935 cmds::name::cmd_flags, \
1936 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1937 } \
1938 , /* NOLINT */
1939 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1940#undef GLES2_CMD_OP
1941};
1942
[email protected]ab09b612013-03-11 22:11:511943ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301944 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511945 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301946 error_state_(error_state) {
1947 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351948}
1949
1950ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301951 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351952}
1953
[email protected]2b10c02d2014-01-29 16:43:021954static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361955 TextureUnit& info = state->texture_units[0];
1956 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021957 scoped_refptr<TextureRef> texture_ref;
1958 switch (target) {
1959 case GL_TEXTURE_2D:
1960 texture_ref = info.bound_texture_2d;
1961 break;
1962 case GL_TEXTURE_CUBE_MAP:
1963 texture_ref = info.bound_texture_cube_map;
1964 break;
1965 case GL_TEXTURE_EXTERNAL_OES:
1966 texture_ref = info.bound_texture_external_oes;
1967 break;
1968 case GL_TEXTURE_RECTANGLE_ARB:
1969 texture_ref = info.bound_texture_rectangle_arb;
1970 break;
1971 default:
1972 NOTREACHED();
1973 break;
1974 }
1975 if (texture_ref.get()) {
1976 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361977 } else {
1978 last_id = 0;
1979 }
1980
[email protected]2b10c02d2014-01-29 16:43:021981 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361982 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1983}
1984
[email protected]2b10c02d2014-01-29 16:43:021985ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1986 GLuint id,
1987 GLenum target)
1988 : state_(state),
1989 target_(target) {
[email protected]ab09b612013-03-11 22:11:511990 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021991 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351992
1993 // TODO(apatrick): Check if there are any other states that need to be reset
1994 // before binding a new texture.
1995 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021996 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351997}
1998
[email protected]2b10c02d2014-01-29 16:43:021999ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:512000 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:022001 "ScopedTextureBinder::dtor", state_->GetErrorState());
2002 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:352003}
2004
[email protected]18e785a2013-10-09 03:29:412005ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:352006 GLuint id)
[email protected]18e785a2013-10-09 03:29:412007 : state_(state) {
[email protected]ab09b612013-03-11 22:11:512008 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:412009 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352010 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
2011}
2012
2013ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512014 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:412015 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
2016 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:352017}
2018
2019ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
2020 GLuint id)
2021 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:512022 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302023 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352024 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:452025 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:352026}
2027
2028ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512029 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302030 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:302031 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:352032}
2033
[email protected]34ff8b0c2010-10-01 20:06:022034ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:272035 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:522036 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:342037 resolve_and_bind_ = (
2038 decoder_->offscreen_target_frame_buffer_.get() &&
2039 decoder_->IsOffscreenBufferMultisampled() &&
2040 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
2041 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:022042 if (!resolve_and_bind_)
2043 return;
2044
[email protected]ab09b612013-03-11 22:11:512045 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302046 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022047 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
2048 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:272049 GLuint targetid;
2050 if (internal) {
2051 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
2052 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:352053 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:272054 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352055 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:362056 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:272057 decoder_->offscreen_resolved_color_texture_->Create();
2058
2059 DCHECK(decoder_->offscreen_saved_color_format_);
2060 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:092061 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
2062 false);
[email protected]de26b3c2011-08-03 21:54:272063 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
2064 decoder_->offscreen_resolved_color_texture_.get());
2065 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
2066 GL_FRAMEBUFFER_COMPLETE) {
2067 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
2068 << "because offscreen resolved FBO was incomplete.";
2069 return;
2070 }
2071 }
2072 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
2073 } else {
2074 targetid = decoder_->offscreen_saved_frame_buffer_->id();
2075 }
2076 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022077 const int width = decoder_->offscreen_size_.width();
2078 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:452079 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:182080 decoder->BlitFramebufferHelper(0,
2081 0,
2082 width,
2083 height,
2084 0,
2085 0,
2086 width,
2087 height,
2088 GL_COLOR_BUFFER_BIT,
2089 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:272090 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022091}
2092
2093ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
2094 if (!resolve_and_bind_)
2095 return;
2096
[email protected]ab09b612013-03-11 22:11:512097 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302098 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022099 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222100 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452101 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182102 }
[email protected]34ff8b0c2010-10-01 20:06:022103}
2104
[email protected]ce296892013-10-24 22:04:362105BackTexture::BackTexture(
2106 MemoryTracker* memory_tracker,
2107 ContextState* state)
2108 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2109 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482110 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252111 id_(0) {
[email protected]6217d392010-03-25 22:08:352112}
2113
[email protected]ed9f9cd2013-02-27 21:12:352114BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352115 // This does not destroy the render texture because that would require that
2116 // the associated GL context was current. Just check that it was explicitly
2117 // destroyed.
2118 DCHECK_EQ(id_, 0u);
2119}
2120
[email protected]ed9f9cd2013-02-27 21:12:352121void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302122 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362123 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352124 Destroy();
2125 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022126 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162131
2132 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2133 // never called on an offscreen context, no data will ever be uploaded to the
2134 // saved offscreen color texture (it is deferred until to when SwapBuffers
2135 // is called). My idea is that some nvidia drivers might have a bug where
2136 // deleting a texture that has never been populated might cause a
2137 // crash.
2138 glTexImage2D(
2139 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482140
2141 bytes_allocated_ = 16u * 16u * 4u;
2142 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352143}
2144
[email protected]ed9f9cd2013-02-27 21:12:352145bool BackTexture::AllocateStorage(
2146 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352147 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302148 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362149 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022150 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092151 uint32 image_size = 0;
2152 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:422153 size.width(), size.height(), 1, format, GL_UNSIGNED_BYTE, 8, &image_size,
[email protected]678a73f2012-12-19 19:22:092154 NULL, NULL);
2155
[email protected]7989c9e2013-01-23 06:39:262156 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2157 return false;
2158 }
2159
[email protected]40d90a22013-04-09 03:39:552160 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092161 if (zero) {
2162 zero_data.reset(new char[image_size]);
2163 memset(zero_data.get(), 0, image_size);
2164 }
[email protected]6217d392010-03-25 22:08:352165
[email protected]8f1d2aa2013-05-10 23:45:382166 glTexImage2D(GL_TEXTURE_2D,
2167 0, // mip level
2168 format,
2169 size.width(),
2170 size.height(),
2171 0, // border
2172 format,
2173 GL_UNSIGNED_BYTE,
2174 zero_data.get());
[email protected]6217d392010-03-25 22:08:352175
[email protected]d37231fa2010-04-09 21:16:022176 size_ = size;
2177
[email protected]1078f912011-12-23 13:12:142178 bool success = glGetError() == GL_NO_ERROR;
2179 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482180 memory_tracker_.TrackMemFree(bytes_allocated_);
2181 bytes_allocated_ = image_size;
2182 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142183 }
2184 return success;
[email protected]6217d392010-03-25 22:08:352185}
2186
[email protected]ed9f9cd2013-02-27 21:12:352187void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352188 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302189 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362190 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022191 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352192 glCopyTexImage2D(GL_TEXTURE_2D,
2193 0, // level
[email protected]3a4d0c52011-06-29 23:11:582194 format,
[email protected]6217d392010-03-25 22:08:352195 0, 0,
2196 size.width(),
2197 size.height(),
2198 0); // border
2199}
2200
[email protected]ed9f9cd2013-02-27 21:12:352201void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352202 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302203 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362204 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352205 glDeleteTextures(1, &id_);
2206 id_ = 0;
2207 }
[email protected]68e81a4a62012-12-13 01:16:482208 memory_tracker_.TrackMemFree(bytes_allocated_);
2209 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352210}
2211
[email protected]ed9f9cd2013-02-27 21:12:352212void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052213 id_ = 0;
2214}
2215
[email protected]d5a28e452013-10-10 01:01:402216BackRenderbuffer::BackRenderbuffer(
2217 RenderbufferManager* renderbuffer_manager,
2218 MemoryTracker* memory_tracker,
2219 ContextState* state)
2220 : renderbuffer_manager_(renderbuffer_manager),
2221 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2222 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482223 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252224 id_(0) {
[email protected]6217d392010-03-25 22:08:352225}
2226
[email protected]ed9f9cd2013-02-27 21:12:352227BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352228 // This does not destroy the render buffer because that would require that
2229 // the associated GL context was current. Just check that it was explicitly
2230 // destroyed.
2231 DCHECK_EQ(id_, 0u);
2232}
2233
[email protected]ed9f9cd2013-02-27 21:12:352234void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302235 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402236 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352237 Destroy();
2238 glGenRenderbuffersEXT(1, &id_);
2239}
2240
[email protected]f42f05b2013-11-15 21:46:182241bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2242 const gfx::Size& size,
2243 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352244 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512245 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402246 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2247 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262248
2249 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402250 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232251 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262252 return false;
2253 }
2254
2255 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2256 return false;
2257 }
2258
[email protected]34ff8b0c2010-10-01 20:06:022259 if (samples <= 1) {
2260 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2261 format,
2262 size.width(),
2263 size.height());
2264 } else {
[email protected]f42f05b2013-11-15 21:46:182265 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2266 GL_RENDERBUFFER,
2267 samples,
2268 format,
2269 size.width(),
2270 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022271 }
[email protected]1078f912011-12-23 13:12:142272 bool success = glGetError() == GL_NO_ERROR;
2273 if (success) {
[email protected]d5a28e452013-10-10 01:01:402274 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482275 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262276 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402277 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482278 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142279 }
2280 return success;
[email protected]6217d392010-03-25 22:08:352281}
2282
[email protected]ed9f9cd2013-02-27 21:12:352283void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352284 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302285 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402286 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352287 glDeleteRenderbuffersEXT(1, &id_);
2288 id_ = 0;
2289 }
[email protected]68e81a4a62012-12-13 01:16:482290 memory_tracker_.TrackMemFree(bytes_allocated_);
2291 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352292}
2293
[email protected]ed9f9cd2013-02-27 21:12:352294void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052295 id_ = 0;
2296}
2297
[email protected]ed9f9cd2013-02-27 21:12:352298BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352299 : decoder_(decoder),
2300 id_(0) {
2301}
2302
[email protected]ed9f9cd2013-02-27 21:12:352303BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352304 // This does not destroy the frame buffer because that would require that
2305 // the associated GL context was current. Just check that it was explicitly
2306 // destroyed.
2307 DCHECK_EQ(id_, 0u);
2308}
2309
[email protected]ed9f9cd2013-02-27 21:12:352310void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302311 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2312 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352313 Destroy();
2314 glGenFramebuffersEXT(1, &id_);
2315}
2316
[email protected]ed9f9cd2013-02-27 21:12:352317void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352318 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512319 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302320 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352321 ScopedFrameBufferBinder binder(decoder_, id_);
2322 GLuint attach_id = texture ? texture->id() : 0;
2323 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2324 GL_COLOR_ATTACHMENT0,
2325 GL_TEXTURE_2D,
2326 attach_id,
2327 0);
2328}
2329
[email protected]ed9f9cd2013-02-27 21:12:352330void BackFramebuffer::AttachRenderBuffer(GLenum target,
2331 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352332 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512333 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302334 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352335 ScopedFrameBufferBinder binder(decoder_, id_);
2336 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2337 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152338 target,
[email protected]6217d392010-03-25 22:08:352339 GL_RENDERBUFFER,
2340 attach_id);
2341}
2342
[email protected]ed9f9cd2013-02-27 21:12:352343void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352344 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302345 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2346 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352347 glDeleteFramebuffersEXT(1, &id_);
2348 id_ = 0;
2349 }
2350}
2351
[email protected]ed9f9cd2013-02-27 21:12:352352void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052353 id_ = 0;
2354}
2355
[email protected]ed9f9cd2013-02-27 21:12:352356GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352357 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302358 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2359 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352360 ScopedFrameBufferBinder binder(decoder_, id_);
2361 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2362}
2363
[email protected]aa7666122011-09-02 19:45:522364GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2365 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322366}
2367
[email protected]aa7666122011-09-02 19:45:522368GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392369 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572370 group_(group),
[email protected]1d82e822013-04-10 21:32:322371 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132372 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282373 unpack_flip_y_(false),
2374 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172375 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242376 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492377 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242378 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402379 fixed_attrib_buffer_id_(0),
2380 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022381 offscreen_target_color_format_(0),
2382 offscreen_target_depth_format_(0),
2383 offscreen_target_stencil_format_(0),
2384 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562385 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052386 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132387 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462388 back_buffer_has_depth_(false),
2389 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422390 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582391 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562392 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052393 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112394 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002395 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432396 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302397 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512398 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222399 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432400 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042401 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102402 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492403 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132404 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062405 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282406 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132407 lose_context_when_out_of_memory_(false),
avi9ab037202014-12-22 23:49:532408 service_logging_(base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]cae20172012-12-07 00:06:192409 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022410 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102411 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002412 texture_state_(group_->feature_info()
2413 ->workarounds()
2414 .texsubimage2d_faster_than_teximage2d),
vmiura1c2b1de2014-09-19 19:03:242415 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2416 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
dyencb86f2f2014-12-09 18:35:412417 gpu_decoder_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2418 TRACE_DISABLED_BY_DEFAULT("gpu_decoder"))),
vmiura1c2b1de2014-09-19 19:03:242419 gpu_trace_level_(2),
2420 gpu_trace_commands_(false),
2421 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102422 validation_texture_(0),
2423 validation_fbo_multisample_(0),
2424 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572425 DCHECK(group);
2426
[email protected]b1122982010-05-17 23:04:242427 attrib_0_value_.v[0] = 0.0f;
2428 attrib_0_value_.v[1] = 0.0f;
2429 attrib_0_value_.v[2] = 0.0f;
2430 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152431
[email protected]c2f8c8402010-12-06 18:07:242432 // The shader translator is used for WebGL even when running on EGL
2433 // because additional restrictions are needed (like only enabling
2434 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562435 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2436 // the empty string to CompileShader and this is not a valid shader.
2437 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
avi9ab037202014-12-22 23:49:532438 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]39ba4f02012-03-26 01:16:002439 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152440 use_shader_translator_ = false;
2441 }
[email protected]96449d2c2009-11-25 00:01:322442}
2443
[email protected]80eb6b52012-01-19 00:14:412444GLES2DecoderImpl::~GLES2DecoderImpl() {
2445}
2446
[email protected]c410da802011-03-14 19:17:412447bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382448 const scoped_refptr<gfx::GLSurface>& surface,
2449 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232450 bool offscreen,
dongseong.hwang4c04a162015-03-04 07:27:332451 const gfx::Size& offscreen_size,
[email protected]e82fb792011-09-22 00:33:292452 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242453 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322454 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382455 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302456 DCHECK(!context_.get());
2457
zmo0ee15862015-03-04 03:50:182458 ContextCreationAttribHelper attrib_parser;
2459 if (!attrib_parser.Parse(attribs))
2460 return false;
2461
jbaumana7604692014-10-17 02:00:392462 surfaceless_ = surface->IsSurfaceless() && !offscreen;
achaulkcf5316f2014-09-26 19:28:422463
[email protected]55e136f2013-04-03 18:50:062464 set_initialized();
[email protected]8f9b8dd2013-09-12 18:05:132465 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142466
avi9ab037202014-12-22 23:49:532467 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2468 switches::kEnableGPUDebugging)) {
[email protected]e844ae22012-01-14 03:36:262469 set_debug(true);
2470 }
2471
avi9ab037202014-12-22 23:49:532472 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2473 switches::kEnableGPUCommandLogging)) {
[email protected]39ba4f02012-03-26 01:16:002474 set_log_commands(true);
2475 }
2476
avi9ab037202014-12-22 23:49:532477 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
zmo0ee15862015-03-04 03:50:182478 switches::kEnableUnsafeES3APIs) &&
2479 attrib_parser.es3_context_required) {
2480 // TODO(zmo): We need to implement capabilities check to ensure we can
2481 // actually create ES3 contexts.
zmo84c08202014-11-23 15:28:402482 set_unsafe_es3_apis_enabled(true);
2483 }
2484
avi9ab037202014-12-22 23:49:532485 compile_shader_always_succeeds_ =
2486 base::CommandLine::ForCurrentProcess()->HasSwitch(
2487 switches::kCompileShaderAlwaysSucceeds);
[email protected]062c38b2012-01-18 03:25:102488
[email protected]63c9b052012-05-17 18:27:382489 // Take ownership of the context and surface. The surface can be replaced with
2490 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382491 context_ = context;
[email protected]63c9b052012-05-17 18:27:382492 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182493
dyen5b1c02ff2015-02-26 01:54:002494 // Create GPU Tracer for timing values.
2495 gpu_tracer_.reset(new GPUTracer(this));
2496
[email protected]828a3932014-04-02 14:43:132497 // Save the loseContextWhenOutOfMemory context creation attribute.
2498 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402499 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132500
[email protected]65f7efe2013-11-28 03:11:472501 // If the failIfMajorPerformanceCaveat context creation attribute was true
2502 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402503 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472504 feature_info_->feature_flags().is_swiftshader) {
2505 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2506 Destroy(true);
2507 return false;
2508 }
2509
[email protected]956aec52013-09-05 15:41:192510 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222511 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392512 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422513 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382514 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032515 return false;
[email protected]a3ded6d2010-10-19 06:44:392516 }
[email protected]b64c24952012-04-19 03:20:272517 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282518
[email protected]e82fb792011-09-22 00:33:292519 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502520
[email protected]af6380962012-11-29 23:24:132521 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482522 vertex_array_manager_.reset(new VertexArrayManager());
2523
2524 GLuint default_vertex_attrib_service_id = 0;
2525 if (features().native_vertex_array_object) {
2526 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2527 glBindVertexArrayOES(default_vertex_attrib_service_id);
2528 }
2529
2530 state_.default_vertex_attrib_manager =
2531 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2532
[email protected]81f20a622014-04-18 01:54:522533 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002534 group_->max_vertex_attribs(),
2535 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462536
[email protected]81f20a622014-04-18 01:54:522537 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572538 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322539
[email protected]7cd76fd2013-06-02 21:11:112540 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532541
[email protected]b63f1d62014-07-18 15:40:592542 image_manager_.reset(new ImageManager);
2543
[email protected]302ce6d2011-07-07 23:28:112544 util_.set_num_compressed_texture_formats(
2545 validators_->compressed_texture_format.GetValues().size());
2546
[email protected]1071e572011-02-09 20:00:122547 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2548 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2549 // OpenGL ES 2.0 does not have this issue.
2550 glEnableVertexAttribArray(0);
2551 }
[email protected]b1122982010-05-17 23:04:242552 glGenBuffersARB(1, &attrib_0_buffer_id_);
2553 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2554 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2555 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402556 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082557
[email protected]1868a342012-11-07 15:56:022558 state_.texture_units.resize(group_->max_texture_units());
2559 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492560 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312561 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492562 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152563 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492564 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072565 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492566 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572567 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312568 }
[email protected]62e155e2012-10-23 22:43:152569 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492570 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072571 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492572 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572573 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462574 }
[email protected]370eaf12013-05-18 09:19:492575 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2576 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572577 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492578 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2579 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572580 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152581 }
[email protected]00f893d2010-08-24 18:55:492582 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502583 CHECK_GL_ERROR();
2584
[email protected]069944672012-04-25 20:52:232585 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402586 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542587 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022588 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432589 // max_sample_count must be initialized to a sane value. If
2590 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2591 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022592 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402593 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022594 max_sample_count);
2595 } else {
2596 offscreen_target_samples_ = 1;
2597 }
[email protected]845c4e32014-08-13 11:50:402598 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022599
2600 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2601 const bool rgb8_supported =
2602 context_->HasExtension("GL_OES_rgb8_rgba8");
2603 // The only available default render buffer formats in GLES2 have very
2604 // little precision. Don't enable multisampling unless 8-bit render
2605 // buffer formats are available--instead fall back to 8-bit textures.
2606 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402607 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022608 GL_RGBA8 : GL_RGB8;
2609 } else {
2610 offscreen_target_samples_ = 1;
[email protected]845c4e32014-08-13 11:50:402611 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022612 GL_RGBA : GL_RGB;
2613 }
2614
2615 // ANGLE only supports packed depth/stencil formats, so use it if it is
2616 // available.
2617 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182618 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272619 VLOG(1) << "GL_OES_packed_depth_stencil "
2620 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402621 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002622 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022623 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2624 offscreen_target_stencil_format_ = 0;
2625 } else {
2626 // It may be the case that this depth/stencil combination is not
2627 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402628 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022629 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402630 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022631 GL_STENCIL_INDEX8 : 0;
2632 }
2633 } else {
[email protected]845c4e32014-08-13 11:50:402634 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022635 GL_RGBA : GL_RGB;
2636
2637 // If depth is requested at all, use the packed depth stencil format if
2638 // it's available, as some desktop GL drivers don't support any non-packed
2639 // formats for depth attachments.
2640 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182641 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272642 VLOG(1) << "GL_EXT_packed_depth_stencil "
2643 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022644
[email protected]845c4e32014-08-13 11:50:402645 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002646 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022647 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2648 offscreen_target_stencil_format_ = 0;
2649 } else {
[email protected]845c4e32014-08-13 11:50:402650 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022651 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402652 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022653 GL_STENCIL_INDEX : 0;
2654 }
2655 }
2656
[email protected]845c4e32014-08-13 11:50:402657 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]97872062010-11-03 19:07:052658 GL_RGBA : GL_RGB;
2659
[email protected]6217d392010-03-25 22:08:352660 // Create the target frame buffer. This is the one that the client renders
2661 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352662 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352663 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022664 // Due to GLES2 format limitations, either the color texture (for
2665 // non-multisampling) or the color render buffer (for multisampling) will be
2666 // attached to the offscreen frame buffer. The render buffer has more
2667 // limited formats available to it, but the texture can't do multisampling.
2668 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402669 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2670 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022671 offscreen_target_color_render_buffer_->Create();
2672 } else {
[email protected]ce296892013-10-24 22:04:362673 offscreen_target_color_texture_.reset(new BackTexture(
2674 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022675 offscreen_target_color_texture_->Create();
2676 }
[email protected]d5a28e452013-10-10 01:01:402677 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2678 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152679 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402680 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2681 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152682 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352683
2684 // Create the saved offscreen texture. The target frame buffer is copied
2685 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352686 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022687 offscreen_saved_frame_buffer_->Create();
2688 //
[email protected]ce296892013-10-24 22:04:362689 offscreen_saved_color_texture_.reset(new BackTexture(
2690 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352691 offscreen_saved_color_texture_->Create();
2692
[email protected]6217d392010-03-25 22:08:352693 // Allocate the render buffers at their initial size and check the status
2694 // of the frame buffers is okay.
dongseong.hwang4c04a162015-03-04 07:27:332695 if (!ResizeOffscreenFrameBuffer(offscreen_size)) {
[email protected]d0498742010-09-20 20:27:012696 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382697 Destroy(true);
[email protected]6217d392010-03-25 22:08:352698 return false;
2699 }
2700
dongseong.hwang4c04a162015-03-04 07:27:332701 state_.viewport_width = offscreen_size.width();
2702 state_.viewport_height = offscreen_size.height();
2703
[email protected]678a73f2012-12-19 19:22:092704 // Allocate the offscreen saved color texture.
2705 DCHECK(offscreen_saved_color_format_);
2706 offscreen_saved_color_texture_->AllocateStorage(
2707 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2708
2709 offscreen_saved_frame_buffer_->AttachRenderTexture(
2710 offscreen_saved_color_texture_.get());
2711 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2712 GL_FRAMEBUFFER_COMPLETE) {
2713 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2714 Destroy(true);
2715 return false;
2716 }
2717
[email protected]6217d392010-03-25 22:08:352718 // Bind to the new default frame buffer (the offscreen target frame buffer).
2719 // This should now be associated with ID zero.
2720 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102721 } else {
2722 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2723 // These are NOT if the back buffer has these proprorties. They are
2724 // if we want the command buffer to enforce them regardless of what
2725 // the real backbuffer is assuming the real back buffer gives us more than
2726 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2727 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2728 // can't do anything about that.
2729
achaulkcf5316f2014-09-26 19:28:422730 if (!surfaceless_) {
2731 GLint v = 0;
2732 glGetIntegerv(GL_ALPHA_BITS, &v);
2733 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2734 // the user requested RGB then RGB. If the user did not specify a
2735 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2736 back_buffer_color_format_ =
2737 (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
2738 glGetIntegerv(GL_DEPTH_BITS, &v);
2739 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
2740 glGetIntegerv(GL_STENCIL_BITS, &v);
2741 back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
2742 }
dongseong.hwang4c04a162015-03-04 07:27:332743
2744 state_.viewport_width = surface->GetSize().width();
2745 state_.viewport_height = surface->GetSize().height();
[email protected]6217d392010-03-25 22:08:352746 }
2747
[email protected]76a0ee102010-04-07 21:03:042748 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2749 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2750 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372751 // mailing list archives. It also implicitly enables the desktop GL
2752 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2753 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152754 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2755 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372756 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152757 }
[email protected]de17df392010-04-23 21:09:412758
[email protected]706b69f2012-07-27 04:59:302759 has_robustness_extension_ =
2760 context->HasExtension("GL_ARB_robustness") ||
oetuaho37cc50e2014-10-31 11:19:202761 context->HasExtension("GL_KHR_robustness") ||
[email protected]706b69f2012-07-27 04:59:302762 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432763
[email protected]c2f8c8402010-12-06 18:07:242764 if (!InitializeShaderTranslator()) {
2765 return false;
[email protected]de17df392010-04-23 21:09:412766 }
[email protected]76a0ee102010-04-07 21:03:042767
[email protected]5904806b2012-05-08 18:10:222768 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282769 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022770 viewport_max_width_ = viewport_params[0];
2771 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282772
[email protected]88a61bf2012-10-27 13:00:422773 state_.scissor_width = state_.viewport_width;
2774 state_.scissor_height = state_.viewport_height;
2775
[email protected]11f3e702012-06-19 19:00:012776 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342777 state_.InitCapabilities(NULL);
2778 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242779 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012780
2781 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2782 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2783 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2784 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
orglofchcad5a6742014-11-07 19:51:122785 DoBindValueBufferCHROMIUM(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, 0);
[email protected]11f3e702012-06-19 19:00:012786
achaulkcf5316f2014-09-26 19:28:422787 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002788#if defined(OS_ANDROID)
2789 // Temporary workaround for Android WebView because this clear ignores the
2790 // clip and corrupts that external UI of the App. Not calling glClear is ok
2791 // because the system already clears the buffer before each draw. Proper
2792 // fix might be setting the scissor clip properly before initialize. See
2793 // crbug.com/259023 for details.
2794 call_gl_clear = surface_->GetHandle();
2795#endif
2796 if (call_gl_clear) {
2797 // Clear the backbuffer.
2798 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2799 }
[email protected]561cc0a62013-05-07 18:34:452800
[email protected]b381ee32014-03-22 02:43:432801 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2802 if (feature_info_->workarounds()
2803 .disable_post_sub_buffers_for_onscreen_surfaces &&
2804 !surface->IsOffscreen())
2805 supports_post_sub_buffer_ = false;
2806
[email protected]62e155e2012-10-23 22:43:152807 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462808 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2809 }
[email protected]dd289a5d62012-06-30 22:05:462810
[email protected]9b753992013-04-27 02:04:412811 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2812 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242813 }
[email protected]85cb4682013-04-20 00:54:242814
[email protected]97419c02013-04-10 02:52:382815 // Only compositor contexts are known to use only the subset of GL
2816 // that can be safely migrated between the iGPU and the dGPU. Mark
2817 // those contexts as safe to forcibly transition between the GPUs.
2818 // http://crbug.com/180876, http://crbug.com/227228
2819 if (!offscreen)
2820 context_->SetSafeToForceGpuSwitch();
2821
[email protected]85a4ac22013-05-31 01:58:472822 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072823 AsyncPixelTransferManager::Create(context.get()));
2824 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592825
sievers2384f2b2014-11-18 02:10:352826 if (workarounds().gl_clear_broken) {
2827 DCHECK(!clear_framebuffer_blit_.get());
2828 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit");
2829 clear_framebuffer_blit_.reset(new ClearFramebufferResourceManager(this));
2830 if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR)
2831 return false;
2832 }
2833
[email protected]91c94eb2013-10-22 10:32:542834 framebuffer_manager()->AddObserver(this);
2835
[email protected]246a70452010-03-05 21:53:502836 return true;
[email protected]96449d2c2009-11-25 00:01:322837}
2838
[email protected]6d668892013-12-04 21:37:122839Capabilities GLES2DecoderImpl::GetCapabilities() {
2840 DCHECK(initialized());
2841
2842 Capabilities caps;
piman1c2e0a852014-11-12 05:17:552843 caps.VisitPrecisions([](GLenum shader, GLenum type,
2844 Capabilities::ShaderPrecision* shader_precision) {
2845 GLint range[2] = {0, 0};
2846 GLint precision = 0;
2847 GetShaderPrecisionFormatImpl(shader, type, range, &precision);
2848 shader_precision->min_range = range[0];
2849 shader_precision->max_range = range[1];
2850 shader_precision->precision = precision;
2851 });
2852 DoGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
2853 &caps.max_combined_texture_image_units);
2854 DoGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps.max_cube_map_texture_size);
2855 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
2856 &caps.max_fragment_uniform_vectors);
2857 DoGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps.max_renderbuffer_size);
2858 DoGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps.max_texture_image_units);
2859 DoGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.max_texture_size);
2860 DoGetIntegerv(GL_MAX_VARYING_VECTORS, &caps.max_varying_vectors);
2861 DoGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps.max_vertex_attribs);
2862 DoGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
2863 &caps.max_vertex_texture_image_units);
2864 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
2865 &caps.max_vertex_uniform_vectors);
2866 DoGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
2867 &caps.num_compressed_texture_formats);
2868 DoGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps.num_shader_binary_formats);
2869 DoGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM,
2870 &caps.bind_generates_resource_chromium);
heejin.r.chung8f143292015-02-05 02:44:002871 if (unsafe_es3_apis_enabled()) {
2872 DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
2873 &caps.max_transform_feedback_separate_attribs);
2874 DoGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
2875 &caps.max_uniform_buffer_bindings);
2876 DoGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
2877 &caps.uniform_buffer_offset_alignment);
2878 }
[email protected]6d668892013-12-04 21:37:122879
[email protected]6d668892013-12-04 21:37:122880 caps.egl_image_external =
2881 feature_info_->feature_flags().oes_egl_image_external;
christiank07b6d8b2015-02-25 09:41:252882 caps.texture_format_atc =
2883 feature_info_->feature_flags().ext_texture_format_atc;
[email protected]6d668892013-12-04 21:37:122884 caps.texture_format_bgra8888 =
2885 feature_info_->feature_flags().ext_texture_format_bgra8888;
christiank07b6d8b2015-02-25 09:41:252886 caps.texture_format_dxt1 =
2887 feature_info_->feature_flags().ext_texture_format_dxt1;
2888 caps.texture_format_dxt5 =
2889 feature_info_->feature_flags().ext_texture_format_dxt5;
[email protected]6d668892013-12-04 21:37:122890 caps.texture_format_etc1 =
2891 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:202892 caps.texture_format_etc1_npot =
2893 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:122894 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2895 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2896 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2897 caps.discard_framebuffer =
2898 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352899 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122900
2901#if defined(OS_MACOSX)
2902 // This is unconditionally true on mac, no need to test for it at runtime.
2903 caps.iosurface = true;
2904#endif
2905
[email protected]b381ee32014-03-22 02:43:432906 caps.post_sub_buffer = supports_post_sub_buffer_;
reveman340109182014-09-30 15:36:452907 caps.image = true;
[email protected]6d668892013-12-04 21:37:122908
ed9198b422014-10-23 15:01:372909 caps.blend_equation_advanced =
2910 feature_info_->feature_flags().blend_equation_advanced;
2911 caps.blend_equation_advanced_coherent =
2912 feature_info_->feature_flags().blend_equation_advanced_coherent;
hendrikwfc25ca6192014-12-02 06:05:132913 caps.texture_rg = feature_info_->feature_flags().ext_texture_rg;
[email protected]6d668892013-12-04 21:37:122914 return caps;
2915}
2916
[email protected]302ce6d2011-07-07 23:28:112917void GLES2DecoderImpl::UpdateCapabilities() {
2918 util_.set_num_compressed_texture_formats(
2919 validators_->compressed_texture_format.GetValues().size());
2920 util_.set_num_shader_binary_formats(
2921 validators_->shader_binary_format.GetValues().size());
2922}
2923
[email protected]c2f8c8402010-12-06 18:07:242924bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442925 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2926
[email protected]c2f8c8402010-12-06 18:07:242927 if (!use_shader_translator_) {
2928 return true;
2929 }
2930 ShBuiltInResources resources;
2931 ShInitBuiltInResources(&resources);
2932 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2933 resources.MaxVertexUniformVectors =
2934 group_->max_vertex_uniform_vectors();
2935 resources.MaxVaryingVectors = group_->max_varying_vectors();
2936 resources.MaxVertexTextureImageUnits =
2937 group_->max_vertex_texture_image_units();
2938 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2939 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2940 resources.MaxFragmentUniformVectors =
2941 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492942 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242943 resources.MaxExpressionComplexity = 256;
2944 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042945
[email protected]46c86752013-05-21 05:08:392946 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212947 GLint precision = 0;
2948 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2949 range, &precision);
[email protected]448e459e2013-06-12 17:00:412950 resources.FragmentPrecisionHigh =
2951 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142952
[email protected]f0d74742011-10-03 16:31:042953 if (force_webgl_glsl_validation_) {
2954 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492955 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132956 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442957 if (!draw_buffers_explicitly_enabled_)
2958 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:062959 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
oetuaho0decd442014-10-13 08:40:462960 resources.NV_draw_buffers =
2961 draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
[email protected]f0d74742011-10-03 16:31:042962 } else {
2963 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152964 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462965 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152966 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062967 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152968 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492969 resources.EXT_draw_buffers =
2970 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492971 resources.EXT_frag_depth =
2972 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:062973 resources.EXT_shader_texture_lod =
2974 features().ext_shader_texture_lod ? 1 : 0;
oetuaho0decd442014-10-13 08:40:462975 resources.NV_draw_buffers =
2976 features().nv_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042977 }
2978
zmo0ee15862015-03-04 03:50:182979 ShShaderSpec shader_spec;
2980 if (force_webgl_glsl_validation_) {
2981 shader_spec = unsafe_es3_apis_enabled() ? SH_WEBGL2_SPEC : SH_WEBGL_SPEC;
2982 } else {
2983 shader_spec = unsafe_es3_apis_enabled() ? SH_GLES3_SPEC : SH_GLES2_SPEC;
2984 }
2985
2986 if ((shader_spec == SH_WEBGL_SPEC || shader_spec == SH_WEBGL2_SPEC) &&
2987 features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022988 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:052989 else
2990 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122991 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2992 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2993 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212994 int driver_bug_workarounds = 0;
2995 if (workarounds().needs_glsl_built_in_function_emulation)
2996 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542997 if (workarounds().init_gl_position_in_vertex_shader)
2998 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112999 if (workarounds().unfold_short_circuit_as_ternary_operation)
3000 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:053001 if (workarounds().init_varyings_without_static_use)
3002 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:063003 if (workarounds().unroll_for_loop_with_sampler_array_index)
3004 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:253005 if (workarounds().scalarize_vec_and_mat_constructor_args)
3006 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:273007 if (workarounds().regenerate_struct_names)
3008 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
[email protected]87fb6ab2012-06-13 22:28:043009
avi9ab037202014-12-22 23:49:533010 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
3011 switches::kEmulateShaderPrecision))
oetuahoaffd85abe2014-12-11 09:47:093012 resources.WEBGL_debug_shader_precision = true;
3013
[email protected]03cef9b2014-04-03 15:58:143014 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:263015 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:143016 shader_spec,
3017 &resources,
[email protected]a6739bc2013-09-07 04:45:213018 implementation_type,
3019 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:043020 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:243021 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:383022 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:243023 return false;
3024 }
[email protected]87fb6ab2012-06-13 22:28:043025
[email protected]03cef9b2014-04-03 15:58:143026 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:263027 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:143028 shader_spec,
3029 &resources,
[email protected]a6739bc2013-09-07 04:45:213030 implementation_type,
3031 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:043032 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:243033 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:383034 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:243035 return false;
3036 }
3037 return true;
3038}
3039
[email protected]ae51d192010-04-27 00:48:033040bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:473041 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353042 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033043 return false;
3044 }
3045 }
[email protected]40d90a22013-04-09 03:39:553046 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033047 glGenBuffersARB(n, service_ids.get());
3048 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353049 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033050 }
3051 return true;
3052}
3053
3054bool GLES2DecoderImpl::GenFramebuffersHelper(
3055 GLsizei n, const GLuint* client_ids) {
3056 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353057 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033058 return false;
3059 }
3060 }
[email protected]40d90a22013-04-09 03:39:553061 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033062 glGenFramebuffersEXT(n, service_ids.get());
3063 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353064 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033065 }
3066 return true;
3067}
3068
3069bool GLES2DecoderImpl::GenRenderbuffersHelper(
3070 GLsizei n, const GLuint* client_ids) {
3071 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353072 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033073 return false;
3074 }
3075 }
[email protected]40d90a22013-04-09 03:39:553076 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033077 glGenRenderbuffersEXT(n, service_ids.get());
3078 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353079 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033080 }
3081 return true;
3082}
3083
orglofchcad5a6742014-11-07 19:51:123084bool GLES2DecoderImpl::GenValuebuffersCHROMIUMHelper(GLsizei n,
3085 const GLuint* client_ids) {
3086 for (GLsizei ii = 0; ii < n; ++ii) {
3087 if (GetValuebuffer(client_ids[ii])) {
3088 return false;
3089 }
3090 }
3091 for (GLsizei ii = 0; ii < n; ++ii) {
3092 CreateValuebuffer(client_ids[ii]);
3093 }
3094 return true;
3095}
3096
[email protected]ae51d192010-04-27 00:48:033097bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
3098 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353099 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033100 return false;
3101 }
3102 }
[email protected]40d90a22013-04-09 03:39:553103 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033104 glGenTextures(n, service_ids.get());
3105 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353106 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033107 }
3108 return true;
3109}
3110
3111void GLES2DecoderImpl::DeleteBuffersHelper(
3112 GLsizei n, const GLuint* client_ids) {
3113 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:213114 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103115 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:243116 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:113117 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:243118 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103119 }
[email protected]ed9f9cd2013-02-27 21:12:353120 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033121 }
[email protected]a93bb842010-02-16 23:03:473122 }
[email protected]07f54fcc2009-12-22 02:46:303123}
3124
[email protected]ae51d192010-04-27 00:48:033125void GLES2DecoderImpl::DeleteFramebuffersHelper(
3126 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453127 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153128 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:113129
[email protected]a25fa872010-03-25 02:57:583130 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353131 Framebuffer* framebuffer =
3132 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103133 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:343134 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]ebfb73c2012-08-15 02:37:453135 GLenum target = supports_separate_framebuffer_binds ?
3136 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
vmiura7d08fee52015-02-18 18:39:343137
3138 // Unbind attachments on FBO before deletion.
3139 if (workarounds().unbind_attachments_on_bound_render_fbo_delete)
3140 framebuffer->DoUnbindGLAttachmentsForWorkaround(target);
3141
[email protected]b177ae22011-11-01 03:29:113142 glBindFramebufferEXT(target, GetBackbufferServiceId());
vmiura7d08fee52015-02-18 18:39:343143 framebuffer_state_.bound_draw_framebuffer = NULL;
3144 framebuffer_state_.clear_state_dirty = true;
[email protected]b177ae22011-11-01 03:29:113145 }
[email protected]9d3b2e12013-10-02 01:04:343146 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
3147 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:453148 GLenum target = supports_separate_framebuffer_binds ?
3149 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113150 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:463151 }
[email protected]70d34263c2013-01-09 00:27:453152 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:353153 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033154 }
[email protected]a25fa872010-03-25 02:57:583155 }
[email protected]07f54fcc2009-12-22 02:46:303156}
3157
[email protected]ae51d192010-04-27 00:48:033158void GLES2DecoderImpl::DeleteRenderbuffersHelper(
3159 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453160 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153161 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:583162 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353163 Renderbuffer* renderbuffer =
3164 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103165 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:113166 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:243167 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103168 }
3169 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453170 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343171 if (framebuffer_state_.bound_read_framebuffer.get()) {
3172 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113173 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103174 }
[email protected]9d3b2e12013-10-02 01:04:343175 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3176 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113177 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103178 }
3179 } else {
[email protected]9d3b2e12013-10-02 01:04:343180 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3181 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113182 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103183 }
3184 }
[email protected]c986af502013-08-14 01:04:443185 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:353186 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033187 }
[email protected]a25fa872010-03-25 02:57:583188 }
[email protected]07f54fcc2009-12-22 02:46:303189}
3190
orglofchcad5a6742014-11-07 19:51:123191void GLES2DecoderImpl::DeleteValuebuffersCHROMIUMHelper(
3192 GLsizei n,
3193 const GLuint* client_ids) {
3194 for (GLsizei ii = 0; ii < n; ++ii) {
3195 Valuebuffer* valuebuffer = GetValuebuffer(client_ids[ii]);
3196 if (valuebuffer) {
3197 if (state_.bound_valuebuffer.get() == valuebuffer) {
3198 state_.bound_valuebuffer = NULL;
3199 }
3200 RemoveValuebuffer(client_ids[ii]);
3201 }
3202 }
3203}
3204
[email protected]ae51d192010-04-27 00:48:033205void GLES2DecoderImpl::DeleteTexturesHelper(
3206 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453207 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153208 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:473209 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:493210 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3211 if (texture_ref) {
3212 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103213 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443214 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463215 }
[email protected]370eaf12013-05-18 09:19:493216 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023217 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493218 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103219 }
3220 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453221 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343222 if (framebuffer_state_.bound_read_framebuffer.get()) {
3223 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113224 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103225 }
[email protected]9d3b2e12013-10-02 01:04:343226 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3227 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113228 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103229 }
3230 } else {
[email protected]9d3b2e12013-10-02 01:04:343231 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3232 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113233 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103234 }
3235 }
[email protected]e51bdf32011-11-23 22:21:463236#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073237 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463238 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3239 ReleaseIOSurfaceForTexture(service_id);
3240 }
3241#endif
[email protected]ed9f9cd2013-02-27 21:12:353242 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033243 }
[email protected]a93bb842010-02-16 23:03:473244 }
[email protected]07f54fcc2009-12-22 02:46:303245}
3246
[email protected]43f28f832010-02-03 02:28:483247// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323248
[email protected]eb54a562010-01-20 21:55:183249bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343250 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383251 return false;
3252
[email protected]177d1342013-12-07 04:20:343253 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:433254 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:293255
jbauman7a059312014-10-16 19:30:543256 MaybeExitOnContextLost();
[email protected]e9f0ca82013-04-01 23:52:293257
[email protected]63c9b052012-05-17 18:27:383258 return false;
[email protected]38d139d2011-07-14 00:38:433259 }
3260
[email protected]69a8701e2013-03-07 21:31:093261 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093262
[email protected]9b753992013-04-27 02:04:413263 // Rebind the FBO if it was unbound by the context.
3264 if (workarounds().unbind_fbo_on_context_switch)
3265 RestoreFramebufferBindings();
3266
[email protected]c986af502013-08-14 01:04:443267 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493268
[email protected]69a8701e2013-03-07 21:31:093269 return true;
3270}
3271
3272void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553273 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323274 if (engine() && query_manager_.get())
3275 query_manager_->ProcessPendingTransferQueries();
3276
[email protected]5b3a8e02013-03-13 05:36:443277 // TODO(epenner): Is there a better place to do this?
3278 // This needs to occur before we execute any batch of commands
3279 // from the client, as the client may have recieved an async
3280 // completion while issuing those commands.
3281 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483282 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183283}
3284
[email protected]8e3e0662010-08-23 18:46:303285static void RebindCurrentFramebuffer(
3286 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063287 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243288 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063289 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463290
[email protected]a3783712012-01-20 22:18:243291 if (framebuffer_id == 0) {
3292 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303293 }
[email protected]297ca1c2011-06-20 23:08:463294
[email protected]8e3e0662010-08-23 18:46:303295 glBindFramebufferEXT(target, framebuffer_id);
3296}
3297
3298void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443299 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463300
[email protected]62e155e2012-10-23 22:43:153301 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303302 RebindCurrentFramebuffer(
3303 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343304 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243305 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303306 } else {
3307 RebindCurrentFramebuffer(
3308 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343309 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243310 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303311 RebindCurrentFramebuffer(
3312 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343313 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243314 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303315 }
[email protected]70d34263c2013-01-09 00:27:453316 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303317}
3318
[email protected]0d6bfdc2011-11-02 01:32:203319bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353320 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203321 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103322 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423323 if (surfaceless_)
3324 return false;
[email protected]60f22d32012-12-12 00:31:583325 if (backbuffer_needs_clear_bits_) {
3326 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323327 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453328 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583329 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473330 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3331 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583332 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453333 state_.SetDeviceDepthMask(GL_TRUE);
3334 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423335 bool reset_draw_buffer = false;
brucedawson18249152014-10-31 23:02:323336 if ((backbuffer_needs_clear_bits_ & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]ee757922014-06-06 05:21:423337 group_->draw_buffer() == GL_NONE) {
3338 reset_draw_buffer = true;
3339 GLenum buf = GL_BACK;
3340 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3341 buf = GL_COLOR_ATTACHMENT0;
3342 glDrawBuffersARB(1, &buf);
3343 }
[email protected]60f22d32012-12-12 00:31:583344 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423345 if (reset_draw_buffer) {
3346 GLenum buf = GL_NONE;
3347 glDrawBuffersARB(1, &buf);
3348 }
[email protected]60f22d32012-12-12 00:31:583349 backbuffer_needs_clear_bits_ = 0;
3350 RestoreClearState();
3351 }
[email protected]0d6bfdc2011-11-02 01:32:203352 return true;
3353 }
3354
[email protected]968351b2011-12-20 08:26:513355 if (framebuffer_manager()->IsComplete(framebuffer)) {
3356 return true;
3357 }
3358
[email protected]0d6bfdc2011-11-02 01:32:203359 GLenum completeness = framebuffer->IsPossiblyComplete();
3360 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513361 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433362 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273363 return false;
3364 }
[email protected]0d6bfdc2011-11-02 01:32:203365
3366 // Are all the attachments cleared?
3367 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3368 texture_manager()->HaveUnclearedMips()) {
3369 if (!framebuffer->IsCleared()) {
3370 // Can we clear them?
[email protected]73276522012-11-09 05:50:203371 if (framebuffer->GetStatus(texture_manager(), target) !=
3372 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513373 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433374 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3375 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203376 return false;
3377 }
3378 ClearUnclearedAttachments(target, framebuffer);
3379 }
3380 }
3381
[email protected]968351b2011-12-20 08:26:513382 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203383 if (framebuffer->GetStatus(texture_manager(), target) !=
3384 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513385 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433386 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3387 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513388 return false;
3389 }
3390 framebuffer_manager()->MarkAsComplete(framebuffer);
3391 }
3392
[email protected]0d6bfdc2011-11-02 01:32:203393 // NOTE: At this point we don't know if the framebuffer is complete but
3394 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273395 return true;
3396}
3397
[email protected]0d6bfdc2011-11-02 01:32:203398bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153399 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513400 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343401 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3402 func_name);
[email protected]28718a92013-04-04 12:12:513403
3404 if (valid)
3405 OnUseFramebuffer();
3406
3407 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203408 }
[email protected]9d3b2e12013-10-02 01:04:343409 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113410 GL_DRAW_FRAMEBUFFER_EXT,
3411 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343412 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113413 GL_READ_FRAMEBUFFER_EXT,
3414 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203415}
3416
[email protected]2ea5950d2014-07-09 18:20:343417bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3418 const char* func_name) {
3419 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3420 framebuffer_state_.bound_read_framebuffer.get() :
3421 framebuffer_state_.bound_draw_framebuffer.get();
3422 if (!framebuffer)
3423 return true;
3424 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3425 LOCAL_SET_GL_ERROR(
3426 GL_INVALID_OPERATION, func_name, "no color image attached");
3427 return false;
3428 }
3429 return true;
3430}
3431
zmo383512cf2014-10-14 00:11:003432bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
3433 TextureRef* texture, GLint level) {
3434 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3435 framebuffer_state_.bound_read_framebuffer.get() :
3436 framebuffer_state_.bound_draw_framebuffer.get();
3437 if (!framebuffer)
3438 return false;
3439 const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
3440 GL_COLOR_ATTACHMENT0);
3441 if (!attachment)
3442 return false;
3443 return attachment->FormsFeedbackLoop(texture, level);
3444}
3445
[email protected]8e3e0662010-08-23 18:46:303446gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353447 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453448 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203449 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353450 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203451 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263452 if (attachment) {
3453 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503454 }
[email protected]9edc6b22010-12-23 02:00:263455 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023456 } else if (offscreen_target_frame_buffer_.get()) {
3457 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353458 } else {
[email protected]f62a5ab2011-05-23 20:34:153459 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023460 }
[email protected]246a70452010-03-05 21:53:503461}
3462
[email protected]68586372013-12-11 01:27:593463GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3464 Framebuffer* framebuffer =
3465 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3466 if (framebuffer != NULL) {
3467 return framebuffer->GetColorAttachmentTextureType();
3468 } else {
3469 return GL_UNSIGNED_BYTE;
3470 }
3471}
3472
[email protected]9edc6b22010-12-23 02:00:263473GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353474 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453475 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203476 if (framebuffer != NULL) {
3477 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463478 } else if (offscreen_target_frame_buffer_.get()) {
3479 return offscreen_target_color_format_;
3480 } else {
3481 return back_buffer_color_format_;
3482 }
3483}
3484
3485GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353486 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453487 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203488 if (framebuffer != NULL) {
3489 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263490 } else if (offscreen_target_frame_buffer_.get()) {
3491 return offscreen_target_color_format_;
3492 } else {
[email protected]32fe9aa2011-01-21 23:47:133493 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263494 }
3495}
3496
[email protected]9a5afa432011-07-22 18:16:393497void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513498 if (!offscreen_saved_color_texture_info_.get())
3499 return;
3500 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3501 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3502 texture_manager()->SetLevelInfo(
3503 offscreen_saved_color_texture_info_.get(),
3504 GL_TEXTURE_2D,
3505 0, // level
3506 GL_RGBA,
3507 offscreen_size_.width(),
3508 offscreen_size_.height(),
3509 1, // depth
3510 0, // border
3511 GL_RGBA,
3512 GL_UNSIGNED_BYTE,
3513 true);
[email protected]737191ee72014-03-09 08:02:423514 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513515 "UpdateParentTextureInfo",
3516 GetErrorState(),
3517 offscreen_saved_color_texture_info_.get(),
3518 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263519 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423520 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513521 "UpdateParentTextureInfo",
3522 GetErrorState(),
3523 offscreen_saved_color_texture_info_.get(),
3524 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263525 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423526 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513527 "UpdateParentTextureInfo",
3528 GetErrorState(),
3529 offscreen_saved_color_texture_info_.get(),
3530 GL_TEXTURE_WRAP_S,
3531 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423532 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513533 "UpdateParentTextureInfo",
3534 GetErrorState(),
3535 offscreen_saved_color_texture_info_.get(),
3536 GL_TEXTURE_WRAP_T,
3537 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443538 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3539 &state_, target);
[email protected]2ad674132013-06-05 07:48:513540 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353541}
3542
[email protected]799b4b22011-08-22 17:09:593543void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073544 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523545 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003546}
3547
[email protected]1d82e822013-04-10 21:32:323548Logger* GLES2DecoderImpl::GetLogger() {
3549 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523550}
3551
[email protected]cac16542014-01-15 17:53:513552void GLES2DecoderImpl::BeginDecoding() {
3553 gpu_tracer_->BeginDecoding();
dyencb86f2f2014-12-09 18:35:413554 gpu_trace_commands_ = gpu_tracer_->IsTracing() && *gpu_decoder_category_;
vmiura1c2b1de2014-09-19 19:03:243555 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3556 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513557}
3558
3559void GLES2DecoderImpl::EndDecoding() {
3560 gpu_tracer_->EndDecoding();
3561}
3562
[email protected]d3eba342013-04-18 21:11:503563ErrorState* GLES2DecoderImpl::GetErrorState() {
3564 return state_.GetErrorState();
3565}
3566
[email protected]e3932abb2013-03-13 00:01:373567void GLES2DecoderImpl::SetShaderCacheCallback(
3568 const ShaderCacheCallback& callback) {
3569 shader_cache_callback_ = callback;
3570}
3571
[email protected]840a7e462013-02-27 01:29:513572void GLES2DecoderImpl::SetWaitSyncPointCallback(
3573 const WaitSyncPointCallback& callback) {
3574 wait_sync_point_callback_ = callback;
3575}
3576
[email protected]85a4ac22013-05-31 01:58:473577AsyncPixelTransferManager*
3578 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3579 return async_pixel_transfer_manager_.get();
3580}
3581
3582void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3583 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593584}
3585
[email protected]498b5c072013-06-04 19:30:073586void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3587 AsyncPixelTransferManager* manager) {
3588 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3589}
3590
[email protected]1318e922010-09-17 22:03:163591bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3592 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493593 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3594 if (texture_ref) {
3595 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163596 return true;
3597 }
3598 return false;
3599}
3600
[email protected]63b465922012-09-06 02:04:523601uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443602 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483603 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523604}
3605
3606base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443607 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483608 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523609}
3610
3611base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3612 return total_processing_commands_time_;
3613}
3614
[email protected]dc25dda2012-09-27 21:36:303615void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3616 total_processing_commands_time_ += time;
3617}
3618
[email protected]63c9b052012-05-17 18:27:383619void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063620 if (!initialized())
3621 return;
3622
[email protected]63c9b052012-05-17 18:27:383623 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053624
[email protected]80eb6b52012-01-19 00:14:413625 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243626 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523627 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023628 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243629 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133630 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343631 framebuffer_state_.bound_read_framebuffer = NULL;
3632 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243633 state_.bound_renderbuffer = NULL;
orglofchcad5a6742014-11-07 19:51:123634 state_.bound_valuebuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413635
[email protected]cadac622013-06-11 16:46:363636 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513637 DCHECK(offscreen_target_color_texture_);
3638 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3639 offscreen_saved_color_texture_->id());
3640 offscreen_saved_color_texture_->Invalidate();
3641 offscreen_saved_color_texture_info_ = NULL;
3642 }
[email protected]eadc96792010-10-27 19:39:393643 if (have_context) {
[email protected]c322e882012-05-23 18:06:183644 if (copy_texture_CHROMIUM_.get()) {
3645 copy_texture_CHROMIUM_->Destroy();
3646 copy_texture_CHROMIUM_.reset();
3647 }
[email protected]43410e92012-04-20 17:06:283648
sievers2384f2b2014-11-18 02:10:353649 clear_framebuffer_blit_.reset();
3650
[email protected]7cd76fd2013-06-02 21:11:113651 if (state_.current_program.get()) {
3652 program_manager()->UnuseProgram(shader_manager(),
3653 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143654 }
3655
[email protected]b1122982010-05-17 23:04:243656 if (attrib_0_buffer_id_) {
3657 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3658 }
[email protected]8fbedc02010-11-18 18:43:403659 if (fixed_attrib_buffer_id_) {
3660 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3661 }
[email protected]b1122982010-05-17 23:04:243662
[email protected]4a4c18b2013-09-13 22:50:103663 if (validation_texture_) {
3664 glDeleteTextures(1, &validation_texture_);
3665 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3666 glDeleteFramebuffersEXT(1, &validation_fbo_);
3667 }
3668
[email protected]97872062010-11-03 19:07:053669 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543670 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053671 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543672 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053673 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023674 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053675 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153676 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053677 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153678 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053679 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023680 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053681 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543682 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273683 if (offscreen_resolved_frame_buffer_.get())
3684 offscreen_resolved_frame_buffer_->Destroy();
3685 if (offscreen_resolved_color_texture_.get())
3686 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053687 } else {
3688 if (offscreen_target_frame_buffer_.get())
3689 offscreen_target_frame_buffer_->Invalidate();
3690 if (offscreen_target_color_texture_.get())
3691 offscreen_target_color_texture_->Invalidate();
3692 if (offscreen_target_color_render_buffer_.get())
3693 offscreen_target_color_render_buffer_->Invalidate();
3694 if (offscreen_target_depth_render_buffer_.get())
3695 offscreen_target_depth_render_buffer_->Invalidate();
3696 if (offscreen_target_stencil_render_buffer_.get())
3697 offscreen_target_stencil_render_buffer_->Invalidate();
3698 if (offscreen_saved_frame_buffer_.get())
3699 offscreen_saved_frame_buffer_->Invalidate();
3700 if (offscreen_saved_color_texture_.get())
3701 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273702 if (offscreen_resolved_frame_buffer_.get())
3703 offscreen_resolved_frame_buffer_->Invalidate();
3704 if (offscreen_resolved_color_texture_.get())
3705 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023706 }
[email protected]83a52d032013-07-24 10:30:373707
3708 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3709 // Otherwise, we can leak objects. http://crbug.com/258772.
3710 // state_.current_program must be reset before group_ is reset because
3711 // the later deletes the ProgramManager object that referred by
3712 // state_.current_program object.
3713 state_.current_program = NULL;
3714
[email protected]43410e92012-04-20 17:06:283715 copy_texture_CHROMIUM_.reset();
sievers2384f2b2014-11-18 02:10:353716 clear_framebuffer_blit_.reset();
[email protected]97872062010-11-03 19:07:053717
[email protected]882ba1e22012-03-08 19:02:533718 if (query_manager_.get()) {
3719 query_manager_->Destroy(have_context);
3720 query_manager_.reset();
3721 }
3722
[email protected]944b62f32012-09-27 02:20:463723 if (vertex_array_manager_ .get()) {
3724 vertex_array_manager_->Destroy(have_context);
3725 vertex_array_manager_.reset();
3726 }
3727
[email protected]d2eaf52f2014-07-31 15:01:243728 if (image_manager_.get()) {
3729 image_manager_->Destroy(have_context);
3730 image_manager_.reset();
3731 }
3732
[email protected]97872062010-11-03 19:07:053733 offscreen_target_frame_buffer_.reset();
3734 offscreen_target_color_texture_.reset();
3735 offscreen_target_color_render_buffer_.reset();
3736 offscreen_target_depth_render_buffer_.reset();
3737 offscreen_target_stencil_render_buffer_.reset();
3738 offscreen_saved_frame_buffer_.reset();
3739 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273740 offscreen_resolved_frame_buffer_.reset();
3741 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463742
[email protected]03cef9b2014-04-03 15:58:143743 // Need to release these before releasing |group_| which may own the
3744 // ShaderTranslatorCache.
3745 fragment_translator_ = NULL;
3746 vertex_translator_ = NULL;
3747
[email protected]85a4ac22013-05-31 01:58:473748 // Should destroy the transfer manager before the texture manager held
3749 // by the context group.
3750 async_pixel_transfer_manager_.reset();
3751
[email protected]7cd76fd2013-06-02 21:11:113752 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393753 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233754 group_->Destroy(this, have_context);
3755 group_ = NULL;
3756 }
3757
3758 if (context_.get()) {
3759 context_->ReleaseCurrent(NULL);
3760 context_ = NULL;
3761 }
3762
[email protected]e51bdf32011-11-23 22:21:463763#if defined(OS_MACOSX)
3764 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3765 it != texture_to_io_surface_map_.end(); ++it) {
3766 CFRelease(it->second);
3767 }
3768 texture_to_io_surface_map_.clear();
3769#endif
[email protected]96449d2c2009-11-25 00:01:323770}
3771
[email protected]63c9b052012-05-17 18:27:383772void GLES2DecoderImpl::SetSurface(
3773 const scoped_refptr<gfx::GLSurface>& surface) {
3774 DCHECK(context_->IsCurrent(NULL));
3775 DCHECK(surface_.get());
3776 surface_ = surface;
3777 RestoreCurrentFramebufferBindings();
3778}
3779
[email protected]aba551b2014-02-08 03:38:323780void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3781 if (!offscreen_saved_color_texture_.get()) {
3782 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3783 return;
3784 }
[email protected]2ad674132013-06-05 07:48:513785 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243786 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073787 offscreen_saved_color_texture_info_ = TextureRef::Create(
3788 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513789 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3790 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393791 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243792 }
[email protected]aba551b2014-02-08 03:38:323793 mailbox_manager()->ProduceTexture(
sievers8b373ec52014-10-24 23:04:063794 mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243795}
3796
[email protected]799b4b22011-08-22 17:09:593797bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3798 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3799 if (!is_offscreen) {
3800 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3801 << " with an onscreen framebuffer.";
3802 return false;
3803 }
3804
3805 if (offscreen_size_ == size)
3806 return true;
3807
3808 offscreen_size_ = size;
3809 int w = offscreen_size_.width();
3810 int h = offscreen_size_.height();
3811 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3812 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3813 << "to allocate storage due to excessive dimensions.";
3814 return false;
3815 }
3816
3817 // Reallocate the offscreen target buffers.
3818 DCHECK(offscreen_target_color_format_);
3819 if (IsOffscreenBufferMultisampled()) {
3820 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253821 feature_info_.get(),
3822 offscreen_size_,
3823 offscreen_target_color_format_,
3824 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593825 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3826 << "to allocate storage for offscreen target color buffer.";
3827 return false;
3828 }
3829 } else {
3830 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093831 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593832 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3833 << "to allocate storage for offscreen target color texture.";
3834 return false;
3835 }
3836 }
3837 if (offscreen_target_depth_format_ &&
3838 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253839 feature_info_.get(),
3840 offscreen_size_,
3841 offscreen_target_depth_format_,
3842 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593843 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3844 << "to allocate storage for offscreen target depth buffer.";
3845 return false;
3846 }
3847 if (offscreen_target_stencil_format_ &&
3848 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253849 feature_info_.get(),
3850 offscreen_size_,
3851 offscreen_target_stencil_format_,
3852 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593853 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3854 << "to allocate storage for offscreen target stencil buffer.";
3855 return false;
3856 }
3857
3858 // Attach the offscreen target buffers to the target frame buffer.
3859 if (IsOffscreenBufferMultisampled()) {
3860 offscreen_target_frame_buffer_->AttachRenderBuffer(
3861 GL_COLOR_ATTACHMENT0,
3862 offscreen_target_color_render_buffer_.get());
3863 } else {
3864 offscreen_target_frame_buffer_->AttachRenderTexture(
3865 offscreen_target_color_texture_.get());
3866 }
3867 if (offscreen_target_depth_format_) {
3868 offscreen_target_frame_buffer_->AttachRenderBuffer(
3869 GL_DEPTH_ATTACHMENT,
3870 offscreen_target_depth_render_buffer_.get());
3871 }
3872 const bool packed_depth_stencil =
3873 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3874 if (packed_depth_stencil) {
3875 offscreen_target_frame_buffer_->AttachRenderBuffer(
3876 GL_STENCIL_ATTACHMENT,
3877 offscreen_target_depth_render_buffer_.get());
3878 } else if (offscreen_target_stencil_format_) {
3879 offscreen_target_frame_buffer_->AttachRenderBuffer(
3880 GL_STENCIL_ATTACHMENT,
3881 offscreen_target_stencil_render_buffer_.get());
3882 }
3883
3884 if (offscreen_target_frame_buffer_->CheckStatus() !=
3885 GL_FRAMEBUFFER_COMPLETE) {
3886 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3887 << "because offscreen FBO was incomplete.";
3888 return false;
3889 }
3890
3891 // Clear the target frame buffer.
3892 {
3893 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3894 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323895 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453896 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593897 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473898 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3899 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:593900 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:453901 state_.SetDeviceDepthMask(GL_TRUE);
3902 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:593903 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3904 RestoreClearState();
3905 }
[email protected]d85ef76d2011-09-08 22:21:433906
3907 // Destroy the offscreen resolved framebuffers.
3908 if (offscreen_resolved_frame_buffer_.get())
3909 offscreen_resolved_frame_buffer_->Destroy();
3910 if (offscreen_resolved_color_texture_.get())
3911 offscreen_resolved_color_texture_->Destroy();
3912 offscreen_resolved_color_texture_.reset();
3913 offscreen_resolved_frame_buffer_.reset();
3914
[email protected]799b4b22011-08-22 17:09:593915 return true;
[email protected]6217d392010-03-25 22:08:353916}
3917
vmiuracd108592014-09-08 14:36:343918error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
3919 const void* cmd_data) {
3920 const gles2::cmds::ResizeCHROMIUM& c =
3921 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:443922 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023923 return error::kDeferCommandUntilLater;
3924
[email protected]799b4b22011-08-22 17:09:593925 GLuint width = static_cast<GLuint>(c.width);
3926 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073927 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593928 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413929
3930 width = std::max(1U, width);
3931 height = std::max(1U, height);
3932
[email protected]a0d989162011-11-22 13:15:073933#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3934 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003935 // Make sure that we are done drawing to the back buffer before resizing.
3936 glFinish();
3937#endif
[email protected]799b4b22011-08-22 17:09:593938 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3939 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493940 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3941 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3942 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593943 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493944 }
[email protected]7ff86b92010-11-25 17:50:003945 }
[email protected]799b4b22011-08-22 17:09:593946
[email protected]9d37f062011-11-22 01:24:523947 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073948 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443949 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493950 if (!context_->IsCurrent(surface_.get())) {
3951 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3952 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053953 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493954 }
[email protected]658f7562011-09-09 05:24:053955 }
[email protected]799b4b22011-08-22 17:09:593956
3957 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393958}
3959
[email protected]96449d2c2009-11-25 00:01:323960const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3961 if (command_id > kStartPoint && command_id < kNumCommands) {
3962 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3963 }
3964 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3965}
3966
vmiura8266ca72014-09-09 21:37:003967// Decode a command, and call the corresponding GL functions.
3968// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
3969// of commands at once, and is now only used for tests that need to track
3970// individual commands.
3971error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
3972 unsigned int arg_count,
3973 const void* cmd_data) {
3974 return DoCommands(1, cmd_data, arg_count + 1, 0);
3975}
3976
3977// Decode multiple commands, and call the corresponding GL functions.
3978// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
3979// changed by a (malicious) client at any time, so if validation has to happen,
3980// it should operate on a copy of them.
3981// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
3982// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:243983template <bool DebugImpl>
3984error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
3985 const void* buffer,
3986 int num_entries,
3987 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:003988 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:143989 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:003990 const CommandBufferEntry* cmd_data =
3991 static_cast<const CommandBufferEntry*>(buffer);
3992 int process_pos = 0;
3993 unsigned int command = 0;
3994
3995 while (process_pos < num_entries && result == error::kNoError &&
3996 commands_to_process_--) {
3997 const unsigned int size = cmd_data->value_header.size;
3998 command = cmd_data->value_header.command;
3999
4000 if (size == 0) {
4001 result = error::kInvalidSize;
4002 break;
4003 }
4004
4005 if (static_cast<int>(size) + process_pos > num_entries) {
4006 result = error::kOutOfBounds;
4007 break;
4008 }
4009
vmiura1c2b1de2014-09-19 19:03:244010 if (DebugImpl) {
4011 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
4012 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:004013
vmiura1c2b1de2014-09-19 19:03:244014 if (log_commands()) {
4015 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
4016 << "cmd: " << GetCommandName(command);
4017 }
vmiura8266ca72014-09-09 21:37:004018 }
4019
4020 const unsigned int arg_count = size - 1;
4021 unsigned int command_index = command - kStartPoint - 1;
4022 if (command_index < arraysize(command_info)) {
4023 const CommandInfo& info = command_info[command_index];
4024 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
4025 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
4026 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
4027 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:244028 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:004029 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
4030 doing_gpu_trace = true;
dyencb86f2f2014-12-09 18:35:414031 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_decoder"),
4032 GetCommandName(command),
4033 kTraceDecoder);
vmiura8266ca72014-09-09 21:37:004034 }
[email protected]cac16542014-01-15 17:53:514035 }
[email protected]cac16542014-01-15 17:53:514036
vmiura8266ca72014-09-09 21:37:004037 uint32 immediate_data_size = (arg_count - info_arg_count) *
4038 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:324039
vmiura8266ca72014-09-09 21:37:004040 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:514041
vmiura1c2b1de2014-09-19 19:03:244042 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:004043 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:514044
vmiura1c2b1de2014-09-19 19:03:244045 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:004046 GLenum error;
4047 while ((error = glGetError()) != GL_NO_ERROR) {
4048 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
4049 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
4050 << " : " << GetCommandName(command);
4051 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
4052 }
[email protected]b9849abf2009-11-25 19:13:194053 }
vmiura8266ca72014-09-09 21:37:004054 } else {
4055 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:324056 }
4057 } else {
vmiura8266ca72014-09-09 21:37:004058 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:324059 }
vmiura1c2b1de2014-09-19 19:03:244060
4061 if (DebugImpl) {
4062 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
4063 GetCommandName(command));
4064 }
4065
vmiura8266ca72014-09-09 21:37:004066 if (result == error::kNoError &&
4067 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:564068 result = current_decoder_error_;
4069 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:004070 }
4071
4072 if (result != error::kDeferCommandUntilLater) {
4073 process_pos += size;
4074 cmd_data += size;
4075 }
[email protected]a3a93e7b2010-08-28 00:48:564076 }
vmiura8266ca72014-09-09 21:37:004077
4078 if (entries_processed)
4079 *entries_processed = process_pos;
4080
4081 if (error::IsError(result)) {
4082 LOG(ERROR) << "Error: " << result << " for Command "
4083 << GetCommandName(command);
4084 }
4085
[email protected]b9849abf2009-11-25 19:13:194086 return result;
[email protected]96449d2c2009-11-25 00:01:324087}
4088
vmiura1c2b1de2014-09-19 19:03:244089error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
4090 const void* buffer,
4091 int num_entries,
4092 int* entries_processed) {
4093 if (gpu_debug_commands_) {
4094 return DoCommandsImpl<true>(
4095 num_commands, buffer, num_entries, entries_processed);
4096 } else {
4097 return DoCommandsImpl<false>(
4098 num_commands, buffer, num_entries, entries_processed);
4099 }
4100}
4101
[email protected]ed9f9cd2013-02-27 21:12:354102void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
4103 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:504104}
4105
[email protected]882ba1e22012-03-08 19:02:534106void GLES2DecoderImpl::DoFinish() {
4107 glFinish();
[email protected]5a36dc132013-07-23 23:17:554108 ProcessPendingReadPixels();
revemancc241eb2014-11-11 03:30:374109 ProcessPendingQueries(true);
[email protected]882ba1e22012-03-08 19:02:534110}
4111
4112void GLES2DecoderImpl::DoFlush() {
4113 glFlush();
revemancc241eb2014-11-11 03:30:374114 ProcessPendingQueries(false);
[email protected]882ba1e22012-03-08 19:02:534115}
4116
[email protected]3916c97e2010-02-25 03:20:504117void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:454118 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:024119 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:514120 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:534121 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:504122 return;
4123 }
[email protected]e259eb412012-10-13 05:47:244124 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:454125 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:504126}
4127
[email protected]051b1372010-04-12 02:42:084128void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:074129 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:084130 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034131 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:074132 buffer = GetBuffer(client_id);
4133 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:354134 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224135 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4136 "glBindBuffer",
4137 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:354138 return;
4139 }
4140
[email protected]b10492f2013-03-08 05:24:074141 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:034142 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354143 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:074144 buffer = GetBuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034145 }
[email protected]051b1372010-04-12 02:42:084146 }
[email protected]b10492f2013-03-08 05:24:074147 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
4148 if (buffer) {
4149 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:514150 LOCAL_SET_GL_ERROR(
4151 GL_INVALID_OPERATION,
4152 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:474153 return;
4154 }
[email protected]b10492f2013-03-08 05:24:074155 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:474156 }
[email protected]96449d2c2009-11-25 00:01:324157 switch (target) {
4158 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074159 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:324160 break;
4161 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074162 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:324163 break;
4164 default:
[email protected]a93bb842010-02-16 23:03:474165 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:324166 break;
4167 }
[email protected]051b1372010-04-12 02:42:084168 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:324169}
4170
[email protected]f3b191b2013-06-19 03:43:544171bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
4172 bool all_draw_buffers) {
4173 Framebuffer* framebuffer =
4174 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4175 if (!all_draw_buffers || !framebuffer) {
4176 return (GLES2Util::GetChannelsForFormat(
4177 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
4178 }
4179 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:464180}
4181
4182bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354183 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454184 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204185 if (framebuffer) {
4186 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:464187 }
4188 if (offscreen_target_frame_buffer_.get()) {
4189 return offscreen_target_depth_format_ != 0;
4190 }
4191 return back_buffer_has_depth_;
4192}
4193
4194bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354195 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454196 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204197 if (framebuffer) {
4198 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464199 }
4200 if (offscreen_target_frame_buffer_.get()) {
4201 return offscreen_target_stencil_format_ != 0 ||
4202 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4203 }
4204 return back_buffer_has_stencil_;
4205}
4206
4207void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444208 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454209 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4210 state_.SetDeviceColorMask(state_.color_mask_red,
4211 state_.color_mask_green,
4212 state_.color_mask_blue,
4213 state_.color_mask_alpha && have_alpha);
4214
[email protected]297ca1c2011-06-20 23:08:464215 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454216 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4217
[email protected]297ca1c2011-06-20 23:08:464218 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454219 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424220 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454221 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424222 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454223
4224 state_.SetDeviceCapabilityState(
4225 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4226 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224227 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444228 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464229 }
4230}
4231
[email protected]1868a342012-11-07 15:56:024232GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114233 return (offscreen_target_frame_buffer_.get())
4234 ? offscreen_target_frame_buffer_->id()
4235 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024236}
4237
[email protected]8875a5f2014-06-27 08:33:474238void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144239 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4240 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064241 // Restore the Framebuffer first because of bugs in Intel drivers.
4242 // Intel drivers incorrectly clip the viewport settings to
4243 // the size of the current framebuffer object.
4244 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164245 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064246}
4247
4248void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344249 GLuint service_id =
4250 framebuffer_state_.bound_draw_framebuffer.get()
4251 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4252 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064253 if (!features().chromium_framebuffer_multisample) {
4254 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4255 } else {
4256 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344257 service_id = framebuffer_state_.bound_read_framebuffer.get()
4258 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114259 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064260 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4261 }
[email protected]70d34263c2013-01-09 00:27:454262 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064263}
4264
[email protected]8875a5f2014-06-27 08:33:474265void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4266 state_.RestoreRenderbufferBindings();
4267}
4268
[email protected]29a4d902013-02-26 20:18:064269void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104270 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4271 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254272 GLenum target = texture->target();
4273 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064274 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254275 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064276 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254277 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064278 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254279 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064280 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254281 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064282 RestoreTextureUnitBindings(state_.active_texture_unit);
4283 }
[email protected]70d34263c2013-01-09 00:27:454284}
4285
[email protected]cd2ef752014-02-12 23:16:034286void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524287 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4288 // other VAOs.
4289 if (feature_info_->feature_flags().native_vertex_array_object)
4290 glBindVertexArrayOES(0);
4291
[email protected]cd2ef752014-02-12 23:16:034292 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
4293 if (i != 0) // Never disable attribute 0
4294 glDisableVertexAttribArray(i);
4295 if(features().angle_instanced_arrays)
4296 glVertexAttribDivisorANGLE(i, 0);
4297 }
4298}
4299
4300void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524301 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034302}
4303
[email protected]454157e2014-05-03 02:49:454304void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4305 state_.SetIgnoreCachedStateForTest(ignore);
4306}
4307
[email protected]70d34263c2013-01-09 00:27:454308void GLES2DecoderImpl::OnFboChanged() const {
4309 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:514310 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
ccameron4ff12a732014-12-12 21:38:194311
4312 if (workarounds().gl_begin_gl_end_on_fbo_change_to_backbuffer) {
4313 GLint bound_fbo_unsigned = -1;
4314 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_fbo_unsigned);
4315 GLuint bound_fbo = static_cast<GLuint>(bound_fbo_unsigned);
4316 if (surface_ && surface_->GetBackingFrameBufferObject() == bound_fbo)
4317 surface_->NotifyWasBound();
4318 }
[email protected]28718a92013-04-04 12:12:514319}
4320
4321// Called after the FBO is checked for completeness.
4322void GLES2DecoderImpl::OnUseFramebuffer() const {
4323 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
4324 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:324325 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514326 glScissor(state_.scissor_x,
4327 state_.scissor_y,
4328 state_.scissor_width,
4329 state_.scissor_height);
4330
4331 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4332 // it's unclear how this bug works.
4333 glFlush();
4334 }
[email protected]b177ae22011-11-01 03:29:114335}
4336
[email protected]051b1372010-04-12 02:42:084337void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064338 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084339 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034340 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064341 framebuffer = GetFramebuffer(client_id);
4342 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354343 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224344 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4345 "glBindFramebuffer",
4346 "id not generated by glGenFramebuffers");
4347 return;
[email protected]bf5a8d132011-08-16 08:39:354348 }
4349
[email protected]4d8f0dd2013-03-09 14:37:064350 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034351 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354352 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064353 framebuffer = GetFramebuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034354 } else {
[email protected]4d8f0dd2013-03-09 14:37:064355 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084356 }
[email protected]4d8f0dd2013-03-09 14:37:064357 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084358 }
[email protected]4d8f0dd2013-03-09 14:37:064359 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304360
4361 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344362 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304363 }
[email protected]cac16542014-01-15 17:53:514364
4365 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304366 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344367 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304368 }
[email protected]6217d392010-03-25 22:08:354369
[email protected]c986af502013-08-14 01:04:444370 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464371
[email protected]b177ae22011-11-01 03:29:114372 // If we are rendering to the backbuffer get the FBO id for any simulated
4373 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064374 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114375 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464376 }
[email protected]6217d392010-03-25 22:08:354377
[email protected]051b1372010-04-12 02:42:084378 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454379 OnFboChanged();
[email protected]86093972010-03-11 00:13:564380}
4381
[email protected]051b1372010-04-12 02:42:084382void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274383 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084384 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034385 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274386 renderbuffer = GetRenderbuffer(client_id);
4387 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354388 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224389 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4390 "glBindRenderbuffer",
4391 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354392 return;
4393 }
4394
[email protected]8875a5f2014-06-27 08:33:474395 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034396 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354397 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274398 renderbuffer = GetRenderbuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034399 } else {
[email protected]ee2a79c32013-03-10 03:50:274400 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084401 }
[email protected]ee2a79c32013-03-10 03:50:274402 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084403 }
[email protected]caa13ed2014-02-17 11:29:204404 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274405 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474406 state_.bound_renderbuffer_valid = true;
4407 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564408}
4409
[email protected]051b1372010-04-12 02:42:084410void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494411 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084412 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034413 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494414 texture_ref = GetTexture(client_id);
4415 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354416 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224417 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4418 "glBindTexture",
4419 "id not generated by glGenTextures");
4420 return;
[email protected]bf5a8d132011-08-16 08:39:354421 }
4422
[email protected]02965c22013-03-09 02:40:074423 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034424 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414425 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354426 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494427 texture_ref = GetTexture(client_id);
[email protected]ae51d192010-04-27 00:48:034428 }
4429 } else {
[email protected]370eaf12013-05-18 09:19:494430 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084431 }
[email protected]ae51d192010-04-27 00:48:034432
[email protected]1958e0e2010-04-22 05:17:154433 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574434 if (texture_ref) {
4435 Texture* texture = texture_ref->texture();
4436 // Check that we are not trying to bind it to a different target.
4437 if (texture->target() != 0 && texture->target() != target) {
4438 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4439 "glBindTexture",
4440 "texture bound to more than 1 target.");
4441 return;
4442 }
4443 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4444 if (texture->target() == 0) {
4445 texture_manager()->SetTarget(texture_ref, target);
4446 }
4447 glBindTexture(target, texture->service_id());
4448 } else {
4449 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154450 }
[email protected]32145a92012-12-17 09:01:594451
[email protected]e259eb412012-10-13 05:47:244452 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504453 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474454 switch (target) {
4455 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494456 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474457 break;
4458 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494459 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474460 break;
[email protected]61eeb33f2011-07-26 15:30:314461 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494462 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314463 break;
[email protected]e51bdf32011-11-23 22:21:464464 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494465 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464466 break;
[email protected]a93bb842010-02-16 23:03:474467 default:
4468 NOTREACHED(); // Validation should prevent us getting here.
4469 break;
4470 }
4471}
4472
[email protected]07f54fcc2009-12-22 02:46:304473void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244474 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124475 if (index != 0 ||
4476 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244477 glDisableVertexAttribArray(index);
4478 }
[email protected]07f54fcc2009-12-22 02:46:304479 } else {
[email protected]ab09b612013-03-11 22:11:514480 LOCAL_SET_GL_ERROR(
4481 GL_INVALID_VALUE,
4482 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304483 }
4484}
4485
[email protected]60f22d32012-12-12 00:31:584486void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4487 GLsizei numAttachments,
4488 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:354489 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584490 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4491
4492 // Validates the attachments. If one of them fails
4493 // the whole command fails.
4494 for (GLsizei i = 0; i < numAttachments; ++i) {
4495 if ((framebuffer &&
4496 !validators_->attachment.IsValid(attachments[i])) ||
4497 (!framebuffer &&
4498 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514499 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4500 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584501 return;
4502 }
4503 }
4504
4505 // Marks each one of them as not cleared
4506 for (GLsizei i = 0; i < numAttachments; ++i) {
4507 if (framebuffer) {
4508 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4509 texture_manager(),
4510 attachments[i],
4511 false);
4512 } else {
4513 switch (attachments[i]) {
4514 case GL_COLOR_EXT:
4515 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4516 break;
4517 case GL_DEPTH_EXT:
4518 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4519 case GL_STENCIL_EXT:
4520 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4521 break;
4522 default:
4523 NOTREACHED();
4524 break;
4525 }
4526 }
4527 }
4528
[email protected]d49c5402013-09-11 15:39:024529 // If the default framebuffer is bound but we are still rendering to an
4530 // FBO, translate attachment names that refer to default framebuffer
4531 // channels to corresponding framebuffer attachments.
4532 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4533 for (GLsizei i = 0; i < numAttachments; ++i) {
4534 GLenum attachment = attachments[i];
4535 if (!framebuffer && GetBackbufferServiceId()) {
4536 switch (attachment) {
4537 case GL_COLOR_EXT:
4538 attachment = GL_COLOR_ATTACHMENT0;
4539 break;
4540 case GL_DEPTH_EXT:
4541 attachment = GL_DEPTH_ATTACHMENT;
4542 break;
4543 case GL_STENCIL_EXT:
4544 attachment = GL_STENCIL_ATTACHMENT;
4545 break;
4546 default:
4547 NOTREACHED();
4548 return;
4549 }
4550 }
4551 translated_attachments[i] = attachment;
4552 }
4553
boliu2e7d8a7a2014-10-16 20:35:204554 ScopedRenderTo do_render(framebuffer);
zmo68fcdc62014-12-05 21:51:494555 if (feature_info_->gl_version_info().is_es3) {
4556 glInvalidateFramebuffer(
4557 target, numAttachments, translated_attachments.get());
4558 } else {
4559 glDiscardFramebufferEXT(
4560 target, numAttachments, translated_attachments.get());
4561 }
[email protected]60f22d32012-12-12 00:31:584562}
4563
[email protected]07f54fcc2009-12-22 02:46:304564void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244565 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304566 glEnableVertexAttribArray(index);
4567 } else {
[email protected]ab09b612013-03-11 22:11:514568 LOCAL_SET_GL_ERROR(
4569 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304570 }
4571}
4572
[email protected]a93bb842010-02-16 23:03:474573void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444574 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4575 &state_, target);
[email protected]370eaf12013-05-18 09:19:494576 if (!texture_ref ||
4577 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514578 LOCAL_SET_GL_ERROR(
4579 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474580 return;
4581 }
[email protected]38c0a972012-05-12 00:48:024582
[email protected]12d95352012-12-14 07:23:544583 if (target == GL_TEXTURE_CUBE_MAP) {
4584 for (int i = 0; i < 6; ++i) {
4585 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494586 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514587 LOCAL_SET_GL_ERROR(
4588 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544589 return;
4590 }
4591 }
4592 } else {
[email protected]370eaf12013-05-18 09:19:494593 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514594 LOCAL_SET_GL_ERROR(
4595 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544596 return;
4597 }
[email protected]7687479c2012-05-14 23:54:044598 }
4599
[email protected]ab09b612013-03-11 22:11:514600 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194601 // Workaround for Mac driver bug. In the large scheme of things setting
4602 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564603 // hit so there's probably no need to make this conditional. The bug appears
4604 // to be that if the filtering mode is set to something that doesn't require
4605 // mipmaps for rendering, or is never set to something other than the default,
4606 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154607 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194608 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4609 }
[email protected]a93bb842010-02-16 23:03:474610 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154611 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494612 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4613 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194614 }
[email protected]ab09b612013-03-11 22:11:514615 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024616 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494617 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024618 }
[email protected]a93bb842010-02-16 23:03:474619}
4620
[email protected]b273e432010-04-12 17:23:584621bool GLES2DecoderImpl::GetHelper(
4622 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584623 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154624 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4625 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434626 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4627 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214628 // Return the GL implementation's preferred format and (see below type)
4629 // if we have the GL extension that exposes this. This allows the GPU
4630 // client to use the implementation's preferred format for glReadPixels
4631 // for optimisation.
4632 //
4633 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4634 // case when requested on integer/floating point buffers but which is
4635 // acceptable on GLES2 and with the GL_OES_read_format extension.
4636 //
4637 // Therefore if an error occurs we swallow the error and use the
4638 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434639 if (params) {
[email protected]c959a09a2014-03-27 11:44:214640 if (context_->HasExtension("GL_OES_read_format")) {
4641 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4642 GetErrorState());
4643 glGetIntegerv(pname, params);
4644 if (glGetError() == GL_NO_ERROR)
4645 return true;
4646 }
[email protected]68586372013-12-11 01:27:594647 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4648 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434649 }
4650 return true;
4651 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4652 *num_written = 1;
4653 if (params) {
[email protected]c959a09a2014-03-27 11:44:214654 if (context_->HasExtension("GL_OES_read_format")) {
4655 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4656 GetErrorState());
4657 glGetIntegerv(pname, params);
4658 if (glGetError() == GL_NO_ERROR)
4659 return true;
4660 }
[email protected]68586372013-12-11 01:27:594661 *params = GLES2Util::GetPreferredGLReadPixelsType(
4662 GetBoundReadFrameBufferInternalFormat(),
4663 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434664 }
4665 return true;
4666 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4667 *num_written = 1;
4668 if (params) {
4669 *params = group_->max_fragment_uniform_vectors();
4670 }
4671 return true;
4672 case GL_MAX_VARYING_VECTORS:
4673 *num_written = 1;
4674 if (params) {
4675 *params = group_->max_varying_vectors();
4676 }
4677 return true;
4678 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4679 *num_written = 1;
4680 if (params) {
4681 *params = group_->max_vertex_uniform_vectors();
4682 }
4683 return true;
[email protected]4e8a5b122010-05-08 22:00:104684 }
[email protected]5cb735d2011-10-13 01:37:234685 }
4686 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244687 case GL_MAX_VIEWPORT_DIMS:
4688 if (offscreen_target_frame_buffer_.get()) {
4689 *num_written = 2;
4690 if (params) {
4691 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4692 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4693 }
4694 return true;
4695 }
[email protected]5cb735d2011-10-13 01:37:234696 return false;
[email protected]84afefa2011-10-19 21:45:534697 case GL_MAX_SAMPLES:
4698 *num_written = 1;
4699 if (params) {
4700 params[0] = renderbuffer_manager()->max_samples();
4701 }
4702 return true;
4703 case GL_MAX_RENDERBUFFER_SIZE:
4704 *num_written = 1;
4705 if (params) {
4706 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4707 }
4708 return true;
[email protected]5cb735d2011-10-13 01:37:234709 case GL_MAX_TEXTURE_SIZE:
4710 *num_written = 1;
4711 if (params) {
4712 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4713 }
4714 return true;
4715 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4716 *num_written = 1;
4717 if (params) {
4718 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4719 }
4720 return true;
[email protected]2f143d482013-03-14 18:04:494721 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4722 *num_written = 1;
4723 if (params) {
4724 params[0] = group_->max_color_attachments();
4725 }
4726 return true;
4727 case GL_MAX_DRAW_BUFFERS_ARB:
4728 *num_written = 1;
4729 if (params) {
4730 params[0] = group_->max_draw_buffers();
4731 }
4732 return true;
[email protected]297ca1c2011-06-20 23:08:464733 case GL_ALPHA_BITS:
4734 *num_written = 1;
4735 if (params) {
4736 GLint v = 0;
4737 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544738 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464739 }
4740 return true;
4741 case GL_DEPTH_BITS:
4742 *num_written = 1;
4743 if (params) {
4744 GLint v = 0;
4745 glGetIntegerv(GL_DEPTH_BITS, &v);
4746 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4747 }
4748 return true;
4749 case GL_STENCIL_BITS:
4750 *num_written = 1;
4751 if (params) {
4752 GLint v = 0;
4753 glGetIntegerv(GL_STENCIL_BITS, &v);
4754 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4755 }
4756 return true;
[email protected]656dcaad2010-05-07 17:18:374757 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114758 *num_written = validators_->compressed_texture_format.GetValues().size();
4759 if (params) {
4760 for (GLint ii = 0; ii < *num_written; ++ii) {
4761 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4762 }
4763 }
[email protected]656dcaad2010-05-07 17:18:374764 return true;
[email protected]b273e432010-04-12 17:23:584765 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4766 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104767 if (params) {
[email protected]302ce6d2011-07-07 23:28:114768 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104769 }
[email protected]b273e432010-04-12 17:23:584770 return true;
4771 case GL_NUM_SHADER_BINARY_FORMATS:
4772 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104773 if (params) {
[email protected]302ce6d2011-07-07 23:28:114774 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104775 }
[email protected]b273e432010-04-12 17:23:584776 return true;
4777 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114778 *num_written = validators_->shader_binary_format.GetValues().size();
4779 if (params) {
4780 for (GLint ii = 0; ii < *num_written; ++ii) {
4781 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4782 }
4783 }
4784 return true;
[email protected]b273e432010-04-12 17:23:584785 case GL_SHADER_COMPILER:
4786 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104787 if (params) {
4788 *params = GL_TRUE;
4789 }
[email protected]b273e432010-04-12 17:23:584790 return true;
[email protected]6b8cf1a2010-05-06 16:13:584791 case GL_ARRAY_BUFFER_BINDING:
4792 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104793 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114794 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104795 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244796 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104797 &client_id);
4798 *params = client_id;
4799 } else {
4800 *params = 0;
4801 }
[email protected]6b8cf1a2010-05-06 16:13:584802 }
4803 return true;
4804 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4805 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104806 if (params) {
[email protected]e259eb412012-10-13 05:47:244807 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104808 GLuint client_id = 0;
4809 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254810 state_.vertex_attrib_manager->element_array_buffer()->
4811 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104812 *params = client_id;
4813 } else {
4814 *params = 0;
4815 }
[email protected]6b8cf1a2010-05-06 16:13:584816 }
4817 return true;
4818 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304819 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584820 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104821 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354822 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454823 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204824 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104825 GLuint client_id = 0;
4826 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204827 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304828 *params = client_id;
4829 } else {
4830 *params = 0;
4831 }
4832 }
4833 return true;
[email protected]ebfb73c2012-08-15 02:37:454834 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304835 *num_written = 1;
4836 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354837 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454838 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204839 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304840 GLuint client_id = 0;
4841 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204842 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104843 *params = client_id;
4844 } else {
4845 *params = 0;
4846 }
[email protected]6b8cf1a2010-05-06 16:13:584847 }
4848 return true;
4849 case GL_RENDERBUFFER_BINDING:
4850 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104851 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354852 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204853 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4854 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104855 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104856 } else {
4857 *params = 0;
4858 }
[email protected]6b8cf1a2010-05-06 16:13:584859 }
4860 return true;
4861 case GL_CURRENT_PROGRAM:
4862 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104863 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114864 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104865 GLuint client_id = 0;
4866 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244867 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104868 *params = client_id;
4869 } else {
4870 *params = 0;
4871 }
[email protected]6b8cf1a2010-05-06 16:13:584872 }
4873 return true;
[email protected]bf835842012-11-19 15:21:514874 case GL_VERTEX_ARRAY_BINDING_OES:
4875 *num_written = 1;
4876 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114877 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:524878 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:514879 GLuint client_id = 0;
4880 vertex_array_manager_->GetClientId(
4881 state_.vertex_attrib_manager->service_id(), &client_id);
4882 *params = client_id;
4883 } else {
4884 *params = 0;
4885 }
4886 }
4887 return true;
[email protected]4e8a5b122010-05-08 22:00:104888 case GL_TEXTURE_BINDING_2D:
4889 *num_written = 1;
4890 if (params) {
[email protected]e259eb412012-10-13 05:47:244891 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114892 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104893 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584894 } else {
4895 *params = 0;
4896 }
[email protected]6b8cf1a2010-05-06 16:13:584897 }
[email protected]4e8a5b122010-05-08 22:00:104898 return true;
4899 case GL_TEXTURE_BINDING_CUBE_MAP:
4900 *num_written = 1;
4901 if (params) {
[email protected]e259eb412012-10-13 05:47:244902 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114903 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104904 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584905 } else {
4906 *params = 0;
4907 }
[email protected]6b8cf1a2010-05-06 16:13:584908 }
[email protected]4e8a5b122010-05-08 22:00:104909 return true;
[email protected]61eeb33f2011-07-26 15:30:314910 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4911 *num_written = 1;
4912 if (params) {
[email protected]e259eb412012-10-13 05:47:244913 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114914 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104915 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314916 } else {
4917 *params = 0;
4918 }
4919 }
4920 return true;
[email protected]e51bdf32011-11-23 22:21:464921 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4922 *num_written = 1;
4923 if (params) {
[email protected]e259eb412012-10-13 05:47:244924 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114925 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104926 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464927 } else {
4928 *params = 0;
4929 }
4930 }
4931 return true;
[email protected]6c75c712012-06-19 15:43:174932 case GL_UNPACK_FLIP_Y_CHROMIUM:
4933 *num_written = 1;
4934 if (params) {
4935 params[0] = unpack_flip_y_;
4936 }
4937 return true;
4938 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4939 *num_written = 1;
4940 if (params) {
4941 params[0] = unpack_premultiply_alpha_;
4942 }
4943 return true;
4944 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4945 *num_written = 1;
4946 if (params) {
4947 params[0] = unpack_unpremultiply_alpha_;
4948 }
4949 return true;
[email protected]6eda6822014-04-03 23:00:504950 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4951 *num_written = 1;
4952 if (params) {
4953 params[0] = group_->bind_generates_resource() ? 1 : 0;
4954 }
4955 return true;
[email protected]b273e432010-04-12 17:23:584956 default:
[email protected]2f143d482013-03-14 18:04:494957 if (pname >= GL_DRAW_BUFFER0_ARB &&
4958 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4959 *num_written = 1;
4960 if (params) {
4961 Framebuffer* framebuffer =
4962 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4963 if (framebuffer) {
4964 params[0] = framebuffer->GetDrawBuffer(pname);
4965 } else { // backbuffer
4966 if (pname == GL_DRAW_BUFFER0_ARB)
4967 params[0] = group_->draw_buffer();
4968 else
4969 params[0] = GL_NONE;
4970 }
4971 }
4972 return true;
4973 }
[email protected]4e8a5b122010-05-08 22:00:104974 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534975 return false;
[email protected]b273e432010-04-12 17:23:584976 }
4977}
4978
[email protected]4e8a5b122010-05-08 22:00:104979bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4980 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264981 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534982 return true;
4983 }
[email protected]4e8a5b122010-05-08 22:00:104984 return GetHelper(pname, NULL, num_values);
4985}
4986
[email protected]7d3c36e2013-07-12 14:13:164987GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4988 if (GL_MAX_SAMPLES == pname &&
4989 features().use_img_for_multisampled_render_to_texture) {
4990 return GL_MAX_SAMPLES_IMG;
4991 }
4992 return pname;
4993}
4994
[email protected]b273e432010-04-12 17:23:584995void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4996 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104997 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534998 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554999 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:265000 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:535001 GetHelper(pname, values.get(), &num_written);
5002 }
[email protected]b273e432010-04-12 17:23:585003 for (GLsizei ii = 0; ii < num_written; ++ii) {
5004 params[ii] = static_cast<GLboolean>(values[ii]);
5005 }
5006 } else {
[email protected]7d3c36e2013-07-12 14:13:165007 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:585008 glGetBooleanv(pname, params);
5009 }
5010}
5011
5012void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
5013 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:105014 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:265015 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:535016 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:555017 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:535018 GetHelper(pname, values.get(), &num_written);
5019 for (GLsizei ii = 0; ii < num_written; ++ii) {
5020 params[ii] = static_cast<GLfloat>(values[ii]);
5021 }
5022 } else {
[email protected]7d3c36e2013-07-12 14:13:165023 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:535024 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:585025 }
[email protected]b273e432010-04-12 17:23:585026 }
5027}
5028
5029void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
5030 DCHECK(params);
5031 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:265032 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:535033 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:165034 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:585035 glGetIntegerv(pname, params);
5036 }
5037}
5038
[email protected]a0c3e972010-04-21 00:49:135039void GLES2DecoderImpl::DoGetProgramiv(
5040 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:425041 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
5042 if (!program) {
[email protected]a0c3e972010-04-21 00:49:135043 return;
5044 }
[email protected]df37b9932013-03-08 05:21:425045 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:135046}
5047
[email protected]17cfbe0e2013-03-07 01:26:085048void GLES2DecoderImpl::DoGetBufferParameteriv(
5049 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:135050 // Just delegate it. Some validation is actually done before this.
5051 buffer_manager()->ValidateAndDoGetBufferParameteriv(
5052 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:085053}
5054
[email protected]258a3313f2011-10-18 20:13:575055void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:425056 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:575057 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515058 LOCAL_SET_GL_ERROR(
5059 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:575060 return;
5061 }
[email protected]68dcb1f2012-04-07 00:14:565062 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515063 LOCAL_SET_GL_ERROR(
5064 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:565065 return;
5066 }
5067 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:515068 LOCAL_SET_GL_ERROR(
5069 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:565070 return;
5071 }
[email protected]df37b9932013-03-08 05:21:425072 Program* program = GetProgramInfoNotShader(
5073 program_id, "glBindAttribLocation");
5074 if (!program) {
[email protected]258a3313f2011-10-18 20:13:575075 return;
[email protected]558847a2010-03-24 07:02:545076 }
zmo460b593e2014-10-13 23:07:455077 // At this point, the program's shaders may not be translated yet,
5078 // therefore, we may not find the hashed attribute name.
5079 // glBindAttribLocation call with original name is useless.
5080 // So instead, we should simply cache the binding, and then call
5081 // Program::ExecuteBindAttribLocationCalls() right before link.
[email protected]df37b9932013-03-08 05:21:425082 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
zmo460b593e2014-10-13 23:07:455083 // TODO(zmo): Get rid of the following glBindAttribLocation call.
[email protected]df37b9932013-03-08 05:21:425084 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:575085}
5086
[email protected]558847a2010-03-24 07:02:545087error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:345088 uint32 immediate_data_size,
5089 const void* cmd_data) {
5090 const gles2::cmds::BindAttribLocationBucket& c =
5091 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:585092 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:545093 GLuint index = static_cast<GLuint>(c.index);
5094 Bucket* bucket = GetBucket(c.name_bucket_id);
5095 if (!bucket || bucket->size() == 0) {
5096 return error::kInvalidArguments;
5097 }
5098 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:185099 if (!bucket->GetAsString(&name_str)) {
5100 return error::kInvalidArguments;
5101 }
[email protected]258a3313f2011-10-18 20:13:575102 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:545103 return error::kNoError;
5104}
5105
[email protected]2be6abf32012-06-26 00:28:335106void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:425107 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:335108 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515109 LOCAL_SET_GL_ERROR(
5110 GL_INVALID_VALUE,
5111 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:335112 return;
5113 }
5114 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515115 LOCAL_SET_GL_ERROR(
5116 GL_INVALID_OPERATION,
5117 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:335118 return;
5119 }
5120 if (location < 0 || static_cast<uint32>(location) >=
5121 (group_->max_fragment_uniform_vectors() +
5122 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:515123 LOCAL_SET_GL_ERROR(
5124 GL_INVALID_VALUE,
5125 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335126 return;
5127 }
[email protected]df37b9932013-03-08 05:21:425128 Program* program = GetProgramInfoNotShader(
5129 program_id, "glBindUniformLocationCHROMIUM");
5130 if (!program) {
[email protected]2be6abf32012-06-26 00:28:335131 return;
5132 }
[email protected]df37b9932013-03-08 05:21:425133 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:515134 LOCAL_SET_GL_ERROR(
5135 GL_INVALID_VALUE,
5136 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335137 }
5138}
5139
[email protected]2be6abf32012-06-26 00:28:335140error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
5141 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:345142 const void* cmd_data) {
5143 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
5144 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
5145 cmd_data);
[email protected]2be6abf32012-06-26 00:28:335146 GLuint program = static_cast<GLuint>(c.program);
5147 GLint location = static_cast<GLint>(c.location);
5148 Bucket* bucket = GetBucket(c.name_bucket_id);
5149 if (!bucket || bucket->size() == 0) {
5150 return error::kInvalidArguments;
5151 }
5152 std::string name_str;
5153 if (!bucket->GetAsString(&name_str)) {
5154 return error::kInvalidArguments;
5155 }
5156 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
5157 return error::kNoError;
5158}
5159
vmiuracd108592014-09-08 14:36:345160error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
5161 const void* cmd_data) {
5162 const gles2::cmds::DeleteShader& c =
5163 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035164 GLuint client_id = c.shader;
5165 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425166 Shader* shader = GetShader(client_id);
5167 if (shader) {
5168 if (!shader->IsDeleted()) {
dyenc6a36cdd2015-02-25 05:24:315169 shader_manager()->Delete(shader);
[email protected]ca488e12010-12-13 20:06:145170 }
[email protected]ae51d192010-04-27 00:48:035171 } else {
[email protected]ab09b612013-03-11 22:11:515172 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:035173 }
[email protected]96449d2c2009-11-25 00:01:325174 }
[email protected]f7a64ee2010-02-01 22:24:145175 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325176}
5177
vmiuracd108592014-09-08 14:36:345178error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
5179 const void* cmd_data) {
5180 const gles2::cmds::DeleteProgram& c =
5181 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035182 GLuint client_id = c.program;
5183 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425184 Program* program = GetProgram(client_id);
5185 if (program) {
5186 if (!program->IsDeleted()) {
5187 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:145188 }
[email protected]ae51d192010-04-27 00:48:035189 } else {
[email protected]ab09b612013-03-11 22:11:515190 LOCAL_SET_GL_ERROR(
5191 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:035192 }
[email protected]96449d2c2009-11-25 00:01:325193 }
[email protected]f7a64ee2010-02-01 22:24:145194 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325195}
5196
[email protected]a7266a92012-06-28 02:11:085197error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:445198 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:205199 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:465200 ApplyDirtyState();
boliu2e7d8a7a2014-10-16 20:35:205201 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
sievers2384f2b2014-11-18 02:10:355202 if (workarounds().gl_clear_broken) {
5203 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround",
5204 GetErrorState());
5205 if (!BoundFramebufferHasDepthAttachment())
5206 mask &= ~GL_DEPTH_BUFFER_BIT;
5207 if (!BoundFramebufferHasStencilAttachment())
5208 mask &= ~GL_STENCIL_BUFFER_BIT;
5209 clear_framebuffer_blit_->ClearFramebuffer(
5210 this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red,
5211 state_.color_clear_green, state_.color_clear_blue,
5212 state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear);
5213 return error::kNoError;
5214 }
[email protected]3a03a8f2011-03-19 00:51:275215 glClear(mask);
5216 }
[email protected]a7266a92012-06-28 02:11:085217 return error::kNoError;
5218}
5219
[email protected]36cef8ce2010-03-16 07:34:455220void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5221 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035222 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065223 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5224 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515225 LOCAL_SET_GL_ERROR(
5226 GL_INVALID_OPERATION,
5227 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455228 return;
5229 }
[email protected]ae51d192010-04-27 00:48:035230 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275231 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035232 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275233 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5234 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515235 LOCAL_SET_GL_ERROR(
5236 GL_INVALID_OPERATION,
5237 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035238 return;
5239 }
[email protected]ee2a79c32013-03-10 03:50:275240 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035241 }
[email protected]ab09b612013-03-11 22:11:515242 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035243 glFramebufferRenderbufferEXT(
5244 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515245 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265246 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275247 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285248 }
[email protected]9d3b2e12013-10-02 01:04:345249 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445250 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465251 }
[email protected]81fc9d02013-03-14 23:53:325252 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285253}
5254
[email protected]3a2e7c7b2010-08-06 01:12:285255void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465256 if (SetCapabilityState(cap, false)) {
5257 glDisable(cap);
5258 }
[email protected]3a2e7c7b2010-08-06 01:12:285259}
5260
5261void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465262 if (SetCapabilityState(cap, true)) {
5263 glEnable(cap);
5264 }
[email protected]3a2e7c7b2010-08-06 01:12:285265}
5266
[email protected]88a61bf2012-10-27 13:00:425267void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5268 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5269 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5270 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285271}
5272
[email protected]b04e24c2013-01-08 18:35:255273void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425274 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5275 state_.sample_coverage_invert = (invert != 0);
5276 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285277}
5278
[email protected]0d6bfdc2011-11-02 01:32:205279// Assumes framebuffer is complete.
5280void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065281 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305282 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205283 // bind this to the DRAW point, clear then bind back to READ
5284 // TODO(gman): I don't think there is any guarantee that an FBO that
5285 // is complete on the READ attachment will be complete as a DRAW
5286 // attachment.
5287 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065288 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305289 }
[email protected]3a2e7c7b2010-08-06 01:12:285290 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425291 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465292 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205293 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465294 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065295 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5296 1.0f);
[email protected]454157e2014-05-03 02:49:455297 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285298 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535299 if (feature_info_->feature_flags().ext_draw_buffers)
5300 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285301 }
5302
[email protected]4d8f0dd2013-03-09 14:37:065303 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5304 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285305 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475306 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5307 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285308 clear_bits |= GL_STENCIL_BUFFER_BIT;
5309 }
5310
[email protected]4d8f0dd2013-03-09 14:37:065311 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5312 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285313 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455314 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285315 clear_bits |= GL_DEPTH_BUFFER_BIT;
5316 }
5317
[email protected]454157e2014-05-03 02:49:455318 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285319 glClear(clear_bits);
5320
brucedawson18249152014-10-31 23:02:325321 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]0e58af82014-08-08 14:02:535322 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425323 framebuffer->RestoreDrawBuffersAfterClear();
5324
[email protected]968351b2011-12-20 08:26:515325 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065326 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285327
[email protected]c007aa02010-09-02 22:22:405328 RestoreClearState();
5329
5330 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065331 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5332 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485333 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065334 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5335 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485336 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405337 }
5338}
5339
5340void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445341 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245342 glClearColor(
5343 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5344 state_.color_clear_alpha);
5345 glClearStencil(state_.stencil_clear);
5346 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225347 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455348 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285349 }
[email protected]36cef8ce2010-03-16 07:34:455350}
5351
5352GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355353 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305354 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205355 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455356 return GL_FRAMEBUFFER_COMPLETE;
5357 }
[email protected]0d6bfdc2011-11-02 01:32:205358 GLenum completeness = framebuffer->IsPossiblyComplete();
5359 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5360 return completeness;
5361 }
[email protected]73276522012-11-09 05:50:205362 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455363}
5364
5365void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035366 GLenum target, GLenum attachment, GLenum textarget,
5367 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165368 DoFramebufferTexture2DCommon(
5369 "glFramebufferTexture2D", target, attachment,
5370 textarget, client_texture_id, level, 0);
5371}
5372
5373void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5374 GLenum target, GLenum attachment, GLenum textarget,
5375 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165376 DoFramebufferTexture2DCommon(
5377 "glFramebufferTexture2DMultisample", target, attachment,
5378 textarget, client_texture_id, level, samples);
5379}
5380
5381void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5382 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5383 GLuint client_texture_id, GLint level, GLsizei samples) {
5384 if (samples > renderbuffer_manager()->max_samples()) {
5385 LOCAL_SET_GL_ERROR(
5386 GL_INVALID_VALUE,
5387 "glFramebufferTexture2DMultisample", "samples too large");
5388 return;
5389 }
[email protected]4d8f0dd2013-03-09 14:37:065390 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5391 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515392 LOCAL_SET_GL_ERROR(
5393 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165394 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455395 return;
5396 }
[email protected]ae51d192010-04-27 00:48:035397 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495398 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035399 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495400 texture_ref = GetTexture(client_texture_id);
5401 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515402 LOCAL_SET_GL_ERROR(
5403 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165404 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035405 return;
5406 }
[email protected]370eaf12013-05-18 09:19:495407 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035408 }
[email protected]0d6bfdc2011-11-02 01:32:205409
[email protected]80eb6b52012-01-19 00:14:415410 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515411 LOCAL_SET_GL_ERROR(
5412 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165413 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205414 return;
5415 }
5416
[email protected]91c94eb2013-10-22 10:32:545417 if (texture_ref)
5418 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5419
[email protected]7d3c36e2013-07-12 14:13:165420 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5421 if (0 == samples) {
5422 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5423 } else {
5424 if (features().use_img_for_multisampled_render_to_texture) {
5425 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5426 service_id, level, samples);
5427 } else {
5428 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5429 service_id, level, samples);
5430 }
5431 }
5432 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265433 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165434 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5435 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285436 }
[email protected]9d3b2e12013-10-02 01:04:345437 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445438 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465439 }
[email protected]91c94eb2013-10-22 10:32:545440
5441 if (texture_ref)
5442 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5443
[email protected]81fc9d02013-03-14 23:53:325444 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455445}
5446
zmo84c08202014-11-23 15:28:405447void GLES2DecoderImpl::DoFramebufferTextureLayer(
5448 GLenum target, GLenum attachment, GLuint client_texture_id,
5449 GLint level, GLint layer) {
5450 // TODO(zmo): Unsafe ES3 API, missing states update.
5451 GLuint service_id = 0;
5452 TextureRef* texture_ref = NULL;
5453 if (client_texture_id) {
5454 texture_ref = GetTexture(client_texture_id);
5455 if (!texture_ref) {
5456 LOCAL_SET_GL_ERROR(
5457 GL_INVALID_OPERATION,
5458 "glFramebufferTextureLayer", "unknown texture_ref");
5459 return;
5460 }
5461 service_id = texture_ref->service_id();
5462 }
5463 glFramebufferTextureLayer(target, attachment, service_id, level, layer);
5464}
5465
[email protected]36cef8ce2010-03-16 07:34:455466void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5467 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065468 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5469 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515470 LOCAL_SET_GL_ERROR(
5471 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205472 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455473 return;
5474 }
[email protected]74c1ec42010-08-12 01:55:575475 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105476 const Framebuffer::Attachment* attachment_object =
5477 framebuffer->GetAttachment(attachment);
5478 *params = attachment_object ? attachment_object->object_name() : 0;
5479 } else {
[email protected]7d3c36e2013-07-12 14:13:165480 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5481 features().use_img_for_multisampled_render_to_texture) {
5482 pname = GL_TEXTURE_SAMPLES_IMG;
5483 }
[email protected]62e65f02013-05-29 22:28:105484 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575485 }
[email protected]36cef8ce2010-03-16 07:34:455486}
5487
5488void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5489 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355490 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205491 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5492 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515493 LOCAL_SET_GL_ERROR(
5494 GL_INVALID_OPERATION,
5495 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455496 return;
5497 }
[email protected]8875a5f2014-06-27 08:33:475498
5499 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275500 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435501 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5502 *params = renderbuffer->internal_format();
5503 break;
5504 case GL_RENDERBUFFER_WIDTH:
5505 *params = renderbuffer->width();
5506 break;
5507 case GL_RENDERBUFFER_HEIGHT:
5508 *params = renderbuffer->height();
5509 break;
[email protected]7d3c36e2013-07-12 14:13:165510 case GL_RENDERBUFFER_SAMPLES_EXT:
5511 if (features().use_img_for_multisampled_render_to_texture) {
5512 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5513 params);
5514 } else {
5515 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5516 params);
5517 }
[email protected]ad84a3a2012-06-08 21:42:435518 default:
5519 glGetRenderbufferParameterivEXT(target, pname, params);
5520 break;
[email protected]b71f52c2010-06-18 22:20:205521 }
[email protected]36cef8ce2010-03-16 07:34:455522}
5523
[email protected]49cabed2013-11-13 18:15:185524void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305525 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5526 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5527 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445528 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165529
[email protected]49cabed2013-11-13 18:15:185530 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165531 return;
5532 }
5533
[email protected]454157e2014-05-03 02:49:455534 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
boliu2e7d8a7a2014-10-16 20:35:205535 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]f42f05b2013-11-15 21:46:185536 BlitFramebufferHelper(
5537 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455538 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5539 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185540}
5541
[email protected]8875a5f2014-06-27 08:33:475542void GLES2DecoderImpl::EnsureRenderbufferBound() {
5543 if (!state_.bound_renderbuffer_valid) {
5544 state_.bound_renderbuffer_valid = true;
5545 glBindRenderbufferEXT(GL_RENDERBUFFER,
5546 state_.bound_renderbuffer.get()
5547 ? state_.bound_renderbuffer->service_id()
5548 : 0);
5549 }
5550}
5551
[email protected]f42f05b2013-11-15 21:46:185552void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5553 const FeatureInfo* feature_info,
5554 GLenum target,
5555 GLsizei samples,
5556 GLenum internal_format,
5557 GLsizei width,
5558 GLsizei height) {
5559 // TODO(sievers): This could be resolved at the GL binding level, but the
5560 // binding process is currently a bit too 'brute force'.
zmo68fcdc62014-12-05 21:51:495561 if (feature_info->gl_version_info().is_angle) {
[email protected]f42f05b2013-11-15 21:46:185562 glRenderbufferStorageMultisampleANGLE(
5563 target, samples, internal_format, width, height);
5564 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5565 glRenderbufferStorageMultisample(
5566 target, samples, internal_format, width, height);
5567 } else {
5568 glRenderbufferStorageMultisampleEXT(
5569 target, samples, internal_format, width, height);
5570 }
5571}
5572
5573void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5574 GLint srcY0,
5575 GLint srcX1,
5576 GLint srcY1,
5577 GLint dstX0,
5578 GLint dstY0,
5579 GLint dstX1,
5580 GLint dstY1,
5581 GLbitfield mask,
5582 GLenum filter) {
5583 // TODO(sievers): This could be resolved at the GL binding level, but the
5584 // binding process is currently a bit too 'brute force'.
zmo68fcdc62014-12-05 21:51:495585 if (feature_info_->gl_version_info().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245586 glBlitFramebufferANGLE(
5587 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185588 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5589 glBlitFramebuffer(
5590 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245591 } else {
5592 glBlitFramebufferEXT(
5593 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5594 }
[email protected]8e3e0662010-08-23 18:46:305595}
5596
[email protected]49cabed2013-11-13 18:15:185597bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5598 GLsizei samples,
5599 GLenum internalformat,
5600 GLsizei width,
5601 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535602 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515603 LOCAL_SET_GL_ERROR(
5604 GL_INVALID_VALUE,
5605 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185606 return false;
[email protected]84afefa2011-10-19 21:45:535607 }
5608
5609 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5610 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515611 LOCAL_SET_GL_ERROR(
5612 GL_INVALID_VALUE,
5613 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185614 return false;
[email protected]84afefa2011-10-19 21:45:535615 }
5616
[email protected]7989c9e2013-01-23 06:39:265617 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235618 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5619 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515620 LOCAL_SET_GL_ERROR(
5621 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205622 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185623 return false;
[email protected]8e3e0662010-08-23 18:46:305624 }
5625
[email protected]7989c9e2013-01-23 06:39:265626 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515627 LOCAL_SET_GL_ERROR(
5628 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205629 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185630 return false;
5631 }
5632
5633 return true;
5634}
5635
5636void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5637 GLenum target, GLsizei samples, GLenum internalformat,
5638 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185639 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5640 if (!renderbuffer) {
5641 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5642 "glRenderbufferStorageMultisampleCHROMIUM",
5643 "no renderbuffer bound");
5644 return;
5645 }
5646
5647 if (!ValidateRenderbufferStorageMultisample(
5648 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265649 return;
5650 }
5651
[email protected]8875a5f2014-06-27 08:33:475652 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235653 GLenum impl_format =
5654 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5655 internalformat);
[email protected]49cabed2013-11-13 18:15:185656 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5657 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185658 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:255659 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185660 GLenum error =
5661 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265662 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105663
5664 if (workarounds().validate_multisample_buffer_allocation) {
5665 if (!VerifyMultisampleRenderbufferIntegrity(
5666 renderbuffer->service_id(), impl_format)) {
5667 LOCAL_SET_GL_ERROR(
5668 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185669 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105670 return;
5671 }
5672 }
5673
[email protected]968351b2011-12-20 08:26:515674 // TODO(gman): If renderbuffers tracked which framebuffers they were
5675 // attached to we could just mark those framebuffers as not complete.
5676 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205677 renderbuffer_manager()->SetInfo(
5678 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265679 }
[email protected]8e3e0662010-08-23 18:46:305680}
5681
[email protected]49cabed2013-11-13 18:15:185682// This is the handler for multisampled_render_to_texture extensions.
5683void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5684 GLenum target, GLsizei samples, GLenum internalformat,
5685 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185686 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5687 if (!renderbuffer) {
5688 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5689 "glRenderbufferStorageMultisampleEXT",
5690 "no renderbuffer bound");
5691 return;
5692 }
5693
5694 if (!ValidateRenderbufferStorageMultisample(
5695 samples, internalformat, width, height)) {
5696 return;
5697 }
5698
[email protected]8875a5f2014-06-27 08:33:475699 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185700 GLenum impl_format =
5701 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5702 internalformat);
5703 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5704 if (features().use_img_for_multisampled_render_to_texture) {
5705 glRenderbufferStorageMultisampleIMG(
5706 target, samples, impl_format, width, height);
5707 } else {
5708 glRenderbufferStorageMultisampleEXT(
5709 target, samples, impl_format, width, height);
5710 }
5711 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5712 if (error == GL_NO_ERROR) {
5713 // TODO(gman): If renderbuffers tracked which framebuffers they were
5714 // attached to we could just mark those framebuffers as not complete.
5715 framebuffer_manager()->IncFramebufferStateChangeCount();
5716 renderbuffer_manager()->SetInfo(
5717 renderbuffer, samples, internalformat, width, height);
5718 }
5719}
5720
[email protected]4a4c18b2013-09-13 22:50:105721// This function validates the allocation of a multisampled renderbuffer
5722// by clearing it to a key color, blitting the contents to a texture, and
5723// reading back the color to ensure it matches the key.
5724bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5725 GLuint renderbuffer, GLenum format) {
5726
5727 // Only validate color buffers.
5728 // These formats have been selected because they are very common or are known
5729 // to be used by the WebGL backbuffer. If problems are observed with other
5730 // color formats they can be added here.
5731 switch(format) {
5732 case GL_RGB:
5733 case GL_RGB8:
5734 case GL_RGBA:
5735 case GL_RGBA8:
5736 break;
5737 default:
5738 return true;
5739 }
5740
5741 GLint draw_framebuffer, read_framebuffer;
5742
5743 // Cache framebuffer and texture bindings.
5744 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5745 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5746
5747 if (!validation_texture_) {
5748 GLint bound_texture;
5749 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5750
5751 // Create additional resources needed for the verification.
5752 glGenTextures(1, &validation_texture_);
5753 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5754 glGenFramebuffersEXT(1, &validation_fbo_);
5755
5756 // Texture only needs to be 1x1.
5757 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5758 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5759 GL_UNSIGNED_BYTE, NULL);
5760
5761 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5762 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5763 GL_TEXTURE_2D, validation_texture_, 0);
5764
5765 glBindTexture(GL_TEXTURE_2D, bound_texture);
5766 }
5767
5768 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5769 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5770 GL_RENDERBUFFER, renderbuffer);
5771
5772 // Cache current state and reset it to the values we require.
5773 GLboolean scissor_enabled = false;
5774 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5775 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455776 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105777
[email protected]454157e2014-05-03 02:49:455778 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105779 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455780 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105781
5782 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5783 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5784 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5785
5786 // Clear the buffer to the desired key color.
5787 glClear(GL_COLOR_BUFFER_BIT);
5788
5789 // Blit from the multisample buffer to a standard texture.
5790 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5791 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5792
[email protected]f42f05b2013-11-15 21:46:185793 BlitFramebufferHelper(
5794 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105795
5796 // Read a pixel from the buffer.
5797 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5798
5799 unsigned char pixel[3] = {0, 0, 0};
5800 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5801
5802 // Detach the renderbuffer.
5803 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5804 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5805 GL_RENDERBUFFER, 0);
5806
5807 // Restore cached state.
5808 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455809 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105810
[email protected]454157e2014-05-03 02:49:455811 state_.SetDeviceColorMask(
5812 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105813 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5814 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5815 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5816
5817 // Return true if the pixel matched the desired key color.
5818 return (pixel[0] == 0xFF &&
5819 pixel[1] == 0x00 &&
5820 pixel[2] == 0xFF);
5821}
5822
[email protected]36cef8ce2010-03-16 07:34:455823void GLES2DecoderImpl::DoRenderbufferStorage(
5824 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355825 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205826 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5827 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515828 LOCAL_SET_GL_ERROR(
5829 GL_INVALID_OPERATION,
5830 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455831 return;
5832 }
[email protected]876f6fee2010-08-02 23:10:325833
[email protected]84afefa2011-10-19 21:45:535834 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5835 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515836 LOCAL_SET_GL_ERROR(
5837 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535838 return;
5839 }
5840
[email protected]7989c9e2013-01-23 06:39:265841 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235842 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5843 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515844 LOCAL_SET_GL_ERROR(
5845 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265846 return;
5847 }
5848
5849 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515850 LOCAL_SET_GL_ERROR(
5851 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265852 return;
[email protected]b71f52c2010-06-18 22:20:205853 }
[email protected]876f6fee2010-08-02 23:10:325854
[email protected]8875a5f2014-06-27 08:33:475855 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:515856 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265857 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235858 target,
5859 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5860 internalformat),
5861 width,
5862 height);
[email protected]ab09b612013-03-11 22:11:515863 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265864 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515865 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5866 // we could just mark those framebuffers as not complete.
5867 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205868 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265869 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265870 }
[email protected]36cef8ce2010-03-16 07:34:455871}
5872
[email protected]df37b9932013-03-08 05:21:425873void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385874 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425875 Program* program = GetProgramInfoNotShader(
5876 program_id, "glLinkProgram");
5877 if (!program) {
[email protected]a93bb842010-02-16 23:03:475878 return;
5879 }
[email protected]05afda12011-01-20 00:17:345880
[email protected]df37b9932013-03-08 05:21:425881 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]df37b9932013-03-08 05:21:425882 if (program->Link(shader_manager(),
[email protected]008401532014-02-07 00:10:505883 workarounds().count_all_in_varyings_packing ?
5884 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115885 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425886 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185887 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425888 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185889 if (workarounds().clear_uniforms_before_first_program_use)
5890 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545891 }
5892 }
vmiura8266ca72014-09-09 21:37:005893
5894 // LinkProgram can be very slow. Exit command processing to allow for
5895 // context preemption and GPU watchdog checks.
5896 ExitCommandProcessingEarly();
[email protected]07f54fcc2009-12-22 02:46:305897};
5898
zmobcb3fdd62014-12-11 00:49:035899void GLES2DecoderImpl::DoSamplerParameterfv(
5900 GLuint sampler, GLenum pname, const GLfloat* params) {
5901 DCHECK(params);
5902 glSamplerParameterf(sampler, pname, params[0]);
5903}
5904
5905void GLES2DecoderImpl::DoSamplerParameteriv(
5906 GLuint sampler, GLenum pname, const GLint* params) {
5907 DCHECK(params);
5908 glSamplerParameteri(sampler, pname, params[0]);
5909}
5910
[email protected]3916c97e2010-02-25 03:20:505911void GLES2DecoderImpl::DoTexParameterf(
5912 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445913 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5914 &state_, target);
[email protected]02965c22013-03-09 02:40:075915 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515916 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245917 return;
[email protected]07f54fcc2009-12-22 02:46:305918 }
[email protected]cbb22e42011-05-12 23:36:245919
[email protected]737191ee72014-03-09 08:02:425920 texture_manager()->SetParameterf(
5921 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305922}
5923
[email protected]3916c97e2010-02-25 03:20:505924void GLES2DecoderImpl::DoTexParameteri(
5925 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445926 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5927 &state_, target);
[email protected]02965c22013-03-09 02:40:075928 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515929 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245930 return;
[email protected]3916c97e2010-02-25 03:20:505931 }
[email protected]cbb22e42011-05-12 23:36:245932
[email protected]737191ee72014-03-09 08:02:425933 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505934 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505935}
5936
5937void GLES2DecoderImpl::DoTexParameterfv(
5938 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445939 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5940 &state_, target);
[email protected]02965c22013-03-09 02:40:075941 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515942 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245943 return;
[email protected]3916c97e2010-02-25 03:20:505944 }
[email protected]cbb22e42011-05-12 23:36:245945
[email protected]737191ee72014-03-09 08:02:425946 texture_manager()->SetParameterf(
5947 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505948}
5949
5950void GLES2DecoderImpl::DoTexParameteriv(
5951 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445952 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5953 &state_, target);
[email protected]02965c22013-03-09 02:40:075954 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515955 LOCAL_SET_GL_ERROR(
5956 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245957 return;
[email protected]3916c97e2010-02-25 03:20:505958 }
[email protected]cbb22e42011-05-12 23:36:245959
[email protected]737191ee72014-03-09 08:02:425960 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505961 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505962}
5963
orglofchcad5a6742014-11-07 19:51:125964bool GLES2DecoderImpl::CheckCurrentValuebuffer(const char* function_name) {
5965 if (!state_.bound_valuebuffer.get()) {
5966 // There is no valuebuffer bound
5967 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5968 "no valuebuffer in use");
5969 return false;
5970 }
5971 return true;
5972}
5973
5974bool GLES2DecoderImpl::CheckCurrentValuebufferForSubscription(
5975 GLenum subscription,
5976 const char* function_name) {
5977 if (!CheckCurrentValuebuffer(function_name)) {
5978 return false;
5979 }
5980 if (!state_.bound_valuebuffer.get()->IsSubscribed(subscription)) {
5981 // The valuebuffer is not subscribed to the target
5982 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5983 "valuebuffer is not subscribed");
5984 return false;
5985 }
5986 return true;
5987}
5988
5989bool GLES2DecoderImpl::CheckSubscriptionTarget(GLint location,
5990 GLenum subscription,
5991 const char* function_name) {
5992 if (!CheckCurrentProgramForUniform(location, function_name)) {
5993 return false;
5994 }
5995 GLint real_location = -1;
5996 GLint array_index = -1;
5997 const Program::UniformInfo* info =
5998 state_.current_program->GetUniformInfoByFakeLocation(
5999 location, &real_location, &array_index);
6000 if (!info) {
6001 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "unknown location");
6002 return false;
6003 }
6004 if ((ValuebufferManager::ApiTypeForSubscriptionTarget(subscription) &
6005 info->accepts_api_type) == 0) {
6006 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6007 "wrong type for subscription");
6008 return false;
6009 }
6010 return true;
6011}
6012
[email protected]939e7362010-05-13 20:49:106013bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:116014 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:436015 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:516016 LOCAL_SET_GL_ERROR(
6017 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:436018 return false;
[email protected]939e7362010-05-13 20:49:106019 }
[email protected]e259eb412012-10-13 05:47:246020 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:516021 LOCAL_SET_GL_ERROR(
6022 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:106023 return false;
6024 }
6025 return true;
6026}
6027
6028bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
6029 GLint location, const char* function_name) {
6030 if (!CheckCurrentProgram(function_name)) {
6031 return false;
6032 }
6033 return location != -1;
6034}
6035
zmof9a81360f2014-10-17 00:06:146036bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
6037 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
6038 if (!framebuffer)
6039 return false;
6040 const Framebuffer::Attachment* attachment =
6041 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
6042 if (!attachment)
6043 return false;
6044
6045 DCHECK(state_.current_program.get());
6046 const Program::SamplerIndices& sampler_indices =
6047 state_.current_program->sampler_indices();
6048 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
6049 const Program::UniformInfo* uniform_info =
6050 state_.current_program->GetUniformInfo(sampler_indices[ii]);
6051 DCHECK(uniform_info);
6052 if (uniform_info->type != GL_SAMPLER_2D)
6053 continue;
6054 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6055 GLuint texture_unit_index = uniform_info->texture_units[jj];
6056 if (texture_unit_index >= state_.texture_units.size())
6057 continue;
6058 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
6059 TextureRef* texture_ref =
6060 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
6061 if (attachment->IsTexture(texture_ref))
6062 return true;
6063 }
6064 }
6065 return false;
6066}
6067
orglofchcad5a6742014-11-07 19:51:126068bool GLES2DecoderImpl::CheckUniformForApiType(
6069 const Program::UniformInfo* info,
6070 const char* function_name,
6071 Program::UniformApiType api_type) {
6072 DCHECK(info);
6073 if ((api_type & info->accepts_api_type) == 0) {
6074 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6075 "wrong uniform function for type");
6076 return false;
6077 }
6078 return true;
6079}
6080
[email protected]43c2f1f2011-03-25 18:35:366081bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:136082 GLint fake_location,
6083 const char* function_name,
6084 Program::UniformApiType api_type,
6085 GLint* real_location,
6086 GLenum* type,
6087 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:366088 DCHECK(type);
6089 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:126090 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:526091
[email protected]1b0a6752012-02-22 03:44:126092 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:106093 return false;
6094 }
[email protected]43c2f1f2011-03-25 18:35:366095 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:356096 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:246097 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:126098 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:366099 if (!info) {
[email protected]ab09b612013-03-11 22:11:516100 LOCAL_SET_GL_ERROR(
6101 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:106102 return false;
6103 }
orglofchcad5a6742014-11-07 19:51:126104 if (!CheckUniformForApiType(info, function_name, api_type)) {
[email protected]476ccb72012-12-06 15:52:526105 return false;
6106 }
[email protected]43c2f1f2011-03-25 18:35:366107 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:516108 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436109 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:366110 return false;
6111 }
6112 *count = std::min(info->size - array_index, *count);
6113 if (*count <= 0) {
6114 return false;
6115 }
6116 *type = info->type;
[email protected]939e7362010-05-13 20:49:106117 return true;
6118}
6119
[email protected]1b0a6752012-02-22 03:44:126120void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
6121 GLenum type = 0;
6122 GLsizei count = 1;
6123 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136124 if (!PrepForSetUniformByLocation(fake_location,
6125 "glUniform1i",
6126 Program::kUniform1i,
6127 &real_location,
6128 &type,
6129 &count)) {
[email protected]3916c97e2010-02-25 03:20:506130 return;
6131 }
[email protected]e259eb412012-10-13 05:47:246132 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026133 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:516134 LOCAL_SET_GL_ERROR(
6135 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466136 return;
6137 }
[email protected]1b0a6752012-02-22 03:44:126138 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:506139}
6140
6141void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:126142 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:366143 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126144 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136145 if (!PrepForSetUniformByLocation(fake_location,
6146 "glUniform1iv",
6147 Program::kUniform1i,
6148 &real_location,
6149 &type,
6150 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366151 return;
6152 }
[email protected]74727112012-06-13 21:18:086153 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
6154 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:246155 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026156 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:516157 LOCAL_SET_GL_ERROR(
6158 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466159 return;
6160 }
[email protected]43c2f1f2011-03-25 18:35:366161 }
[email protected]1b0a6752012-02-22 03:44:126162 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:506163}
6164
[email protected]939e7362010-05-13 20:49:106165void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:126166 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366167 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126168 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136169 if (!PrepForSetUniformByLocation(fake_location,
6170 "glUniform1fv",
6171 Program::kUniform1f,
6172 &real_location,
6173 &type,
6174 &count)) {
[email protected]939e7362010-05-13 20:49:106175 return;
6176 }
6177 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:556178 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:106179 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:536180 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106181 }
[email protected]1b0a6752012-02-22 03:44:126182 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106183 } else {
[email protected]1b0a6752012-02-22 03:44:126184 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106185 }
6186}
6187
6188void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:126189 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366190 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126191 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136192 if (!PrepForSetUniformByLocation(fake_location,
6193 "glUniform2fv",
6194 Program::kUniform2f,
6195 &real_location,
6196 &type,
6197 &count)) {
[email protected]939e7362010-05-13 20:49:106198 return;
6199 }
6200 if (type == GL_BOOL_VEC2) {
6201 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:556202 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106203 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536204 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106205 }
[email protected]1b0a6752012-02-22 03:44:126206 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106207 } else {
[email protected]1b0a6752012-02-22 03:44:126208 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106209 }
6210}
6211
6212void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:126213 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366214 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126215 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136216 if (!PrepForSetUniformByLocation(fake_location,
6217 "glUniform3fv",
6218 Program::kUniform3f,
6219 &real_location,
6220 &type,
6221 &count)) {
[email protected]939e7362010-05-13 20:49:106222 return;
6223 }
6224 if (type == GL_BOOL_VEC3) {
6225 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:556226 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106227 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536228 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106229 }
[email protected]1b0a6752012-02-22 03:44:126230 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106231 } else {
[email protected]1b0a6752012-02-22 03:44:126232 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106233 }
6234}
6235
6236void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:126237 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366238 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126239 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136240 if (!PrepForSetUniformByLocation(fake_location,
6241 "glUniform4fv",
6242 Program::kUniform4f,
6243 &real_location,
6244 &type,
6245 &count)) {
[email protected]939e7362010-05-13 20:49:106246 return;
6247 }
6248 if (type == GL_BOOL_VEC4) {
6249 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:556250 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106251 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536252 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106253 }
[email protected]1b0a6752012-02-22 03:44:126254 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106255 } else {
[email protected]1b0a6752012-02-22 03:44:126256 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106257 }
6258}
6259
[email protected]43c2f1f2011-03-25 18:35:366260void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:126261 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366262 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126263 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136264 if (!PrepForSetUniformByLocation(fake_location,
6265 "glUniform2iv",
6266 Program::kUniform2i,
6267 &real_location,
6268 &type,
6269 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366270 return;
6271 }
[email protected]1b0a6752012-02-22 03:44:126272 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366273}
6274
6275void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:126276 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366277 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126278 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136279 if (!PrepForSetUniformByLocation(fake_location,
6280 "glUniform3iv",
6281 Program::kUniform3i,
6282 &real_location,
6283 &type,
6284 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366285 return;
6286 }
[email protected]1b0a6752012-02-22 03:44:126287 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366288}
6289
6290void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:126291 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366292 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126293 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136294 if (!PrepForSetUniformByLocation(fake_location,
6295 "glUniform4iv",
6296 Program::kUniform4i,
6297 &real_location,
6298 &type,
6299 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366300 return;
6301 }
[email protected]1b0a6752012-02-22 03:44:126302 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366303}
6304
6305void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126306 GLint fake_location, GLsizei count, GLboolean transpose,
6307 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366308 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126309 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136310 if (!PrepForSetUniformByLocation(fake_location,
6311 "glUniformMatrix2fv",
6312 Program::kUniformMatrix2f,
6313 &real_location,
6314 &type,
6315 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366316 return;
6317 }
[email protected]1b0a6752012-02-22 03:44:126318 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366319}
6320
6321void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126322 GLint fake_location, GLsizei count, GLboolean transpose,
6323 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366324 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126325 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136326 if (!PrepForSetUniformByLocation(fake_location,
6327 "glUniformMatrix3fv",
6328 Program::kUniformMatrix3f,
6329 &real_location,
6330 &type,
6331 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366332 return;
6333 }
[email protected]1b0a6752012-02-22 03:44:126334 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366335}
6336
6337void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126338 GLint fake_location, GLsizei count, GLboolean transpose,
6339 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366340 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126341 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136342 if (!PrepForSetUniformByLocation(fake_location,
6343 "glUniformMatrix4fv",
6344 Program::kUniformMatrix4f,
6345 &real_location,
6346 &type,
6347 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366348 return;
6349 }
[email protected]1b0a6752012-02-22 03:44:126350 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366351}
6352
[email protected]df37b9932013-03-08 05:21:426353void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036354 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426355 Program* program = NULL;
6356 if (program_id) {
6357 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6358 if (!program) {
[email protected]ae51d192010-04-27 00:48:036359 return;
6360 }
[email protected]df37b9932013-03-08 05:21:426361 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506362 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516363 LOCAL_SET_GL_ERROR(
6364 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506365 return;
6366 }
[email protected]df37b9932013-03-08 05:21:426367 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506368 }
[email protected]7cd76fd2013-06-02 21:11:116369 if (state_.current_program.get()) {
6370 program_manager()->UnuseProgram(shader_manager(),
6371 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146372 }
[email protected]df37b9932013-03-08 05:21:426373 state_.current_program = program;
6374 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546375 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116376 if (state_.current_program.get()) {
6377 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186378 if (workarounds().clear_uniforms_before_first_program_use)
6379 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146380 }
[email protected]3916c97e2010-02-25 03:20:506381}
6382
[email protected]ab09b612013-03-11 22:11:516383void GLES2DecoderImpl::RenderWarning(
6384 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326385 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016386}
6387
[email protected]ab09b612013-03-11 22:11:516388void GLES2DecoderImpl::PerformanceWarning(
6389 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506390 logger_.LogMessage(filename, line,
6391 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016392}
6393
[email protected]91c94eb2013-10-22 10:32:546394void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6395 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546396 // Image is already in use if texture is attached to a framebuffer.
6397 if (texture && !texture->IsAttachedToFramebuffer()) {
6398 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6399 if (image) {
6400 ScopedGLErrorSuppressor suppressor(
6401 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6402 GetErrorState());
6403 glBindTexture(textarget, texture->service_id());
6404 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026405 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546406 }
6407 }
6408}
6409
6410void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6411 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546412 // Image is still in use if texture is attached to a framebuffer.
6413 if (texture && !texture->IsAttachedToFramebuffer()) {
6414 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6415 if (image) {
6416 ScopedGLErrorSuppressor suppressor(
6417 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6418 GetErrorState());
6419 glBindTexture(textarget, texture->service_id());
6420 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026421 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546422 }
6423 }
6424}
6425
[email protected]e56131d22013-07-28 16:14:116426bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116427 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546428 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556429 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116430 return true;
[email protected]ef526492010-06-02 23:12:256431 }
[email protected]e2367b42013-05-31 03:37:216432
[email protected]ef526492010-06-02 23:12:256433 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356434 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246435 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506436 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356437 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246438 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506439 DCHECK(uniform_info);
6440 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6441 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026442 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246443 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546444 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366445 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546446 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6447 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256448 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506449 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6450 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546451 textarget,
[email protected]00f893d2010-08-24 18:55:496452 texture_manager()->black_texture_id(uniform_info->type));
dongseong.hwang7d87d722015-01-14 20:02:406453 if (!texture_ref) {
6454 LOCAL_RENDER_WARNING(
6455 std::string("there is no texture bound to the unit ") +
6456 base::IntToString(texture_unit_index));
6457 } else {
6458 LOCAL_RENDER_WARNING(
6459 std::string("texture bound to texture unit ") +
6460 base::IntToString(texture_unit_index) +
6461 " is not renderable. It maybe non-power-of-2 and have"
6462 " incompatible texture filtering.");
6463 }
[email protected]91c94eb2013-10-22 10:32:546464 continue;
[email protected]3916c97e2010-02-25 03:20:506465 }
[email protected]91c94eb2013-10-22 10:32:546466
[email protected]4e7b89202014-01-28 01:44:066467 if (textarget != GL_TEXTURE_CUBE_MAP) {
6468 Texture* texture = texture_ref->texture();
6469 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6470 if (image && !texture->IsAttachedToFramebuffer()) {
6471 ScopedGLErrorSuppressor suppressor(
6472 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6473 textures_set = true;
6474 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6475 image->WillUseTexImage();
6476 continue;
6477 }
[email protected]91c94eb2013-10-22 10:32:546478 }
[email protected]3916c97e2010-02-25 03:20:506479 }
6480 // else: should this be an error?
6481 }
6482 }
[email protected]e56131d22013-07-28 16:14:116483 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506484}
6485
[email protected]91c94eb2013-10-22 10:32:546486void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116487 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356488 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116489 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506490 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356491 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246492 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506493 DCHECK(uniform_info);
6494 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6495 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026496 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246497 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116498 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546499 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496500 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506501 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496502 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116503 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6504 ? texture_unit.bound_texture_2d.get()
6505 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506506 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496507 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546508 continue;
6509 }
6510
[email protected]4e7b89202014-01-28 01:44:066511 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6512 Texture* texture = texture_ref->texture();
6513 gfx::GLImage* image =
6514 texture->GetLevelImage(texture_unit.bind_target, 0);
6515 if (image && !texture->IsAttachedToFramebuffer()) {
6516 ScopedGLErrorSuppressor suppressor(
6517 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6518 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6519 image->DidUseTexImage();
6520 continue;
6521 }
[email protected]3916c97e2010-02-25 03:20:506522 }
6523 }
6524 }
6525 }
6526 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246527 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306528}
6529
[email protected]0d6bfdc2011-11-02 01:32:206530bool GLES2DecoderImpl::ClearUnclearedTextures() {
6531 // Only check if there are some uncleared textures.
6532 if (!texture_manager()->HaveUnsafeTextures()) {
6533 return true;
6534 }
6535
6536 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116537 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356538 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116539 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206540 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356541 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246542 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206543 DCHECK(uniform_info);
6544 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6545 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026546 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246547 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496548 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366549 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496550 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6551 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206552 return false;
6553 }
6554 }
6555 }
6556 }
6557 }
6558 }
6559 return true;
6560}
6561
[email protected]c6aef902012-02-14 03:31:426562bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106563 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6564 GLsizei primcount) {
6565 DCHECK(instanced || primcount == 1);
6566
[email protected]689fa1c52010-06-09 18:35:036567 // NOTE: We specifically do not check current_program->IsValid() because
6568 // it could never be invalid since glUseProgram would have failed. While
6569 // glLinkProgram could later mark the program as invalid the previous
6570 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116571 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506572 // The program does not exist.
6573 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516574 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506575 return false;
6576 }
[email protected]c6aef902012-02-14 03:31:426577
zmof9a81360f2014-10-17 00:06:146578 if (CheckDrawingFeedbackLoops()) {
6579 LOCAL_SET_GL_ERROR(
6580 GL_INVALID_OPERATION, function_name,
6581 "Source and destination textures of the draw are the same.");
6582 return false;
6583 }
6584
[email protected]7cd76fd2013-06-02 21:11:116585 return state_.vertex_attrib_manager
6586 ->ValidateBindings(function_name,
6587 this,
6588 feature_info_.get(),
6589 state_.current_program.get(),
6590 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106591 instanced,
[email protected]7cd76fd2013-06-02 21:11:116592 primcount);
[email protected]b1122982010-05-17 23:04:246593}
6594
[email protected]c13e1da62011-09-09 21:48:306595bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436596 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306597 DCHECK(simulated);
6598 *simulated = false;
6599
[email protected]876f6fee2010-08-02 23:10:326600 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306601 return true;
[email protected]876f6fee2010-08-02 23:10:326602
[email protected]ac77603c72013-03-08 13:52:066603 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356604 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246605 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246606 bool attrib_0_used =
6607 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066608 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306609 return true;
[email protected]b1122982010-05-17 23:04:246610 }
6611
[email protected]b1122982010-05-17 23:04:246612 // Make a buffer with a single repeated vec4 value enough to
6613 // simulate the constant value that is supposed to be here.
6614 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306615 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476616 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306617
6618 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476619 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306620 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516621 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306622 return false;
6623 }
6624
[email protected]ab09b612013-03-11 22:11:516625 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016626 "Attribute 0 is disabled. This has signficant performance penalty");
6627
[email protected]ab09b612013-03-11 22:11:516628 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306629 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6630
[email protected]8f0b86c2f2012-04-10 05:48:286631 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6632 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496633 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306634 GLenum error = glGetError();
6635 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516636 LOCAL_SET_GL_ERROR(
6637 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306638 return false;
6639 }
[email protected]fc753442011-02-04 19:49:496640 }
[email protected]af6380962012-11-29 23:24:136641
6642 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286643 if (new_buffer ||
6644 (attrib_0_used &&
6645 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136646 (value.v[0] != attrib_0_value_.v[0] ||
6647 value.v[1] != attrib_0_value_.v[1] ||
6648 value.v[2] != attrib_0_value_.v[2] ||
6649 value.v[3] != attrib_0_value_.v[3])))) {
6650 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496651 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6652 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136653 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246654 attrib_0_size_ = size_needed;
6655 }
6656
6657 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6658
[email protected]ac77603c72013-03-08 13:52:066659 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426660 glVertexAttribDivisorANGLE(0, 0);
6661
[email protected]c13e1da62011-09-09 21:48:306662 *simulated = true;
[email protected]b1122982010-05-17 23:04:246663 return true;
[email protected]b1122982010-05-17 23:04:246664}
6665
[email protected]3fc38e22014-05-30 00:13:236666void GLES2DecoderImpl::RestoreStateForAttrib(
6667 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066668 const VertexAttrib* attrib =
6669 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236670 if (restore_array_binding) {
6671 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6672 Buffer* buffer = attrib->buffer();
6673 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6674 glVertexAttribPointer(
6675 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6676 attrib->gl_stride(), ptr);
6677 }
[email protected]ac77603c72013-03-08 13:52:066678 if (attrib->divisor())
6679 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246680 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236681 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6682 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286683
[email protected]265f8992012-07-20 01:03:146684 // Never touch vertex attribute 0's state (in particular, never
6685 // disable it) when running on desktop GL because it will never be
6686 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066687 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146688 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066689 if (attrib->enabled()) {
6690 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146691 } else {
[email protected]ac77603c72013-03-08 13:52:066692 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146693 }
[email protected]43410e92012-04-20 17:06:286694 }
[email protected]b1122982010-05-17 23:04:246695}
[email protected]07f54fcc2009-12-22 02:46:306696
[email protected]8fbedc02010-11-18 18:43:406697bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436698 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426699 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406700 DCHECK(simulated);
6701 *simulated = false;
6702 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6703 return true;
6704
[email protected]e259eb412012-10-13 05:47:246705 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406706 return true;
6707 }
6708
[email protected]ab09b612013-03-11 22:11:516709 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016710 "GL_FIXED attributes have a signficant performance penalty");
6711
[email protected]8fbedc02010-11-18 18:43:406712 // NOTE: we could be smart and try to check if a buffer is used
6713 // twice in 2 different attribs, find the overlapping parts and therefore
6714 // duplicate the minimum amount of data but this whole code path is not meant
6715 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6716 // tests so we just add to the buffer attrib used.
6717
[email protected]c13e1da62011-09-09 21:48:306718 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066719 const VertexAttribManager::VertexAttribList& enabled_attribs =
6720 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6721 for (VertexAttribManager::VertexAttribList::const_iterator it =
6722 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6723 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356724 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066725 state_.current_program->GetAttribInfoByLocation(attrib->index());
6726 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6727 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426728 GLuint num_vertices = max_accessed + 1;
6729 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516730 LOCAL_SET_GL_ERROR(
6731 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426732 return false;
6733 }
[email protected]8fbedc02010-11-18 18:43:406734 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066735 attrib->CanAccess(max_accessed) &&
6736 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476737 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066738 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476739 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516740 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436741 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406742 return false;
6743 }
6744 }
6745 }
6746
[email protected]3aad1a32012-09-07 20:54:476747 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6748 uint32 size_needed = 0;
6749 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306750 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516751 LOCAL_SET_GL_ERROR(
6752 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406753 return false;
6754 }
6755
[email protected]ab09b612013-03-11 22:11:516756 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406757
6758 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306759 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406760 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306761 GLenum error = glGetError();
6762 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516763 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436764 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306765 return false;
6766 }
[email protected]8fbedc02010-11-18 18:43:406767 }
6768
6769 // Copy the elements and convert to float
6770 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066771 for (VertexAttribManager::VertexAttribList::const_iterator it =
6772 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6773 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356774 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066775 state_.current_program->GetAttribInfoByLocation(attrib->index());
6776 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426777 max_vertex_accessed);
6778 GLuint num_vertices = max_accessed + 1;
6779 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516780 LOCAL_SET_GL_ERROR(
6781 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426782 return false;
6783 }
[email protected]8fbedc02010-11-18 18:43:406784 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066785 attrib->CanAccess(max_accessed) &&
6786 attrib->type() == GL_FIXED) {
penghuang5a3210b2014-10-29 18:24:366787 int num_elements = attrib->size() * num_vertices;
6788 const int src_size = num_elements * sizeof(int32);
6789 const int dst_size = num_elements * sizeof(float);
6790 scoped_ptr<float[]> data(new float[num_elements]);
[email protected]8fbedc02010-11-18 18:43:406791 const int32* src = reinterpret_cast<const int32 *>(
penghuang5a3210b2014-10-29 18:24:366792 attrib->buffer()->GetRange(attrib->offset(), src_size));
[email protected]8fbedc02010-11-18 18:43:406793 const int32* end = src + num_elements;
6794 float* dst = data.get();
6795 while (src != end) {
6796 *dst++ = static_cast<float>(*src++) / 65536.0f;
6797 }
penghuang5a3210b2014-10-29 18:24:366798 glBufferSubData(GL_ARRAY_BUFFER, offset, dst_size, data.get());
[email protected]8fbedc02010-11-18 18:43:406799 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066800 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406801 reinterpret_cast<GLvoid*>(offset));
penghuang5a3210b2014-10-29 18:24:366802 offset += dst_size;
[email protected]8fbedc02010-11-18 18:43:406803 }
6804 }
6805 *simulated = true;
6806 return true;
6807}
6808
6809void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6810 // There's no need to call glVertexAttribPointer because we shadow all the
6811 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246812 glBindBuffer(
6813 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116814 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6815 : 0);
[email protected]8fbedc02010-11-18 18:43:406816}
6817
[email protected]ad84a3a2012-06-08 21:42:436818error::Error GLES2DecoderImpl::DoDrawArrays(
6819 const char* function_name,
6820 bool instanced,
6821 GLenum mode,
6822 GLint first,
6823 GLsizei count,
6824 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226825 error::Error error = WillAccessBoundFramebufferForDraw();
6826 if (error != error::kNoError)
6827 return error;
[email protected]38d139d2011-07-14 00:38:436828 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516829 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436830 return error::kNoError;
6831 }
6832 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516833 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436834 return error::kNoError;
6835 }
[email protected]c6aef902012-02-14 03:31:426836 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516837 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426838 return error::kNoError;
6839 }
[email protected]ad84a3a2012-06-08 21:42:436840 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436841 return error::kNoError;
6842 }
6843 // We have to check this here because the prototype for glDrawArrays
6844 // is GLint not GLsizei.
6845 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516846 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436847 return error::kNoError;
6848 }
6849
[email protected]ac6904d62014-07-30 12:00:106850 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:516851 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436852 return error::kNoError;
6853 }
6854
6855 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:106856 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206857 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516858 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206859 return error::kNoError;
6860 }
[email protected]c13e1da62011-09-09 21:48:306861 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436862 if (!SimulateAttrib0(
6863 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306864 return error::kNoError;
6865 }
[email protected]38d139d2011-07-14 00:38:436866 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436867 if (SimulateFixedAttribs(
6868 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6869 primcount)) {
[email protected]e56131d22013-07-28 16:14:116870 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436871 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376872 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426873 if (!instanced) {
6874 glDrawArrays(mode, first, count);
6875 } else {
6876 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6877 }
[email protected]38d139d2011-07-14 00:38:436878 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546879 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436880 }
6881 if (simulated_fixed_attribs) {
6882 RestoreStateForSimulatedFixedAttribs();
6883 }
6884 }
6885 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236886 // We don't have to restore attrib 0 generic data at the end of this
6887 // function even if it is simulated. This is because we will simulate
6888 // it in each draw call, and attrib 0 generic data queries use cached
6889 // values instead of passing down to the underlying driver.
6890 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:436891 }
[email protected]38d139d2011-07-14 00:38:436892 }
6893 return error::kNoError;
6894}
6895
vmiuracd108592014-09-08 14:36:346896error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
6897 const void* cmd_data) {
6898 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436899 return DoDrawArrays("glDrawArrays",
6900 false,
[email protected]c6aef902012-02-14 03:31:426901 static_cast<GLenum>(c.mode),
6902 static_cast<GLint>(c.first),
6903 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:106904 1);
[email protected]c6aef902012-02-14 03:31:426905}
6906
6907error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:346908 uint32 immediate_data_size,
6909 const void* cmd_data) {
6910 const gles2::cmds::DrawArraysInstancedANGLE& c =
6911 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156912 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516913 LOCAL_SET_GL_ERROR(
6914 GL_INVALID_OPERATION,
6915 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426916 return error::kNoError;
6917 }
[email protected]ad84a3a2012-06-08 21:42:436918 return DoDrawArrays("glDrawArraysIntancedANGLE",
6919 true,
[email protected]c6aef902012-02-14 03:31:426920 static_cast<GLenum>(c.mode),
6921 static_cast<GLint>(c.first),
6922 static_cast<GLsizei>(c.count),
6923 static_cast<GLsizei>(c.primcount));
6924}
6925
[email protected]ad84a3a2012-06-08 21:42:436926error::Error GLES2DecoderImpl::DoDrawElements(
6927 const char* function_name,
6928 bool instanced,
6929 GLenum mode,
6930 GLsizei count,
6931 GLenum type,
6932 int32 offset,
6933 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226934 error::Error error = WillAccessBoundFramebufferForDraw();
6935 if (error != error::kNoError)
6936 return error;
[email protected]e259eb412012-10-13 05:47:246937 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516938 LOCAL_SET_GL_ERROR(
6939 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296940 return error::kNoError;
6941 }
6942
[email protected]8eee29c2010-04-29 03:38:296943 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516944 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296945 return error::kNoError;
6946 }
6947 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516948 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296949 return error::kNoError;
6950 }
[email protected]9438b012010-06-15 22:55:056951 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516952 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296953 return error::kNoError;
6954 }
[email protected]9438b012010-06-15 22:55:056955 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516956 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296957 return error::kNoError;
6958 }
[email protected]c6aef902012-02-14 03:31:426959 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516960 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426961 return error::kNoError;
6962 }
[email protected]8eee29c2010-04-29 03:38:296963
[email protected]ad84a3a2012-06-08 21:42:436964 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276965 return error::kNoError;
6966 }
6967
[email protected]ac6904d62014-07-30 12:00:106968 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:316969 return error::kNoError;
6970 }
6971
[email protected]8eee29c2010-04-29 03:38:296972 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086973 Buffer* element_array_buffer =
6974 state_.vertex_attrib_manager->element_array_buffer();
6975
6976 if (!element_array_buffer->GetMaxValueForRange(
6977 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516978 LOCAL_SET_GL_ERROR(
6979 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296980 return error::kNoError;
6981 }
6982
[email protected]ac6904d62014-07-30 12:00:106983 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206984 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516985 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206986 return error::kNoError;
6987 }
[email protected]c13e1da62011-09-09 21:48:306988 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436989 if (!SimulateAttrib0(
6990 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306991 return error::kNoError;
6992 }
[email protected]8fbedc02010-11-18 18:43:406993 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436994 if (SimulateFixedAttribs(
6995 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6996 primcount)) {
[email protected]e56131d22013-07-28 16:14:116997 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466998 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086999 // TODO(gman): Refactor to hide these details in BufferManager or
7000 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:407001 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:087002 bool used_client_side_array = false;
7003 if (element_array_buffer->IsClientSideArray()) {
7004 used_client_side_array = true;
7005 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
7006 indices = element_array_buffer->GetRange(offset, 0);
7007 }
7008
[email protected]00c2cf92014-03-14 00:08:377009 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:427010 if (!instanced) {
7011 glDrawElements(mode, count, type, indices);
7012 } else {
7013 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
7014 }
[email protected]17cfbe0e2013-03-07 01:26:087015
7016 if (used_client_side_array) {
7017 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
7018 element_array_buffer->service_id());
7019 }
7020
[email protected]8fbedc02010-11-18 18:43:407021 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:547022 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:407023 }
7024 if (simulated_fixed_attribs) {
7025 RestoreStateForSimulatedFixedAttribs();
7026 }
[email protected]ba3176a2009-12-16 18:19:467027 }
[email protected]b1122982010-05-17 23:04:247028 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:237029 // We don't have to restore attrib 0 generic data at the end of this
7030 // function even if it is simulated. This is because we will simulate
7031 // it in each draw call, and attrib 0 generic data queries use cached
7032 // values instead of passing down to the underlying driver.
7033 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:247034 }
[email protected]96449d2c2009-11-25 00:01:327035 }
[email protected]f7a64ee2010-02-01 22:24:147036 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327037}
7038
vmiuracd108592014-09-08 14:36:347039error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
7040 const void* cmd_data) {
7041 const gles2::cmds::DrawElements& c =
7042 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:437043 return DoDrawElements("glDrawElements",
7044 false,
[email protected]c6aef902012-02-14 03:31:427045 static_cast<GLenum>(c.mode),
7046 static_cast<GLsizei>(c.count),
7047 static_cast<GLenum>(c.type),
7048 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:107049 1);
[email protected]c6aef902012-02-14 03:31:427050}
7051
7052error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:347053 uint32 immediate_data_size,
7054 const void* cmd_data) {
7055 const gles2::cmds::DrawElementsInstancedANGLE& c =
7056 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157057 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517058 LOCAL_SET_GL_ERROR(
7059 GL_INVALID_OPERATION,
7060 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427061 return error::kNoError;
7062 }
[email protected]ad84a3a2012-06-08 21:42:437063 return DoDrawElements("glDrawElementsInstancedANGLE",
7064 true,
[email protected]c6aef902012-02-14 03:31:427065 static_cast<GLenum>(c.mode),
7066 static_cast<GLsizei>(c.count),
7067 static_cast<GLenum>(c.type),
7068 static_cast<int32>(c.index_offset),
7069 static_cast<GLsizei>(c.primcount));
7070}
7071
[email protected]269200b12010-11-18 22:53:067072GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:237073 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
7074 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:077075 Buffer* buffer = GetBuffer(buffer_id);
7076 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:037077 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517078 LOCAL_SET_GL_ERROR(
7079 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:237080 } else {
[email protected]b10492f2013-03-08 05:24:077081 if (!buffer->GetMaxValueForRange(
7082 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:037083 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517084 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:067085 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437086 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:237087 }
7088 }
7089 return max_vertex_accessed;
7090}
7091
zmo1bb3d1d2015-01-21 20:29:437092void GLES2DecoderImpl::DoShaderSource(
7093 GLuint client_id, GLsizei count, const char** data, const GLint* length) {
7094 std::string str;
7095 for (GLsizei ii = 0; ii < count; ++ii) {
dyen7b0b4ba52015-02-04 21:38:067096 if (length && length[ii] > 0)
7097 str.append(data[ii], length[ii]);
7098 else
7099 str.append(data[ii]);
zmo1bb3d1d2015-01-21 20:29:437100 }
[email protected]df37b9932013-03-08 05:21:427101 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
7102 if (!shader) {
zmo1bb3d1d2015-01-21 20:29:437103 return;
[email protected]96449d2c2009-11-25 00:01:327104 }
[email protected]45bf5152010-02-12 00:11:317105 // Note: We don't actually call glShaderSource here. We wait until
dyen7b0b4ba52015-02-04 21:38:067106 // we actually compile the shader.
zmo576a0492014-09-13 01:12:327107 shader->set_source(str);
[email protected]558847a2010-03-24 07:02:547108}
7109
zmo38923562015-01-29 20:17:397110void GLES2DecoderImpl::DoTransformFeedbackVaryings(
7111 GLuint client_program_id, GLsizei count, const char* const* varyings,
7112 GLenum buffer_mode) {
7113 Program* program = GetProgramInfoNotShader(
7114 client_program_id, "glTransformFeedbackVaryings");
7115 if (!program) {
7116 return;
7117 }
7118 glTransformFeedbackVaryings(
7119 program->service_id(), count, varyings, buffer_mode);
7120}
7121
[email protected]ae51d192010-04-27 00:48:037122void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:387123 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:427124 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
7125 if (!shader) {
[email protected]45bf5152010-02-12 00:11:317126 return;
7127 }
dyen0ff9e4402015-02-12 22:27:437128
7129 scoped_refptr<ShaderTranslatorInterface> translator;
[email protected]b1d2dcb2010-05-17 19:24:187130 if (use_shader_translator_) {
dyen0ff9e4402015-02-12 22:27:437131 translator = shader->shader_type() == GL_VERTEX_SHADER ?
7132 vertex_translator_ : fragment_translator_;
[email protected]de17df392010-04-23 21:09:417133 }
[email protected]de17df392010-04-23 21:09:417134
dyen0ff9e4402015-02-12 22:27:437135 const Shader::TranslatedShaderSourceType source_type =
7136 feature_info_->feature_flags().angle_translated_shader_source ?
7137 Shader::kANGLE : Shader::kGL;
7138 shader->RequestCompile(translator, source_type);
vmiura8266ca72014-09-09 21:37:007139}
[email protected]45bf5152010-02-12 00:11:317140
[email protected]ddd968b82010-03-02 00:44:297141void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:427142 GLuint shader_id, GLenum pname, GLint* params) {
7143 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
7144 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:297145 return;
7146 }
dyen0ff9e4402015-02-12 22:27:437147
7148 // Compile now for statuses that require it.
7149 switch (pname) {
7150 case GL_COMPILE_STATUS:
7151 case GL_INFO_LOG_LENGTH:
7152 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
7153 shader->DoCompile();
7154 break;
7155
7156 default:
7157 break;
7158 }
7159
[email protected]8f1ccdac2010-05-19 21:01:487160 switch (pname) {
7161 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:327162 *params = shader->source().size();
7163 if (*params)
7164 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:487165 return;
7166 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:327167 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:417168 return;
[email protected]8f1ccdac2010-05-19 21:01:487169 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:327170 *params = shader->log_info().size();
7171 if (*params)
7172 ++(*params);
[email protected]e5186162010-06-14 18:54:417173 return;
[email protected]d6a53e42011-10-05 00:09:367174 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:327175 *params = shader->translated_source().size();
7176 if (*params)
7177 ++(*params);
[email protected]d6a53e42011-10-05 00:09:367178 return;
[email protected]8f1ccdac2010-05-19 21:01:487179 default:
7180 break;
[email protected]ddd968b82010-03-02 00:44:297181 }
[email protected]df37b9932013-03-08 05:21:427182 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:297183}
7184
vmiuracd108592014-09-08 14:36:347185error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
7186 const void* cmd_data) {
7187 const gles2::cmds::GetShaderSource& c =
7188 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427189 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:037190 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7191 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427192 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:327193 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:297194 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:297195 return error::kNoError;
7196 }
zmo576a0492014-09-13 01:12:327197 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:037198 return error::kNoError;
7199}
7200
[email protected]d6a53e42011-10-05 00:09:367201error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
7202 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347203 const void* cmd_data) {
7204 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
7205 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
7206 cmd_data);
[email protected]df37b9932013-03-08 05:21:427207 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:367208 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7209 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427210 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:207211 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:427212 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:367213 bucket->SetSize(0);
7214 return error::kNoError;
7215 }
7216
dyen0ff9e4402015-02-12 22:27:437217 // Make sure translator has been utilized in compile.
7218 shader->DoCompile();
7219
zmo576a0492014-09-13 01:12:327220 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:367221 return error::kNoError;
7222}
7223
[email protected]ae51d192010-04-27 00:48:037224error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:347225 uint32 immediate_data_size,
7226 const void* cmd_data) {
7227 const gles2::cmds::GetProgramInfoLog& c =
7228 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427229 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:587230 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7231 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427232 Program* program = GetProgramInfoNotShader(
7233 program_id, "glGetProgramInfoLog");
7234 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:467235 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037236 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:317237 }
[email protected]df37b9932013-03-08 05:21:427238 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:037239 return error::kNoError;
7240}
7241
7242error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:347243 uint32 immediate_data_size,
7244 const void* cmd_data) {
7245 const gles2::cmds::GetShaderInfoLog& c =
7246 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427247 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:587248 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7249 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427250 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:327251 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:467252 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037253 return error::kNoError;
7254 }
dyen0ff9e4402015-02-12 22:27:437255
7256 // Shader must be compiled in order to get the info log.
7257 shader->DoCompile();
7258
zmo576a0492014-09-13 01:12:327259 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:037260 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327261}
7262
[email protected]d058bca2012-11-26 10:27:267263bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
7264 return state_.GetEnabled(cap);
7265}
7266
[email protected]1958e0e2010-04-22 05:17:157267bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:217268 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107269 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157270}
7271
7272bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357273 const Framebuffer* framebuffer =
7274 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107275 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157276}
7277
7278bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367279 // IsProgram is true for programs as soon as they are created, until they are
7280 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:357281 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:107282 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157283}
7284
7285bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357286 const Renderbuffer* renderbuffer =
7287 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107288 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157289}
7290
7291bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367292 // IsShader is true for shaders as soon as they are created, until they
7293 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:357294 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:107295 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157296}
7297
7298bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:497299 const TextureRef* texture_ref = GetTexture(client_id);
7300 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:037301}
7302
7303void GLES2DecoderImpl::DoAttachShader(
7304 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427305 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587306 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:427307 if (!program) {
[email protected]ae51d192010-04-27 00:48:037308 return;
[email protected]1958e0e2010-04-22 05:17:157309 }
[email protected]df37b9932013-03-08 05:21:427310 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
7311 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037312 return;
7313 }
[email protected]df37b9932013-03-08 05:21:427314 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517315 LOCAL_SET_GL_ERROR(
7316 GL_INVALID_OPERATION,
7317 "glAttachShader",
7318 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:317319 return;
7320 }
[email protected]df37b9932013-03-08 05:21:427321 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037322}
7323
7324void GLES2DecoderImpl::DoDetachShader(
7325 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427326 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587327 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427328 if (!program) {
[email protected]ae51d192010-04-27 00:48:037329 return;
7330 }
[email protected]df37b9932013-03-08 05:21:427331 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7332 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037333 return;
7334 }
[email protected]df37b9932013-03-08 05:21:427335 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517336 LOCAL_SET_GL_ERROR(
7337 GL_INVALID_OPERATION,
7338 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227339 return;
7340 }
[email protected]df37b9932013-03-08 05:21:427341 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037342}
7343
7344void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427345 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587346 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427347 if (!program) {
[email protected]ae51d192010-04-27 00:48:037348 return;
7349 }
[email protected]df37b9932013-03-08 05:21:427350 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157351}
7352
[email protected]ac77603c72013-03-08 13:52:067353void GLES2DecoderImpl::GetVertexAttribHelper(
7354 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247355 switch (pname) {
7356 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067357 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247358 if (buffer && !buffer->IsDeleted()) {
7359 GLuint client_id;
7360 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7361 *params = client_id;
7362 }
7363 break;
7364 }
7365 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067366 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247367 break;
7368 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067369 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247370 break;
7371 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067372 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247373 break;
7374 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067375 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247376 break;
7377 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067378 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247379 break;
[email protected]c6aef902012-02-14 03:31:427380 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067381 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427382 break;
[email protected]ac77603c72013-03-08 13:52:067383 default:
7384 NOTREACHED();
7385 break;
7386 }
7387}
7388
[email protected]4c6f5462014-03-05 00:26:567389void GLES2DecoderImpl::DoGetTexParameterfv(
7390 GLenum target, GLenum pname, GLfloat* params) {
7391 InitTextureMaxAnisotropyIfNeeded(target, pname);
7392 glGetTexParameterfv(target, pname, params);
7393}
7394
7395void GLES2DecoderImpl::DoGetTexParameteriv(
7396 GLenum target, GLenum pname, GLint* params) {
7397 InitTextureMaxAnisotropyIfNeeded(target, pname);
7398 glGetTexParameteriv(target, pname, params);
7399}
7400
7401void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7402 GLenum target, GLenum pname) {
7403 if (!workarounds().init_texture_max_anisotropy)
7404 return;
7405 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7406 !validators_->texture_parameter.IsValid(pname)) {
7407 return;
7408 }
7409
7410 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7411 &state_, target);
7412 if (!texture_ref) {
7413 LOCAL_SET_GL_ERROR(
7414 GL_INVALID_OPERATION,
7415 "glGetTexParamter{fi}v", "unknown texture for target");
7416 return;
7417 }
7418 Texture* texture = texture_ref->texture();
7419 texture->InitTextureMaxAnisotropyIfNeeded(target);
7420}
7421
[email protected]ac77603c72013-03-08 13:52:067422void GLES2DecoderImpl::DoGetVertexAttribfv(
7423 GLuint index, GLenum pname, GLfloat* params) {
7424 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7425 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517426 LOCAL_SET_GL_ERROR(
7427 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067428 return;
7429 }
7430 switch (pname) {
7431 case GL_CURRENT_VERTEX_ATTRIB: {
7432 const Vec4& value = state_.attrib_values[index];
7433 params[0] = value.v[0];
7434 params[1] = value.v[1];
7435 params[2] = value.v[2];
7436 params[3] = value.v[3];
7437 break;
7438 }
7439 default: {
7440 GLint value = 0;
7441 GetVertexAttribHelper(attrib, pname, &value);
7442 *params = static_cast<GLfloat>(value);
7443 break;
7444 }
7445 }
7446}
7447
7448void GLES2DecoderImpl::DoGetVertexAttribiv(
7449 GLuint index, GLenum pname, GLint* params) {
7450 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7451 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517452 LOCAL_SET_GL_ERROR(
7453 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067454 return;
7455 }
7456 switch (pname) {
[email protected]af6380962012-11-29 23:24:137457 case GL_CURRENT_VERTEX_ATTRIB: {
7458 const Vec4& value = state_.attrib_values[index];
7459 params[0] = static_cast<GLint>(value.v[0]);
7460 params[1] = static_cast<GLint>(value.v[1]);
7461 params[2] = static_cast<GLint>(value.v[2]);
7462 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247463 break;
[email protected]af6380962012-11-29 23:24:137464 }
[email protected]b1122982010-05-17 23:04:247465 default:
[email protected]ac77603c72013-03-08 13:52:067466 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247467 break;
7468 }
7469}
7470
[email protected]af6380962012-11-29 23:24:137471bool GLES2DecoderImpl::SetVertexAttribValue(
7472 const char* function_name, GLuint index, const GLfloat* value) {
7473 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517474 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137475 return false;
[email protected]b1122982010-05-17 23:04:247476 }
[email protected]af6380962012-11-29 23:24:137477 Vec4& v = state_.attrib_values[index];
7478 v.v[0] = value[0];
7479 v.v[1] = value[1];
7480 v.v[2] = value[2];
7481 v.v[3] = value[3];
7482 return true;
7483}
7484
7485void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7486 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7487 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7488 glVertexAttrib1f(index, v0);
7489 }
[email protected]b1122982010-05-17 23:04:247490}
7491
7492void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137493 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7494 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7495 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247496 }
[email protected]b1122982010-05-17 23:04:247497}
7498
7499void GLES2DecoderImpl::DoVertexAttrib3f(
7500 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137501 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7502 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7503 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247504 }
[email protected]b1122982010-05-17 23:04:247505}
7506
7507void GLES2DecoderImpl::DoVertexAttrib4f(
7508 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137509 GLfloat v[4] = { v0, v1, v2, v3, };
7510 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7511 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247512 }
[email protected]b1122982010-05-17 23:04:247513}
7514
7515void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137516 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7517 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7518 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247519 }
[email protected]b1122982010-05-17 23:04:247520}
7521
7522void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137523 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7524 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7525 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247526 }
[email protected]b1122982010-05-17 23:04:247527}
7528
7529void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137530 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7531 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7532 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247533 }
[email protected]b1122982010-05-17 23:04:247534}
7535
7536void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137537 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7538 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247539 }
[email protected]b1122982010-05-17 23:04:247540}
7541
zmo0c4b7cf2014-11-26 00:52:117542error::Error GLES2DecoderImpl::HandleVertexAttribIPointer(
7543 uint32 immediate_data_size,
7544 const void* cmd_data) {
7545 // TODO(zmo): Unsafe ES3 API, missing states update.
7546 if (!unsafe_es3_apis_enabled())
7547 return error::kUnknownCommand;
7548 const gles2::cmds::VertexAttribIPointer& c =
7549 *static_cast<const gles2::cmds::VertexAttribIPointer*>(cmd_data);
7550 GLuint indx = c.indx;
7551 GLint size = c.size;
7552 GLenum type = c.type;
7553 GLsizei stride = c.stride;
7554 GLsizei offset = c.offset;
7555 const void* ptr = reinterpret_cast<const void*>(offset);
7556 glVertexAttribIPointer(indx, size, type, stride, ptr);
7557 return error::kNoError;
7558}
7559
[email protected]f7a64ee2010-02-01 22:24:147560error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347561 uint32 immediate_data_size,
7562 const void* cmd_data) {
7563 const gles2::cmds::VertexAttribPointer& c =
7564 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467565
[email protected]7cd76fd2013-06-02 21:11:117566 if (!state_.bound_array_buffer.get() ||
7567 state_.bound_array_buffer->IsDeleted()) {
7568 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527569 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517570 LOCAL_SET_GL_ERROR(
7571 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467572 return error::kNoError;
7573 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517574 LOCAL_SET_GL_ERROR(
7575 GL_INVALID_VALUE,
7576 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467577 return error::kNoError;
7578 }
[email protected]96449d2c2009-11-25 00:01:327579 }
[email protected]8eee29c2010-04-29 03:38:297580
7581 GLuint indx = c.indx;
7582 GLint size = c.size;
7583 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327584 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:297585 GLsizei stride = c.stride;
7586 GLsizei offset = c.offset;
7587 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057588 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517589 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297590 return error::kNoError;
7591 }
[email protected]9438b012010-06-15 22:55:057592 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517593 LOCAL_SET_GL_ERROR(
7594 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297595 return error::kNoError;
7596 }
7597 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517598 LOCAL_SET_GL_ERROR(
7599 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297600 return error::kNoError;
7601 }
7602 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517603 LOCAL_SET_GL_ERROR(
7604 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297605 return error::kNoError;
7606 }
7607 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517608 LOCAL_SET_GL_ERROR(
7609 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297610 return error::kNoError;
7611 }
7612 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517613 LOCAL_SET_GL_ERROR(
7614 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297615 return error::kNoError;
7616 }
7617 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317618 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127619 // component_size must be a power of two to use & as optimized modulo.
7620 DCHECK(GLES2Util::IsPOT(component_size));
7621 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517622 LOCAL_SET_GL_ERROR(
7623 GL_INVALID_OPERATION,
7624 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317625 return error::kNoError;
7626 }
[email protected]a07a23602014-08-05 11:36:127627 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517628 LOCAL_SET_GL_ERROR(
7629 GL_INVALID_OPERATION,
7630 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297631 return error::kNoError;
7632 }
[email protected]7cd76fd2013-06-02 21:11:117633 state_.vertex_attrib_manager
7634 ->SetAttribInfo(indx,
7635 state_.bound_array_buffer.get(),
7636 size,
7637 type,
7638 normalized,
7639 stride,
7640 stride != 0 ? stride : component_size * size,
7641 offset);
[email protected]8fbedc02010-11-18 18:43:407642 if (type != GL_FIXED) {
7643 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7644 }
[email protected]f7a64ee2010-02-01 22:24:147645 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327646}
7647
[email protected]43410e92012-04-20 17:06:287648void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7649 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247650 state_.viewport_x = x;
7651 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027652 state_.viewport_width = std::min(width, viewport_max_width_);
7653 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287654 glViewport(x, y, width, height);
7655}
7656
[email protected]c6aef902012-02-14 03:31:427657error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347658 uint32 immediate_data_size,
7659 const void* cmd_data) {
7660 const gles2::cmds::VertexAttribDivisorANGLE& c =
7661 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157662 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517663 LOCAL_SET_GL_ERROR(
7664 GL_INVALID_OPERATION,
7665 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537666 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427667 }
7668 GLuint index = c.index;
7669 GLuint divisor = c.divisor;
7670 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517671 LOCAL_SET_GL_ERROR(
7672 GL_INVALID_VALUE,
7673 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427674 return error::kNoError;
7675 }
7676
[email protected]e259eb412012-10-13 05:47:247677 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427678 index,
7679 divisor);
7680 glVertexAttribDivisorANGLE(index, divisor);
7681 return error::kNoError;
7682}
7683
[email protected]68586372013-12-11 01:27:597684template <typename pixel_data_type>
7685static void WriteAlphaData(
7686 void *pixels, uint32 row_count, uint32 channel_count,
7687 uint32 alpha_channel_index, uint32 unpadded_row_size,
7688 uint32 padded_row_size, pixel_data_type alpha_value) {
7689 DCHECK_GT(channel_count, 0U);
7690 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7691 uint32 unpadded_row_size_in_elements =
7692 unpadded_row_size / sizeof(pixel_data_type);
7693 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7694 uint32 padded_row_size_in_elements =
7695 padded_row_size / sizeof(pixel_data_type);
7696 pixel_data_type* dst =
7697 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7698 for (uint32 yy = 0; yy < row_count; ++yy) {
7699 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7700 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7701 *d = alpha_value;
7702 }
7703 dst += padded_row_size_in_elements;
7704 }
7705}
7706
[email protected]5a36dc132013-07-23 23:17:557707void GLES2DecoderImpl::FinishReadPixels(
7708 const cmds::ReadPixels& c,
7709 GLuint buffer) {
7710 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7711 GLsizei width = c.width;
7712 GLsizei height = c.height;
7713 GLenum format = c.format;
7714 GLenum type = c.type;
7715 typedef cmds::ReadPixels::Result Result;
7716 uint32 pixels_size;
7717 Result* result = NULL;
7718 if (c.result_shm_id != 0) {
7719 result = GetSharedMemoryAs<Result*>(
7720 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7721 if (!result) {
7722 if (buffer != 0) {
7723 glDeleteBuffersARB(1, &buffer);
7724 }
7725 return;
7726 }
7727 }
7728 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427729 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]5a36dc132013-07-23 23:17:557730 NULL, NULL);
7731 void* pixels = GetSharedMemoryAs<void*>(
7732 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7733 if (!pixels) {
7734 if (buffer != 0) {
7735 glDeleteBuffersARB(1, &buffer);
7736 }
7737 return;
7738 }
7739
7740 if (buffer != 0) {
7741 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337742 void* data;
7743 if (features().map_buffer_range) {
7744 data = glMapBufferRange(
7745 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7746 } else {
7747 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7748 }
miub70d78592014-11-15 03:53:477749 if (!data) {
7750 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer",
7751 "Unable to map memory for readback.");
7752 return;
7753 }
[email protected]5a36dc132013-07-23 23:17:557754 memcpy(pixels, data, pixels_size);
7755 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7756 // have to restore the state.
7757 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7758 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7759 glDeleteBuffersARB(1, &buffer);
7760 }
7761
7762 if (result != NULL) {
7763 *result = true;
7764 }
7765
7766 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7767 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7768 if ((channels_exist & 0x0008) == 0 &&
7769 workarounds().clear_alpha_in_readpixels) {
7770 // Set the alpha to 255 because some drivers are buggy in this regard.
7771 uint32 temp_size;
7772
7773 uint32 unpadded_row_size;
7774 uint32 padded_row_size;
7775 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427776 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]5a36dc132013-07-23 23:17:557777 &unpadded_row_size, &padded_row_size)) {
7778 return;
7779 }
[email protected]68586372013-12-11 01:27:597780
7781 uint32 channel_count = 0;
7782 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557783 switch (format) {
7784 case GL_RGBA:
7785 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597786 channel_count = 4;
7787 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557788 break;
[email protected]68586372013-12-11 01:27:597789 case GL_ALPHA:
7790 channel_count = 1;
7791 alpha_channel = 0;
7792 break;
7793 }
7794
7795 if (channel_count > 0) {
7796 switch (type) {
7797 case GL_UNSIGNED_BYTE:
7798 WriteAlphaData<uint8>(
7799 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7800 padded_row_size, 0xFF);
7801 break;
7802 case GL_FLOAT:
7803 WriteAlphaData<float>(
7804 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7805 padded_row_size, 1.0f);
7806 break;
7807 case GL_HALF_FLOAT:
7808 WriteAlphaData<uint16>(
7809 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7810 padded_row_size, 0x3C00);
7811 break;
[email protected]5a36dc132013-07-23 23:17:557812 }
[email protected]5a36dc132013-07-23 23:17:557813 }
7814 }
7815}
7816
vmiuracd108592014-09-08 14:36:347817error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7818 const void* cmd_data) {
7819 const gles2::cmds::ReadPixels& c =
7820 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:217821 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227822 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7823 if (fbo_error != error::kNoError)
7824 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317825 GLint x = c.x;
7826 GLint y = c.y;
7827 GLsizei width = c.width;
7828 GLsizei height = c.height;
7829 GLenum format = c.format;
7830 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327831 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:567832 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517833 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567834 return error::kNoError;
7835 }
[email protected]ed9f9cd2013-02-27 21:12:357836 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187837 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347838 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427839 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:247840 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187841 return error::kOutOfBounds;
7842 }
[email protected]612d2f82009-12-08 20:49:317843 void* pixels = GetSharedMemoryAs<void*>(
7844 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107845 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147846 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467847 }
[email protected]de43f082013-04-02 01:16:107848 Result* result = NULL;
7849 if (c.result_shm_id != 0) {
7850 result = GetSharedMemoryAs<Result*>(
7851 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7852 if (!result) {
7853 return error::kOutOfBounds;
7854 }
7855 }
[email protected]a51788e2010-02-24 21:54:257856
[email protected]9438b012010-06-15 22:55:057857 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517858 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297859 return error::kNoError;
7860 }
[email protected]68586372013-12-11 01:27:597861 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517862 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127863 return error::kNoError;
7864 }
[email protected]68586372013-12-11 01:27:597865 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7866 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7867 // format and type are acceptable enums but not guaranteed to be supported
7868 // for this framebuffer. Have to ask gl if they are valid.
7869 GLint preferred_format = 0;
7870 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7871 GLint preferred_type = 0;
7872 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7873 if (format != static_cast<GLenum>(preferred_format) ||
7874 type != static_cast<GLenum>(preferred_type)) {
7875 LOCAL_SET_GL_ERROR(
7876 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7877 "with the current read framebuffer");
7878 return error::kNoError;
7879 }
7880 }
[email protected]57f223832010-03-19 01:57:567881 if (width == 0 || height == 0) {
7882 return error::kNoError;
7883 }
7884
[email protected]57f223832010-03-19 01:57:567885 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307886 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567887
[email protected]3aad1a32012-09-07 20:54:477888 int32 max_x;
7889 int32 max_y;
7890 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517891 LOCAL_SET_GL_ERROR(
7892 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147893 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317894 }
[email protected]57f223832010-03-19 01:57:567895
[email protected]2ea5950d2014-07-09 18:20:347896 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
7897 return error::kNoError;
7898 }
7899
[email protected]0d6bfdc2011-11-02 01:32:207900 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7901 return error::kNoError;
7902 }
7903
[email protected]caa13ed2014-02-17 11:29:207904 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107905
7906 ScopedResolvedFrameBufferBinder binder(this, false, true);
7907
[email protected]d37231fa2010-04-09 21:16:027908 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567909 // The user requested an out of range area. Get the results 1 line
7910 // at a time.
7911 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347912 uint32 unpadded_row_size;
7913 uint32 padded_row_size;
7914 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427915 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347916 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517917 LOCAL_SET_GL_ERROR(
7918 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567919 return error::kNoError;
7920 }
7921
7922 GLint dest_x_offset = std::max(-x, 0);
7923 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347924 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427925 dest_x_offset, 1, 1, format, type, state_.pack_alignment,
7926 &dest_row_offset, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517927 LOCAL_SET_GL_ERROR(
7928 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567929 return error::kNoError;
7930 }
7931
7932 // Copy each row into the larger dest rect.
7933 int8* dst = static_cast<int8*>(pixels);
7934 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027935 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567936 GLint read_width = read_end_x - read_x;
7937 for (GLint yy = 0; yy < height; ++yy) {
7938 GLint ry = y + yy;
7939
7940 // Clear the row.
7941 memset(dst, 0, unpadded_row_size);
7942
7943 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027944 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567945 glReadPixels(
7946 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7947 }
7948 dst += padded_row_size;
7949 }
7950 } else {
[email protected]5a36dc132013-07-23 23:17:557951 if (async && features().use_async_readpixels) {
miu50cef602014-11-11 01:35:417952 GLuint buffer = 0;
[email protected]5a36dc132013-07-23 23:17:557953 glGenBuffersARB(1, &buffer);
7954 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
miub70d78592014-11-15 03:53:477955 // For ANGLE client version 2, GL_STREAM_READ is not available.
zmo68fcdc62014-12-05 21:51:497956 const GLenum usage_hint = feature_info_->gl_version_info().is_angle ?
7957 GL_STATIC_DRAW : GL_STREAM_READ;
miub70d78592014-11-15 03:53:477958 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint);
[email protected]5a36dc132013-07-23 23:17:557959 GLenum error = glGetError();
7960 if (error == GL_NO_ERROR) {
7961 glReadPixels(x, y, width, height, format, type, 0);
7962 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7963 new FenceCallback()));
7964 WaitForReadPixels(base::Bind(
7965 &GLES2DecoderImpl::FinishReadPixels,
7966 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7967 <GLES2DecoderImpl>(this),
7968 c, buffer));
7969 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7970 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597971 } else {
7972 // On error, unbind pack buffer and fall through to sync readpixels
7973 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
miu50cef602014-11-11 01:35:417974 glDeleteBuffersARB(1, &buffer);
[email protected]5a36dc132013-07-23 23:17:557975 }
7976 }
[email protected]57f223832010-03-19 01:57:567977 glReadPixels(x, y, width, height, format, type, pixels);
7978 }
[email protected]ab09b612013-03-11 22:11:517979 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257980 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107981 if (result != NULL) {
7982 *result = true;
7983 }
[email protected]5a36dc132013-07-23 23:17:557984 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257985 }
[email protected]4848b9f82011-03-10 18:37:567986
[email protected]f7a64ee2010-02-01 22:24:147987 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327988}
7989
vmiuracd108592014-09-08 14:36:347990error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
7991 const void* cmd_data) {
7992 const gles2::cmds::PixelStorei& c =
7993 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:197994 GLenum pname = c.pname;
7995 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057996 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517997 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127998 return error::kNoError;
7999 }
[email protected]222471d2011-11-30 18:06:398000 switch (pname) {
8001 case GL_PACK_ALIGNMENT:
8002 case GL_UNPACK_ALIGNMENT:
8003 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:518004 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:208005 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:398006 return error::kNoError;
8007 }
[email protected]164d6d52012-05-05 00:55:038008 break;
[email protected]0a1e9ad2012-05-04 21:13:038009 case GL_UNPACK_FLIP_Y_CHROMIUM:
8010 unpack_flip_y_ = (param != 0);
8011 return error::kNoError;
8012 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
8013 unpack_premultiply_alpha_ = (param != 0);
8014 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:178015 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
8016 unpack_unpremultiply_alpha_ = (param != 0);
8017 return error::kNoError;
[email protected]222471d2011-11-30 18:06:398018 default:
8019 break;
[email protected]b9849abf2009-11-25 19:13:198020 }
8021 glPixelStorei(pname, param);
8022 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:438023 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:248024 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:438025 break;
8026 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:428027 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:438028 break;
8029 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:248030 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:438031 break;
8032 default:
8033 // Validation should have prevented us from getting here.
8034 NOTREACHED();
8035 break;
[email protected]b9849abf2009-11-25 19:13:198036 }
[email protected]f7a64ee2010-02-01 22:24:148037 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198038}
8039
[email protected]1c75a3702011-11-11 14:15:288040error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:348041 uint32 immediate_data_size,
8042 const void* cmd_data) {
8043 const gles2::cmds::PostSubBufferCHROMIUM& c =
8044 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:388045 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:278046 {
8047 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
8048 }
[email protected]b381ee32014-03-22 02:43:438049 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:518050 LOCAL_SET_GL_ERROR(
8051 GL_INVALID_OPERATION,
8052 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:288053 return error::kNoError;
8054 }
[email protected]8f9b8dd2013-09-12 18:05:138055 bool is_tracing;
8056 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
8057 &is_tracing);
8058 if (is_tracing) {
8059 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
8060 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
8061 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
8062 is_offscreen ? offscreen_size_ : surface_->GetSize());
8063 }
[email protected]7794d512012-04-17 20:36:498064 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:288065 return error::kNoError;
[email protected]7794d512012-04-17 20:36:498066 } else {
8067 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:288068 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:498069 }
[email protected]1c75a3702011-11-11 14:15:288070}
8071
[email protected]957f0642014-04-09 16:50:018072error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
8073 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348074 const void* cmd_data) {
8075 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
8076 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:108077 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
8078 if (!ref) {
8079 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8080 "glScheduleOverlayPlaneCHROMIUM",
8081 "unknown texture");
8082 return error::kNoError;
8083 }
8084 gfx::GLImage* image =
8085 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
8086 if (!image) {
8087 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8088 "glScheduleOverlayPlaneCHROMIUM",
8089 "unsupported texture format");
8090 return error::kNoError;
8091 }
8092 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
8093 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
8094 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
8095 "glScheduleOverlayPlaneCHROMIUM",
8096 "invalid transform enum");
8097 return error::kNoError;
8098 }
8099 if (!surface_->ScheduleOverlayPlane(
8100 c.plane_z_order,
8101 transform,
8102 image,
8103 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
8104 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
8105 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8106 "glScheduleOverlayPlaneCHROMIUM",
8107 "failed to schedule overlay");
8108 }
[email protected]957f0642014-04-09 16:50:018109 return error::kNoError;
8110}
8111
[email protected]558847a2010-03-24 07:02:548112error::Error GLES2DecoderImpl::GetAttribLocationHelper(
8113 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8114 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578115 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518116 LOCAL_SET_GL_ERROR(
8117 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578118 return error::kNoError;
8119 }
[email protected]df37b9932013-03-08 05:21:428120 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:588121 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:428122 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148123 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198124 }
[email protected]df37b9932013-03-08 05:21:428125 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518126 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438127 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258128 return error::kNoError;
8129 }
[email protected]b9849abf2009-11-25 19:13:198130 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548131 location_shm_id, location_shm_offset, sizeof(GLint));
8132 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148133 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198134 }
[email protected]558847a2010-03-24 07:02:548135 // Require the client to init this incase the context is lost and we are no
8136 // longer executing commands.
8137 if (*location != -1) {
8138 return error::kGenericError;
8139 }
[email protected]df37b9932013-03-08 05:21:428140 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148141 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198142}
8143
[email protected]558847a2010-03-24 07:02:548144error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:348145 uint32 immediate_data_size,
8146 const void* cmd_data) {
8147 const gles2::cmds::GetAttribLocation& c =
8148 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548149 Bucket* bucket = GetBucket(c.name_bucket_id);
8150 if (!bucket) {
8151 return error::kInvalidArguments;
8152 }
8153 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188154 if (!bucket->GetAsString(&name_str)) {
8155 return error::kInvalidArguments;
8156 }
[email protected]558847a2010-03-24 07:02:548157 return GetAttribLocationHelper(
8158 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8159}
8160
8161error::Error GLES2DecoderImpl::GetUniformLocationHelper(
8162 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8163 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578164 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518165 LOCAL_SET_GL_ERROR(
8166 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578167 return error::kNoError;
8168 }
[email protected]df37b9932013-03-08 05:21:428169 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:208170 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:428171 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148172 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198173 }
[email protected]df37b9932013-03-08 05:21:428174 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518175 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438176 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258177 return error::kNoError;
8178 }
[email protected]b9849abf2009-11-25 19:13:198179 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548180 location_shm_id, location_shm_offset, sizeof(GLint));
8181 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148182 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198183 }
[email protected]558847a2010-03-24 07:02:548184 // Require the client to init this incase the context is lost an we are no
8185 // longer executing commands.
8186 if (*location != -1) {
8187 return error::kGenericError;
8188 }
[email protected]df37b9932013-03-08 05:21:428189 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148190 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198191}
8192
[email protected]f7a64ee2010-02-01 22:24:148193error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:348194 uint32 immediate_data_size,
8195 const void* cmd_data) {
8196 const gles2::cmds::GetUniformLocation& c =
8197 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548198 Bucket* bucket = GetBucket(c.name_bucket_id);
8199 if (!bucket) {
8200 return error::kInvalidArguments;
8201 }
8202 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188203 if (!bucket->GetAsString(&name_str)) {
8204 return error::kInvalidArguments;
8205 }
[email protected]558847a2010-03-24 07:02:548206 return GetUniformLocationHelper(
8207 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:198208}
8209
zmo155435a42015-02-13 05:06:538210error::Error GLES2DecoderImpl::HandleGetUniformIndices(
8211 uint32 immediate_data_size,
8212 const void* cmd_data) {
8213 if (!unsafe_es3_apis_enabled())
8214 return error::kUnknownCommand;
8215 const gles2::cmds::GetUniformIndices& c =
8216 *static_cast<const gles2::cmds::GetUniformIndices*>(cmd_data);
8217 Bucket* bucket = GetBucket(c.names_bucket_id);
8218 if (!bucket) {
8219 return error::kInvalidArguments;
8220 }
8221 GLsizei count = 0;
8222 std::vector<char*> names;
8223 std::vector<GLint> len;
8224 if (!bucket->GetAsStrings(&count, &names, &len) || count <= 0) {
8225 return error::kInvalidArguments;
8226 }
8227 typedef cmds::GetUniformIndices::Result Result;
8228 Result* result = GetSharedMemoryAs<Result*>(
8229 c.indices_shm_id, c.indices_shm_offset,
8230 Result::ComputeSize(static_cast<size_t>(count)));
8231 GLuint* indices = result ? result->GetData() : NULL;
8232 if (indices == NULL) {
8233 return error::kOutOfBounds;
8234 }
8235 // Check that the client initialized the result.
8236 if (result->size != 0) {
8237 return error::kInvalidArguments;
8238 }
8239 Program* program = GetProgramInfoNotShader(c.program, "glGetUniformIndices");
8240 if (!program) {
8241 return error::kNoError;
8242 }
8243 GLuint service_id = program->service_id();
8244 GLint link_status = GL_FALSE;
8245 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
8246 if (link_status != GL_TRUE) {
8247 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8248 "glGetUniformIndices", "program not linked");
8249 return error::kNoError;
8250 }
8251 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetUniformIndices");
8252 glGetUniformIndices(service_id, count, &names[0], indices);
8253 GLenum error = glGetError();
8254 if (error == GL_NO_ERROR) {
8255 result->SetNumResults(count);
8256 } else {
8257 LOCAL_SET_GL_ERROR(error, "GetUniformIndices", "");
8258 }
8259 return error::kNoError;
8260}
8261
zmo5393fb52015-01-27 01:50:488262error::Error GLES2DecoderImpl::GetFragDataLocationHelper(
8263 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8264 const std::string& name_str) {
8265 GLint* location = GetSharedMemoryAs<GLint*>(
8266 location_shm_id, location_shm_offset, sizeof(GLint));
8267 if (!location) {
8268 return error::kOutOfBounds;
8269 }
8270 // Require the client to init this incase the context is lost and we are no
8271 // longer executing commands.
8272 if (*location != -1) {
8273 return error::kGenericError;
8274 }
8275 Program* program = GetProgramInfoNotShader(
8276 client_id, "glGetFragDataLocation");
8277 if (!program) {
8278 return error::kNoError;
8279 }
8280 *location = glGetFragDataLocation(program->service_id(), name_str.c_str());
8281 return error::kNoError;
8282}
8283
8284error::Error GLES2DecoderImpl::HandleGetFragDataLocation(
8285 uint32 immediate_data_size,
8286 const void* cmd_data) {
8287 if (!unsafe_es3_apis_enabled())
8288 return error::kUnknownCommand;
8289 const gles2::cmds::GetFragDataLocation& c =
8290 *static_cast<const gles2::cmds::GetFragDataLocation*>(cmd_data);
8291 Bucket* bucket = GetBucket(c.name_bucket_id);
8292 if (!bucket) {
8293 return error::kInvalidArguments;
8294 }
8295 std::string name_str;
8296 if (!bucket->GetAsString(&name_str)) {
8297 return error::kInvalidArguments;
8298 }
8299 return GetFragDataLocationHelper(
8300 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8301}
8302
zmo4a16ff992015-02-05 22:18:418303error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex(
8304 uint32 immediate_data_size, const void* cmd_data) {
8305 if (!unsafe_es3_apis_enabled())
8306 return error::kUnknownCommand;
8307 const gles2::cmds::GetUniformBlockIndex& c =
8308 *static_cast<const gles2::cmds::GetUniformBlockIndex*>(cmd_data);
8309 Bucket* bucket = GetBucket(c.name_bucket_id);
8310 if (!bucket) {
8311 return error::kInvalidArguments;
8312 }
8313 std::string name_str;
8314 if (!bucket->GetAsString(&name_str)) {
8315 return error::kInvalidArguments;
8316 }
8317 GLuint* index = GetSharedMemoryAs<GLuint*>(
8318 c.index_shm_id, c.index_shm_offset, sizeof(GLuint));
8319 if (!index) {
8320 return error::kOutOfBounds;
8321 }
8322 // Require the client to init this in case the context is lost and we are no
8323 // longer executing commands.
8324 if (*index != GL_INVALID_INDEX) {
8325 return error::kGenericError;
8326 }
8327 Program* program = GetProgramInfoNotShader(
8328 c.program, "glGetUniformBlockIndex");
8329 if (!program) {
8330 return error::kNoError;
8331 }
8332 *index = glGetUniformBlockIndex(program->service_id(), name_str.c_str());
8333 return error::kNoError;
8334}
8335
vmiuracd108592014-09-08 14:36:348336error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
8337 const void* cmd_data) {
8338 const gles2::cmds::GetString& c =
8339 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:298340 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:058341 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:518342 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:298343 return error::kNoError;
8344 }
[email protected]959e9072013-09-20 16:58:388345 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:048346 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:158347 switch (name) {
8348 case GL_VERSION:
8349 str = "OpenGL ES 2.0 Chromium";
8350 break;
8351 case GL_SHADING_LANGUAGE_VERSION:
8352 str = "OpenGL ES GLSL ES 1.0 Chromium";
8353 break;
[email protected]32939602012-05-09 06:25:168354 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:168355 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:388356 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
8357 // They are used by WEBGL_debug_renderer_info.
8358 if (!force_webgl_glsl_validation_)
8359 str = "Chromium";
[email protected]32939602012-05-09 06:25:168360 break;
[email protected]1958e0e2010-04-22 05:17:158361 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:048362 {
[email protected]70dc60932013-06-04 03:33:498363 // For WebGL contexts, strip out the OES derivatives and
8364 // EXT frag depth extensions if they have not been enabled.
8365 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:048366 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:498367 if (!derivatives_explicitly_enabled_) {
8368 size_t offset = extensions.find(kOESDerivativeExtension);
8369 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098370 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:498371 std::string());
8372 }
8373 }
8374 if (!frag_depth_explicitly_enabled_) {
8375 size_t offset = extensions.find(kEXTFragDepthExtension);
8376 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098377 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:498378 std::string());
8379 }
[email protected]f0d74742011-10-03 16:31:048380 }
[email protected]aff39ac82013-06-08 04:53:138381 if (!draw_buffers_explicitly_enabled_) {
8382 size_t offset = extensions.find(kEXTDrawBuffersExtension);
8383 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098384 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:138385 std::string());
8386 }
8387 }
[email protected]93c2fd82014-04-16 02:46:068388 if (!shader_texture_lod_explicitly_enabled_) {
8389 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
8390 if (std::string::npos != offset) {
8391 extensions.replace(offset,
8392 arraysize(kEXTShaderTextureLodExtension),
8393 std::string());
8394 }
8395 }
[email protected]f0d74742011-10-03 16:31:048396 } else {
[email protected]6f5fac9d12012-06-26 21:02:458397 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:048398 }
[email protected]b381ee32014-03-22 02:43:438399 if (supports_post_sub_buffer_)
8400 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:458401 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:048402 }
[email protected]1958e0e2010-04-22 05:17:158403 break;
8404 default:
[email protected]1958e0e2010-04-22 05:17:158405 break;
8406 }
[email protected]ddd968b82010-03-02 00:44:298407 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:158408 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:298409 return error::kNoError;
8410}
8411
vmiuracd108592014-09-08 14:36:348412error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
8413 const void* cmd_data) {
8414 const gles2::cmds::BufferData& c =
8415 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:118416 GLenum target = static_cast<GLenum>(c.target);
8417 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
8418 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8419 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8420 GLenum usage = static_cast<GLenum>(c.usage);
8421 const void* data = NULL;
8422 if (data_shm_id != 0 || data_shm_offset != 0) {
8423 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
8424 if (!data) {
8425 return error::kOutOfBounds;
8426 }
8427 }
[email protected]0fbba3732013-07-17 15:40:138428 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:148429 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198430}
8431
[email protected]0c86dbf2010-03-05 08:14:118432void GLES2DecoderImpl::DoBufferSubData(
8433 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:138434 // Just delegate it. Some validation is actually done before this.
8435 buffer_manager()->ValidateAndDoBufferSubData(
8436 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:198437}
8438
[email protected]0d6bfdc2011-11-02 01:32:208439bool GLES2DecoderImpl::ClearLevel(
boliu45dc77a2015-02-25 23:26:318440 Texture* texture,
[email protected]0d6bfdc2011-11-02 01:32:208441 unsigned target,
8442 int level,
[email protected]d8e6c9242014-02-20 16:56:258443 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:208444 unsigned format,
8445 unsigned type,
8446 int width,
[email protected]4502e6492011-12-14 19:39:158447 int height,
8448 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:008449 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:008450 if (feature_info_->feature_flags().angle_depth_texture &&
8451 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:008452 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
8453 // on depth formats.
8454 GLuint fb = 0;
8455 glGenFramebuffersEXT(1, &fb);
8456 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
8457
8458 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
8459 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
8460 GL_DEPTH_ATTACHMENT;
8461
boliu45dc77a2015-02-25 23:26:318462 glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, attachment, target,
8463 texture->service_id(), level);
[email protected]81375742012-06-08 00:04:008464 // ANGLE promises a depth only attachment ok.
8465 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8466 GL_FRAMEBUFFER_COMPLETE) {
8467 return false;
8468 }
8469 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:478470 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8471 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008472 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458473 state_.SetDeviceDepthMask(GL_TRUE);
8474 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:008475 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8476
8477 RestoreClearState();
8478
8479 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358480 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008481 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8482 GLuint fb_service_id =
8483 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8484 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8485 return true;
8486 }
8487
[email protected]45d15a62012-04-18 14:33:178488 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8489
8490 uint32 size;
8491 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348492 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428493 width, height, 1, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178494 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208495 return false;
8496 }
[email protected]45d15a62012-04-18 14:33:178497
[email protected]a5d3dad2012-05-26 04:34:448498 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8499
[email protected]45d15a62012-04-18 14:33:178500 int tile_height;
8501
8502 if (size > kMaxZeroSize) {
8503 if (kMaxZeroSize < padded_row_size) {
8504 // That'd be an awfully large texture.
8505 return false;
8506 }
8507 // We should never have a large total size with a zero row size.
8508 DCHECK_GT(padded_row_size, 0U);
8509 tile_height = kMaxZeroSize / padded_row_size;
8510 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428511 width, tile_height, 1, format, type, state_.unpack_alignment, &size,
[email protected]e259eb412012-10-13 05:47:248512 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178513 return false;
8514 }
[email protected]4502e6492011-12-14 19:39:158515 } else {
[email protected]45d15a62012-04-18 14:33:178516 tile_height = height;
8517 }
8518
8519 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558520 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178521 memset(zero.get(), 0, size);
boliu45dc77a2015-02-25 23:26:318522 glBindTexture(texture->target(), texture->service_id());
[email protected]45d15a62012-04-18 14:33:178523
boliu45dc77a2015-02-25 23:26:318524 bool has_images = texture->HasImages();
[email protected]45d15a62012-04-18 14:33:178525 GLint y = 0;
8526 while (y < height) {
8527 GLint h = y + tile_height > height ? height - y : tile_height;
boliu45dc77a2015-02-25 23:26:318528 if (is_texture_immutable || h != height || has_images) {
[email protected]45d15a62012-04-18 14:33:178529 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8530 } else {
[email protected]8f1d2aa2013-05-10 23:45:388531 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258532 target, level, internal_format, width, h, 0, format, type,
8533 zero.get());
[email protected]45d15a62012-04-18 14:33:178534 }
8535 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158536 }
boliu45dc77a2015-02-25 23:26:318537 TextureRef* bound_texture =
8538 texture_manager()->GetTextureInfoForTarget(&state_, texture->target());
8539 glBindTexture(texture->target(),
8540 bound_texture ? bound_texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208541 return true;
8542}
8543
[email protected]ad84a3a2012-06-08 21:42:438544namespace {
8545
8546const int kS3TCBlockWidth = 4;
8547const int kS3TCBlockHeight = 4;
8548const int kS3TCDXT1BlockSize = 8;
8549const int kS3TCDXT3AndDXT5BlockSize = 16;
8550
8551bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518552 return (size == 1) ||
8553 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438554}
8555
[email protected]8aec81ec2014-04-29 01:04:518556bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128557 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518558}
8559
[email protected]ad84a3a2012-06-08 21:42:438560} // anonymous namespace.
8561
8562bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8563 const char* function_name,
8564 GLsizei width, GLsizei height, GLenum format, size_t size) {
8565 unsigned int bytes_required = 0;
8566
8567 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518568 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438569 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518570 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8571 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438572 int num_blocks_across =
8573 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8574 int num_blocks_down =
8575 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8576 int num_blocks = num_blocks_across * num_blocks_down;
8577 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8578 break;
8579 }
[email protected]8aec81ec2014-04-29 01:04:518580 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8581 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438582 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8583 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8584 int num_blocks_across =
8585 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8586 int num_blocks_down =
8587 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8588 int num_blocks = num_blocks_across * num_blocks_down;
8589 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8590 break;
8591 }
[email protected]8aec81ec2014-04-29 01:04:518592 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8593 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8594 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8595 break;
8596 }
8597 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8598 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8599 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078600 break;
8601 }
[email protected]ad84a3a2012-06-08 21:42:438602 default:
[email protected]ab09b612013-03-11 22:11:518603 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438604 return false;
8605 }
8606
8607 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518608 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438609 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8610 return false;
8611 }
8612
8613 return true;
8614}
8615
8616bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8617 const char* function_name,
8618 GLint level, GLsizei width, GLsizei height, GLenum format) {
8619 switch (format) {
8620 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8621 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8622 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8623 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8624 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518625 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438626 GL_INVALID_OPERATION, function_name,
8627 "width or height invalid for level");
8628 return false;
8629 }
8630 return true;
8631 }
[email protected]8aec81ec2014-04-29 01:04:518632 case GL_ATC_RGB_AMD:
8633 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8634 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8635 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078636 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518637 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078638 GL_INVALID_OPERATION, function_name,
8639 "width or height invalid for level");
8640 return false;
8641 }
8642 return true;
[email protected]8aec81ec2014-04-29 01:04:518643 }
8644 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8645 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8646 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8647 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8648 if (!IsValidPVRTCSize(level, width) ||
8649 !IsValidPVRTCSize(level, height)) {
8650 LOCAL_SET_GL_ERROR(
8651 GL_INVALID_OPERATION, function_name,
8652 "width or height invalid for level");
8653 return false;
8654 }
8655 return true;
8656 }
[email protected]ad84a3a2012-06-08 21:42:438657 default:
8658 return false;
8659 }
8660}
8661
8662bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8663 const char* function_name,
8664 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8665 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358666 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438667 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518668 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438669 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8670 return false;
8671 }
8672
8673 switch (format) {
8674 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8675 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8676 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8677 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8678 const int kBlockWidth = 4;
8679 const int kBlockHeight = 4;
8680 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518681 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438682 GL_INVALID_OPERATION, function_name,
8683 "xoffset or yoffset not multiple of 4");
8684 return false;
8685 }
8686 GLsizei tex_width = 0;
8687 GLsizei tex_height = 0;
8688 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8689 width - xoffset > tex_width ||
8690 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518691 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438692 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8693 return false;
8694 }
8695 return ValidateCompressedTexDimensions(
8696 function_name, level, width, height, format);
8697 }
[email protected]8aec81ec2014-04-29 01:04:518698 case GL_ATC_RGB_AMD:
8699 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8700 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8701 LOCAL_SET_GL_ERROR(
8702 GL_INVALID_OPERATION, function_name,
8703 "not supported for ATC textures");
8704 return false;
8705 }
[email protected]2d3765b2012-10-03 00:31:078706 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518707 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078708 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208709 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078710 return false;
8711 }
[email protected]8aec81ec2014-04-29 01:04:518712 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8713 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8714 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8715 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8716 if ((xoffset != 0) || (yoffset != 0)) {
8717 LOCAL_SET_GL_ERROR(
8718 GL_INVALID_OPERATION, function_name,
8719 "xoffset and yoffset must be zero");
8720 return false;
8721 }
8722 GLsizei tex_width = 0;
8723 GLsizei tex_height = 0;
8724 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8725 width != tex_width ||
8726 height != tex_height) {
8727 LOCAL_SET_GL_ERROR(
8728 GL_INVALID_OPERATION, function_name,
8729 "dimensions must match existing texture level dimensions");
8730 return false;
8731 }
8732 return ValidateCompressedTexDimensions(
8733 function_name, level, width, height, format);
8734 }
[email protected]ad84a3a2012-06-08 21:42:438735 default:
8736 return false;
8737 }
8738}
8739
[email protected]a93bb842010-02-16 23:03:478740error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8741 GLenum target,
8742 GLint level,
8743 GLenum internal_format,
8744 GLsizei width,
8745 GLsizei height,
8746 GLint border,
8747 GLsizei image_size,
8748 const void* data) {
[email protected]a93bb842010-02-16 23:03:478749 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058750 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518751 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8752 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298753 return error::kNoError;
8754 }
[email protected]9438b012010-06-15 22:55:058755 if (!validators_->compressed_texture_format.IsValid(
8756 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518757 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538758 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478759 return error::kNoError;
8760 }
[email protected]80eb6b52012-01-19 00:14:418761 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478762 border != 0) {
[email protected]ab09b612013-03-11 22:11:518763 LOCAL_SET_GL_ERROR(
8764 GL_INVALID_VALUE,
8765 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478766 return error::kNoError;
8767 }
[email protected]c986af502013-08-14 01:04:448768 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8769 &state_, target);
[email protected]370eaf12013-05-18 09:19:498770 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518771 LOCAL_SET_GL_ERROR(
8772 GL_INVALID_VALUE,
8773 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478774 return error::kNoError;
8775 }
[email protected]370eaf12013-05-18 09:19:498776 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078777 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518778 LOCAL_SET_GL_ERROR(
8779 GL_INVALID_OPERATION,
8780 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438781 return error::kNoError;
8782 }
8783
8784 if (!ValidateCompressedTexDimensions(
8785 "glCompressedTexImage2D", level, width, height, internal_format) ||
8786 !ValidateCompressedTexFuncData(
8787 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178788 return error::kNoError;
8789 }
[email protected]968351b2011-12-20 08:26:518790
[email protected]7989c9e2013-01-23 06:39:268791 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518792 LOCAL_SET_GL_ERROR(
8793 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268794 return error::kNoError;
8795 }
8796
[email protected]02965c22013-03-09 02:40:078797 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448798 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518799 }
8800
[email protected]40d90a22013-04-09 03:39:558801 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478802 if (!data) {
8803 zero.reset(new int8[image_size]);
8804 memset(zero.get(), 0, image_size);
8805 data = zero.get();
8806 }
[email protected]ab09b612013-03-11 22:11:518807 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478808 glCompressedTexImage2D(
8809 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518810 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438811 if (error == GL_NO_ERROR) {
8812 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498813 texture_ref, target, level, internal_format,
8814 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438815 }
vmiura8266ca72014-09-09 21:37:008816
8817 // This may be a slow command. Exit command processing to allow for
8818 // context preemption and GPU watchdog checks.
8819 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:478820 return error::kNoError;
8821}
8822
[email protected]f7a64ee2010-02-01 22:24:148823error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:348824 uint32 immediate_data_size,
8825 const void* cmd_data) {
8826 const gles2::cmds::CompressedTexImage2D& c =
8827 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198828 GLenum target = static_cast<GLenum>(c.target);
8829 GLint level = static_cast<GLint>(c.level);
8830 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8831 GLsizei width = static_cast<GLsizei>(c.width);
8832 GLsizei height = static_cast<GLsizei>(c.height);
8833 GLint border = static_cast<GLint>(c.border);
8834 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8835 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8836 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8837 const void* data = NULL;
8838 if (data_shm_id != 0 || data_shm_offset != 0) {
8839 data = GetSharedMemoryAs<const void*>(
8840 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468841 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148842 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198843 }
8844 }
[email protected]a93bb842010-02-16 23:03:478845 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198846 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198847}
8848
[email protected]b6140d02010-05-17 14:47:168849error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:348850 uint32 immediate_data_size,
8851 const void* cmd_data) {
8852 const gles2::cmds::CompressedTexImage2DBucket& c =
8853 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168854 GLenum target = static_cast<GLenum>(c.target);
8855 GLint level = static_cast<GLint>(c.level);
8856 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8857 GLsizei width = static_cast<GLsizei>(c.width);
8858 GLsizei height = static_cast<GLsizei>(c.height);
8859 GLint border = static_cast<GLint>(c.border);
8860 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288861 if (!bucket) {
8862 return error::kInvalidArguments;
8863 }
8864 uint32 data_size = bucket->size();
8865 GLsizei imageSize = data_size;
8866 const void* data = bucket->GetData(0, data_size);
8867 if (!data) {
8868 return error::kInvalidArguments;
8869 }
[email protected]b6140d02010-05-17 14:47:168870 return DoCompressedTexImage2D(
8871 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288872 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168873}
8874
8875error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8876 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348877 const void* cmd_data) {
8878 const gles2::cmds::CompressedTexSubImage2DBucket& c =
8879 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168880 GLenum target = static_cast<GLenum>(c.target);
8881 GLint level = static_cast<GLint>(c.level);
8882 GLint xoffset = static_cast<GLint>(c.xoffset);
8883 GLint yoffset = static_cast<GLint>(c.yoffset);
8884 GLsizei width = static_cast<GLsizei>(c.width);
8885 GLsizei height = static_cast<GLsizei>(c.height);
8886 GLenum format = static_cast<GLenum>(c.format);
8887 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288888 if (!bucket) {
8889 return error::kInvalidArguments;
8890 }
[email protected]b6140d02010-05-17 14:47:168891 uint32 data_size = bucket->size();
8892 GLsizei imageSize = data_size;
8893 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288894 if (!data) {
8895 return error::kInvalidArguments;
8896 }
[email protected]9438b012010-06-15 22:55:058897 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518898 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538899 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168900 return error::kNoError;
8901 }
[email protected]9438b012010-06-15 22:55:058902 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518903 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8904 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058905 return error::kNoError;
8906 }
[email protected]b6140d02010-05-17 14:47:168907 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518908 LOCAL_SET_GL_ERROR(
8909 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168910 return error::kNoError;
8911 }
8912 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518913 LOCAL_SET_GL_ERROR(
8914 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168915 return error::kNoError;
8916 }
8917 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518918 LOCAL_SET_GL_ERROR(
8919 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168920 return error::kNoError;
8921 }
[email protected]cadde4a2010-07-31 17:10:438922 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168923 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8924 return error::kNoError;
8925}
8926
vmiuracd108592014-09-08 14:36:348927error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
8928 const void* cmd_data) {
8929 const gles2::cmds::TexImage2D& c =
8930 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138931 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8932 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:448933 // Set as failed for now, but if it successed, this will be set to not failed.
8934 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198935 GLenum target = static_cast<GLenum>(c.target);
8936 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448937 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8938 // for internalformat.
8939 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198940 GLsizei width = static_cast<GLsizei>(c.width);
8941 GLsizei height = static_cast<GLsizei>(c.height);
8942 GLint border = static_cast<GLint>(c.border);
8943 GLenum format = static_cast<GLenum>(c.format);
8944 GLenum type = static_cast<GLenum>(c.type);
8945 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8946 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188947 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348948 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428949 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
8950 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:188951 return error::kOutOfBounds;
8952 }
[email protected]b9849abf2009-11-25 19:13:198953 const void* pixels = NULL;
8954 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8955 pixels = GetSharedMemoryAs<const void*>(
8956 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468957 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148958 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198959 }
8960 }
[email protected]f598f422012-12-07 08:30:038961
[email protected]c986af502013-08-14 01:04:448962 TextureManager::DoTextImage2DArguments args = {
8963 target, level, internal_format, width, height, border, format, type,
8964 pixels, pixels_size};
8965 texture_manager()->ValidateAndDoTexImage2D(
8966 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:008967
8968 // This may be a slow command. Exit command processing to allow for
8969 // context preemption and GPU watchdog checks.
8970 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038971 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198972}
8973
zmobcadd6592015-01-08 20:13:428974error::Error GLES2DecoderImpl::HandleTexImage3D(uint32 immediate_data_size,
8975 const void* cmd_data) {
8976 // TODO(zmo): Unsafe ES3 API.
8977 if (!unsafe_es3_apis_enabled())
8978 return error::kUnknownCommand;
8979
8980 const gles2::cmds::TexImage3D& c =
8981 *static_cast<const gles2::cmds::TexImage3D*>(cmd_data);
8982 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage3D",
8983 "widthXheight", c.width * c.height, "depth", c.depth);
8984 GLenum target = static_cast<GLenum>(c.target);
8985 GLint level = static_cast<GLint>(c.level);
8986 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8987 GLsizei width = static_cast<GLsizei>(c.width);
8988 GLsizei height = static_cast<GLsizei>(c.height);
8989 GLsizei depth = static_cast<GLsizei>(c.depth);
8990 GLint border = static_cast<GLint>(c.border);
8991 GLenum format = static_cast<GLenum>(c.format);
8992 GLenum type = static_cast<GLenum>(c.type);
8993 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8994 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
8995 uint32 pixels_size;
8996 if (!GLES2Util::ComputeImageDataSizes(
8997 width, height, depth, format, type, state_.unpack_alignment, &pixels_size,
8998 NULL, NULL)) {
8999 return error::kOutOfBounds;
9000 }
9001 const void* pixels = NULL;
9002 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
9003 pixels = GetSharedMemoryAs<const void*>(
9004 pixels_shm_id, pixels_shm_offset, pixels_size);
9005 if (!pixels) {
9006 return error::kOutOfBounds;
9007 }
9008 }
9009
9010 glTexImage3D(target, level, internal_format, width, height, depth, border,
9011 format, type, pixels);
9012
9013 // This may be a slow command. Exit command processing to allow for
9014 // context preemption and GPU watchdog checks.
9015 ExitCommandProcessingEarly();
9016 return error::kNoError;
9017}
9018
[email protected]cadde4a2010-07-31 17:10:439019void GLES2DecoderImpl::DoCompressedTexSubImage2D(
9020 GLenum target,
9021 GLint level,
9022 GLint xoffset,
9023 GLint yoffset,
9024 GLsizei width,
9025 GLsizei height,
9026 GLenum format,
9027 GLsizei image_size,
9028 const void * data) {
[email protected]c986af502013-08-14 01:04:449029 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9030 &state_, target);
[email protected]370eaf12013-05-18 09:19:499031 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519032 LOCAL_SET_GL_ERROR(
9033 GL_INVALID_OPERATION,
9034 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439035 return;
9036 }
[email protected]370eaf12013-05-18 09:19:499037 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:439038 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:529039 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079040 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519041 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:529042 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439043 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:529044 return;
9045 }
9046 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:519047 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:529048 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439049 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:529050 return;
9051 }
[email protected]02965c22013-03-09 02:40:079052 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529053 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519054 LOCAL_SET_GL_ERROR(
9055 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:439056 return;
9057 }
[email protected]ad84a3a2012-06-08 21:42:439058
9059 if (!ValidateCompressedTexFuncData(
9060 "glCompressedTexSubImage2D", width, height, format, image_size) ||
9061 !ValidateCompressedTexSubDimensions(
9062 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:079063 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:439064 return;
9065 }
9066
9067
[email protected]0d6bfdc2011-11-02 01:32:209068 // Note: There is no need to deal with texture cleared tracking here
9069 // because the validation above means you can only get here if the level
9070 // is already a matching compressed format and in that case
9071 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:439072 glCompressedTexSubImage2D(
9073 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:009074
9075 // This may be a slow command. Exit command processing to allow for
9076 // context preemption and GPU watchdog checks.
9077 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439078}
9079
[email protected]6e288612010-12-21 20:45:039080static void Clip(
9081 GLint start, GLint range, GLint sourceRange,
9082 GLint* out_start, GLint* out_range) {
9083 DCHECK(out_start);
9084 DCHECK(out_range);
9085 if (start < 0) {
9086 range += start;
9087 start = 0;
9088 }
9089 GLint end = start + range;
9090 if (end > sourceRange) {
9091 range -= end - sourceRange;
9092 }
9093 *out_start = start;
9094 *out_range = range;
9095}
9096
[email protected]cadde4a2010-07-31 17:10:439097void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:449098 GLenum target,
9099 GLint level,
9100 GLenum internal_format,
9101 GLint x,
9102 GLint y,
9103 GLsizei width,
9104 GLsizei height,
9105 GLint border) {
[email protected]09e17272012-11-30 10:30:449106 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449107 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9108 &state_, target);
[email protected]370eaf12013-05-18 09:19:499109 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519110 LOCAL_SET_GL_ERROR(
9111 GL_INVALID_OPERATION,
9112 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439113 return;
9114 }
[email protected]370eaf12013-05-18 09:19:499115 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079116 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519117 LOCAL_SET_GL_ERROR(
9118 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:539119 return;
[email protected]97dc7cbe2011-12-06 17:26:179120 }
[email protected]80eb6b52012-01-19 00:14:419121 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:189122 border != 0) {
[email protected]ab09b612013-03-11 22:11:519123 LOCAL_SET_GL_ERROR(
9124 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:189125 return;
9126 }
[email protected]17a961192014-02-14 15:20:529127 if (!texture_manager()->ValidateFormatAndTypeCombination(
9128 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
9129 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:009130 return;
9131 }
[email protected]f5719fb2010-08-04 18:27:189132
[email protected]9edc6b22010-12-23 02:00:269133 // Check we have compatible formats.
9134 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9135 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9136 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
9137
9138 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519139 LOCAL_SET_GL_ERROR(
9140 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269141 return;
9142 }
9143
[email protected]81375742012-06-08 00:04:009144 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519145 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009146 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:269147 "glCopyTexImage2D", "can not be used with depth or stencil textures");
9148 return;
9149 }
9150
9151 uint32 estimated_size = 0;
9152 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429153 width, height, 1, internal_format, GL_UNSIGNED_BYTE,
9154 state_.unpack_alignment, &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519155 LOCAL_SET_GL_ERROR(
9156 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269157 return;
9158 }
9159
9160 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519161 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:009162 return;
9163 }
9164
[email protected]2ea5950d2014-07-09 18:20:349165 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
9166 return;
9167 }
9168
zmo383512cf2014-10-14 00:11:009169 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9170 LOCAL_SET_GL_ERROR(
9171 GL_INVALID_OPERATION,
9172 "glCopyTexImage2D", "source and destination textures are the same");
9173 return;
9174 }
9175
[email protected]a0b78dc2011-11-11 10:43:109176 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
9177 return;
9178 }
9179
[email protected]ab09b612013-03-11 22:11:519180 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:279181 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039182 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:269183
[email protected]02965c22013-03-09 02:40:079184 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:449185 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:469186 }
9187
[email protected]9edc6b22010-12-23 02:00:269188 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:039189 GLint copyX = 0;
9190 GLint copyY = 0;
9191 GLint copyWidth = 0;
9192 GLint copyHeight = 0;
9193 Clip(x, width, size.width(), &copyX, &copyWidth);
9194 Clip(y, height, size.height(), &copyY, &copyHeight);
9195
9196 if (copyX != x ||
9197 copyY != y ||
9198 copyWidth != width ||
9199 copyHeight != height) {
9200 // some part was clipped so clear the texture.
boliu45dc77a2015-02-25 23:26:319201 if (!ClearLevel(texture, target, level, internal_format, internal_format,
9202 GL_UNSIGNED_BYTE, width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:519203 LOCAL_SET_GL_ERROR(
9204 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:039205 return;
9206 }
[email protected]6e288612010-12-21 20:45:039207 if (copyHeight > 0 && copyWidth > 0) {
9208 GLint dx = copyX - x;
9209 GLint dy = copyY - y;
9210 GLint destX = dx;
9211 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:379212 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039213 glCopyTexSubImage2D(target, level,
9214 destX, destY, copyX, copyY,
9215 copyWidth, copyHeight);
9216 }
9217 } else {
[email protected]00c2cf92014-03-14 00:08:379218 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039219 glCopyTexImage2D(target, level, internal_format,
9220 copyX, copyY, copyWidth, copyHeight, border);
9221 }
[email protected]ab09b612013-03-11 22:11:519222 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:439223 if (error == GL_NO_ERROR) {
9224 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499225 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:209226 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:439227 }
vmiura8266ca72014-09-09 21:37:009228
9229 // This may be a slow command. Exit command processing to allow for
9230 // context preemption and GPU watchdog checks.
9231 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439232}
9233
9234void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:449235 GLenum target,
9236 GLint level,
9237 GLint xoffset,
9238 GLint yoffset,
9239 GLint x,
9240 GLint y,
9241 GLsizei width,
9242 GLsizei height) {
[email protected]09e17272012-11-30 10:30:449243 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449244 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9245 &state_, target);
[email protected]370eaf12013-05-18 09:19:499246 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519247 LOCAL_SET_GL_ERROR(
9248 GL_INVALID_OPERATION,
9249 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439250 return;
9251 }
[email protected]370eaf12013-05-18 09:19:499252 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:439253 GLenum type = 0;
9254 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:079255 if (!texture->GetLevelType(target, level, &type, &format) ||
9256 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529257 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519258 LOCAL_SET_GL_ERROR(
9259 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:439260 return;
9261 }
[email protected]85a4ac22013-05-31 01:58:479262 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519263 LOCAL_SET_GL_ERROR(
9264 GL_INVALID_OPERATION,
9265 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599266 return;
9267 }
[email protected]9edc6b22010-12-23 02:00:269268
9269 // Check we have compatible formats.
9270 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9271 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9272 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
9273
[email protected]2d3765b2012-10-03 00:31:079274 if (!channels_needed ||
9275 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519276 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439277 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269278 return;
9279 }
9280
[email protected]81375742012-06-08 00:04:009281 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519282 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009283 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439284 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:009285 return;
9286 }
9287
[email protected]2ea5950d2014-07-09 18:20:349288 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
9289 return;
9290 }
9291
zmo383512cf2014-10-14 00:11:009292 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9293 LOCAL_SET_GL_ERROR(
9294 GL_INVALID_OPERATION,
9295 "glCopyTexSubImage2D", "source and destination textures are the same");
9296 return;
9297 }
9298
[email protected]a0b78dc2011-11-11 10:43:109299 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
9300 return;
9301 }
9302
[email protected]de26b3c2011-08-03 21:54:279303 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039304 gfx::Size size = GetBoundReadFrameBufferSize();
9305 GLint copyX = 0;
9306 GLint copyY = 0;
9307 GLint copyWidth = 0;
9308 GLint copyHeight = 0;
9309 Clip(x, width, size.width(), &copyX, &copyWidth);
9310 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:209311
dongseong.hwang351519f2015-01-21 14:33:599312 if (xoffset != 0 || yoffset != 0 || width != size.width() ||
9313 height != size.height()) {
9314 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
9315 level)) {
9316 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D",
9317 "dimensions too big");
9318 return;
9319 }
9320 } else {
9321 // Write all pixels in below.
9322 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]0d6bfdc2011-11-02 01:32:209323 }
9324
[email protected]6e288612010-12-21 20:45:039325 if (copyX != x ||
9326 copyY != y ||
9327 copyWidth != width ||
9328 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:209329 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:039330 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:349331 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429332 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:249333 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519334 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439335 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:039336 return;
9337 }
[email protected]40d90a22013-04-09 03:39:559338 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:039339 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:379340 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039341 glTexSubImage2D(
9342 target, level, xoffset, yoffset, width, height,
9343 format, type, zero.get());
9344 }
[email protected]0d6bfdc2011-11-02 01:32:209345
[email protected]6e288612010-12-21 20:45:039346 if (copyHeight > 0 && copyWidth > 0) {
9347 GLint dx = copyX - x;
9348 GLint dy = copyY - y;
9349 GLint destX = xoffset + dx;
9350 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:379351 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039352 glCopyTexSubImage2D(target, level,
9353 destX, destY, copyX, copyY,
9354 copyWidth, copyHeight);
9355 }
vmiura8266ca72014-09-09 21:37:009356
9357 // This may be a slow command. Exit command processing to allow for
9358 // context preemption and GPU watchdog checks.
9359 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439360}
9361
[email protected]f598f422012-12-07 08:30:039362bool GLES2DecoderImpl::ValidateTexSubImage2D(
9363 error::Error* error,
9364 const char* function_name,
9365 GLenum target,
9366 GLint level,
9367 GLint xoffset,
9368 GLint yoffset,
9369 GLsizei width,
9370 GLsizei height,
9371 GLenum format,
9372 GLenum type,
9373 const void * data) {
9374 (*error) = error::kNoError;
9375 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:519376 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:039377 return false;
9378 }
9379 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:519380 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:039381 return false;
9382 }
9383 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:519384 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:039385 return false;
9386 }
[email protected]c986af502013-08-14 01:04:449387 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9388 &state_, target);
[email protected]370eaf12013-05-18 09:19:499389 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519390 LOCAL_SET_GL_ERROR(
9391 GL_INVALID_OPERATION,
9392 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:039393 return false;
[email protected]cadde4a2010-07-31 17:10:439394 }
[email protected]370eaf12013-05-18 09:19:499395 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:529396 GLenum current_type = 0;
9397 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079398 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519399 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:039400 GL_INVALID_OPERATION, function_name, "level does not exist.");
9401 return false;
[email protected]df6cf1ad2011-01-29 01:20:529402 }
[email protected]17a961192014-02-14 15:20:529403 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
9404 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:039405 return false;
[email protected]df6cf1ad2011-01-29 01:20:529406 }
9407 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:519408 LOCAL_SET_GL_ERROR(
9409 GL_INVALID_OPERATION,
9410 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:039411 return false;
[email protected]df6cf1ad2011-01-29 01:20:529412 }
[email protected]85a4ac22013-05-31 01:58:479413 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519414 LOCAL_SET_GL_ERROR(
9415 GL_INVALID_OPERATION,
9416 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599417 return false;
9418 }
[email protected]02965c22013-03-09 02:40:079419 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529420 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519421 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:039422 return false;
[email protected]cadde4a2010-07-31 17:10:439423 }
[email protected]81375742012-06-08 00:04:009424 if ((GLES2Util::GetChannelsForFormat(format) &
9425 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519426 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009427 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:039428 function_name, "can not supply data for depth or stencil textures");
9429 return false;
[email protected]81375742012-06-08 00:04:009430 }
[email protected]f598f422012-12-07 08:30:039431 if (data == NULL) {
9432 (*error) = error::kOutOfBounds;
9433 return false;
9434 }
9435 return true;
9436}
[email protected]81375742012-06-08 00:04:009437
[email protected]f598f422012-12-07 08:30:039438error::Error GLES2DecoderImpl::DoTexSubImage2D(
9439 GLenum target,
9440 GLint level,
9441 GLint xoffset,
9442 GLint yoffset,
9443 GLsizei width,
9444 GLsizei height,
9445 GLenum format,
9446 GLenum type,
9447 const void * data) {
9448 error::Error error = error::kNoError;
9449 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
9450 xoffset, yoffset, width, height, format, type, data)) {
9451 return error;
9452 }
[email protected]c986af502013-08-14 01:04:449453 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9454 &state_, target);
[email protected]370eaf12013-05-18 09:19:499455 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:159456 GLsizei tex_width = 0;
9457 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:079458 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:159459 DCHECK(ok);
9460 if (xoffset != 0 || yoffset != 0 ||
9461 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:499462 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
9463 target, level)) {
[email protected]ab09b612013-03-11 22:11:519464 LOCAL_SET_GL_ERROR(
9465 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:039466 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:309467 }
[email protected]c986af502013-08-14 01:04:449468 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159469 glTexSubImage2D(
9470 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:039471 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:209472 }
[email protected]4502e6492011-12-14 19:39:159473
[email protected]345ba902013-11-14 21:39:009474 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
boliu45dc77a2015-02-25 23:26:319475 !texture->IsImmutable() &&
9476 !texture->HasImages()) {
[email protected]c986af502013-08-14 01:04:449477 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:259478 GLenum internal_format;
9479 GLenum tex_type;
9480 texture->GetLevelType(target, level, &tex_type, &internal_format);
9481 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
9482 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:389483 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:259484 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:159485 } else {
[email protected]c986af502013-08-14 01:04:449486 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159487 glTexSubImage2D(
9488 target, level, xoffset, yoffset, width, height, format, type, data);
9489 }
[email protected]370eaf12013-05-18 09:19:499490 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:009491
9492 // This may be a slow command. Exit command processing to allow for
9493 // context preemption and GPU watchdog checks.
9494 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039495 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:439496}
9497
vmiuracd108592014-09-08 14:36:349498error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
9499 const void* cmd_data) {
9500 const gles2::cmds::TexSubImage2D& c =
9501 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139502 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
9503 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:009504 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:449505 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:009506 return error::kNoError;
9507
9508 GLenum target = static_cast<GLenum>(c.target);
9509 GLint level = static_cast<GLint>(c.level);
9510 GLint xoffset = static_cast<GLint>(c.xoffset);
9511 GLint yoffset = static_cast<GLint>(c.yoffset);
9512 GLsizei width = static_cast<GLsizei>(c.width);
9513 GLsizei height = static_cast<GLsizei>(c.height);
9514 GLenum format = static_cast<GLenum>(c.format);
9515 GLenum type = static_cast<GLenum>(c.type);
9516 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:349517 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429518 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]e259eb412012-10-13 05:47:249519 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:009520 return error::kOutOfBounds;
9521 }
9522 const void* pixels = GetSharedMemoryAs<const void*>(
9523 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:039524 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:009525 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:009526}
9527
zmobcadd6592015-01-08 20:13:429528// TODO(zmo): Remove the below stub once we add the real function binding.
9529// Currently it's missing due to a gmock limitation.
9530static void glTexSubImage3D(
9531 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
9532 GLsizei height, GLsizei width, GLsizei depth, GLenum format, GLenum type,
9533 const void* pixels) {
9534 NOTIMPLEMENTED();
9535}
9536
9537error::Error GLES2DecoderImpl::HandleTexSubImage3D(uint32 immediate_data_size,
9538 const void* cmd_data) {
9539 // TODO(zmo): Unsafe ES3 API.
9540 if (!unsafe_es3_apis_enabled())
9541 return error::kUnknownCommand;
9542
9543 const gles2::cmds::TexSubImage3D& c =
9544 *static_cast<const gles2::cmds::TexSubImage3D*>(cmd_data);
9545 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage3D",
9546 "widthXheight", c.width * c.height, "depth", c.depth);
9547 GLenum target = static_cast<GLenum>(c.target);
9548 GLint level = static_cast<GLint>(c.level);
9549 GLint xoffset = static_cast<GLint>(c.xoffset);
9550 GLint yoffset = static_cast<GLint>(c.yoffset);
9551 GLint zoffset = static_cast<GLint>(c.zoffset);
9552 GLsizei width = static_cast<GLsizei>(c.width);
9553 GLsizei height = static_cast<GLsizei>(c.height);
9554 GLsizei depth = static_cast<GLsizei>(c.depth);
9555 GLenum format = static_cast<GLenum>(c.format);
9556 GLenum type = static_cast<GLenum>(c.type);
9557 uint32 data_size;
9558 if (!GLES2Util::ComputeImageDataSizes(
9559 width, height, depth, format, type, state_.unpack_alignment, &data_size,
9560 NULL, NULL)) {
9561 return error::kOutOfBounds;
9562 }
9563 const void* pixels = GetSharedMemoryAs<const void*>(
9564 c.pixels_shm_id, c.pixels_shm_offset, data_size);
9565 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
9566 depth, format, type, pixels);
9567 return error::kNoError;
9568}
9569
[email protected]f7a64ee2010-02-01 22:24:149570error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349571 uint32 immediate_data_size,
9572 const void* cmd_data) {
9573 const gles2::cmds::GetVertexAttribPointerv& c =
9574 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369575 GLuint index = static_cast<GLuint>(c.index);
9576 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359577 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259578 Result* result = GetSharedMemoryAs<Result*>(
9579 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369580 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149581 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369582 }
[email protected]07d0cc82010-02-17 04:51:409583 // Check that the client initialized the result.
9584 if (result->size != 0) {
9585 return error::kInvalidArguments;
9586 }
[email protected]9438b012010-06-15 22:55:059587 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519588 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9589 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149590 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369591 }
[email protected]3916c97e2010-02-25 03:20:509592 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519593 LOCAL_SET_GL_ERROR(
9594 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149595 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369596 }
[email protected]0bfd9882010-02-05 23:02:259597 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089598 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359599 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149600 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329601}
9602
[email protected]f7b85372010-02-03 01:11:379603bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:429604 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:379605 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:129606 error::Error* error, GLint* real_location,
9607 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:109608 DCHECK(error);
9609 DCHECK(service_id);
9610 DCHECK(result_pointer);
9611 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129612 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379613 *error = error::kNoError;
9614 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259615 SizedResult<GLint>* result;
9616 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9617 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9618 if (!result) {
[email protected]f7b85372010-02-03 01:11:379619 *error = error::kOutOfBounds;
9620 return false;
9621 }
[email protected]0bfd9882010-02-05 23:02:259622 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379623 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259624 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429625 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9626 if (!program) {
[email protected]ae51d192010-04-27 00:48:039627 return false;
9628 }
[email protected]df37b9932013-03-08 05:21:429629 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379630 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519631 LOCAL_SET_GL_ERROR(
9632 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379633 return false;
9634 }
[email protected]df37b9932013-03-08 05:21:429635 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369636 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359637 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429638 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129639 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369640 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379641 // No such location.
[email protected]ab09b612013-03-11 22:11:519642 LOCAL_SET_GL_ERROR(
9643 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379644 return false;
9645 }
[email protected]43c2f1f2011-03-25 18:35:369646 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509647 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379648 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519649 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379650 return false;
9651 }
[email protected]0bfd9882010-02-05 23:02:259652 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9653 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9654 if (!result) {
[email protected]f7b85372010-02-03 01:11:379655 *error = error::kOutOfBounds;
9656 return false;
9657 }
[email protected]0bfd9882010-02-05 23:02:259658 result->size = size;
[email protected]939e7362010-05-13 20:49:109659 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379660 return true;
9661}
9662
vmiuracd108592014-09-08 14:36:349663error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9664 const void* cmd_data) {
9665 const gles2::cmds::GetUniformiv& c =
9666 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379667 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339668 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379669 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109670 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:129671 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379672 Error error;
[email protected]0bfd9882010-02-05 23:02:259673 void* result;
[email protected]f7b85372010-02-03 01:11:379674 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129675 program, fake_location, c.params_shm_id, c.params_shm_offset,
9676 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:259677 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129678 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359679 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379680 }
9681 return error;
[email protected]96449d2c2009-11-25 00:01:329682}
9683
vmiuracd108592014-09-08 14:36:349684error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9685 const void* cmd_data) {
9686 const gles2::cmds::GetUniformfv& c =
9687 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379688 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339689 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379690 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129691 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379692 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359693 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109694 Result* result;
9695 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:379696 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129697 program, fake_location, c.params_shm_id, c.params_shm_offset,
9698 &error, &real_location, &service_id,
9699 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:109700 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9701 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
9702 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:559703 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129704 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109705 GLfloat* dst = result->GetData();
9706 for (GLsizei ii = 0; ii < num_values; ++ii) {
9707 dst[ii] = (temp[ii] != 0);
9708 }
9709 } else {
[email protected]1b0a6752012-02-22 03:44:129710 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109711 }
[email protected]f7b85372010-02-03 01:11:379712 }
9713 return error;
[email protected]96449d2c2009-11-25 00:01:329714}
9715
[email protected]f7a64ee2010-02-01 22:24:149716error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349717 uint32 immediate_data_size,
9718 const void* cmd_data) {
9719 const gles2::cmds::GetShaderPrecisionFormat& c =
9720 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259721 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9722 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359723 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259724 Result* result = GetSharedMemoryAs<Result*>(
9725 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9726 if (!result) {
9727 return error::kOutOfBounds;
9728 }
[email protected]07d0cc82010-02-17 04:51:409729 // Check that the client initialized the result.
9730 if (result->success != 0) {
9731 return error::kInvalidArguments;
9732 }
[email protected]9438b012010-06-15 22:55:059733 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519734 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539735 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299736 return error::kNoError;
9737 }
[email protected]9438b012010-06-15 22:55:059738 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519739 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539740 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299741 return error::kNoError;
9742 }
9743
9744 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409745
[email protected]46c86752013-05-21 05:08:399746 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409747 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219748 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409749
9750 result->min_range = range[0];
9751 result->max_range = range[1];
9752 result->precision = precision;
9753
[email protected]f7a64ee2010-02-01 22:24:149754 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329755}
9756
[email protected]f7a64ee2010-02-01 22:24:149757error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349758 uint32 immediate_data_size,
9759 const void* cmd_data) {
9760 const gles2::cmds::GetAttachedShaders& c =
9761 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259762 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429763 GLuint program_id = static_cast<GLuint>(c.program);
9764 Program* program = GetProgramInfoNotShader(
9765 program_id, "glGetAttachedShaders");
9766 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259767 return error::kNoError;
9768 }
[email protected]ed9f9cd2013-02-27 21:12:359769 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259770 uint32 max_count = Result::ComputeMaxResults(result_size);
9771 Result* result = GetSharedMemoryAs<Result*>(
9772 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9773 if (!result) {
9774 return error::kOutOfBounds;
9775 }
[email protected]07d0cc82010-02-17 04:51:409776 // Check that the client initialized the result.
9777 if (result->size != 0) {
9778 return error::kInvalidArguments;
9779 }
[email protected]0bfd9882010-02-05 23:02:259780 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039781 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429782 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259783 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039784 if (!shader_manager()->GetClientId(result->GetData()[ii],
9785 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259786 NOTREACHED();
9787 return error::kGenericError;
9788 }
9789 }
9790 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149791 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329792}
9793
[email protected]f7a64ee2010-02-01 22:24:149794error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349795 uint32 immediate_data_size,
9796 const void* cmd_data) {
9797 const gles2::cmds::GetActiveUniform& c =
9798 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429799 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259800 GLuint index = c.index;
9801 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359802 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259803 Result* result = GetSharedMemoryAs<Result*>(
9804 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9805 if (!result) {
9806 return error::kOutOfBounds;
9807 }
[email protected]07d0cc82010-02-17 04:51:409808 // Check that the client initialized the result.
9809 if (result->success != 0) {
9810 return error::kInvalidArguments;
9811 }
[email protected]df37b9932013-03-08 05:21:429812 Program* program = GetProgramInfoNotShader(
9813 program_id, "glGetActiveUniform");
9814 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259815 return error::kNoError;
9816 }
[email protected]ed9f9cd2013-02-27 21:12:359817 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429818 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:259819 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:519820 LOCAL_SET_GL_ERROR(
9821 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259822 return error::kNoError;
9823 }
9824 result->success = 1; // true.
9825 result->size = uniform_info->size;
9826 result->type = uniform_info->type;
9827 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299828 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149829 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329830}
9831
zmoa2b555d2015-02-06 23:50:399832error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockiv(
9833 uint32 immediate_data_size, const void* cmd_data) {
9834 if (!unsafe_es3_apis_enabled())
9835 return error::kUnknownCommand;
9836 const gles2::cmds::GetActiveUniformBlockiv& c =
9837 *static_cast<const gles2::cmds::GetActiveUniformBlockiv*>(cmd_data);
9838 GLuint program_id = c.program;
9839 GLuint index = static_cast<GLuint>(c.index);
9840 GLenum pname = static_cast<GLenum>(c.pname);
9841 Program* program = GetProgramInfoNotShader(
zmo8fab00c2015-02-07 02:45:059842 program_id, "glGetActiveUniformBlockiv");
zmoa2b555d2015-02-06 23:50:399843 if (!program) {
9844 return error::kNoError;
9845 }
9846 GLuint service_id = program->service_id();
9847 GLint link_status = GL_FALSE;
9848 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
9849 if (link_status != GL_TRUE) {
9850 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9851 "glGetActiveActiveUniformBlockiv", "program not linked");
9852 return error::kNoError;
9853 }
9854 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformBlockiv");
9855 GLsizei num_values = 1;
9856 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
9857 GLint num = 0;
9858 glGetActiveUniformBlockiv(
9859 service_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &num);
9860 GLenum error = glGetError();
9861 if (error != GL_NO_ERROR) {
9862 // Assume this will the same error if calling with pname.
9863 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
9864 return error::kNoError;
9865 }
9866 num_values = static_cast<GLsizei>(num);
9867 }
9868 typedef cmds::GetActiveUniformBlockiv::Result Result;
9869 Result* result = GetSharedMemoryAs<Result*>(
9870 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
9871 GLint* params = result ? result->GetData() : NULL;
9872 if (params == NULL) {
9873 return error::kOutOfBounds;
9874 }
9875 // Check that the client initialized the result.
9876 if (result->size != 0) {
9877 return error::kInvalidArguments;
9878 }
9879 glGetActiveUniformBlockiv(service_id, index, pname, params);
9880 GLenum error = glGetError();
9881 if (error == GL_NO_ERROR) {
9882 result->SetNumResults(num_values);
9883 } else {
9884 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
9885 }
9886 return error::kNoError;
9887}
9888
zmo4a16ff992015-02-05 22:18:419889error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockName(
9890 uint32 immediate_data_size, const void* cmd_data) {
9891 if (!unsafe_es3_apis_enabled())
9892 return error::kUnknownCommand;
9893 const gles2::cmds::GetActiveUniformBlockName& c =
9894 *static_cast<const gles2::cmds::GetActiveUniformBlockName*>(cmd_data);
9895 GLuint program_id = c.program;
9896 GLuint index = c.index;
9897 uint32 name_bucket_id = c.name_bucket_id;
9898 typedef cmds::GetActiveUniformBlockName::Result Result;
9899 Result* result = GetSharedMemoryAs<Result*>(
9900 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9901 if (!result) {
9902 return error::kOutOfBounds;
9903 }
9904 // Check that the client initialized the result.
9905 if (*result != 0) {
9906 return error::kInvalidArguments;
9907 }
9908 Program* program = GetProgramInfoNotShader(
9909 program_id, "glGetActiveUniformBlockName");
9910 if (!program) {
9911 return error::kNoError;
9912 }
9913 GLuint service_id = program->service_id();
9914 GLint link_status = GL_FALSE;
9915 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
9916 if (link_status != GL_TRUE) {
9917 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9918 "glGetActiveActiveUniformBlockName", "program not linked");
9919 return error::kNoError;
9920 }
9921 GLint max_length = 0;
9922 glGetProgramiv(
9923 service_id, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_length);
9924 // Increase one so &buffer[0] is always valid.
9925 GLsizei buf_size = static_cast<GLsizei>(max_length) + 1;
9926 std::vector<char> buffer(buf_size);
9927 GLsizei length = 0;
9928 glGetActiveUniformBlockName(
9929 service_id, index, buf_size, &length, &buffer[0]);
9930 if (length == 0) {
9931 *result = 0;
9932 return error::kNoError;
9933 }
9934 *result = 1;
9935 Bucket* bucket = CreateBucket(name_bucket_id);
9936 DCHECK_GT(buf_size, length);
9937 DCHECK_EQ(0, buffer[length]);
9938 bucket->SetFromString(&buffer[0]);
9939 return error::kNoError;
9940}
9941
zmoc7e7e13f2015-02-17 22:07:079942error::Error GLES2DecoderImpl::HandleGetActiveUniformsiv(
9943 uint32 immediate_data_size, const void* cmd_data) {
9944 if (!unsafe_es3_apis_enabled())
9945 return error::kUnknownCommand;
9946 const gles2::cmds::GetActiveUniformsiv& c =
9947 *static_cast<const gles2::cmds::GetActiveUniformsiv*>(cmd_data);
9948 GLuint program_id = c.program;
9949 GLenum pname = static_cast<GLenum>(c.pname);
9950 Bucket* bucket = GetBucket(c.indices_bucket_id);
9951 if (!bucket) {
9952 return error::kInvalidArguments;
9953 }
9954 GLsizei count = static_cast<GLsizei>(bucket->size() / sizeof(GLuint));
9955 const GLuint* indices = bucket->GetDataAs<const GLuint*>(0, bucket->size());
9956 typedef cmds::GetActiveUniformsiv::Result Result;
9957 Result* result = GetSharedMemoryAs<Result*>(
9958 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(count));
9959 GLint* params = result ? result->GetData() : NULL;
9960 if (params == NULL) {
9961 return error::kOutOfBounds;
9962 }
9963 // Check that the client initialized the result.
9964 if (result->size != 0) {
9965 return error::kInvalidArguments;
9966 }
9967 Program* program = GetProgramInfoNotShader(
9968 program_id, "glGetActiveUniformsiv");
9969 if (!program) {
9970 return error::kNoError;
9971 }
9972 GLuint service_id = program->service_id();
9973 GLint link_status = GL_FALSE;
9974 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
9975 if (link_status != GL_TRUE) {
9976 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9977 "glGetActiveUniformsiv", "program not linked");
9978 return error::kNoError;
9979 }
9980 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformsiv");
9981 glGetActiveUniformsiv(service_id, count, indices, pname, params);
9982 GLenum error = glGetError();
9983 if (error == GL_NO_ERROR) {
9984 result->SetNumResults(count);
9985 } else {
9986 LOCAL_SET_GL_ERROR(error, "GetActiveUniformsiv", "");
9987 }
9988 return error::kNoError;
9989}
9990
vmiuracd108592014-09-08 14:36:349991error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
9992 const void* cmd_data) {
9993 const gles2::cmds::GetActiveAttrib& c =
9994 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429995 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259996 GLuint index = c.index;
9997 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359998 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:259999 Result* result = GetSharedMemoryAs<Result*>(
10000 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10001 if (!result) {
10002 return error::kOutOfBounds;
10003 }
[email protected]07d0cc82010-02-17 04:51:4010004 // Check that the client initialized the result.
10005 if (result->success != 0) {
10006 return error::kInvalidArguments;
10007 }
[email protected]df37b9932013-03-08 05:21:4210008 Program* program = GetProgramInfoNotShader(
10009 program_id, "glGetActiveAttrib");
10010 if (!program) {
[email protected]0bfd9882010-02-05 23:02:2510011 return error::kNoError;
10012 }
[email protected]ed9f9cd2013-02-27 21:12:3510013 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:4210014 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:2510015 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:5110016 LOCAL_SET_GL_ERROR(
10017 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:2510018 return error::kNoError;
10019 }
10020 result->success = 1; // true.
10021 result->size = attrib_info->size;
10022 result->type = attrib_info->type;
10023 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:2910024 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:1410025 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:3210026}
10027
vmiuracd108592014-09-08 14:36:3410028error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
10029 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:5810030#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:5110031 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:5810032 return error::kNoError;
10033#else
10034 GLsizei n = static_cast<GLsizei>(c.n);
10035 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:5110036 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:5810037 return error::kNoError;
10038 }
10039 GLsizei length = static_cast<GLsizei>(c.length);
10040 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:5110041 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:5810042 return error::kNoError;
10043 }
10044 uint32 data_size;
10045 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
10046 return error::kOutOfBounds;
10047 }
10048 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
10049 c.shaders_shm_id, c.shaders_shm_offset, data_size);
10050 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
10051 const void* binary = GetSharedMemoryAs<const void*>(
10052 c.binary_shm_id, c.binary_shm_offset, length);
10053 if (shaders == NULL || binary == NULL) {
10054 return error::kOutOfBounds;
10055 }
[email protected]0782b14b2014-05-24 13:04:1610056 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:5810057 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:4210058 Shader* shader = GetShader(shaders[ii]);
10059 if (!shader) {
[email protected]ab09b612013-03-11 22:11:5110060 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:5810061 return error::kNoError;
10062 }
[email protected]df37b9932013-03-08 05:21:4210063 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:5810064 }
10065 // TODO(gman): call glShaderBinary
10066 return error::kNoError;
10067#endif
10068}
10069
[email protected]6d792ee12013-05-15 00:40:5610070void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:4910071 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:0810072
[email protected]64ace852011-05-19 21:49:4910073 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:4210074 // TRACE_EVENT for gpu tests:
10075 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:4210076 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:4210077 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
10078 "width", (is_offscreen ? offscreen_size_.width() :
10079 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:5610080 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:4910081 "offscreen", is_offscreen,
10082 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:1510083 {
[email protected]a36ed4832014-04-24 16:40:2710084 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:1510085 }
10086
dyenb547eff62015-01-17 00:14:5610087 ScopedGPUTrace scoped_gpu_trace(gpu_tracer_.get(), kTraceDecoder,
10088 "gpu_toplevel", "SwapBuffer");
10089
[email protected]8f9b8dd2013-09-12 18:05:1310090 bool is_tracing;
10091 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
10092 &is_tracing);
10093 if (is_tracing) {
10094 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
10095 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
10096 is_offscreen ? offscreen_size_ : surface_->GetSize());
10097 }
10098
[email protected]6217d392010-03-25 22:08:3510099 // If offscreen then don't actually SwapBuffers to the display. Just copy
10100 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:4910101 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:3110102 TRACE_EVENT2("gpu", "Offscreen",
10103 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:5310104 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
10105 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
10106 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
10107 // fix this.
[email protected]62e155e2012-10-23 22:43:1510108 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:5310109 offscreen_saved_frame_buffer_->Create();
10110 glFinish();
10111 }
10112
10113 // Allocate the offscreen saved color texture.
10114 DCHECK(offscreen_saved_color_format_);
10115 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:0910116 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:5310117
10118 offscreen_saved_frame_buffer_->AttachRenderTexture(
10119 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:0510120 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
10121 if (offscreen_saved_frame_buffer_->CheckStatus() !=
10122 GL_FRAMEBUFFER_COMPLETE) {
10123 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
10124 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:5610125 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
10126 return;
[email protected]f0cfe752013-01-14 01:09:0510127 }
[email protected]1fb8c482011-08-31 01:01:5310128
[email protected]f0cfe752013-01-14 01:09:0510129 // Clear the offscreen color texture.
10130 // TODO(piman): Is this still necessary?
10131 {
10132 ScopedFrameBufferBinder binder(this,
10133 offscreen_saved_frame_buffer_->id());
10134 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:4510135 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
10136 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:0510137 glClear(GL_COLOR_BUFFER_BIT);
10138 RestoreClearState();
10139 }
[email protected]1fb8c482011-08-31 01:01:5310140 }
10141
10142 UpdateParentTextureInfo();
10143 }
10144
[email protected]f0cfe752013-01-14 01:09:0510145 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:5610146 return;
[email protected]ab09b612013-03-11 22:11:5110147 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010148 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:3510149
[email protected]34ff8b0c2010-10-01 20:06:0210150 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:1310151 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:2710152 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:4810153 } else {
[email protected]069944672012-04-25 20:52:2310154 ScopedFrameBufferBinder binder(this,
10155 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:1310156
[email protected]069944672012-04-25 20:52:2310157 if (offscreen_target_buffer_preserved_) {
10158 // Copy the target frame buffer to the saved offscreen texture.
10159 offscreen_saved_color_texture_->Copy(
10160 offscreen_saved_color_texture_->size(),
10161 offscreen_saved_color_format_);
10162 } else {
10163 // Flip the textures in the parent context via the texture manager.
10164 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:4910165 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:2310166 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:5610167
[email protected]069944672012-04-25 20:52:2310168 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
10169 offscreen_target_frame_buffer_->AttachRenderTexture(
10170 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:4810171 }
[email protected]069944672012-04-25 20:52:2310172
10173 // Ensure the side effects of the copy are visible to the parent
10174 // context. There is no need to do this for ANGLE because it uses a
10175 // single D3D device for all contexts.
zmo68fcdc62014-12-05 21:51:4910176 if (!feature_info_->gl_version_info().is_angle)
[email protected]069944672012-04-25 20:52:2310177 glFlush();
[email protected]0c8c9d22010-06-25 17:36:3910178 }
[email protected]6217d392010-03-25 22:08:3510179 } else {
[email protected]f62a5ab2011-05-23 20:34:1510180 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:0110181 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:5610182 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:0110183 }
[email protected]6217d392010-03-25 22:08:3510184 }
vmiura8266ca72014-09-09 21:37:0010185
10186 // This may be a slow command. Exit command processing to allow for
10187 // context preemption and GPU watchdog checks.
10188 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:3510189}
10190
bajones2345c1f2014-12-09 04:45:5110191void GLES2DecoderImpl::DoSwapInterval(int interval)
10192{
10193 context_->SetSwapInterval(interval);
10194}
10195
[email protected]d4239852011-08-12 04:51:2210196error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:3410197 uint32 immediate_data_size,
10198 const void* cmd_data) {
10199 const gles2::cmds::EnableFeatureCHROMIUM& c =
10200 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:1810201 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2810202 if (!bucket || bucket->size() == 0) {
10203 return error::kInvalidArguments;
10204 }
[email protected]ed9f9cd2013-02-27 21:12:3510205 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:1810206 Result* result = GetSharedMemoryAs<Result*>(
10207 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10208 if (!result) {
10209 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:1010210 }
[email protected]b1d2dcb2010-05-17 19:24:1810211 // Check that the client initialized the result.
10212 if (*result != 0) {
10213 return error::kInvalidArguments;
10214 }
10215 std::string feature_str;
10216 if (!bucket->GetAsString(&feature_str)) {
10217 return error::kInvalidArguments;
10218 }
10219
10220 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:2210221 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:1810222 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:2210223 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
penghuang0140c182015-01-12 23:20:1210224 buffer_manager()->set_allow_fixed_attribs(true);
[email protected]8fbedc02010-11-18 18:43:4010225 // TODO(gman): decide how to remove the need for this const_cast.
10226 // I could make validators_ non const but that seems bad as this is the only
10227 // place it is needed. I could make some special friend class of validators
10228 // just to allow this to set them. That seems silly. I could refactor this
10229 // code to use the extension mechanism or the initialization attributes to
10230 // turn this feature on. Given that the only real point of this is to make
10231 // the conformance tests pass and given that there is lots of real work that
10232 // needs to be done it seems like refactoring for one to one of those
10233 // methods is a very low priority.
10234 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:0410235 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
10236 force_webgl_glsl_validation_ = true;
10237 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:1810238 } else {
10239 return error::kNoError;
10240 }
10241
10242 *result = 1; // true.
10243 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:1010244}
10245
[email protected]c2f8c8402010-12-06 18:07:2410246error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
10247 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:3410248 const void* cmd_data) {
10249 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
10250 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
10251 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2410252 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:3510253 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:1910254 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:2410255 bucket->SetFromString(info->extensions().c_str());
10256 return error::kNoError;
10257}
10258
10259error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:3410260 uint32 immediate_data_size,
10261 const void* cmd_data) {
10262 const gles2::cmds::RequestExtensionCHROMIUM& c =
10263 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2410264 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2810265 if (!bucket || bucket->size() == 0) {
10266 return error::kInvalidArguments;
10267 }
[email protected]c2f8c8402010-12-06 18:07:2410268 std::string feature_str;
10269 if (!bucket->GetAsString(&feature_str)) {
10270 return error::kInvalidArguments;
10271 }
10272
[email protected]4b7eba92013-01-08 02:23:5610273 bool desire_webgl_glsl_validation =
10274 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
10275 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:4910276 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:1310277 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:0610278 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:5610279 if (force_webgl_glsl_validation_) {
10280 desire_standard_derivatives =
10281 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:4910282 desire_frag_depth =
10283 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:1310284 desire_draw_buffers =
10285 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:0610286 desire_shader_texture_lod =
10287 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:0410288 }
10289
[email protected]4b7eba92013-01-08 02:23:5610290 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:4910291 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:1310292 desire_frag_depth != frag_depth_explicitly_enabled_ ||
10293 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:4910294 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
10295 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
10296 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:1310297 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:0610298 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:2410299 InitializeShaderTranslator();
10300 }
10301
[email protected]302ce6d2011-07-07 23:28:1110302 UpdateCapabilities();
10303
[email protected]c2f8c8402010-12-06 18:07:2410304 return error::kNoError;
10305}
10306
[email protected]2318d342011-07-11 22:27:4210307error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:3410308 uint32 immediate_data_size,
10309 const void* cmd_data) {
10310 const gles2::cmds::GetProgramInfoCHROMIUM& c =
10311 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:4210312 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:4210313 uint32 bucket_id = c.bucket_id;
10314 Bucket* bucket = CreateBucket(bucket_id);
10315 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:4210316 Program* program = NULL;
10317 program = GetProgram(program_id);
10318 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:4610319 return error::kNoError;
[email protected]2318d342011-07-11 22:27:4210320 }
[email protected]df37b9932013-03-08 05:21:4210321 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:4210322 return error::kNoError;
10323}
10324
zmo4a16ff992015-02-05 22:18:4110325error::Error GLES2DecoderImpl::HandleGetUniformBlocksCHROMIUM(
10326 uint32 immediate_data_size, const void* cmd_data) {
10327 if (!unsafe_es3_apis_enabled())
10328 return error::kUnknownCommand;
10329 const gles2::cmds::GetUniformBlocksCHROMIUM& c =
10330 *static_cast<const gles2::cmds::GetUniformBlocksCHROMIUM*>(cmd_data);
10331 GLuint program_id = static_cast<GLuint>(c.program);
10332 uint32 bucket_id = c.bucket_id;
10333 Bucket* bucket = CreateBucket(bucket_id);
10334 bucket->SetSize(sizeof(UniformBlocksHeader)); // in case we fail.
10335 Program* program = NULL;
10336 program = GetProgram(program_id);
10337 if (!program || !program->IsValid()) {
10338 return error::kNoError;
10339 }
10340 program->GetUniformBlocks(bucket);
10341 return error::kNoError;
10342}
10343
zmoc7e7e13f2015-02-17 22:07:0710344error::Error GLES2DecoderImpl::HandleGetUniformsES3CHROMIUM(
10345 uint32 immediate_data_size, const void* cmd_data) {
10346 if (!unsafe_es3_apis_enabled())
10347 return error::kUnknownCommand;
10348 const gles2::cmds::GetUniformsES3CHROMIUM& c =
10349 *static_cast<const gles2::cmds::GetUniformsES3CHROMIUM*>(cmd_data);
10350 GLuint program_id = static_cast<GLuint>(c.program);
10351 uint32 bucket_id = c.bucket_id;
10352 Bucket* bucket = CreateBucket(bucket_id);
10353 bucket->SetSize(sizeof(UniformsES3Header)); // in case we fail.
10354 Program* program = NULL;
10355 program = GetProgram(program_id);
10356 if (!program || !program->IsValid()) {
10357 return error::kNoError;
10358 }
10359 program->GetUniformsES3(bucket);
10360 return error::kNoError;
10361}
10362
zmo10842492015-02-12 00:44:1610363error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVarying(
10364 uint32 immediate_data_size,
10365 const void* cmd_data) {
10366 if (!unsafe_es3_apis_enabled())
10367 return error::kUnknownCommand;
10368 const gles2::cmds::GetTransformFeedbackVarying& c =
10369 *static_cast<const gles2::cmds::GetTransformFeedbackVarying*>(cmd_data);
10370 GLuint program_id = c.program;
10371 GLuint index = c.index;
10372 uint32 name_bucket_id = c.name_bucket_id;
10373 typedef cmds::GetTransformFeedbackVarying::Result Result;
10374 Result* result = GetSharedMemoryAs<Result*>(
10375 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10376 if (!result) {
10377 return error::kOutOfBounds;
10378 }
10379 // Check that the client initialized the result.
10380 if (result->success != 0) {
10381 return error::kInvalidArguments;
10382 }
10383 Program* program = GetProgramInfoNotShader(
10384 program_id, "glGetTransformFeedbackVarying");
10385 if (!program) {
10386 return error::kNoError;
10387 }
10388 GLuint service_id = program->service_id();
10389 GLint link_status = GL_FALSE;
10390 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10391 if (link_status != GL_TRUE) {
10392 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10393 "glGetTransformFeedbackVarying", "program not linked");
10394 return error::kNoError;
10395 }
10396 GLint max_length = 0;
10397 glGetProgramiv(
10398 service_id, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_length);
10399 max_length = std::max(1, max_length);
10400 std::vector<char> buffer(max_length);
10401 GLsizei length = 0;
10402 GLsizei size = 0;
10403 GLenum type = 0;
10404 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetTransformFeedbackVarying");
10405 glGetTransformFeedbackVarying(
10406 service_id, index, max_length, &length, &size, &type, &buffer[0]);
10407 GLenum error = glGetError();
10408 if (error != GL_NO_ERROR) {
10409 LOCAL_SET_GL_ERROR(error, "glGetTransformFeedbackVarying", "");
10410 return error::kNoError;
10411 }
10412 result->success = 1; // true.
10413 result->size = static_cast<int32_t>(size);
10414 result->type = static_cast<uint32_t>(type);
10415 Bucket* bucket = CreateBucket(name_bucket_id);
10416 DCHECK(length >= 0 && length < max_length);
10417 buffer[length] = '\0'; // Just to be safe.
10418 bucket->SetFromString(&buffer[0]);
10419 return error::kNoError;
10420}
10421
10422error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVaryingsCHROMIUM(
10423 uint32 immediate_data_size, const void* cmd_data) {
10424 if (!unsafe_es3_apis_enabled())
10425 return error::kUnknownCommand;
10426 const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM& c =
10427 *static_cast<const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM*>(
10428 cmd_data);
10429 GLuint program_id = static_cast<GLuint>(c.program);
10430 uint32 bucket_id = c.bucket_id;
10431 Bucket* bucket = CreateBucket(bucket_id);
10432 bucket->SetSize(sizeof(TransformFeedbackVaryingsHeader)); // in case we fail.
10433 Program* program = NULL;
10434 program = GetProgram(program_id);
10435 if (!program || !program->IsValid()) {
10436 return error::kNoError;
10437 }
10438 program->GetTransformFeedbackVaryings(bucket);
10439 return error::kNoError;
10440}
10441
[email protected]38d139d2011-07-14 00:38:4310442error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
10443 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:4310444 case GL_NO_ERROR:
10445 // TODO(kbr): improve the precision of the error code in this case.
10446 // Consider delegating to context for error code if MakeCurrent fails.
10447 return error::kUnknown;
10448 case GL_GUILTY_CONTEXT_RESET_ARB:
10449 return error::kGuilty;
10450 case GL_INNOCENT_CONTEXT_RESET_ARB:
10451 return error::kInnocent;
10452 case GL_UNKNOWN_CONTEXT_RESET_ARB:
10453 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:4310454 }
10455
10456 NOTREACHED();
10457 return error::kUnknown;
10458}
10459
jbauman7a059312014-10-16 19:30:5410460void GLES2DecoderImpl::MaybeExitOnContextLost() {
10461 // Some D3D drivers cannot recover from device lost in the GPU process
10462 // sandbox. Allow a new GPU process to launch.
10463 if (workarounds().exit_on_context_lost) {
10464 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
10465 << " a D3D device in the Chrome GPU process sandbox.";
10466#if defined(OS_WIN)
10467 base::win::SetShouldCrashOnProcessDetach(false);
10468#endif
10469 exit(0);
10470 }
10471}
10472
[email protected]38d139d2011-07-14 00:38:4310473bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:0910474 if (reset_status_ != GL_NO_ERROR) {
jbauman7a059312014-10-16 19:30:5410475 MaybeExitOnContextLost();
[email protected]c4485aad62012-12-17 10:19:0910476 return true;
10477 }
dongseong.hwange1cb2aa2015-02-11 09:33:3310478 if (IsRobustnessSupported()) {
10479 GLenum status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:4310480 if (status != GL_NO_ERROR) {
10481 // The graphics card was reset. Signal a lost context to the application.
10482 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:2210483 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:4310484 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:0910485 << " context lost via ARB/EXT_robustness. Reset status = "
10486 << GLES2Util::GetStringEnum(status);
jbauman7a059312014-10-16 19:30:5410487 MaybeExitOnContextLost();
[email protected]38d139d2011-07-14 00:38:4310488 return true;
10489 }
10490 }
10491 return false;
10492}
10493
[email protected]93a7d98f2013-07-11 00:04:2210494bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
10495 return WasContextLost() && reset_by_robustness_extension_;
10496}
10497
[email protected]c4485aad62012-12-17 10:19:0910498void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
10499 // Only loses the context once.
10500 if (reset_status_ != GL_NO_ERROR) {
10501 return;
10502 }
10503
oetuaho37cc50e2014-10-31 11:19:2010504 if (workarounds().use_virtualized_gl_contexts) {
10505 // If the context is virtual, the real context being guilty does not ensure
10506 // that the virtual context is guilty.
10507 if (reset_status == GL_GUILTY_CONTEXT_RESET_ARB) {
10508 reset_status = GL_UNKNOWN_CONTEXT_RESET_ARB;
10509 }
10510 } else if (reset_status == GL_UNKNOWN_CONTEXT_RESET_ARB &&
dongseong.hwange1cb2aa2015-02-11 09:33:3310511 IsRobustnessSupported()) {
oetuaho37cc50e2014-10-31 11:19:2010512 // If the reason for the call was a GL error, we can try to determine the
10513 // reset status more accurately.
10514 GLenum driver_status = glGetGraphicsResetStatusARB();
10515 if (driver_status == GL_GUILTY_CONTEXT_RESET_ARB ||
10516 driver_status == GL_INNOCENT_CONTEXT_RESET_ARB) {
10517 reset_status = driver_status;
10518 }
10519 }
10520
[email protected]c4485aad62012-12-17 10:19:0910521 // Marks this context as lost.
10522 reset_status_ = reset_status;
10523 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:0910524}
10525
[email protected]b096d032013-03-08 03:08:0110526error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410527 uint32 immediate_data_size,
10528 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:0110529 return error::kUnknownCommand;
10530}
10531
[email protected]840a7e462013-02-27 01:29:5110532error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410533 uint32 immediate_data_size,
10534 const void* cmd_data) {
10535 const gles2::cmds::WaitSyncPointCHROMIUM& c =
10536 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
sievers173a20d2014-10-22 18:19:3210537 uint32 sync_point = c.sync_point;
[email protected]840a7e462013-02-27 01:29:5110538 if (wait_sync_point_callback_.is_null())
10539 return error::kNoError;
10540
sievers173a20d2014-10-22 18:19:3210541 return wait_sync_point_callback_.Run(sync_point) ?
[email protected]840a7e462013-02-27 01:29:5110542 error::kNoError : error::kDeferCommandUntilLater;
10543}
10544
[email protected]5dfc457b2013-12-13 11:13:0710545error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:3410546 uint32 immediate_data_size,
10547 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:0710548 if (surface_->DeferDraws())
10549 return error::kDeferCommandUntilLater;
10550 if (!surface_->SetBackbufferAllocation(false))
10551 return error::kLostContext;
10552 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
10553 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
10554 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
10555 return error::kNoError;
10556}
10557
[email protected]882ba1e22012-03-08 19:02:5310558bool GLES2DecoderImpl::GenQueriesEXTHelper(
10559 GLsizei n, const GLuint* client_ids) {
10560 for (GLsizei ii = 0; ii < n; ++ii) {
10561 if (query_manager_->GetQuery(client_ids[ii])) {
10562 return false;
10563 }
10564 }
[email protected]4eea7e62014-04-22 21:14:4310565 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:5310566 return true;
10567}
10568
10569void GLES2DecoderImpl::DeleteQueriesEXTHelper(
10570 GLsizei n, const GLuint* client_ids) {
10571 for (GLsizei ii = 0; ii < n; ++ii) {
10572 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
10573 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:1310574 ContextState::QueryMap::iterator it =
10575 state_.current_queries.find(query->target());
10576 if (it != state_.current_queries.end())
10577 state_.current_queries.erase(it);
10578
[email protected]c45f1972012-03-14 07:27:3610579 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:5310580 }
[email protected]4eea7e62014-04-22 21:14:4310581 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:5310582 }
10583}
10584
revemancc241eb2014-11-11 03:30:3710585bool GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
[email protected]22e3f552012-03-13 01:54:1910586 if (query_manager_.get() == NULL) {
10587 return false;
10588 }
revemancc241eb2014-11-11 03:30:3710589 if (!query_manager_->ProcessPendingQueries(did_finish)) {
[email protected]22e3f552012-03-13 01:54:1910590 current_decoder_error_ = error::kOutOfBounds;
10591 }
10592 return query_manager_->HavePendingQueries();
10593}
10594
[email protected]5a36dc132013-07-23 23:17:5510595// Note that if there are no pending readpixels right now,
10596// this function will call the callback immediately.
10597void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
10598 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
10599 pending_readpixel_fences_.back()->callbacks.push_back(callback);
10600 } else {
10601 callback.Run();
10602 }
10603}
10604
10605void GLES2DecoderImpl::ProcessPendingReadPixels() {
10606 while (!pending_readpixel_fences_.empty() &&
10607 pending_readpixel_fences_.front()->fence->HasCompleted()) {
10608 std::vector<base::Closure> callbacks =
10609 pending_readpixel_fences_.front()->callbacks;
10610 pending_readpixel_fences_.pop();
10611 for (size_t i = 0; i < callbacks.size(); i++) {
10612 callbacks[i].Run();
10613 }
10614 }
10615}
10616
[email protected]2b1767cf2013-03-16 09:25:0510617bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510618 return !pending_readpixel_fences_.empty() ||
10619 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510620}
10621
10622void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510623 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:4810624 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:0510625 return;
[email protected]b68b100752013-06-05 08:34:4810626 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510627 ProcessFinishedAsyncTransfers();
10628}
10629
vmiuracd108592014-09-08 14:36:3410630error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
10631 const void* cmd_data) {
10632 const gles2::cmds::BeginQueryEXT& c =
10633 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310634 GLenum target = static_cast<GLenum>(c.target);
10635 GLuint client_id = static_cast<GLuint>(c.id);
10636 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
10637 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10638
[email protected]c45f1972012-03-14 07:27:3610639 switch (target) {
10640 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:5510641 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:3110642 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
10643 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:0010644 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:3610645 break;
[email protected]6a25ae422014-04-17 23:48:2710646 case GL_COMMANDS_COMPLETED_CHROMIUM:
10647 if (!features().chromium_sync_query) {
10648 LOCAL_SET_GL_ERROR(
10649 GL_INVALID_OPERATION, "glBeginQueryEXT",
10650 "not enabled for commands completed queries");
10651 return error::kNoError;
10652 }
10653 break;
[email protected]c45f1972012-03-14 07:27:3610654 default:
[email protected]62e155e2012-10-23 22:43:1510655 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:5110656 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:0010657 GL_INVALID_OPERATION, "glBeginQueryEXT",
10658 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:3610659 return error::kNoError;
10660 }
10661 break;
[email protected]882ba1e22012-03-08 19:02:5310662 }
10663
[email protected]8ebd46c2014-01-08 12:06:1310664 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110665 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310666 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:5310667 return error::kNoError;
10668 }
10669
10670 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:5110671 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:5310672 return error::kNoError;
10673 }
10674
10675 QueryManager::Query* query = query_manager_->GetQuery(client_id);
10676 if (!query) {
[email protected]4eea7e62014-04-22 21:14:4310677 if (!query_manager_->IsValidQuery(client_id)) {
10678 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10679 "glBeginQueryEXT",
10680 "id not made by glGenQueriesEXT");
10681 return error::kNoError;
10682 }
[email protected]c45f1972012-03-14 07:27:3610683 query = query_manager_->CreateQuery(
10684 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:5310685 }
10686
[email protected]c45f1972012-03-14 07:27:3610687 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110688 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310689 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:5310690 return error::kNoError;
10691 } else if (query->shm_id() != sync_shm_id ||
10692 query->shm_offset() != sync_shm_offset) {
10693 DLOG(ERROR) << "Shared memory used by query not the same as before";
10694 return error::kInvalidArguments;
10695 }
10696
[email protected]c45f1972012-03-14 07:27:3610697 if (!query_manager_->BeginQuery(query)) {
10698 return error::kOutOfBounds;
10699 }
[email protected]882ba1e22012-03-08 19:02:5310700
[email protected]8ebd46c2014-01-08 12:06:1310701 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:5310702 return error::kNoError;
10703}
10704
vmiuracd108592014-09-08 14:36:3410705error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
10706 const void* cmd_data) {
10707 const gles2::cmds::EndQueryEXT& c =
10708 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310709 GLenum target = static_cast<GLenum>(c.target);
10710 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:1310711 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:5310712
[email protected]8ebd46c2014-01-08 12:06:1310713 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110714 LOCAL_SET_GL_ERROR(
10715 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:5310716 return error::kNoError;
10717 }
[email protected]882ba1e22012-03-08 19:02:5310718
[email protected]8ebd46c2014-01-08 12:06:1310719 QueryManager::Query* query = it->second.get();
10720 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:3610721 return error::kOutOfBounds;
10722 }
10723
[email protected]fe8d73c2013-02-16 22:37:3210724 query_manager_->ProcessPendingTransferQueries();
10725
[email protected]8ebd46c2014-01-08 12:06:1310726 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:5310727 return error::kNoError;
10728}
10729
[email protected]944b62f32012-09-27 02:20:4610730bool GLES2DecoderImpl::GenVertexArraysOESHelper(
10731 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610732 for (GLsizei ii = 0; ii < n; ++ii) {
10733 if (GetVertexAttribManager(client_ids[ii])) {
10734 return false;
10735 }
10736 }
[email protected]ab4fd7282012-10-12 16:25:5710737
[email protected]62e155e2012-10-23 22:43:1510738 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710739 // Emulated VAO
10740 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810741 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:5710742 }
10743 } else {
[email protected]40d90a22013-04-09 03:39:5510744 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:5710745
10746 glGenVertexArraysOES(n, service_ids.get());
10747 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810748 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:5710749 }
[email protected]944b62f32012-09-27 02:20:4610750 }
[email protected]ab4fd7282012-10-12 16:25:5710751
[email protected]944b62f32012-09-27 02:20:4610752 return true;
10753}
10754
10755void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
10756 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610757 for (GLsizei ii = 0; ii < n; ++ii) {
10758 VertexAttribManager* vao =
10759 GetVertexAttribManager(client_ids[ii]);
10760 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:1110761 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:1110762 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:4610763 }
10764 RemoveVertexAttribManager(client_ids[ii]);
10765 }
10766 }
10767}
10768
10769void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610770 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:4610771 if (client_id != 0) {
10772 vao = GetVertexAttribManager(client_id);
10773 if (!vao) {
10774 // Unlike most Bind* methods, the spec explicitly states that VertexArray
10775 // only allows names that have been previously generated. As such, we do
10776 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:5110777 LOCAL_SET_GL_ERROR(
10778 GL_INVALID_OPERATION,
10779 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:4610780 current_decoder_error_ = error::kNoError;
10781 return;
[email protected]944b62f32012-09-27 02:20:4610782 }
[email protected]944b62f32012-09-27 02:20:4610783 } else {
[email protected]81f20a622014-04-18 01:54:5210784 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4610785 }
10786
[email protected]ab4fd7282012-10-12 16:25:5710787 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110788 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2410789 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1510790 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710791 EmulateVertexArrayState();
10792 } else {
[email protected]da364812014-05-09 21:39:4810793 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5710794 glBindVertexArrayOES(service_id);
10795 }
10796 }
10797}
10798
10799// Used when OES_vertex_array_object isn't natively supported
10800void GLES2DecoderImpl::EmulateVertexArrayState() {
10801 // Setup the Vertex attribute state
10802 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2310803 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5710804 }
10805
10806 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2110807 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2410808 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5710809 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
10810 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4610811}
10812
10813bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610814 const VertexAttribManager* vao =
10815 GetVertexAttribManager(client_id);
10816 return vao && vao->IsValid() && !vao->IsDeleted();
10817}
10818
[email protected]e51bdf32011-11-23 22:21:4610819#if defined(OS_MACOSX)
10820void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
10821 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
10822 texture_id);
10823 if (it != texture_to_io_surface_map_.end()) {
10824 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5310825 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4610826 CFRelease(surface);
10827 texture_to_io_surface_map_.erase(it);
10828 }
10829}
10830#endif
10831
10832void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
10833 GLenum target, GLsizei width, GLsizei height,
10834 GLuint io_surface_id, GLuint plane) {
10835#if defined(OS_MACOSX)
10836 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5110837 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310838 GL_INVALID_OPERATION,
10839 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4610840 return;
10841 }
10842
[email protected]e51bdf32011-11-23 22:21:4610843 if (target != GL_TEXTURE_RECTANGLE_ARB) {
10844 // This might be supported in the future, and if we could require
10845 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
10846 // could delete a lot of code. For now, perform strict validation so we
10847 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5110848 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610849 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310850 "glTexImageIOSurface2DCHROMIUM",
10851 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4610852 return;
10853 }
10854
[email protected]09d50362012-10-18 20:54:3710855 // Default target might be conceptually valid, but disallow it to avoid
10856 // accidents.
[email protected]c986af502013-08-14 01:04:4410857 TextureRef* texture_ref =
10858 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910859 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110860 LOCAL_SET_GL_ERROR(
10861 GL_INVALID_OPERATION,
10862 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4610863 return;
10864 }
[email protected]e51bdf32011-11-23 22:21:4610865
10866 // Look up the new IOSurface. Note that because of asynchrony
10867 // between processes this might fail; during live resizing the
10868 // plugin process might allocate and release an IOSurface before
10869 // this process gets a chance to look it up. Hold on to any old
10870 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5310871 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4610872 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5110873 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310874 GL_INVALID_OPERATION,
10875 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4610876 return;
10877 }
10878
10879 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4910880 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4610881
10882 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
10883 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4910884 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4610885
10886 CGLContextObj context =
10887 static_cast<CGLContextObj>(context_->GetHandle());
10888
[email protected]c3a6b4a2014-06-04 09:25:5310889 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4610890 context,
10891 target,
10892 GL_RGBA,
10893 width,
10894 height,
10895 GL_BGRA,
10896 GL_UNSIGNED_INT_8_8_8_8_REV,
10897 surface,
10898 plane);
10899
10900 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5110901 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610902 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310903 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4610904 return;
10905 }
10906
10907 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910908 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4610909 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
10910
10911#else
[email protected]ab09b612013-03-11 22:11:5110912 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310913 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4610914#endif
10915}
10916
[email protected]97dc7cbe2011-12-06 17:26:1710917static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
10918 switch (internalformat) {
10919 case GL_RGB565:
10920 return GL_RGB;
10921 case GL_RGBA4:
10922 return GL_RGBA;
10923 case GL_RGB5_A1:
10924 return GL_RGBA;
10925 case GL_RGB8_OES:
10926 return GL_RGB;
10927 case GL_RGBA8_OES:
10928 return GL_RGBA;
10929 case GL_LUMINANCE8_ALPHA8_EXT:
10930 return GL_LUMINANCE_ALPHA;
10931 case GL_LUMINANCE8_EXT:
10932 return GL_LUMINANCE;
10933 case GL_ALPHA8_EXT:
10934 return GL_ALPHA;
10935 case GL_RGBA32F_EXT:
10936 return GL_RGBA;
10937 case GL_RGB32F_EXT:
10938 return GL_RGB;
10939 case GL_ALPHA32F_EXT:
10940 return GL_ALPHA;
10941 case GL_LUMINANCE32F_EXT:
10942 return GL_LUMINANCE;
10943 case GL_LUMINANCE_ALPHA32F_EXT:
10944 return GL_LUMINANCE_ALPHA;
10945 case GL_RGBA16F_EXT:
10946 return GL_RGBA;
10947 case GL_RGB16F_EXT:
10948 return GL_RGB;
10949 case GL_ALPHA16F_EXT:
10950 return GL_ALPHA;
10951 case GL_LUMINANCE16F_EXT:
10952 return GL_LUMINANCE;
10953 case GL_LUMINANCE_ALPHA16F_EXT:
10954 return GL_LUMINANCE_ALPHA;
10955 case GL_BGRA8_EXT:
10956 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5910957 case GL_SRGB8_ALPHA8_EXT:
10958 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1710959 default:
10960 return GL_NONE;
10961 }
10962}
10963
dongseong.hwang46305b12015-03-05 18:28:0410964bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUM(
10965 const char* function_name,
10966 GLenum target,
10967 TextureRef* source_texture_ref,
10968 TextureRef* dest_texture_ref,
10969 GLenum dest_internal_format) {
[email protected]370eaf12013-05-18 09:19:4910970 if (!source_texture_ref || !dest_texture_ref) {
dongseong.hwang46305b12015-03-05 18:28:0410971 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown texture id");
10972 return false;
[email protected]43410e92012-04-20 17:06:2810973 }
10974
10975 if (GL_TEXTURE_2D != target) {
dongseong.hwang46305b12015-03-05 18:28:0410976 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
10977 "invalid texture target");
10978 return false;
[email protected]43410e92012-04-20 17:06:2810979 }
10980
[email protected]370eaf12013-05-18 09:19:4910981 Texture* source_texture = source_texture_ref->texture();
10982 Texture* dest_texture = dest_texture_ref->texture();
dongseong.hwang46305b12015-03-05 18:28:0410983 if (source_texture == dest_texture) {
10984 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
10985 "source and destination textures are the same");
10986 return false;
10987 }
10988
[email protected]02965c22013-03-09 02:40:0710989 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2510990 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3410991 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
10992 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
dongseong.hwang46305b12015-03-05 18:28:0410993 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
[email protected]3ecc1052013-09-26 08:59:0010994 "invalid texture target binding");
dongseong.hwang46305b12015-03-05 18:28:0410995 return false;
[email protected]0a1e9ad2012-05-04 21:13:0310996 }
10997
dongseong.hwang46305b12015-03-05 18:28:0410998 GLenum source_type = 0;
10999 GLenum source_internal_format = 0;
11000 source_texture->GetLevelType(source_texture->target(), 0, &source_type,
11001 &source_internal_format);
[email protected]43410e92012-04-20 17:06:2811002
dongseong.hwang46305b12015-03-05 18:28:0411003 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
11004 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
11005 // renderable on some platforms.
11006 bool valid_dest_format = dest_internal_format == GL_RGB ||
11007 dest_internal_format == GL_RGBA ||
11008 dest_internal_format == GL_BGRA_EXT;
11009 bool valid_source_format = source_internal_format == GL_ALPHA ||
11010 source_internal_format == GL_RGB ||
11011 source_internal_format == GL_RGBA ||
11012 source_internal_format == GL_LUMINANCE ||
11013 source_internal_format == GL_LUMINANCE_ALPHA ||
11014 source_internal_format == GL_BGRA_EXT;
11015 if (!valid_source_format || !valid_dest_format) {
11016 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11017 "invalid internal format");
11018 return false;
11019 }
11020 return true;
11021}
11022
11023void GLES2DecoderImpl::DoCopyTextureCHROMIUM(GLenum target,
11024 GLuint source_id,
11025 GLuint dest_id,
11026 GLenum internal_format,
11027 GLenum dest_type) {
11028 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
11029
11030 TextureRef* source_texture_ref = GetTexture(source_id);
11031 TextureRef* dest_texture_ref = GetTexture(dest_id);
11032 Texture* source_texture = source_texture_ref->texture();
11033 Texture* dest_texture = dest_texture_ref->texture();
11034 int source_width = 0;
11035 int source_height = 0;
[email protected]3e0dfd72014-02-21 06:28:4111036 gfx::GLImage* image =
11037 source_texture->GetLevelImage(source_texture->target(), 0);
11038 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5511039 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5611040 source_width = size.width();
11041 source_height = size.height();
11042 if (source_width <= 0 || source_height <= 0) {
11043 LOCAL_SET_GL_ERROR(
11044 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5511045 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5611046 return;
11047 }
[email protected]3ecc1052013-09-26 08:59:0011048 } else {
11049 if (!source_texture->GetLevelSize(
11050 source_texture->target(), 0, &source_width, &source_height)) {
11051 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
11052 "glCopyTextureChromium",
11053 "source texture has no level 0");
11054 return;
11055 }
11056
11057 // Check that this type of texture is allowed.
dongseong.hwang46305b12015-03-05 18:28:0411058 if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
11059 source_width, source_height, 1)) {
[email protected]3ecc1052013-09-26 08:59:0011060 LOCAL_SET_GL_ERROR(
11061 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
11062 return;
11063 }
[email protected]377976552013-05-14 23:32:5611064 }
11065
[email protected]a6e3d282014-08-22 22:20:4411066 GLenum source_type = 0;
11067 GLenum source_internal_format = 0;
11068 source_texture->GetLevelType(
11069 source_texture->target(), 0, &source_type, &source_internal_format);
11070
dongseong.hwang46305b12015-03-05 18:28:0411071 if (dest_texture->IsImmutable()) {
11072 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyTextureCHROMIUM",
11073 "texture is immutable");
11074 return;
11075 }
11076
11077 if (!ValidateCopyTextureCHROMIUM("glCopyTextureCHROMIUM", target,
11078 source_texture_ref, dest_texture_ref,
11079 internal_format)) {
11080 return;
11081 }
11082
11083 // Clear the source texture if necessary.
11084 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
11085 source_texture->target(), 0)) {
11086 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM",
11087 "dimensions too big");
[email protected]a6e3d282014-08-22 22:20:4411088 return;
11089 }
11090
[email protected]cf6b8f62012-05-25 21:43:3711091 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
11092 // needed because it takes 10s of milliseconds to initialize.
11093 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5111094 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3711095 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2711096 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3711097 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5111098 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3711099 return;
11100 }
11101
[email protected]efc87712014-07-09 00:22:4711102 GLenum dest_type_previous = dest_type;
11103 GLenum dest_internal_format = internal_format;
dongseong.hwang46305b12015-03-05 18:28:0411104 int dest_width = 0;
11105 int dest_height = 0;
11106 bool dest_level_defined =
11107 dest_texture->GetLevelSize(GL_TEXTURE_2D, 0, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2811108
[email protected]0a1e9ad2012-05-04 21:13:0311109 if (dest_level_defined) {
dongseong.hwang46305b12015-03-05 18:28:0411110 dest_texture->GetLevelType(GL_TEXTURE_2D, 0, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0711111 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0311112 }
11113
11114 // Resize the destination texture to the dimensions of the source texture.
11115 if (!dest_level_defined || dest_width != source_width ||
11116 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5411117 dest_internal_format != internal_format ||
11118 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2811119 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5111120 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0711121 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
dongseong.hwang46305b12015-03-05 18:28:0411122 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, source_width, source_height,
11123 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5111124 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0311125 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0211126 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2811127 return;
[email protected]0a1e9ad2012-05-04 21:13:0311128 }
[email protected]43410e92012-04-20 17:06:2811129
11130 texture_manager()->SetLevelInfo(
dongseong.hwang46305b12015-03-05 18:28:0411131 dest_texture_ref, GL_TEXTURE_2D, 0, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0311132 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2511133 } else {
dongseong.hwang46305b12015-03-05 18:28:0411134 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0,
11135 true);
[email protected]43410e92012-04-20 17:06:2811136 }
11137
[email protected]00c2cf92014-03-14 00:08:3711138 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5411139
revemance8fbe82014-09-05 02:19:5211140 // Try using GLImage::CopyTexImage when possible.
11141 bool unpack_premultiply_alpha_change =
11142 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
dongseong.hwang46305b12015-03-05 18:28:0411143 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change) {
revemance8fbe82014-09-05 02:19:5211144 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
11145 if (image->CopyTexImage(GL_TEXTURE_2D))
11146 return;
11147 }
11148
11149 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
11150
[email protected]5394a4102013-04-18 05:41:3711151 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
11152 // before presenting.
11153 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
11154 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
dongseong.hwang46305b12015-03-05 18:28:0411155 // instead of using kIdentityMatrix crbug.com/226218.
[email protected]5394a4102013-04-18 05:41:3711156 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
dongseong.hwang46305b12015-03-05 18:28:0411157 this, source_texture->target(), source_texture->service_id(),
11158 dest_texture->service_id(), source_width, source_height, unpack_flip_y_,
11159 unpack_premultiply_alpha_, unpack_unpremultiply_alpha_,
11160 kIdentityMatrix);
[email protected]5394a4102013-04-18 05:41:3711161 } else {
dongseong.hwang46305b12015-03-05 18:28:0411162 copy_texture_CHROMIUM_->DoCopyTexture(
11163 this, source_texture->target(), source_texture->service_id(),
11164 source_internal_format, dest_texture->service_id(), internal_format,
11165 source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
11166 unpack_unpremultiply_alpha_);
11167 }
11168
11169 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
11170}
11171
11172void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(GLenum target,
11173 GLuint source_id,
11174 GLuint dest_id,
11175 GLint xoffset,
11176 GLint yoffset) {
11177 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopySubTextureCHROMIUM");
11178
11179 TextureRef* source_texture_ref = GetTexture(source_id);
11180 TextureRef* dest_texture_ref = GetTexture(dest_id);
11181 Texture* source_texture = source_texture_ref->texture();
11182 Texture* dest_texture = dest_texture_ref->texture();
11183 int source_width = 0;
11184 int source_height = 0;
11185 gfx::GLImage* image =
11186 source_texture->GetLevelImage(source_texture->target(), 0);
11187 if (image) {
11188 gfx::Size size = image->GetSize();
11189 source_width = size.width();
11190 source_height = size.height();
11191 if (source_width <= 0 || source_height <= 0) {
11192 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
11193 "invalid image size");
11194 return;
11195 }
11196 } else {
11197 if (!source_texture->GetLevelSize(source_texture->target(), 0,
11198 &source_width, &source_height)) {
11199 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
11200 "source texture has no level 0");
11201 return;
11202 }
11203
11204 // Check that this type of texture is allowed.
11205 if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
11206 source_width, source_height, 1)) {
11207 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
11208 "source texture bad dimensions");
11209 return;
11210 }
11211 }
11212
11213 GLenum source_type = 0;
11214 GLenum source_internal_format = 0;
11215 source_texture->GetLevelType(source_texture->target(), 0, &source_type,
11216 &source_internal_format);
11217 GLenum dest_type = 0;
11218 GLenum dest_internal_format = 0;
11219 bool dest_level_defined = dest_texture->GetLevelType(
11220 dest_texture->target(), 0, &dest_type, &dest_internal_format);
11221 if (!dest_level_defined) {
11222 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopySubTextureCHROMIUM",
11223 "destination texture is not defined");
11224 return;
11225 }
11226 if (!dest_texture->ValidForTexture(dest_texture->target(), 0, xoffset,
11227 yoffset, source_width, source_height,
11228 dest_type)) {
11229 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
11230 "destination texture bad dimensions.");
11231 return;
11232 }
11233
11234 if (!ValidateCopyTextureCHROMIUM("glCopySubTextureCHROMIUM", target,
11235 source_texture_ref, dest_texture_ref,
11236 dest_internal_format)) {
11237 return;
11238 }
11239
11240 // Clear the source texture if necessary.
11241 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
11242 source_texture->target(), 0)) {
11243 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM",
11244 "source texture dimensions too big");
11245 return;
11246 }
11247
11248 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
11249 // needed because it takes 10s of milliseconds to initialize.
11250 if (!copy_texture_CHROMIUM_.get()) {
11251 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopySubTextureCHROMIUM");
11252 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
11253 copy_texture_CHROMIUM_->Initialize(this);
11254 RestoreCurrentFramebufferBindings();
11255 if (LOCAL_PEEK_GL_ERROR("glCopySubTextureCHROMIUM") != GL_NO_ERROR)
11256 return;
11257 }
11258
11259 int dest_width = 0;
11260 int dest_height = 0;
11261 bool ok =
11262 dest_texture->GetLevelSize(GL_TEXTURE_2D, 0, &dest_width, &dest_height);
11263 DCHECK(ok);
11264 if (xoffset != 0 || yoffset != 0 || source_width != dest_width ||
11265 source_height != dest_height) {
11266 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target,
11267 0)) {
11268 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM",
11269 "destination texture dimensions too big");
11270 return;
11271 }
11272 } else {
11273 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0,
11274 true);
11275 }
11276
11277 ScopedModifyPixels modify(dest_texture_ref);
11278
11279 // Try using GLImage::CopyTexSubImage when possible.
11280 bool unpack_premultiply_alpha_change =
11281 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
11282 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change &&
11283 !xoffset && !yoffset) {
11284 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
11285 if (image->CopyTexImage(GL_TEXTURE_2D))
11286 return;
11287 }
11288
11289 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
11290
11291 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
11292 // before presenting.
11293 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
11294 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
11295 // instead of using kIdentityMatrix crbug.com/226218.
11296 copy_texture_CHROMIUM_->DoCopySubTextureWithTransform(
11297 this, source_texture->target(), source_texture->service_id(),
11298 dest_texture->service_id(), xoffset, yoffset, dest_width, dest_height,
11299 source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
11300 unpack_unpremultiply_alpha_, kIdentityMatrix);
11301 } else {
11302 copy_texture_CHROMIUM_->DoCopySubTexture(
11303 this, source_texture->target(), source_texture->service_id(),
11304 source_internal_format, dest_texture->service_id(),
11305 dest_internal_format, xoffset, yoffset, dest_width, dest_height,
11306 source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
11307 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3711308 }
[email protected]91c94eb2013-10-22 10:32:5411309
11310 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2811311}
11312
[email protected]97dc7cbe2011-12-06 17:26:1711313static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
11314 switch (internalformat) {
11315 case GL_RGB565:
11316 return GL_UNSIGNED_SHORT_5_6_5;
11317 case GL_RGBA4:
11318 return GL_UNSIGNED_SHORT_4_4_4_4;
11319 case GL_RGB5_A1:
11320 return GL_UNSIGNED_SHORT_5_5_5_1;
11321 case GL_RGB8_OES:
11322 return GL_UNSIGNED_BYTE;
11323 case GL_RGBA8_OES:
11324 return GL_UNSIGNED_BYTE;
11325 case GL_LUMINANCE8_ALPHA8_EXT:
11326 return GL_UNSIGNED_BYTE;
11327 case GL_LUMINANCE8_EXT:
11328 return GL_UNSIGNED_BYTE;
11329 case GL_ALPHA8_EXT:
11330 return GL_UNSIGNED_BYTE;
11331 case GL_RGBA32F_EXT:
11332 return GL_FLOAT;
11333 case GL_RGB32F_EXT:
11334 return GL_FLOAT;
11335 case GL_ALPHA32F_EXT:
11336 return GL_FLOAT;
11337 case GL_LUMINANCE32F_EXT:
11338 return GL_FLOAT;
11339 case GL_LUMINANCE_ALPHA32F_EXT:
11340 return GL_FLOAT;
11341 case GL_RGBA16F_EXT:
11342 return GL_HALF_FLOAT_OES;
11343 case GL_RGB16F_EXT:
11344 return GL_HALF_FLOAT_OES;
11345 case GL_ALPHA16F_EXT:
11346 return GL_HALF_FLOAT_OES;
11347 case GL_LUMINANCE16F_EXT:
11348 return GL_HALF_FLOAT_OES;
11349 case GL_LUMINANCE_ALPHA16F_EXT:
11350 return GL_HALF_FLOAT_OES;
11351 case GL_BGRA8_EXT:
11352 return GL_UNSIGNED_BYTE;
11353 default:
11354 return GL_NONE;
11355 }
11356}
11357
11358void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4411359 GLenum target,
11360 GLint levels,
11361 GLenum internal_format,
11362 GLsizei width,
11363 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1311364 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
11365 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4111366 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0011367 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5111368 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311369 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1711370 return;
11371 }
[email protected]c986af502013-08-14 01:04:4411372 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11373 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911374 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111375 LOCAL_SET_GL_ERROR(
11376 GL_INVALID_OPERATION,
11377 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1711378 return;
11379 }
[email protected]370eaf12013-05-18 09:19:4911380 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0711381 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4411382 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1711383 }
[email protected]02965c22013-03-09 02:40:0711384 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5111385 LOCAL_SET_GL_ERROR(
11386 GL_INVALID_OPERATION,
11387 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1711388 return;
11389 }
[email protected]7989c9e2013-01-23 06:39:2611390
11391 GLenum format = ExtractFormatFromStorageFormat(internal_format);
11392 GLenum type = ExtractTypeFromStorageFormat(internal_format);
11393
11394 {
11395 GLsizei level_width = width;
11396 GLsizei level_height = height;
11397 uint32 estimated_size = 0;
11398 for (int ii = 0; ii < levels; ++ii) {
11399 uint32 level_size = 0;
11400 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211401 level_width, level_height, 1, format, type, state_.unpack_alignment,
[email protected]7989c9e2013-01-23 06:39:2611402 &estimated_size, NULL, NULL) ||
11403 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5111404 LOCAL_SET_GL_ERROR(
11405 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2611406 return;
11407 }
11408 level_width = std::max(1, level_width >> 1);
11409 level_height = std::max(1, level_height >> 1);
11410 }
11411 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5111412 LOCAL_SET_GL_ERROR(
11413 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611414 return;
11415 }
11416 }
11417
[email protected]ab09b612013-03-11 22:11:5111418 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3811419 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5111420 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1711421 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1511422 GLsizei level_width = width;
11423 GLsizei level_height = height;
11424 for (int ii = 0; ii < levels; ++ii) {
11425 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911426 texture_ref, target, ii, format,
11427 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1511428 level_width = std::max(1, level_width >> 1);
11429 level_height = std::max(1, level_height >> 1);
11430 }
[email protected]02965c22013-03-09 02:40:0711431 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1711432 }
[email protected]97dc7cbe2011-12-06 17:26:1711433}
[email protected]e51bdf32011-11-23 22:21:4611434
[email protected]78b514b2012-05-01 21:50:5911435error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3411436 uint32 immediate_data_size,
11437 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3511438 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5911439}
11440
11441void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3711442 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0211443 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3211444 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3711445 "mailbox[0]", static_cast<unsigned char>(data[0]));
11446
[email protected]43f253da2014-06-10 17:51:2211447 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11448 &state_, target);
11449 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
11450}
11451
11452void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
11453 GLenum target, const GLbyte* data) {
11454 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
11455 "context", logger_.GetLogPrefix(),
11456 "mailbox[0]", static_cast<unsigned char>(data[0]));
11457
11458 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
11459 target, data);
11460}
11461
11462void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
11463 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3711464 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2211465 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3711466 "mailbox that was not generated by "
11467 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0211468
[email protected]370eaf12013-05-18 09:19:4911469 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111470 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2211471 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5911472 return;
11473 }
11474
[email protected]62e65f02013-05-29 22:28:1011475 Texture* produced = texture_manager()->Produce(texture_ref);
11476 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5111477 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2211478 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
11479 return;
11480 }
11481
11482 if (produced->target() != target) {
11483 LOCAL_SET_GL_ERROR(
11484 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5911485 return;
11486 }
11487
sievers8b373ec52014-10-24 23:04:0611488 group_->mailbox_manager()->ProduceTexture(mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5911489}
11490
11491void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3711492 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0211493 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3211494 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3711495 "mailbox[0]", static_cast<unsigned char>(data[0]));
11496 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
11497 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
11498 "mailbox that was not generated by "
11499 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0211500
[email protected]62e65f02013-05-29 22:28:1011501 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4411502 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1111503 if (!texture_ref.get()) {
11504 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11505 "glConsumeTextureCHROMIUM",
11506 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5911507 return;
11508 }
[email protected]62e65f02013-05-29 22:28:1011509 GLuint client_id = texture_ref->client_id();
11510 if (!client_id) {
11511 LOCAL_SET_GL_ERROR(
11512 GL_INVALID_OPERATION,
11513 "glConsumeTextureCHROMIUM", "unknown texture for target");
11514 return;
11515 }
sievers8b373ec52014-10-24 23:04:0611516 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]62e65f02013-05-29 22:28:1011517 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5111518 LOCAL_SET_GL_ERROR(
11519 GL_INVALID_OPERATION,
11520 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5911521 return;
11522 }
[email protected]62e65f02013-05-29 22:28:1011523 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5111524 LOCAL_SET_GL_ERROR(
11525 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1011526 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5911527 return;
11528 }
[email protected]62e65f02013-05-29 22:28:1011529
11530 DeleteTexturesHelper(1, &client_id);
11531 texture_ref = texture_manager()->Consume(client_id, texture);
11532 glBindTexture(target, texture_ref->service_id());
11533
11534 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
11535 unit.bind_target = target;
11536 switch (target) {
11537 case GL_TEXTURE_2D:
11538 unit.bound_texture_2d = texture_ref;
11539 break;
11540 case GL_TEXTURE_CUBE_MAP:
11541 unit.bound_texture_cube_map = texture_ref;
11542 break;
11543 case GL_TEXTURE_EXTERNAL_OES:
11544 unit.bound_texture_external_oes = texture_ref;
11545 break;
11546 case GL_TEXTURE_RECTANGLE_ARB:
11547 unit.bound_texture_rectangle_arb = texture_ref;
11548 break;
11549 default:
11550 NOTREACHED(); // Validation should prevent us getting here.
11551 break;
11552 }
[email protected]78b514b2012-05-01 21:50:5911553}
11554
[email protected]43f253da2014-06-10 17:51:2211555error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
11556 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3411557 const void* cmd_data) {
11558 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
11559 *static_cast<
11560 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
11561 cmd_data);
[email protected]43f253da2014-06-10 17:51:2211562 GLenum target = static_cast<GLenum>(c.target);
11563 uint32_t data_size;
11564 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
11565 return error::kOutOfBounds;
11566 }
11567 if (data_size > immediate_data_size) {
11568 return error::kOutOfBounds;
11569 }
11570 const GLbyte* mailbox =
11571 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
11572 if (!validators_->texture_bind_target.IsValid(target)) {
11573 LOCAL_SET_GL_ERROR_INVALID_ENUM(
11574 "glCreateAndConsumeTextureCHROMIUM", target, "target");
11575 return error::kNoError;
11576 }
11577 if (mailbox == NULL) {
11578 return error::kOutOfBounds;
11579 }
11580 uint32_t client_id = c.client_id;
11581 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
11582 return error::kNoError;
11583}
11584
11585void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
11586 const GLbyte* data, GLuint client_id) {
11587 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
11588 "context", logger_.GetLogPrefix(),
11589 "mailbox[0]", static_cast<unsigned char>(data[0]));
11590 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
11591 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
11592 "passed a mailbox that was not "
11593 "generated by GenMailboxCHROMIUM.";
11594
11595 TextureRef* texture_ref = GetTexture(client_id);
11596 if (texture_ref) {
11597 LOCAL_SET_GL_ERROR(
11598 GL_INVALID_OPERATION,
11599 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
11600 return;
11601 }
sievers8b373ec52014-10-24 23:04:0611602 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]43f253da2014-06-10 17:51:2211603 if (!texture) {
11604 LOCAL_SET_GL_ERROR(
11605 GL_INVALID_OPERATION,
11606 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
11607 return;
11608 }
11609 if (texture->target() != target) {
11610 LOCAL_SET_GL_ERROR(
11611 GL_INVALID_OPERATION,
11612 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
11613 return;
11614 }
11615
[email protected]43f253da2014-06-10 17:51:2211616 texture_ref = texture_manager()->Consume(client_id, texture);
11617}
11618
orglofchcad5a6742014-11-07 19:51:1211619bool GLES2DecoderImpl::DoIsValuebufferCHROMIUM(GLuint client_id) {
11620 const Valuebuffer* valuebuffer = GetValuebuffer(client_id);
11621 return valuebuffer && valuebuffer->IsValid();
11622}
11623
11624void GLES2DecoderImpl::DoBindValueBufferCHROMIUM(GLenum target,
11625 GLuint client_id) {
11626 Valuebuffer* valuebuffer = NULL;
11627 if (client_id != 0) {
11628 valuebuffer = GetValuebuffer(client_id);
11629 if (!valuebuffer) {
11630 if (!group_->bind_generates_resource()) {
11631 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindValuebufferCHROMIUM",
11632 "id not generated by glBindValuebufferCHROMIUM");
11633 return;
11634 }
11635
11636 // It's a new id so make a valuebuffer for it.
11637 CreateValuebuffer(client_id);
11638 valuebuffer = GetValuebuffer(client_id);
11639 }
11640 valuebuffer->MarkAsValid();
11641 }
11642 state_.bound_valuebuffer = valuebuffer;
11643}
11644
11645void GLES2DecoderImpl::DoSubscribeValueCHROMIUM(GLenum target,
11646 GLenum subscription) {
11647 if (!CheckCurrentValuebuffer("glSubscribeValueCHROMIUM")) {
11648 return;
11649 }
11650 state_.bound_valuebuffer.get()->AddSubscription(subscription);
11651}
11652
11653void GLES2DecoderImpl::DoPopulateSubscribedValuesCHROMIUM(GLenum target) {
11654 if (!CheckCurrentValuebuffer("glPopulateSubscribedValuesCHROMIUM")) {
11655 return;
11656 }
11657 valuebuffer_manager()->UpdateValuebufferState(state_.bound_valuebuffer.get());
11658}
11659
11660void GLES2DecoderImpl::DoUniformValueBufferCHROMIUM(GLint location,
11661 GLenum target,
11662 GLenum subscription) {
11663 if (!CheckCurrentValuebufferForSubscription(
11664 subscription, "glPopulateSubscribedValuesCHROMIUM")) {
11665 return;
11666 }
11667 if (!CheckSubscriptionTarget(location, subscription,
11668 "glPopulateSubscribedValuesCHROMIUM")) {
11669 return;
11670 }
11671 const ValueState* state =
11672 state_.bound_valuebuffer.get()->GetState(subscription);
11673 if (state) {
11674 switch (subscription) {
11675 case GL_MOUSE_POSITION_CHROMIUM:
11676 DoUniform2iv(location, 1, state->int_value);
11677 break;
11678 default:
11679 NOTREACHED() << "Unhandled uniform subscription target "
11680 << subscription;
11681 break;
11682 }
11683 }
11684}
11685
[email protected]d2a0e1a2012-08-12 02:25:0111686void GLES2DecoderImpl::DoInsertEventMarkerEXT(
11687 GLsizei length, const GLchar* marker) {
11688 if (!marker) {
11689 marker = "";
11690 }
11691 debug_marker_manager_.SetMarker(
11692 length ? std::string(marker, length) : std::string(marker));
11693}
11694
11695void GLES2DecoderImpl::DoPushGroupMarkerEXT(
11696 GLsizei length, const GLchar* marker) {
11697 if (!marker) {
11698 marker = "";
11699 }
[email protected]cac16542014-01-15 17:53:5111700 std::string name = length ? std::string(marker, length) : std::string(marker);
11701 debug_marker_manager_.PushGroup(name);
dyen4bb43282015-01-08 01:09:5611702 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_group_marker"), name,
11703 kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111704}
11705
11706void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
11707 debug_marker_manager_.PopGroup();
dyen4bb43282015-01-08 01:09:5611708 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111709}
11710
[email protected]09d50362012-10-18 20:54:3711711void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
11712 GLenum target, GLint image_id) {
11713 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711714
[email protected]bc26e8d2014-01-29 00:40:3011715 if (target == GL_TEXTURE_CUBE_MAP) {
11716 LOCAL_SET_GL_ERROR(
11717 GL_INVALID_ENUM,
11718 "glBindTexImage2DCHROMIUM", "invalid target");
11719 return;
11720 }
11721
[email protected]09d50362012-10-18 20:54:3711722 // Default target might be conceptually valid, but disallow it to avoid
11723 // accidents.
[email protected]c986af502013-08-14 01:04:4411724 TextureRef* texture_ref =
11725 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911726 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111727 LOCAL_SET_GL_ERROR(
11728 GL_INVALID_OPERATION,
11729 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711730 return;
11731 }
11732
11733 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11734 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111735 LOCAL_SET_GL_ERROR(
11736 GL_INVALID_OPERATION,
11737 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711738 return;
11739 }
11740
[email protected]b8160812013-04-09 00:41:0411741 {
11742 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011743 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611744 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0411745 LOCAL_SET_GL_ERROR(
11746 GL_INVALID_OPERATION,
11747 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
11748 return;
11749 }
[email protected]09d50362012-10-18 20:54:3711750 }
11751
11752 gfx::Size size = gl_image->GetSize();
11753 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911754 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3711755 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4911756 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3711757}
11758
11759void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
11760 GLenum target, GLint image_id) {
11761 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711762
11763 // Default target might be conceptually valid, but disallow it to avoid
11764 // accidents.
[email protected]c986af502013-08-14 01:04:4411765 TextureRef* texture_ref =
11766 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911767 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111768 LOCAL_SET_GL_ERROR(
11769 GL_INVALID_OPERATION,
11770 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711771 return;
11772 }
11773
11774 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11775 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111776 LOCAL_SET_GL_ERROR(
11777 GL_INVALID_OPERATION,
11778 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711779 return;
11780 }
11781
11782 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4911783 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3711784 return;
11785
[email protected]b8160812013-04-09 00:41:0411786 {
11787 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011788 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611789 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0411790 }
[email protected]09d50362012-10-18 20:54:3711791
11792 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911793 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3711794 GL_RGBA, GL_UNSIGNED_BYTE, false);
11795}
[email protected]d2a0e1a2012-08-12 02:25:0111796
[email protected]94307712012-11-16 23:26:1111797error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3411798 uint32 immediate_data_size,
11799 const void* cmd_data) {
11800 const gles2::cmds::TraceBeginCHROMIUM& c =
11801 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
dyencb86f2f2014-12-09 18:35:4111802 Bucket* category_bucket = GetBucket(c.category_bucket_id);
11803 Bucket* name_bucket = GetBucket(c.name_bucket_id);
11804 if (!category_bucket || category_bucket->size() == 0 ||
11805 !name_bucket || name_bucket->size() == 0) {
[email protected]94307712012-11-16 23:26:1111806 return error::kInvalidArguments;
11807 }
dyencb86f2f2014-12-09 18:35:4111808
11809 std::string category_name;
11810 std::string trace_name;
11811 if (!category_bucket->GetAsString(&category_name) ||
11812 !name_bucket->GetAsString(&trace_name)) {
[email protected]94307712012-11-16 23:26:1111813 return error::kInvalidArguments;
11814 }
dyencb86f2f2014-12-09 18:35:4111815
dyencb86f2f2014-12-09 18:35:4111816 if (!gpu_tracer_->Begin(category_name, trace_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5111817 LOCAL_SET_GL_ERROR(
11818 GL_INVALID_OPERATION,
11819 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1411820 return error::kNoError;
11821 }
[email protected]94307712012-11-16 23:26:1111822 return error::kNoError;
11823}
11824
11825void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
dyen4bb43282015-01-08 01:09:5611826 if (!gpu_tracer_->End(kTraceCHROMIUM)) {
11827 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11828 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1111829 return;
11830 }
[email protected]94307712012-11-16 23:26:1111831}
11832
[email protected]2f143d482013-03-14 18:04:4911833void GLES2DecoderImpl::DoDrawBuffersEXT(
11834 GLsizei count, const GLenum* bufs) {
11835 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
11836 LOCAL_SET_GL_ERROR(
11837 GL_INVALID_VALUE,
11838 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
11839 return;
11840 }
11841
11842 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
11843 if (framebuffer) {
11844 for (GLsizei i = 0; i < count; ++i) {
11845 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
11846 bufs[i] != GL_NONE) {
11847 LOCAL_SET_GL_ERROR(
11848 GL_INVALID_OPERATION,
11849 "glDrawBuffersEXT",
11850 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
11851 return;
11852 }
11853 }
11854 glDrawBuffersARB(count, bufs);
11855 framebuffer->SetDrawBuffers(count, bufs);
11856 } else { // backbuffer
11857 if (count > 1 ||
11858 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
11859 LOCAL_SET_GL_ERROR(
11860 GL_INVALID_OPERATION,
11861 "glDrawBuffersEXT",
11862 "more than one buffer or bufs not GL_NONE or GL_BACK");
11863 return;
11864 }
11865 GLenum mapped_buf = bufs[0];
11866 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
11867 bufs[0] == GL_BACK) {
11868 mapped_buf = GL_COLOR_ATTACHMENT0;
11869 }
11870 glDrawBuffersARB(count, &mapped_buf);
11871 group_->set_draw_buffer(bufs[0]);
11872 }
11873}
11874
[email protected]a6a09f852014-05-23 13:05:0311875void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
11876 group_->LoseContexts(other);
11877 reset_status_ = current;
11878 current_decoder_error_ = error::kLostContext;
11879}
11880
kkinnunen337d59632014-08-26 10:19:5711881void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
11882 const GLfloat* matrix) {
11883 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11884 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11885 if (!features().chromium_path_rendering) {
11886 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11887 "glMatrixLoadfCHROMIUM",
11888 "function not available");
11889 return;
11890 }
11891
11892 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11893 ? state_.projection_matrix
11894 : state_.modelview_matrix;
11895 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
11896 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11897 // since the values of the _NV and _CHROMIUM tokens match.
11898 glMatrixLoadfEXT(matrix_mode, matrix);
11899}
11900
11901void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
11902 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11903 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11904
11905 if (!features().chromium_path_rendering) {
11906 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11907 "glMatrixLoadIdentityCHROMIUM",
11908 "function not available");
11909 return;
11910 }
11911
kkinnunen337d59632014-08-26 10:19:5711912 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11913 ? state_.projection_matrix
11914 : state_.modelview_matrix;
11915 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
11916 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11917 // since the values of the _NV and _CHROMIUM tokens match.
11918 glMatrixLoadIdentityEXT(matrix_mode);
11919}
11920
[email protected]32145a92012-12-17 09:01:5911921bool GLES2DecoderImpl::ValidateAsyncTransfer(
11922 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4711923 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5911924 GLenum target,
11925 GLint level,
11926 const void * data) {
11927 // We only support async uploads to 2D textures for now.
11928 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111929 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5911930 return false;
11931 }
11932 // We only support uploads to level zero for now.
11933 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5111934 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5911935 return false;
11936 }
11937 // A transfer buffer must be bound, even for asyncTexImage2D.
11938 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5111939 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5911940 return false;
11941 }
11942 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4711943 if (!texture_ref ||
11944 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5111945 LOCAL_SET_GL_ERROR(
11946 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911947 function_name, "transfer already in progress");
11948 return false;
11949 }
11950 return true;
11951}
11952
[email protected]e3c4a9ab2014-03-31 09:07:0211953base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
11954 uint32 async_upload_token,
11955 uint32 sync_data_shm_id,
11956 uint32 sync_data_shm_offset) {
11957 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2511958 if (!buffer.get() ||
11959 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0211960 return base::Closure();
11961
11962 AsyncMemoryParams mem_params(buffer,
11963 sync_data_shm_offset,
11964 sizeof(AsyncUploadSync));
11965
11966 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
11967 new AsyncUploadTokenCompletionObserver(async_upload_token));
11968
11969 return base::Bind(
11970 &AsyncPixelTransferManager::AsyncNotifyCompletion,
11971 base::Unretained(GetAsyncPixelTransferManager()),
11972 mem_params,
11973 observer);
11974}
11975
[email protected]69023942012-11-30 19:57:1611976error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411977 uint32 immediate_data_size,
11978 const void* cmd_data) {
11979 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
11980 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611981 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611982 GLenum target = static_cast<GLenum>(c.target);
11983 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4411984 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1611985 GLsizei width = static_cast<GLsizei>(c.width);
11986 GLsizei height = static_cast<GLsizei>(c.height);
11987 GLint border = static_cast<GLint>(c.border);
11988 GLenum format = static_cast<GLenum>(c.format);
11989 GLenum type = static_cast<GLenum>(c.type);
11990 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
11991 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
11992 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0211993 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11994 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11995 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11996
11997 base::ScopedClosureRunner scoped_completion_callback;
11998 if (async_upload_token) {
11999 base::Closure completion_closure =
12000 AsyncUploadTokenCompletionClosure(async_upload_token,
12001 sync_data_shm_id,
12002 sync_data_shm_offset);
12003 if (completion_closure.is_null())
12004 return error::kInvalidArguments;
12005
12006 scoped_completion_callback.Reset(completion_closure);
12007 }
[email protected]32145a92012-12-17 09:01:5912008
12009 // TODO(epenner): Move this and copies of this memory validation
12010 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1612011 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4212012 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
12013 NULL, NULL)) {
[email protected]69023942012-11-30 19:57:1612014 return error::kOutOfBounds;
12015 }
12016 const void* pixels = NULL;
12017 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
12018 pixels = GetSharedMemoryAs<const void*>(
12019 pixels_shm_id, pixels_shm_offset, pixels_size);
12020 if (!pixels) {
12021 return error::kOutOfBounds;
12022 }
12023 }
12024
[email protected]c986af502013-08-14 01:04:4412025 TextureManager::DoTextImage2DArguments args = {
12026 target, level, internal_format, width, height, border, format, type,
12027 pixels, pixels_size};
12028 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5912029 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4412030 if (!texture_manager()->ValidateTexImage2D(
12031 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5912032 return error::kNoError;
12033 }
12034
12035 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4912036 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5912037 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4712038 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5912039 return error::kNoError;
12040
12041 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0712042 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5112043 LOCAL_SET_GL_ERROR(
12044 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5912045 "glAsyncTexImage2DCHROMIUM", "already defined");
12046 return error::kNoError;
12047 }
12048
[email protected]7989c9e2013-01-23 06:39:2612049 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5112050 LOCAL_SET_GL_ERROR(
12051 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2612052 return error::kNoError;
12053 }
12054
[email protected]5b3a8e02013-03-13 05:36:4412055 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3812056 AsyncTexImage2DParams tex_params = {
12057 target, level, static_cast<GLenum>(internal_format),
12058 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1212059 AsyncMemoryParams mem_params(
12060 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5912061
[email protected]5b3a8e02013-03-13 05:36:4412062 // Set up the async state if needed, and make the texture
12063 // immutable so the async state stays valid. The level info
12064 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1812065 AsyncPixelTransferDelegate* delegate =
12066 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
12067 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4412068 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5912069
[email protected]896425e2013-06-12 17:27:1812070 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4412071 tex_params,
12072 mem_params,
12073 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4912074 // The callback is only invoked if the transfer delegate still
12075 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4412076 // ownership that both of these pointers are valid.
12077 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4912078 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4412079 tex_params));
[email protected]f598f422012-12-07 08:30:0312080 return error::kNoError;
[email protected]69023942012-11-30 19:57:1612081}
12082
12083error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412084 uint32 immediate_data_size,
12085 const void* cmd_data) {
12086 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
12087 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1612088 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1612089 GLenum target = static_cast<GLenum>(c.target);
12090 GLint level = static_cast<GLint>(c.level);
12091 GLint xoffset = static_cast<GLint>(c.xoffset);
12092 GLint yoffset = static_cast<GLint>(c.yoffset);
12093 GLsizei width = static_cast<GLsizei>(c.width);
12094 GLsizei height = static_cast<GLsizei>(c.height);
12095 GLenum format = static_cast<GLenum>(c.format);
12096 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0212097 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
12098 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
12099 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
12100
12101 base::ScopedClosureRunner scoped_completion_callback;
12102 if (async_upload_token) {
12103 base::Closure completion_closure =
12104 AsyncUploadTokenCompletionClosure(async_upload_token,
12105 sync_data_shm_id,
12106 sync_data_shm_offset);
12107 if (completion_closure.is_null())
12108 return error::kInvalidArguments;
12109
12110 scoped_completion_callback.Reset(completion_closure);
12111 }
[email protected]32145a92012-12-17 09:01:5912112
12113 // TODO(epenner): Move this and copies of this memory validation
12114 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1612115 uint32 data_size;
12116 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4212117 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]69023942012-11-30 19:57:1612118 NULL, NULL)) {
12119 return error::kOutOfBounds;
12120 }
12121 const void* pixels = GetSharedMemoryAs<const void*>(
12122 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5912123
12124 // All the normal glTexSubImage2D validation.
12125 error::Error error = error::kNoError;
12126 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
12127 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
12128 return error;
[email protected]69023942012-11-30 19:57:1612129 }
12130
[email protected]32145a92012-12-17 09:01:5912131 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4412132 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
12133 &state_, target);
[email protected]370eaf12013-05-18 09:19:4912134 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5912135 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4712136 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5912137 return error::kNoError;
12138
12139 // Guarantee async textures are always 'cleared' as follows:
12140 // - AsyncTexImage2D can not redefine an existing texture
12141 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
12142 // - AsyncTexSubImage2D clears synchronously if not already cleared.
12143 // - Textures become immutable after an async call.
12144 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0712145 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4912146 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
12147 target, level)) {
[email protected]ab09b612013-03-11 22:11:5112148 LOCAL_SET_GL_ERROR(
12149 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2512150 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5912151 return error::kNoError;
12152 }
12153 }
12154
[email protected]5b3a8e02013-03-13 05:36:4412155 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0312156 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5912157 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1212158 AsyncMemoryParams mem_params(
12159 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1812160 AsyncPixelTransferDelegate* delegate =
12161 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
12162 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4412163 // TODO(epenner): We may want to enforce exclusive use
12164 // of async APIs in which case this should become an error,
12165 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0312166 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4412167 0, 0, 0, 0, 0, 0};
12168 texture->GetLevelSize(target, level, &define_params.width,
12169 &define_params.height);
12170 texture->GetLevelType(target, level, &define_params.type,
12171 &define_params.internal_format);
12172 // Set up the async state if needed, and make the texture
12173 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1812174 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4712175 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4412176 texture->SetImmutable(true);
12177 }
12178
[email protected]896425e2013-06-12 17:27:1812179 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5912180 return error::kNoError;
[email protected]69023942012-11-30 19:57:1612181}
12182
[email protected]a00c1f742013-03-05 17:02:1612183error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412184 uint32 immediate_data_size,
12185 const void* cmd_data) {
12186 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
12187 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1612188 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
12189 GLenum target = static_cast<GLenum>(c.target);
12190
12191 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5112192 LOCAL_SET_GL_ERROR(
12193 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1612194 return error::kNoError;
12195 }
[email protected]c986af502013-08-14 01:04:4412196 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
12197 &state_, target);
[email protected]370eaf12013-05-18 09:19:4912198 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5112199 LOCAL_SET_GL_ERROR(
12200 GL_INVALID_OPERATION,
12201 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1612202 return error::kNoError;
12203 }
[email protected]896425e2013-06-12 17:27:1812204 AsyncPixelTransferDelegate* delegate =
12205 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
12206 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4912207 LOCAL_SET_GL_ERROR(
12208 GL_INVALID_OPERATION,
12209 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
12210 return error::kNoError;
12211 }
[email protected]896425e2013-06-12 17:27:1812212 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0912213 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1612214 return error::kNoError;
12215}
12216
[email protected]e3c4a9ab2014-03-31 09:07:0212217error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412218 uint32 immediate_data_size,
12219 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0212220 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
12221
12222 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
12223 ProcessFinishedAsyncTransfers();
12224 return error::kNoError;
12225}
12226
zmo8fab00c2015-02-07 02:45:0512227error::Error GLES2DecoderImpl::HandleUniformBlockBinding(
12228 uint32_t immediate_data_size, const void* cmd_data) {
12229 if (!unsafe_es3_apis_enabled())
12230 return error::kUnknownCommand;
12231 const gles2::cmds::UniformBlockBinding& c =
12232 *static_cast<const gles2::cmds::UniformBlockBinding*>(cmd_data);
12233 GLuint client_id = c.program;
12234 GLuint index = static_cast<GLuint>(c.index);
12235 GLuint binding = static_cast<GLuint>(c.binding);
12236 Program* program = GetProgramInfoNotShader(
12237 client_id, "glUniformBlockBinding");
12238 if (!program) {
12239 return error::kNoError;
12240 }
12241 GLuint service_id = program->service_id();
12242 glUniformBlockBinding(service_id, index, binding);
12243 return error::kNoError;
12244}
12245
zmo3366957e2015-02-18 23:40:0712246error::Error GLES2DecoderImpl::HandleClientWaitSync(
12247 uint32_t immediate_data_size, const void* cmd_data) {
12248 if (!unsafe_es3_apis_enabled())
12249 return error::kUnknownCommand;
12250 const gles2::cmds::ClientWaitSync& c =
12251 *static_cast<const gles2::cmds::ClientWaitSync*>(cmd_data);
12252 GLuint sync = static_cast<GLuint>(c.sync);
12253 GLbitfield flags = static_cast<GLbitfield>(c.flags);
12254 GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1);
12255 typedef cmds::ClientWaitSync::Result Result;
12256 Result* result_dst = GetSharedMemoryAs<Result*>(
12257 c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
12258 if (!result_dst) {
12259 return error::kOutOfBounds;
12260 }
12261 if (*result_dst != GL_WAIT_FAILED) {
12262 return error::kInvalidArguments;
12263 }
12264 GLsync service_sync = 0;
12265 if (!group_->GetSyncServiceId(sync, &service_sync)) {
12266 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "ClientWaitSync", "invalid sync");
12267 return error::kNoError;
12268 }
12269 *result_dst = glClientWaitSync(service_sync, flags, timeout);
12270 return error::kNoError;
12271}
12272
zmo41e40582015-02-19 02:13:3012273error::Error GLES2DecoderImpl::HandleWaitSync(
12274 uint32_t immediate_data_size, const void* cmd_data) {
12275 if (!unsafe_es3_apis_enabled())
12276 return error::kUnknownCommand;
12277 const gles2::cmds::WaitSync& c =
12278 *static_cast<const gles2::cmds::WaitSync*>(cmd_data);
12279 GLuint sync = static_cast<GLuint>(c.sync);
12280 GLbitfield flags = static_cast<GLbitfield>(c.flags);
12281 GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1);
12282 GLsync service_sync = 0;
12283 if (!group_->GetSyncServiceId(sync, &service_sync)) {
12284 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "WaitSync", "invalid sync");
12285 return error::kNoError;
12286 }
12287 glWaitSync(service_sync, flags, timeout);
12288 return error::kNoError;
12289}
12290
[email protected]91c94eb2013-10-22 10:32:5412291void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
12292 TextureRef* texture_ref) {
12293 Texture* texture = texture_ref->texture();
12294 DoDidUseTexImageIfNeeded(texture, texture->target());
12295}
12296
oetuaho37cc50e2014-10-31 11:19:2012297void GLES2DecoderImpl::OnContextLostError() {
12298 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
12299}
12300
[email protected]828a3932014-04-02 14:43:1312301void GLES2DecoderImpl::OnOutOfMemoryError() {
12302 if (lose_context_when_out_of_memory_) {
12303 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]828a3932014-04-02 14:43:1312304 }
12305}
12306
[email protected]96449d2c2009-11-25 00:01:3212307// Include the auto-generated part of this file. We split this because it means
12308// we can easily edit the non-auto generated parts right here in this file
12309// instead of having to edit some template or the code generator.
12310#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
12311
12312} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2512313} // namespace gpu