blob: b26b252191485db9d4542fb322fe12f561bd2a4d [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]1078f912011-12-23 13:12:1420#include "base/debug/trace_event.h"
[email protected]b2e92592014-01-10 15:47:1521#include "base/debug/trace_event_synthetic_delay.h"
[email protected]5aa95ac2014-08-14 15:20:5622#include "base/float_util.h"
[email protected]3b63f8f42011-03-28 01:54:1523#include "base/memory/scoped_ptr.h"
[email protected]e3c4a9ab2014-03-31 09:07:0224#include "base/numerics/safe_math.h"
[email protected]f4390962013-06-11 07:29:2225#include "base/strings/string_number_conversions.h"
[email protected]6d668892013-12-04 21:37:1226#include "base/strings/string_split.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
[email protected]f0d74742011-10-03 16:31:0484static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4985static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1386static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]93c2fd82014-04-16 02:46:0687static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
[email protected]693ca512012-11-13 18:09:1388
[email protected]448e459e2013-06-12 17:00:4189static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
90 GLint rangeMax,
91 GLint precision) {
92 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
93}
94
[email protected]8dc1bf92013-03-12 03:58:2195static void GetShaderPrecisionFormatImpl(GLenum shader_type,
96 GLenum precision_type,
97 GLint *range, GLint *precision) {
98 switch (precision_type) {
99 case GL_LOW_INT:
100 case GL_MEDIUM_INT:
101 case GL_HIGH_INT:
102 // These values are for a 32-bit twos-complement integer format.
103 range[0] = 31;
104 range[1] = 30;
105 *precision = 0;
106 break;
107 case GL_LOW_FLOAT:
108 case GL_MEDIUM_FLOAT:
109 case GL_HIGH_FLOAT:
110 // These values are for an IEEE single-precision floating-point format.
111 range[0] = 127;
112 range[1] = 127;
113 *precision = 23;
114 break;
115 default:
116 NOTREACHED();
117 break;
118 }
119
[email protected]8af4d5e2013-03-15 23:55:33120 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
121 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21122 // This function is sometimes defined even though it's really just
123 // a stub, so we need to set range and precision as if it weren't
124 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44125 // On Mac OS with some GPUs, calling this generates a
126 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
127 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21128 glGetShaderPrecisionFormat(shader_type, precision_type,
129 range, precision);
[email protected]448e459e2013-06-12 17:00:41130
131 // TODO(brianderson): Make the following official workarounds.
132
133 // Some drivers have bugs where they report the ranges as a negative number.
134 // Taking the absolute value here shouldn't hurt because negative numbers
135 // aren't expected anyway.
136 range[0] = abs(range[0]);
137 range[1] = abs(range[1]);
138
139 // If the driver reports a precision for highp float that isn't actually
140 // highp, don't pretend like it's supported because shader compilation will
141 // fail anyway.
142 if (precision_type == GL_HIGH_FLOAT &&
143 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
144 range[0] = 0;
145 range[1] = 0;
146 *precision = 0;
147 }
[email protected]8dc1bf92013-03-12 03:58:21148 }
149}
150
[email protected]d286ebbc2014-07-03 17:19:10151static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
152 switch (plane_transform) {
153 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
154 return gfx::OVERLAY_TRANSFORM_NONE;
155 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
156 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
157 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
158 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
159 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
160 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
161 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
162 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
163 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
164 return gfx::OVERLAY_TRANSFORM_ROTATE_270;
165 default:
166 return gfx::OVERLAY_TRANSFORM_INVALID;
167 }
168}
169
[email protected]b04e24c2013-01-08 18:35:25170} // namespace
[email protected]f0d74742011-10-03 16:31:04171
[email protected]6217d392010-03-25 22:08:35172class GLES2DecoderImpl;
173
[email protected]ab09b612013-03-11 22:11:51174// Local versions of the SET_GL_ERROR macros
175#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50176 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51177#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50178 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
179 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51180#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50181 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
182 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51183#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50184 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
185 function_name)
[email protected]ab09b612013-03-11 22:11:51186#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50187 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51188#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50189 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51190#define LOCAL_PERFORMANCE_WARNING(msg) \
191 PerformanceWarning(__FILE__, __LINE__, msg)
192#define LOCAL_RENDER_WARNING(msg) \
193 RenderWarning(__FILE__, __LINE__, msg)
194
[email protected]07f54fcc2009-12-22 02:46:30195// Check that certain assumptions the code makes are true. There are places in
196// the code where shared memory is passed direclty to GL. Example, glUniformiv,
197// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
198// a few others) are 32bits. If they are not 32bits the code will have to change
199// to call those GL functions with service side memory and then copy the results
200// to shared memory, converting the sizes.
201COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
202 GLint_not_same_size_as_uint32);
203COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
204 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37205COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
206 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30207
[email protected]43f28f832010-02-03 02:28:48208// TODO(kbr): the use of this anonymous namespace core dumps the
209// linker on Mac OS X 10.6 when the symbol ordering file is used
210// namespace {
[email protected]96449d2c2009-11-25 00:01:32211
212// Returns the address of the first byte after a struct.
213template <typename T>
214const void* AddressAfterStruct(const T& pod) {
215 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
216}
217
[email protected]07f54fcc2009-12-22 02:46:30218// Returns the address of the frst byte after the struct or NULL if size >
219// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32220template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30221RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
222 uint32 size,
223 uint32 immediate_data_size) {
224 return (size <= immediate_data_size) ?
225 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
226 NULL;
[email protected]96449d2c2009-11-25 00:01:32227}
228
[email protected]07f54fcc2009-12-22 02:46:30229// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18230bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32231 GLuint count,
232 size_t size,
[email protected]a76b0052010-03-05 00:33:18233 unsigned int elements_per_unit,
234 uint32* dst) {
235 uint32 value;
236 if (!SafeMultiplyUint32(count, size, &value)) {
237 return false;
238 }
239 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
240 return false;
241 }
242 *dst = value;
243 return true;
[email protected]96449d2c2009-11-25 00:01:32244}
245
[email protected]258a3313f2011-10-18 20:13:57246// Return true if a character belongs to the ASCII subset as defined in
247// GLSL ES 1.0 spec section 3.1.
248static bool CharacterIsValidForGLES(unsigned char c) {
249 // Printing characters are valid except " $ ` @ \ ' DEL.
250 if (c >= 32 && c <= 126 &&
251 c != '"' &&
252 c != '$' &&
253 c != '`' &&
254 c != '@' &&
255 c != '\\' &&
256 c != '\'') {
257 return true;
258 }
259 // Horizontal tab, line feed, vertical tab, form feed, carriage return
260 // are also valid.
261 if (c >= 9 && c <= 13) {
262 return true;
263 }
264
265 return false;
266}
267
268static bool StringIsValidForGLES(const char* str) {
269 for (; *str; ++str) {
270 if (!CharacterIsValidForGLES(*str)) {
271 return false;
272 }
273 }
274 return true;
275}
276
[email protected]6217d392010-03-25 22:08:35277// This class prevents any GL errors that occur when it is in scope from
278// being reported to the client.
279class ScopedGLErrorSuppressor {
280 public:
[email protected]ab09b612013-03-11 22:11:51281 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30282 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35283 ~ScopedGLErrorSuppressor();
284 private:
[email protected]ab09b612013-03-11 22:11:51285 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30286 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35287 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
288};
289
[email protected]2b10c02d2014-01-29 16:43:02290// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35291// object goes out of scope. Also temporarily switches to using active texture
292// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02293class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35294 public:
[email protected]00c2cf92014-03-14 00:08:37295 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02296 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35297
298 private:
[email protected]ce296892013-10-24 22:04:36299 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02300 GLenum target_;
301 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35302};
303
304// Temporarily changes a decoder's bound render buffer and restore it when this
305// object goes out of scope.
306class ScopedRenderBufferBinder {
307 public:
[email protected]00c2cf92014-03-14 00:08:37308 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35309 ~ScopedRenderBufferBinder();
310
311 private:
[email protected]18e785a2013-10-09 03:29:41312 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35313 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
314};
315
316// Temporarily changes a decoder's bound frame buffer and restore it when this
317// object goes out of scope.
318class ScopedFrameBufferBinder {
319 public:
[email protected]00c2cf92014-03-14 00:08:37320 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35321 ~ScopedFrameBufferBinder();
322
323 private:
324 GLES2DecoderImpl* decoder_;
325 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
326};
327
[email protected]34ff8b0c2010-10-01 20:06:02328// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52329// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27330// if it is bound or enforce_internal_framebuffer is true. If internal is
331// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02332class ScopedResolvedFrameBufferBinder {
333 public:
[email protected]00c2cf92014-03-14 00:08:37334 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
335 bool enforce_internal_framebuffer,
336 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02337 ~ScopedResolvedFrameBufferBinder();
338
339 private:
340 GLES2DecoderImpl* decoder_;
341 bool resolve_and_bind_;
342 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
343};
344
[email protected]00c2cf92014-03-14 00:08:37345class ScopedModifyPixels {
346 public:
347 explicit ScopedModifyPixels(TextureRef* ref);
348 ~ScopedModifyPixels();
349
350 private:
351 TextureRef* ref_;
352};
353
354ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
355 if (ref_)
356 ref_->texture()->OnWillModifyPixels();
357}
358
359ScopedModifyPixels::~ScopedModifyPixels() {
360 if (ref_)
361 ref_->texture()->OnDidModifyPixels();
362}
363
364class ScopedRenderTo {
365 public:
366 explicit ScopedRenderTo(Framebuffer* framebuffer);
367 ~ScopedRenderTo();
368
369 private:
370 const Framebuffer* framebuffer_;
371};
372
373ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
374 : framebuffer_(framebuffer) {
375 if (framebuffer)
376 framebuffer_->OnWillRenderTo();
377}
378
379ScopedRenderTo::~ScopedRenderTo() {
380 if (framebuffer_)
381 framebuffer_->OnDidRenderTo();
382}
383
[email protected]6217d392010-03-25 22:08:35384// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35385class BackTexture {
[email protected]6217d392010-03-25 22:08:35386 public:
[email protected]ce296892013-10-24 22:04:36387 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35388 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35389
390 // Create a new render texture.
391 void Create();
392
393 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09394 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35395
396 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58397 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35398
399 // Destroy the render texture. This must be explicitly called before
400 // destroying this object.
401 void Destroy();
402
[email protected]97872062010-11-03 19:07:05403 // Invalidate the texture. This can be used when a context is lost and it is
404 // not possible to make it current in order to free the resource.
405 void Invalidate();
406
[email protected]6217d392010-03-25 22:08:35407 GLuint id() const {
408 return id_;
409 }
410
[email protected]d37231fa2010-04-09 21:16:02411 gfx::Size size() const {
412 return size_;
413 }
414
[email protected]6217d392010-03-25 22:08:35415 private:
[email protected]ff6493f2012-07-31 19:52:25416 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36417 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48418 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35419 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02420 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35421 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35422};
423
424// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35425class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35426 public:
[email protected]d5a28e452013-10-10 01:01:40427 explicit BackRenderbuffer(
428 RenderbufferManager* renderbuffer_manager,
429 MemoryTracker* memory_tracker,
430 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35431 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35432
433 // Create a new render buffer.
434 void Create();
435
436 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18437 bool AllocateStorage(const FeatureInfo* feature_info,
438 const gfx::Size& size,
439 GLenum format,
440 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35441
442 // Destroy the render buffer. This must be explicitly called before destroying
443 // this object.
444 void Destroy();
445
[email protected]97872062010-11-03 19:07:05446 // Invalidate the render buffer. This can be used when a context is lost and
447 // it is not possible to make it current in order to free the resource.
448 void Invalidate();
449
[email protected]6217d392010-03-25 22:08:35450 GLuint id() const {
451 return id_;
452 }
453
454 private:
[email protected]d5a28e452013-10-10 01:01:40455 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25456 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40457 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48458 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35459 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35460 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35461};
462
463// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35464class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35465 public:
[email protected]ed9f9cd2013-02-27 21:12:35466 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
467 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35468
469 // Create a new frame buffer.
470 void Create();
471
472 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35473 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35474
[email protected]b9363b22010-06-09 22:06:15475 // Attach a render buffer to a frame buffer. Note that this unbinds any
476 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35477 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35478
[email protected]6217d392010-03-25 22:08:35479 // Destroy the frame buffer. This must be explicitly called before destroying
480 // this object.
481 void Destroy();
482
[email protected]97872062010-11-03 19:07:05483 // Invalidate the frame buffer. This can be used when a context is lost and it
484 // is not possible to make it current in order to free the resource.
485 void Invalidate();
486
[email protected]6217d392010-03-25 22:08:35487 // See glCheckFramebufferStatusEXT.
488 GLenum CheckStatus();
489
490 GLuint id() const {
491 return id_;
492 }
493
494 private:
495 GLES2DecoderImpl* decoder_;
496 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35497 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35498};
[email protected]34ff8b0c2010-10-01 20:06:02499
[email protected]5a36dc132013-07-23 23:17:55500struct FenceCallback {
501 explicit FenceCallback()
502 : fence(gfx::GLFence::Create()) {
503 DCHECK(fence);
504 }
[email protected]5a36dc132013-07-23 23:17:55505 std::vector<base::Closure> callbacks;
506 scoped_ptr<gfx::GLFence> fence;
507};
508
[email protected]e3c4a9ab2014-03-31 09:07:02509class AsyncUploadTokenCompletionObserver
510 : public AsyncPixelTransferCompletionObserver {
511 public:
512 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
513 : async_upload_token_(async_upload_token) {
514 }
515
dcheng1f4d1d72014-10-21 16:21:58516 void DidComplete(const AsyncMemoryParams& mem_params) override {
dcheng6ef3c5552014-08-30 05:34:19517 DCHECK(mem_params.buffer().get());
[email protected]e3c4a9ab2014-03-31 09:07:02518 void* data = mem_params.GetDataAddress();
519 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
520 sync->SetAsyncUploadToken(async_upload_token_);
521 }
522
523 private:
dcheng1f4d1d72014-10-21 16:21:58524 ~AsyncUploadTokenCompletionObserver() override {}
[email protected]e3c4a9ab2014-03-31 09:07:02525
526 uint32 async_upload_token_;
527
528 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
529};
530
[email protected]43f28f832010-02-03 02:28:48531// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32532
[email protected]efc87712014-07-09 00:22:47533// static
534const unsigned int GLES2Decoder::kDefaultStencilMask =
535 static_cast<unsigned int>(-1);
536
[email protected]ddb1e5a2010-12-13 20:10:45537bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
538 uint32* service_texture_id) {
539 return false;
540}
541
[email protected]a3ded6d2010-10-19 06:44:39542GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06543 : initialized_(false),
544 debug_(false),
zmo84c08202014-11-23 15:28:40545 log_commands_(false),
546 unsafe_es3_apis_enabled_(false) {
[email protected]96449d2c2009-11-25 00:01:32547}
548
[email protected]3916c97e2010-02-25 03:20:50549GLES2Decoder::~GLES2Decoder() {
550}
551
[email protected]cac16542014-01-15 17:53:51552void GLES2Decoder::BeginDecoding() {}
553
554void GLES2Decoder::EndDecoding() {}
555
[email protected]f39f4b3f2010-05-12 17:04:08556// This class implements GLES2Decoder so we don't have to expose all the GLES2
557// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54558class GLES2DecoderImpl : public GLES2Decoder,
[email protected]828a3932014-04-02 14:43:13559 public FramebufferManager::TextureDetachObserver,
560 public ErrorStateClient {
[email protected]f39f4b3f2010-05-12 17:04:08561 public:
[email protected]aa7666122011-09-02 19:45:52562 explicit GLES2DecoderImpl(ContextGroup* group);
dcheng1f4d1d72014-10-21 16:21:58563 ~GLES2DecoderImpl() override;
[email protected]f39f4b3f2010-05-12 17:04:08564
[email protected]96449d2c2009-11-25 00:01:32565 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58566 Error DoCommand(unsigned int command,
567 unsigned int arg_count,
568 const void* args) override;
[email protected]96449d2c2009-11-25 00:01:32569
dcheng1f4d1d72014-10-21 16:21:58570 error::Error DoCommands(unsigned int num_commands,
571 const void* buffer,
572 int num_entries,
573 int* entries_processed) override;
vmiura8266ca72014-09-09 21:37:00574
vmiura1c2b1de2014-09-19 19:03:24575 template <bool DebugImpl>
576 error::Error DoCommandsImpl(unsigned int num_commands,
577 const void* buffer,
578 int num_entries,
579 int* entries_processed);
580
[email protected]96449d2c2009-11-25 00:01:32581 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58582 const char* GetCommandName(unsigned int command_id) const override;
[email protected]96449d2c2009-11-25 00:01:32583
584 // Overridden from GLES2Decoder.
dcheng1f4d1d72014-10-21 16:21:58585 bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
586 const scoped_refptr<gfx::GLContext>& context,
587 bool offscreen,
588 const gfx::Size& size,
589 const DisallowedFeatures& disallowed_features,
590 const std::vector<int32>& attribs) override;
591 void Destroy(bool have_context) override;
592 void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
593 void ProduceFrontBuffer(const Mailbox& mailbox) override;
594 bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
[email protected]9a5afa432011-07-22 18:16:39595 void UpdateParentTextureInfo();
dcheng1f4d1d72014-10-21 16:21:58596 bool MakeCurrent() override;
597 GLES2Util* GetGLES2Util() override { return &util_; }
598 gfx::GLContext* GetGLContext() override { return context_.get(); }
599 ContextGroup* GetContextGroup() override { return group_.get(); }
600 Capabilities GetCapabilities() override;
601 void RestoreState(const ContextState* prev_state) override;
[email protected]29a4d902013-02-26 20:18:06602
dcheng1f4d1d72014-10-21 16:21:58603 void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); }
604 void RestoreAllTextureUnitBindings(
mohan.reddy5e1b8952014-10-08 01:38:17605 const ContextState* prev_state) const override {
[email protected]5baa86bc2014-01-16 04:33:16606 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55607 }
dcheng1f4d1d72014-10-21 16:21:58608 void RestoreActiveTextureUnitBinding(unsigned int target) const override {
[email protected]4b2d2b262014-03-21 22:05:27609 state_.RestoreActiveTextureUnitBinding(target);
610 }
dcheng1f4d1d72014-10-21 16:21:58611 void RestoreBufferBindings() const override {
[email protected]29a4d902013-02-26 20:18:06612 state_.RestoreBufferBindings();
613 }
dcheng1f4d1d72014-10-21 16:21:58614 void RestoreGlobalState() const override { state_.RestoreGlobalState(NULL); }
615 void RestoreProgramBindings() const override {
[email protected]29a4d902013-02-26 20:18:06616 state_.RestoreProgramBindings();
617 }
dcheng1f4d1d72014-10-21 16:21:58618 void RestoreTextureUnitBindings(unsigned unit) const override {
[email protected]5baa86bc2014-01-16 04:33:16619 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06620 }
dcheng1f4d1d72014-10-21 16:21:58621 void RestoreFramebufferBindings() const override;
622 void RestoreRenderbufferBindings() override;
623 void RestoreTextureState(unsigned service_id) const override;
[email protected]29a4d902013-02-26 20:18:06624
dcheng1f4d1d72014-10-21 16:21:58625 void ClearAllAttributes() const override;
626 void RestoreAllAttributes() const override;
[email protected]cd2ef752014-02-12 23:16:03627
dcheng1f4d1d72014-10-21 16:21:58628 QueryManager* GetQueryManager() override { return query_manager_.get(); }
629 VertexArrayManager* GetVertexArrayManager() override {
[email protected]944b62f32012-09-27 02:20:46630 return vertex_array_manager_.get();
631 }
dcheng1f4d1d72014-10-21 16:21:58632 ImageManager* GetImageManager() override { return image_manager_.get(); }
revemancc241eb2014-11-11 03:30:37633 bool ProcessPendingQueries(bool did_finish) override;
dcheng1f4d1d72014-10-21 16:21:58634 bool HasMoreIdleWork() override;
635 void PerformIdleWork() override;
[email protected]43f28f832010-02-03 02:28:48636
dcheng1f4d1d72014-10-21 16:21:58637 void WaitForReadPixels(base::Closure callback) override;
[email protected]5a36dc132013-07-23 23:17:55638
dcheng1f4d1d72014-10-21 16:21:58639 void SetResizeCallback(
mohan.reddy5e1b8952014-10-08 01:38:17640 const base::Callback<void(gfx::Size, float)>& callback) override;
[email protected]22f320a2011-08-30 01:17:00641
dcheng1f4d1d72014-10-21 16:21:58642 Logger* GetLogger() override;
[email protected]cac16542014-01-15 17:53:51643
dcheng1f4d1d72014-10-21 16:21:58644 void BeginDecoding() override;
645 void EndDecoding() override;
[email protected]cac16542014-01-15 17:53:51646
dcheng1f4d1d72014-10-21 16:21:58647 ErrorState* GetErrorState() override;
648 const ContextState* GetContextState() override { return &state_; }
[email protected]1d82e822013-04-10 21:32:32649
dcheng1f4d1d72014-10-21 16:21:58650 void SetShaderCacheCallback(const ShaderCacheCallback& callback) override;
651 void SetWaitSyncPointCallback(const WaitSyncPointCallback& callback) override;
[email protected]22f320a2011-08-30 01:17:00652
dcheng1f4d1d72014-10-21 16:21:58653 AsyncPixelTransferManager* GetAsyncPixelTransferManager() override;
654 void ResetAsyncPixelTransferManagerForTest() override;
655 void SetAsyncPixelTransferManagerForTest(
mohan.reddy5e1b8952014-10-08 01:38:17656 AsyncPixelTransferManager* manager) override;
dcheng1f4d1d72014-10-21 16:21:58657 void SetIgnoreCachedStateForTest(bool ignore) override;
[email protected]69a8701e2013-03-07 21:31:09658 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59659
dcheng1f4d1d72014-10-21 16:21:58660 bool GetServiceTextureId(uint32 client_texture_id,
661 uint32* service_texture_id) override;
[email protected]43f28f832010-02-03 02:28:48662
dcheng1f4d1d72014-10-21 16:21:58663 uint32 GetTextureUploadCount() override;
664 base::TimeDelta GetTotalTextureUploadTime() override;
665 base::TimeDelta GetTotalProcessingCommandsTime() override;
666 void AddProcessingCommandsTime(base::TimeDelta) override;
[email protected]63b465922012-09-06 02:04:52667
[email protected]8e3e0662010-08-23 18:46:30668 // Restores the current state to the user's settings.
669 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30670
[email protected]297ca1c2011-06-20 23:08:46671 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
672 void ApplyDirtyState();
673
674 // These check the state of the currently bound framebuffer or the
675 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54676 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
677 // check with all attached and enabled color attachments.
678 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46679 bool BoundFramebufferHasDepthAttachment();
680 bool BoundFramebufferHasStencilAttachment();
681
dcheng1f4d1d72014-10-21 16:21:58682 error::ContextLostReason GetContextLostReason() override;
[email protected]38d139d2011-07-14 00:38:43683
[email protected]91c94eb2013-10-22 10:32:54684 // Overridden from FramebufferManager::TextureDetachObserver:
dcheng1f4d1d72014-10-21 16:21:58685 void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) override;
[email protected]91c94eb2013-10-22 10:32:54686
[email protected]828a3932014-04-02 14:43:13687 // Overriden from ErrorStateClient.
oetuaho37cc50e2014-10-31 11:19:20688 void OnContextLostError() override;
dcheng1f4d1d72014-10-21 16:21:58689 void OnOutOfMemoryError() override;
[email protected]828a3932014-04-02 14:43:13690
[email protected]8875a5f2014-06-27 08:33:47691 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
692 void EnsureRenderbufferBound();
693
[email protected]f42f05b2013-11-15 21:46:18694 // Helpers to facilitate calling into compatible extensions.
695 static void RenderbufferStorageMultisampleHelper(
696 const FeatureInfo* feature_info,
697 GLenum target,
698 GLsizei samples,
699 GLenum internal_format,
700 GLsizei width,
701 GLsizei height);
702
703 void BlitFramebufferHelper(GLint srcX0,
704 GLint srcY0,
705 GLint srcX1,
706 GLint srcY1,
707 GLint dstX0,
708 GLint dstY0,
709 GLint dstX1,
710 GLint dstY1,
711 GLbitfield mask,
712 GLenum filter);
[email protected]345ba902013-11-14 21:39:00713
[email protected]96449d2c2009-11-25 00:01:32714 private:
[email protected]70d34263c2013-01-09 00:27:45715 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02716 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35717 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35718
[email protected]c2f8c8402010-12-06 18:07:24719 // Initialize or re-initialize the shader translator.
720 bool InitializeShaderTranslator();
721
[email protected]302ce6d2011-07-07 23:28:11722 void UpdateCapabilities();
723
[email protected]ae51d192010-04-27 00:48:03724 // Helpers for the glGen and glDelete functions.
725 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
726 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
727 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
728 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
729 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
730 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
731 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
732 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
orglofchcad5a6742014-11-07 19:51:12733 bool GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
734 void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53735 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
736 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46737 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
738 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47739
[email protected]e3c4a9ab2014-03-31 09:07:02740 // Helper for async upload token completion notification callback.
741 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
742 uint32 sync_data_shm_id,
743 uint32 sync_data_shm_offset);
744
745
746
[email protected]70d34263c2013-01-09 00:27:45747 // Workarounds
748 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51749 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45750
[email protected]3916c97e2010-02-25 03:20:50751 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50752 BufferManager* buffer_manager() {
753 return group_->buffer_manager();
754 }
755
[email protected]a25fa872010-03-25 02:57:58756 RenderbufferManager* renderbuffer_manager() {
757 return group_->renderbuffer_manager();
758 }
759
760 FramebufferManager* framebuffer_manager() {
761 return group_->framebuffer_manager();
762 }
763
orglofchcad5a6742014-11-07 19:51:12764 ValuebufferManager* valuebuffer_manager() {
765 return group_->valuebuffer_manager();
766 }
767
[email protected]3916c97e2010-02-25 03:20:50768 ProgramManager* program_manager() {
769 return group_->program_manager();
770 }
771
772 ShaderManager* shader_manager() {
773 return group_->shader_manager();
774 }
775
[email protected]03cef9b2014-04-03 15:58:14776 ShaderTranslatorCache* shader_translator_cache() {
777 return group_->shader_translator_cache();
778 }
779
[email protected]29a4d902013-02-26 20:18:06780 const TextureManager* texture_manager() const {
781 return group_->texture_manager();
782 }
783
[email protected]3916c97e2010-02-25 03:20:50784 TextureManager* texture_manager() {
785 return group_->texture_manager();
786 }
787
[email protected]78b514b2012-05-01 21:50:59788 MailboxManager* mailbox_manager() {
789 return group_->mailbox_manager();
790 }
791
[email protected]b63f1d62014-07-18 15:40:59792 ImageManager* image_manager() { return image_manager_.get(); }
[email protected]09d50362012-10-18 20:54:37793
[email protected]944b62f32012-09-27 02:20:46794 VertexArrayManager* vertex_array_manager() {
795 return vertex_array_manager_.get();
796 }
797
[email protected]7989c9e2013-01-23 06:39:26798 MemoryTracker* memory_tracker() {
799 return group_->memory_tracker();
800 }
801
802 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
803 MemoryTracker* tracker = memory_tracker();
804 if (tracker) {
805 return tracker->EnsureGPUMemoryAvailable(estimated_size);
806 }
807 return true;
808 }
809
[email protected]34ff8b0c2010-10-01 20:06:02810 bool IsOffscreenBufferMultisampled() const {
811 return offscreen_target_samples_ > 1;
812 }
813
[email protected]ed9f9cd2013-02-27 21:12:35814 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49815 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03816 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35817 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47818 }
819
820 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49821 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07822 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47823 }
824
825 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35826 void RemoveTexture(GLuint client_id) {
827 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50828 }
[email protected]a93bb842010-02-16 23:03:47829
[email protected]d37231fa2010-04-09 21:16:02830 // Get the size (in pixels) of the currently bound frame buffer (either FBO
831 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30832 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02833
[email protected]9edc6b22010-12-23 02:00:26834 // Get the format of the currently bound frame buffer (either FBO or regular
835 // back buffer)
[email protected]68586372013-12-11 01:27:59836 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26837 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46838 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26839
[email protected]a93bb842010-02-16 23:03:47840 // Wrapper for CompressedTexImage2D commands.
841 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37842 GLenum target,
843 GLint level,
844 GLenum internal_format,
845 GLsizei width,
846 GLsizei height,
847 GLint border,
848 GLsizei image_size,
849 const void* data);
[email protected]a93bb842010-02-16 23:03:47850
[email protected]cadde4a2010-07-31 17:10:43851 // Wrapper for CompressedTexSubImage2D.
852 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37853 GLenum target,
854 GLint level,
855 GLint xoffset,
856 GLint yoffset,
857 GLsizei width,
858 GLsizei height,
859 GLenum format,
860 GLsizei imageSize,
861 const void * data);
[email protected]cadde4a2010-07-31 17:10:43862
863 // Wrapper for CopyTexImage2D.
864 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37865 GLenum target,
866 GLint level,
867 GLenum internal_format,
868 GLint x,
869 GLint y,
870 GLsizei width,
871 GLsizei height,
872 GLint border);
[email protected]cadde4a2010-07-31 17:10:43873
[email protected]6d792ee12013-05-15 00:40:56874 // Wrapper for SwapBuffers.
875 void DoSwapBuffers();
876
[email protected]cadde4a2010-07-31 17:10:43877 // Wrapper for CopyTexSubImage2D.
878 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37879 GLenum target,
880 GLint level,
881 GLint xoffset,
882 GLint yoffset,
883 GLint x,
884 GLint y,
885 GLsizei width,
886 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43887
[email protected]f598f422012-12-07 08:30:03888 // Validation for TexSubImage2D.
889 bool ValidateTexSubImage2D(
890 error::Error* error,
891 const char* function_name,
892 GLenum target,
893 GLint level,
894 GLint xoffset,
895 GLint yoffset,
896 GLsizei width,
897 GLsizei height,
898 GLenum format,
899 GLenum type,
900 const void * data);
901
[email protected]cadde4a2010-07-31 17:10:43902 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03903 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37904 GLenum target,
905 GLint level,
906 GLint xoffset,
907 GLint yoffset,
908 GLsizei width,
909 GLsizei height,
910 GLenum format,
911 GLenum type,
912 const void * data);
[email protected]cadde4a2010-07-31 17:10:43913
[email protected]32145a92012-12-17 09:01:59914 // Extra validation for async tex(Sub)Image2D.
915 bool ValidateAsyncTransfer(
916 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47917 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59918 GLenum target,
919 GLint level,
920 const void * data);
921
[email protected]e51bdf32011-11-23 22:21:46922 // Wrapper for TexImageIOSurface2DCHROMIUM.
923 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37924 GLenum target,
925 GLsizei width,
926 GLsizei height,
927 GLuint io_surface_id,
928 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46929
[email protected]43410e92012-04-20 17:06:28930 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37931 GLenum target,
932 GLuint source_id,
933 GLuint target_id,
934 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54935 GLenum internal_format,
936 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28937
[email protected]97dc7cbe2011-12-06 17:26:17938 // Wrapper for TexStorage2DEXT.
939 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37940 GLenum target,
941 GLint levels,
942 GLenum internal_format,
943 GLsizei width,
944 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17945
[email protected]78b514b2012-05-01 21:50:59946 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22947 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
948 const GLbyte* key);
949 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
950 GLenum target, const GLbyte* data);
951
[email protected]78b514b2012-05-01 21:50:59952 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22953 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
954 GLuint client_id);
[email protected]78b514b2012-05-01 21:50:59955
orglofchcad5a6742014-11-07 19:51:12956 bool DoIsValuebufferCHROMIUM(GLuint client_id);
957 void DoBindValueBufferCHROMIUM(GLenum target, GLuint valuebuffer);
958 void DoSubscribeValueCHROMIUM(GLenum target, GLenum subscription);
959 void DoPopulateSubscribedValuesCHROMIUM(GLenum target);
960 void DoUniformValueBufferCHROMIUM(GLint location,
961 GLenum target,
962 GLenum subscription);
963
[email protected]09d50362012-10-18 20:54:37964 void DoBindTexImage2DCHROMIUM(
965 GLenum target,
966 GLint image_id);
967 void DoReleaseTexImage2DCHROMIUM(
968 GLenum target,
969 GLint image_id);
970
[email protected]94307712012-11-16 23:26:11971 void DoTraceEndCHROMIUM(void);
972
[email protected]2f143d482013-03-14 18:04:49973 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
974
[email protected]a6a09f852014-05-23 13:05:03975 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
976
kkinnunen337d59632014-08-26 10:19:57977 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
978 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
979
[email protected]ed9f9cd2013-02-27 21:12:35980 // Creates a Program for the given program.
981 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57982 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35983 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47984 }
985
[email protected]07f54fcc2009-12-22 02:46:30986 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35987 Program* GetProgram(GLuint client_id) {
988 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46989 }
[email protected]07f54fcc2009-12-22 02:46:30990
[email protected]cae20172012-12-07 00:06:19991#if defined(NDEBUG)
992 void LogClientServiceMapping(
993 const char* /* function_name */,
994 GLuint /* client_id */,
995 GLuint /* service_id */) {
996 }
997 template<typename T>
998 void LogClientServiceForInfo(
999 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
1000 }
1001#else
1002 void LogClientServiceMapping(
1003 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:261004 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:471005 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
1006 << ": client_id = " << client_id
1007 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:261008 }
[email protected]cae20172012-12-07 00:06:191009 }
1010 template<typename T>
1011 void LogClientServiceForInfo(
1012 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:261013 if (info) {
[email protected]cae20172012-12-07 00:06:191014 LogClientServiceMapping(function_name, client_id, info->service_id());
1015 }
1016 }
1017#endif
1018
[email protected]6b8cf1a2010-05-06 16:13:581019 // Gets the program info for the given program. If it's not a program
1020 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:351021 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:581022 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421023 Program* program = GetProgram(client_id);
1024 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351025 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511026 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431027 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581028 } else {
[email protected]ab09b612013-03-11 22:11:511029 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581030 }
1031 }
[email protected]df37b9932013-03-08 05:21:421032 LogClientServiceForInfo(program, client_id, function_name);
1033 return program;
[email protected]6b8cf1a2010-05-06 16:13:581034 }
1035
1036
[email protected]ed9f9cd2013-02-27 21:12:351037 // Creates a Shader for the given shader.
1038 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571039 GLuint client_id,
1040 GLuint service_id,
1041 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351042 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571043 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311044 }
1045
1046 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351047 Shader* GetShader(GLuint client_id) {
1048 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311049 }
1050
[email protected]6b8cf1a2010-05-06 16:13:581051 // Gets the shader info for the given shader. If it's not a shader generates a
1052 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351053 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581054 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421055 Shader* shader = GetShader(client_id);
1056 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351057 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511058 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431059 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581060 } else {
[email protected]ab09b612013-03-11 22:11:511061 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431062 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581063 }
1064 }
[email protected]df37b9932013-03-08 05:21:421065 LogClientServiceForInfo(shader, client_id, function_name);
1066 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581067 }
1068
[email protected]a93bb842010-02-16 23:03:471069 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351070 void CreateBuffer(GLuint client_id, GLuint service_id) {
1071 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471072 }
1073
[email protected]07f54fcc2009-12-22 02:46:301074 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211075 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071076 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1077 return buffer;
[email protected]1d32bc82010-01-13 22:06:461078 }
[email protected]07f54fcc2009-12-22 02:46:301079
[email protected]a93bb842010-02-16 23:03:471080 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1081 // on glDeleteBuffers so we can make sure the user does not try to render
1082 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351083 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471084
[email protected]a25fa872010-03-25 02:57:581085 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351086 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1087 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581088 }
1089
1090 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061091 Framebuffer* GetFramebuffer(GLuint client_id) {
1092 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581093 }
1094
1095 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351096 void RemoveFramebuffer(GLuint client_id) {
1097 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581098 }
1099
1100 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351101 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1102 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031103 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581104 }
1105
1106 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271107 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1108 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581109 }
1110
1111 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351112 void RemoveRenderbuffer(GLuint client_id) {
1113 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581114 }
1115
orglofchcad5a6742014-11-07 19:51:121116 // Creates a valuebuffer info for the given valuebuffer.
1117 void CreateValuebuffer(GLuint client_id) {
1118 return valuebuffer_manager()->CreateValuebuffer(client_id);
1119 }
1120
1121 // Gets the valuebuffer info for a given valuebuffer.
1122 Valuebuffer* GetValuebuffer(GLuint client_id) {
1123 return valuebuffer_manager()->GetValuebuffer(client_id);
1124 }
1125
1126 // Removes the valuebuffer info for the given valuebuffer.
1127 void RemoveValuebuffer(GLuint client_id) {
1128 valuebuffer_manager()->RemoveValuebuffer(client_id);
1129 }
1130
[email protected]944b62f32012-09-27 02:20:461131 // Gets the vertex attrib manager for the given vertex array.
1132 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1133 VertexAttribManager* info =
1134 vertex_array_manager()->GetVertexAttribManager(client_id);
1135 return info;
1136 }
1137
1138 // Removes the vertex attrib manager for the given vertex array.
1139 void RemoveVertexAttribManager(GLuint client_id) {
1140 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1141 }
1142
1143 // Creates a vertex attrib manager for the given vertex array.
[email protected]da364812014-05-09 21:39:481144 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1145 GLuint client_id,
1146 GLuint service_id,
1147 bool client_visible) {
1148 return vertex_array_manager()->CreateVertexAttribManager(
1149 client_id, service_id, group_->max_vertex_attribs(), client_visible);
[email protected]944b62f32012-09-27 02:20:461150 }
1151
[email protected]258a3313f2011-10-18 20:13:571152 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331153 void DoBindUniformLocationCHROMIUM(
1154 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571155
[email protected]558847a2010-03-24 07:02:541156 error::Error GetAttribLocationHelper(
1157 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1158 const std::string& name_str);
1159
1160 error::Error GetUniformLocationHelper(
1161 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1162 const std::string& name_str);
1163
[email protected]3916c97e2010-02-25 03:20:501164 // Helper for glShaderSource.
1165 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031166 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301167
[email protected]0d6bfdc2011-11-02 01:32:201168 // Clear any textures used by the current program.
1169 bool ClearUnclearedTextures();
1170
[email protected]0d6bfdc2011-11-02 01:32:201171 // Clears any uncleared attachments attached to the given frame buffer.
1172 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061173 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281174
[email protected]0d6bfdc2011-11-02 01:32:201175 // overridden from GLES2Decoder
dcheng1f4d1d72014-10-21 16:21:581176 bool ClearLevel(unsigned service_id,
1177 unsigned bind_target,
1178 unsigned target,
1179 int level,
1180 unsigned internal_format,
1181 unsigned format,
1182 unsigned type,
1183 int width,
1184 int height,
1185 bool is_texture_immutable) override;
[email protected]0d6bfdc2011-11-02 01:32:201186
[email protected]c007aa02010-09-02 22:22:401187 // Restore all GL state that affects clearing.
1188 void RestoreClearState();
1189
[email protected]3a2e7c7b2010-08-06 01:12:281190 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461191 // Returns: true if glEnable/glDisable should actually be called.
1192 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281193
[email protected]0d6bfdc2011-11-02 01:32:201194 // Check that the currently bound framebuffers are valid.
1195 // Generates GL error if not.
1196 bool CheckBoundFramebuffersValid(const char* func_name);
1197
[email protected]2ea5950d2014-07-09 18:20:341198 // Check that the currently bound read framebuffer has a color image
1199 // attached. Generates GL error if not.
1200 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1201
zmo383512cf2014-10-14 00:11:001202 // Check that the currently bound read framebuffer's color image
1203 // isn't the target texture of the glCopyTex{Sub}Image2D.
1204 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
1205
[email protected]0d6bfdc2011-11-02 01:32:201206 // Check if a framebuffer meets our requirements.
1207 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351208 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201209 GLenum target,
1210 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271211
orglofchcad5a6742014-11-07 19:51:121212 // Check if the current valuebuffer exists and is valid. If not generates
1213 // the appropriate GL error. Returns true if the current valuebuffer is in
1214 // a usable state.
1215 bool CheckCurrentValuebuffer(const char* function_name);
1216
1217 // Check if the current valuebuffer exists and is valiud and that the
1218 // value buffer is actually subscribed to the given subscription
1219 bool CheckCurrentValuebufferForSubscription(GLenum subscription,
1220 const char* function_name);
1221
1222 // Check if the location can be used for the given subscription target. If not
1223 // generates the appropriate GL error. Returns true if the location is usable
1224 bool CheckSubscriptionTarget(GLint location,
1225 GLenum subscription,
1226 const char* function_name);
1227
[email protected]939e7362010-05-13 20:49:101228 // Checks if the current program exists and is valid. If not generates the
1229 // appropriate GL error. Returns true if the current program is in a usable
1230 // state.
1231 bool CheckCurrentProgram(const char* function_name);
1232
1233 // Checks if the current program exists and is valid and that location is not
1234 // -1. If the current program is not valid generates the appropriate GL
1235 // error. Returns true if the current program is in a usable state and
1236 // location is not -1.
1237 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1238
zmof9a81360f2014-10-17 00:06:141239 // Checks if the current program samples a texture that is also the color
1240 // image of the current bound framebuffer, i.e., the source and destination
1241 // of the draw operation are the same.
1242 bool CheckDrawingFeedbackLoops();
1243
orglofchcad5a6742014-11-07 19:51:121244 // Checks if |api_type| is valid for the given uniform
1245 // If the api type is not valid generates the appropriate GL
1246 // error. Returns true if |api_type| is valid for the uniform
1247 bool CheckUniformForApiType(const Program::UniformInfo* info,
1248 const char* function_name,
1249 Program::UniformApiType api_type);
1250
[email protected]939e7362010-05-13 20:49:101251 // Gets the type of a uniform for a location in the current program. Sets GL
1252 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361253 // program is valid and the location exists. Adjusts count so it
1254 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131255 bool PrepForSetUniformByLocation(GLint fake_location,
1256 const char* function_name,
1257 Program::UniformApiType api_type,
1258 GLint* real_location,
1259 GLenum* type,
1260 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101261
[email protected]b177ae22011-11-01 03:29:111262 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021263 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111264
[email protected]b273e432010-04-12 17:23:581265 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1266 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1267
[email protected]ac77603c72013-03-08 13:52:061268 // Helper for glGetVertexAttrib
1269 void GetVertexAttribHelper(
1270 const VertexAttrib* attrib, GLenum pname, GLint* param);
1271
[email protected]96449d2c2009-11-25 00:01:321272 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031273 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321274
1275 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031276 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321277
[email protected]3916c97e2010-02-25 03:20:501278 // Wrapper for glActiveTexture
1279 void DoActiveTexture(GLenum texture_unit);
1280
[email protected]ae51d192010-04-27 00:48:031281 // Wrapper for glAttachShader
1282 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1283
[email protected]96449d2c2009-11-25 00:01:321284 // Wrapper for glBindBuffer since we need to track the current targets.
1285 void DoBindBuffer(GLenum target, GLuint buffer);
1286
[email protected]86093972010-03-11 00:13:561287 // Wrapper for glBindFramebuffer since we need to track the current targets.
1288 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1289
1290 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1291 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1292
[email protected]a93bb842010-02-16 23:03:471293 // Wrapper for glBindTexture since we need to track the current targets.
1294 void DoBindTexture(GLenum target, GLuint texture);
1295
[email protected]944b62f32012-09-27 02:20:461296 // Wrapper for glBindVertexArrayOES
1297 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571298 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461299
[email protected]49cabed2013-11-13 18:15:181300 // Wrapper for glBlitFramebufferCHROMIUM.
1301 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301302 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1303 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1304 GLbitfield mask, GLenum filter);
1305
[email protected]36cef8ce2010-03-16 07:34:451306 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111307 void DoBufferSubData(
1308 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1309
[email protected]36cef8ce2010-03-16 07:34:451310 // Wrapper for glCheckFramebufferStatus
1311 GLenum DoCheckFramebufferStatus(GLenum target);
1312
[email protected]3a03a8f2011-03-19 00:51:271313 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081314 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271315
[email protected]88a61bf2012-10-27 13:00:421316 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421317 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251318 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281319
[email protected]45bf5152010-02-12 00:11:311320 // Wrapper for glCompileShader.
1321 void DoCompileShader(GLuint shader);
1322
[email protected]ae51d192010-04-27 00:48:031323 // Wrapper for glDetachShader
1324 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1325
[email protected]3a2e7c7b2010-08-06 01:12:281326 // Wrapper for glDisable
1327 void DoDisable(GLenum cap);
1328
[email protected]07f54fcc2009-12-22 02:46:301329 // Wrapper for glDisableVertexAttribArray.
1330 void DoDisableVertexAttribArray(GLuint index);
1331
[email protected]60f22d32012-12-12 00:31:581332 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1333 // attachments.
1334 void DoDiscardFramebufferEXT(GLenum target,
1335 GLsizei numAttachments,
1336 const GLenum* attachments);
1337
[email protected]3a2e7c7b2010-08-06 01:12:281338 // Wrapper for glEnable
1339 void DoEnable(GLenum cap);
1340
[email protected]07f54fcc2009-12-22 02:46:301341 // Wrapper for glEnableVertexAttribArray.
1342 void DoEnableVertexAttribArray(GLuint index);
1343
[email protected]882ba1e22012-03-08 19:02:531344 // Wrapper for glFinish.
1345 void DoFinish();
1346
1347 // Wrapper for glFlush.
1348 void DoFlush();
1349
[email protected]36cef8ce2010-03-16 07:34:451350 // Wrapper for glFramebufferRenderbufffer.
1351 void DoFramebufferRenderbuffer(
1352 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1353 GLuint renderbuffer);
1354
1355 // Wrapper for glFramebufferTexture2D.
1356 void DoFramebufferTexture2D(
1357 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1358 GLint level);
1359
[email protected]7d3c36e2013-07-12 14:13:161360 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1361 void DoFramebufferTexture2DMultisample(
1362 GLenum target, GLenum attachment, GLenum textarget,
1363 GLuint texture, GLint level, GLsizei samples);
1364
1365 // Common implementation for both DoFramebufferTexture2D wrappers.
1366 void DoFramebufferTexture2DCommon(const char* name,
1367 GLenum target, GLenum attachment, GLenum textarget,
1368 GLuint texture, GLint level, GLsizei samples);
1369
zmo84c08202014-11-23 15:28:401370 // Wrapper for glFramebufferTextureLayer.
1371 void DoFramebufferTextureLayer(
1372 GLenum target, GLenum attachment, GLuint texture, GLint level,
1373 GLint layer);
1374
[email protected]a93bb842010-02-16 23:03:471375 // Wrapper for glGenerateMipmap
1376 void DoGenerateMipmap(GLenum target);
1377
[email protected]7d3c36e2013-07-12 14:13:161378 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1379 // to account for different pname values defined in different extension
1380 // variants.
1381 GLenum AdjustGetPname(GLenum pname);
1382
[email protected]b273e432010-04-12 17:23:581383 // Wrapper for DoGetBooleanv.
1384 void DoGetBooleanv(GLenum pname, GLboolean* params);
1385
1386 // Wrapper for DoGetFloatv.
1387 void DoGetFloatv(GLenum pname, GLfloat* params);
1388
[email protected]36cef8ce2010-03-16 07:34:451389 // Wrapper for glGetFramebufferAttachmentParameteriv.
1390 void DoGetFramebufferAttachmentParameteriv(
1391 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1392
[email protected]a0c3e972010-04-21 00:49:131393 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581394 void DoGetIntegerv(GLenum pname, GLint* params);
1395
[email protected]29a9eb52010-04-13 09:04:231396 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061397 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231398 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1399
[email protected]17cfbe0e2013-03-07 01:26:081400 // Wrapper for glGetBufferParameteriv.
1401 void DoGetBufferParameteriv(
1402 GLenum target, GLenum pname, GLint* params);
1403
[email protected]a0c3e972010-04-21 00:49:131404 // Wrapper for glGetProgramiv.
1405 void DoGetProgramiv(
1406 GLuint program_id, GLenum pname, GLint* params);
1407
[email protected]36cef8ce2010-03-16 07:34:451408 // Wrapper for glRenderbufferParameteriv.
1409 void DoGetRenderbufferParameteriv(
1410 GLenum target, GLenum pname, GLint* params);
1411
[email protected]ddd968b82010-03-02 00:44:291412 // Wrapper for glGetShaderiv
1413 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1414
[email protected]4c6f5462014-03-05 00:26:561415 // Wrappers for glGetTexParameter.
1416 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1417 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1418 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1419
[email protected]b1122982010-05-17 23:04:241420 // Wrappers for glGetVertexAttrib.
1421 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1422 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1423
[email protected]1958e0e2010-04-22 05:17:151424 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241425 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151426 bool DoIsBuffer(GLuint client_id);
1427 bool DoIsFramebuffer(GLuint client_id);
1428 bool DoIsProgram(GLuint client_id);
1429 bool DoIsRenderbuffer(GLuint client_id);
1430 bool DoIsShader(GLuint client_id);
1431 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461432 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151433
[email protected]07f54fcc2009-12-22 02:46:301434 // Wrapper for glLinkProgram
1435 void DoLinkProgram(GLuint program);
1436
[email protected]36cef8ce2010-03-16 07:34:451437 // Wrapper for glRenderbufferStorage.
1438 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031439 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451440
[email protected]49cabed2013-11-13 18:15:181441 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1442 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301443 GLenum target, GLsizei samples, GLenum internalformat,
1444 GLsizei width, GLsizei height);
1445
[email protected]49cabed2013-11-13 18:15:181446 // Handler for glRenderbufferStorageMultisampleEXT
1447 // (multisampled_render_to_texture).
1448 void DoRenderbufferStorageMultisampleEXT(
1449 GLenum target, GLsizei samples, GLenum internalformat,
1450 GLsizei width, GLsizei height);
1451
1452 // Common validation for multisample extensions.
1453 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1454 GLenum internalformat,
1455 GLsizei width,
1456 GLsizei height);
1457
[email protected]4a4c18b2013-09-13 22:50:101458 // Verifies that the currently bound multisample renderbuffer is valid
1459 // Very slow! Only done on platforms with driver bugs that return invalid
1460 // buffers under memory pressure
1461 bool VerifyMultisampleRenderbufferIntegrity(
1462 GLuint renderbuffer, GLenum format);
1463
[email protected]b273e432010-04-12 17:23:581464 // Wrapper for glReleaseShaderCompiler.
1465 void DoReleaseShaderCompiler() { }
1466
[email protected]3916c97e2010-02-25 03:20:501467 // Wrappers for glTexParameter functions.
1468 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1469 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1470 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1471 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1472
1473 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1474 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121475 void DoUniform1i(GLint fake_location, GLint v0);
1476 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1477 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1478 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1479 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101480
1481 // Wrappers for glUniformfv because some drivers don't correctly accept
1482 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121483 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1484 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1485 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1486 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501487
[email protected]43c2f1f2011-03-25 18:35:361488 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121489 GLint fake_location, GLsizei count, GLboolean transpose,
1490 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361491 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121492 GLint fake_location, GLsizei count, GLboolean transpose,
1493 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361494 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121495 GLint fake_location, GLsizei count, GLboolean transpose,
1496 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361497
[email protected]af6380962012-11-29 23:24:131498 bool SetVertexAttribValue(
1499 const char* function_name, GLuint index, const GLfloat* value);
1500
[email protected]b1122982010-05-17 23:04:241501 // Wrappers for glVertexAttrib??
1502 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1503 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1504 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1505 void DoVertexAttrib4f(
1506 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1507 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1508 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1509 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1510 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1511
[email protected]43410e92012-04-20 17:06:281512 // Wrapper for glViewport
1513 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1514
[email protected]07f54fcc2009-12-22 02:46:301515 // Wrapper for glUseProgram
1516 void DoUseProgram(GLuint program);
1517
[email protected]ae51d192010-04-27 00:48:031518 // Wrapper for glValidateProgram.
1519 void DoValidateProgram(GLuint program_client_id);
1520
[email protected]d2a0e1a2012-08-12 02:25:011521 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1522 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1523 void DoPopGroupMarkerEXT(void);
1524
[email protected]4e8a5b122010-05-08 22:00:101525 // Gets the number of values that will be returned by glGetXXX. Returns
1526 // false if pname is unknown.
1527 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1528
[email protected]07f54fcc2009-12-22 02:46:301529 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431530 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101531 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1532 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301533
[email protected]c13e1da62011-09-09 21:48:301534 // Returns true if successful, simulated will be true if attrib0 was
1535 // simulated.
[email protected]c6aef902012-02-14 03:31:421536 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431537 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231538 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241539
[email protected]91c94eb2013-10-22 10:32:541540 // If an image is bound to texture, this will call Will/DidUseTexImage
1541 // if needed.
1542 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1543 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1544
1545 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111546 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541547 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501548
[email protected]8fbedc02010-11-18 18:43:401549 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421550 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431551 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421552 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401553 void RestoreStateForSimulatedFixedAttribs();
1554
[email protected]c6aef902012-02-14 03:31:421555 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101556 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421557 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431558 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421559 bool instanced, GLenum mode, GLint first, GLsizei count,
1560 GLsizei primcount);
1561 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431562 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421563 bool instanced, GLenum mode, GLsizei count, GLenum type,
1564 int32 offset, GLsizei primcount);
1565
[email protected]61eeb33f2011-07-26 15:30:311566 GLenum GetBindTargetForSamplerType(GLenum type) {
1567 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461568 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1569 switch (type) {
1570 case GL_SAMPLER_2D:
1571 return GL_TEXTURE_2D;
1572 case GL_SAMPLER_CUBE:
1573 return GL_TEXTURE_CUBE_MAP;
1574 case GL_SAMPLER_EXTERNAL_OES:
1575 return GL_TEXTURE_EXTERNAL_OES;
1576 case GL_SAMPLER_2D_RECT_ARB:
1577 return GL_TEXTURE_RECTANGLE_ARB;
1578 }
1579
1580 NOTREACHED();
1581 return 0;
[email protected]61eeb33f2011-07-26 15:30:311582 }
1583
[email protected]8e3e0662010-08-23 18:46:301584 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061585 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1586 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301587 switch (target) {
1588 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451589 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341590 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301591 break;
[email protected]ebfb73c2012-08-15 02:37:451592 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341593 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301594 break;
1595 default:
1596 NOTREACHED();
1597 break;
1598 }
[email protected]4d8f0dd2013-03-09 14:37:061599 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301600 }
1601
[email protected]ed9f9cd2013-02-27 21:12:351602 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201603 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271604 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201605 switch (target) {
1606 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111607 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201608 break;
1609 default:
1610 NOTREACHED();
1611 break;
1612 }
[email protected]ee2a79c32013-03-10 03:50:271613 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201614 }
1615
[email protected]f7b85372010-02-03 01:11:371616 // Validates the program and location for a glGetUniform call and returns
1617 // a SizeResult setup to receive the result. Returns true if glGetUniform
1618 // should be called.
1619 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121620 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371621 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121622 error::Error* error, GLint* real_location, GLuint* service_id,
1623 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371624
jbauman7a059312014-10-16 19:30:541625 void MaybeExitOnContextLost();
dcheng1f4d1d72014-10-21 16:21:581626 bool WasContextLost() override;
1627 bool WasContextLostByRobustnessExtension() override;
1628 void LoseContext(uint32 reset_status) override;
[email protected]38d139d2011-07-14 00:38:431629
[email protected]e51bdf32011-11-23 22:21:461630#if defined(OS_MACOSX)
1631 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1632#endif
1633
[email protected]ad84a3a2012-06-08 21:42:431634 bool ValidateCompressedTexDimensions(
1635 const char* function_name,
1636 GLint level, GLsizei width, GLsizei height, GLenum format);
1637 bool ValidateCompressedTexFuncData(
1638 const char* function_name,
1639 GLsizei width, GLsizei height, GLenum format, size_t size);
1640 bool ValidateCompressedTexSubDimensions(
1641 const char* function_name,
1642 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1643 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351644 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431645
[email protected]ab09b612013-03-11 22:11:511646 void RenderWarning(const char* filename, int line, const std::string& msg);
1647 void PerformanceWarning(
1648 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011649
[email protected]62e155e2012-10-23 22:43:151650 const FeatureInfo::FeatureFlags& features() const {
1651 return feature_info_->feature_flags();
1652 }
1653
1654 const FeatureInfo::Workarounds& workarounds() const {
1655 return feature_info_->workarounds();
1656 }
1657
[email protected]a7266a92012-06-28 02:11:081658 bool ShouldDeferDraws() {
1659 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341660 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081661 surface_->DeferDraws();
1662 }
1663
[email protected]09e17272012-11-30 10:30:441664 bool ShouldDeferReads() {
1665 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341666 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441667 surface_->DeferDraws();
1668 }
1669
[email protected]c76fe672013-12-13 23:30:221670 error::Error WillAccessBoundFramebufferForDraw() {
1671 if (ShouldDeferDraws())
1672 return error::kDeferCommandUntilLater;
1673 if (!offscreen_target_frame_buffer_.get() &&
1674 !framebuffer_state_.bound_draw_framebuffer.get() &&
1675 !surface_->SetBackbufferAllocation(true))
1676 return error::kLostContext;
1677 return error::kNoError;
1678 }
1679
1680 error::Error WillAccessBoundFramebufferForRead() {
1681 if (ShouldDeferReads())
1682 return error::kDeferCommandUntilLater;
1683 if (!offscreen_target_frame_buffer_.get() &&
1684 !framebuffer_state_.bound_read_framebuffer.get() &&
1685 !surface_->SetBackbufferAllocation(true))
1686 return error::kLostContext;
1687 return error::kNoError;
1688 }
1689
vmiura8266ca72014-09-09 21:37:001690 // Set remaining commands to process to 0 to force DoCommands to return
1691 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1692 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1693
[email protected]5a36dc132013-07-23 23:17:551694 void ProcessPendingReadPixels();
1695 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1696
[email protected]96449d2c2009-11-25 00:01:321697 // Generate a member function prototype for each command in an automated and
1698 // typesafe way.
vmiuracd108592014-09-08 14:36:341699#define GLES2_CMD_OP(name) \
1700 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321701
1702 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1703
1704 #undef GLES2_CMD_OP
1705
[email protected]2f2d7042010-04-14 21:45:581706 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381707 scoped_refptr<gfx::GLSurface> surface_;
1708 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021709
[email protected]a3ded6d2010-10-19 06:44:391710 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351711 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391712
[email protected]1d82e822013-04-10 21:32:321713 DebugMarkerManager debug_marker_manager_;
1714 Logger logger_;
1715
[email protected]e259eb412012-10-13 05:47:241716 // All the state for this context.
1717 ContextState state_;
1718
[email protected]34ff8b0c2010-10-01 20:06:021719 // Current width and height of the offscreen frame buffer.
1720 gfx::Size offscreen_size_;
1721
[email protected]96449d2c2009-11-25 00:01:321722 // Util to help with GL.
1723 GLES2Util util_;
1724
[email protected]43410e92012-04-20 17:06:281725 // unpack flip y as last set by glPixelStorei
1726 bool unpack_flip_y_;
1727
[email protected]6c75c712012-06-19 15:43:171728 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281729 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171730 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281731
[email protected]b1122982010-05-17 23:04:241732 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1733 GLuint attrib_0_buffer_id_;
1734
1735 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131736 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241737
[email protected]fc753442011-02-04 19:49:491738 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1739 bool attrib_0_buffer_matches_value_;
1740
[email protected]b1122982010-05-17 23:04:241741 // The size of attrib 0.
1742 GLsizei attrib_0_size_;
1743
[email protected]8fbedc02010-11-18 18:43:401744 // The buffer used to simulate GL_FIXED attribs.
1745 GLuint fixed_attrib_buffer_id_;
1746
1747 // The size of fiixed attrib buffer.
1748 GLsizei fixed_attrib_buffer_size_;
1749
[email protected]b9363b22010-06-09 22:06:151750 // The offscreen frame buffer that the client renders to. With EGL, the
1751 // depth and stencil buffers are separate. With regular GL there is a single
1752 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1753 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351754 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1755 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1756 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1757 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1758 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021759 GLenum offscreen_target_color_format_;
1760 GLenum offscreen_target_depth_format_;
1761 GLenum offscreen_target_stencil_format_;
1762 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561763 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351764
[email protected]de26b3c2011-08-03 21:54:271765 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351766 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1767 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491768 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351769 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271770
1771 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351772 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1773 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051774 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351775
[email protected]882ba1e22012-03-08 19:02:531776 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531777
[email protected]944b62f32012-09-27 02:20:461778 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1779
[email protected]b63f1d62014-07-18 15:40:591780 scoped_ptr<ImageManager> image_manager_;
1781
[email protected]729c0b42013-05-26 02:05:071782 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001783
[email protected]840a7e462013-02-27 01:29:511784 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481785
[email protected]e3932abb2013-03-13 00:01:371786 ShaderCacheCallback shader_cache_callback_;
1787
[email protected]85a4ac22013-05-31 01:58:471788 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421789
[email protected]32fe9aa2011-01-21 23:47:131790 // The format of the back buffer_
1791 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461792 bool back_buffer_has_depth_;
1793 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131794
achaulkcf5316f2014-09-26 19:28:421795 bool surfaceless_;
1796
[email protected]60f22d32012-12-12 00:31:581797 // Backbuffer attachments that are currently undefined.
1798 uint32 backbuffer_needs_clear_bits_;
1799
[email protected]a6a09f852014-05-23 13:05:031800 // The current decoder error communicates the decoder error through command
1801 // processing functions that do not return the error value. Should be set only
1802 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561803 error::Error current_decoder_error_;
1804
[email protected]b1d2dcb2010-05-17 19:24:181805 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041806 scoped_refptr<ShaderTranslator> vertex_translator_;
1807 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181808
[email protected]e82fb792011-09-22 00:33:291809 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411810
[email protected]915a59a12010-09-30 21:29:111811 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051812 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351813 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051814
[email protected]65225772011-05-12 21:10:241815 int frame_number_;
1816
vmiura8266ca72014-09-09 21:37:001817 // Number of commands remaining to be processed in DoCommands().
1818 int commands_to_process_;
1819
[email protected]706b69f2012-07-27 04:59:301820 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431821 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221822 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431823 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431824
[email protected]f0d74742011-10-03 16:31:041825 // These flags are used to override the state of the shared feature_info_
1826 // member. Because the same FeatureInfo instance may be shared among many
1827 // contexts, the assumptions on the availablity of extensions in WebGL
1828 // contexts may be broken. These flags override the shared state to preserve
1829 // WebGL semantics.
1830 bool force_webgl_glsl_validation_;
1831 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491832 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131833 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061834 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041835
[email protected]062c38b2012-01-18 03:25:101836 bool compile_shader_always_succeeds_;
1837
[email protected]828a3932014-04-02 14:43:131838 // An optional behaviour to lose the context and group when OOM.
1839 bool lose_context_when_out_of_memory_;
1840
[email protected]cae20172012-12-07 00:06:191841 // Log extra info.
1842 bool service_logging_;
1843
[email protected]e51bdf32011-11-23 22:21:461844#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531845 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461846 TextureToIOSurfaceMap texture_to_io_surface_map_;
1847#endif
1848
[email protected]43410e92012-04-20 17:06:281849 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
sievers2384f2b2014-11-18 02:10:351850 scoped_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_;
[email protected]43410e92012-04-20 17:06:281851
[email protected]1868a342012-11-07 15:56:021852 // Cached values of the currently assigned viewport dimensions.
1853 GLsizei viewport_max_width_;
1854 GLsizei viewport_max_height_;
1855
[email protected]63b465922012-09-06 02:04:521856 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521857 base::TimeDelta total_processing_commands_time_;
1858
[email protected]c986af502013-08-14 01:04:441859 // States related to each manager.
1860 DecoderTextureState texture_state_;
1861 DecoderFramebufferState framebuffer_state_;
1862
[email protected]fb97b662013-02-20 23:02:141863 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131864 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:241865 const unsigned char* cb_command_trace_category_;
[email protected]cac16542014-01-15 17:53:511866 int gpu_trace_level_;
1867 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:241868 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:111869
[email protected]5a36dc132013-07-23 23:17:551870 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1871
[email protected]4a4c18b2013-09-13 22:50:101872 // Used to validate multisample renderbuffers if needed
1873 GLuint validation_texture_;
1874 GLuint validation_fbo_multisample_;
1875 GLuint validation_fbo_;
1876
vmiuracd108592014-09-08 14:36:341877 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1878 uint32 immediate_data_size,
1879 const void* data);
1880
1881 // A struct to hold info about each command.
1882 struct CommandInfo {
1883 CmdHandler cmd_handler;
1884 uint8 arg_flags; // How to handle the arguments for this command
1885 uint8 cmd_flags; // How to handle this command
1886 uint16 arg_count; // How many arguments are expected for this command.
1887 };
1888
1889 // A table of CommandInfo for all the commands.
1890 static const CommandInfo command_info[kNumCommands - kStartPoint];
1891
[email protected]96449d2c2009-11-25 00:01:321892 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1893};
1894
vmiuracd108592014-09-08 14:36:341895const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1896#define GLES2_CMD_OP(name) \
1897 { \
1898 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
1899 cmds::name::cmd_flags, \
1900 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1901 } \
1902 , /* NOLINT */
1903 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1904#undef GLES2_CMD_OP
1905};
1906
[email protected]ab09b612013-03-11 22:11:511907ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301908 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511909 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301910 error_state_(error_state) {
1911 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351912}
1913
1914ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301915 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351916}
1917
[email protected]2b10c02d2014-01-29 16:43:021918static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361919 TextureUnit& info = state->texture_units[0];
1920 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021921 scoped_refptr<TextureRef> texture_ref;
1922 switch (target) {
1923 case GL_TEXTURE_2D:
1924 texture_ref = info.bound_texture_2d;
1925 break;
1926 case GL_TEXTURE_CUBE_MAP:
1927 texture_ref = info.bound_texture_cube_map;
1928 break;
1929 case GL_TEXTURE_EXTERNAL_OES:
1930 texture_ref = info.bound_texture_external_oes;
1931 break;
1932 case GL_TEXTURE_RECTANGLE_ARB:
1933 texture_ref = info.bound_texture_rectangle_arb;
1934 break;
1935 default:
1936 NOTREACHED();
1937 break;
1938 }
1939 if (texture_ref.get()) {
1940 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361941 } else {
1942 last_id = 0;
1943 }
1944
[email protected]2b10c02d2014-01-29 16:43:021945 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361946 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1947}
1948
[email protected]2b10c02d2014-01-29 16:43:021949ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1950 GLuint id,
1951 GLenum target)
1952 : state_(state),
1953 target_(target) {
[email protected]ab09b612013-03-11 22:11:511954 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021955 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351956
1957 // TODO(apatrick): Check if there are any other states that need to be reset
1958 // before binding a new texture.
1959 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021960 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351961}
1962
[email protected]2b10c02d2014-01-29 16:43:021963ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511964 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021965 "ScopedTextureBinder::dtor", state_->GetErrorState());
1966 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351967}
1968
[email protected]18e785a2013-10-09 03:29:411969ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351970 GLuint id)
[email protected]18e785a2013-10-09 03:29:411971 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511972 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411973 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351974 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1975}
1976
1977ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511978 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411979 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1980 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351981}
1982
1983ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1984 GLuint id)
1985 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511986 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301987 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351988 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451989 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351990}
1991
1992ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511993 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301994 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:301995 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351996}
1997
[email protected]34ff8b0c2010-10-01 20:06:021998ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271999 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:522000 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:342001 resolve_and_bind_ = (
2002 decoder_->offscreen_target_frame_buffer_.get() &&
2003 decoder_->IsOffscreenBufferMultisampled() &&
2004 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
2005 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:022006 if (!resolve_and_bind_)
2007 return;
2008
[email protected]ab09b612013-03-11 22:11:512009 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302010 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022011 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
2012 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:272013 GLuint targetid;
2014 if (internal) {
2015 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
2016 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:352017 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:272018 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352019 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:362020 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:272021 decoder_->offscreen_resolved_color_texture_->Create();
2022
2023 DCHECK(decoder_->offscreen_saved_color_format_);
2024 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:092025 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
2026 false);
[email protected]de26b3c2011-08-03 21:54:272027 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
2028 decoder_->offscreen_resolved_color_texture_.get());
2029 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
2030 GL_FRAMEBUFFER_COMPLETE) {
2031 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
2032 << "because offscreen resolved FBO was incomplete.";
2033 return;
2034 }
2035 }
2036 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
2037 } else {
2038 targetid = decoder_->offscreen_saved_frame_buffer_->id();
2039 }
2040 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022041 const int width = decoder_->offscreen_size_.width();
2042 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:452043 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:182044 decoder->BlitFramebufferHelper(0,
2045 0,
2046 width,
2047 height,
2048 0,
2049 0,
2050 width,
2051 height,
2052 GL_COLOR_BUFFER_BIT,
2053 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:272054 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022055}
2056
2057ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
2058 if (!resolve_and_bind_)
2059 return;
2060
[email protected]ab09b612013-03-11 22:11:512061 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302062 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022063 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222064 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452065 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182066 }
[email protected]34ff8b0c2010-10-01 20:06:022067}
2068
[email protected]ce296892013-10-24 22:04:362069BackTexture::BackTexture(
2070 MemoryTracker* memory_tracker,
2071 ContextState* state)
2072 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2073 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482074 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252075 id_(0) {
[email protected]6217d392010-03-25 22:08:352076}
2077
[email protected]ed9f9cd2013-02-27 21:12:352078BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352079 // This does not destroy the render texture because that would require that
2080 // the associated GL context was current. Just check that it was explicitly
2081 // destroyed.
2082 DCHECK_EQ(id_, 0u);
2083}
2084
[email protected]ed9f9cd2013-02-27 21:12:352085void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302086 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362087 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352088 Destroy();
2089 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022090 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262091 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2092 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582093 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2094 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162095
2096 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2097 // never called on an offscreen context, no data will ever be uploaded to the
2098 // saved offscreen color texture (it is deferred until to when SwapBuffers
2099 // is called). My idea is that some nvidia drivers might have a bug where
2100 // deleting a texture that has never been populated might cause a
2101 // crash.
2102 glTexImage2D(
2103 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482104
2105 bytes_allocated_ = 16u * 16u * 4u;
2106 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352107}
2108
[email protected]ed9f9cd2013-02-27 21:12:352109bool BackTexture::AllocateStorage(
2110 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352111 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302112 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362113 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022114 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092115 uint32 image_size = 0;
2116 GLES2Util::ComputeImageDataSizes(
2117 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
2118 NULL, NULL);
2119
[email protected]7989c9e2013-01-23 06:39:262120 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2121 return false;
2122 }
2123
[email protected]40d90a22013-04-09 03:39:552124 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092125 if (zero) {
2126 zero_data.reset(new char[image_size]);
2127 memset(zero_data.get(), 0, image_size);
2128 }
[email protected]6217d392010-03-25 22:08:352129
[email protected]8f1d2aa2013-05-10 23:45:382130 glTexImage2D(GL_TEXTURE_2D,
2131 0, // mip level
2132 format,
2133 size.width(),
2134 size.height(),
2135 0, // border
2136 format,
2137 GL_UNSIGNED_BYTE,
2138 zero_data.get());
[email protected]6217d392010-03-25 22:08:352139
[email protected]d37231fa2010-04-09 21:16:022140 size_ = size;
2141
[email protected]1078f912011-12-23 13:12:142142 bool success = glGetError() == GL_NO_ERROR;
2143 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482144 memory_tracker_.TrackMemFree(bytes_allocated_);
2145 bytes_allocated_ = image_size;
2146 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142147 }
2148 return success;
[email protected]6217d392010-03-25 22:08:352149}
2150
[email protected]ed9f9cd2013-02-27 21:12:352151void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352152 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302153 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362154 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022155 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352156 glCopyTexImage2D(GL_TEXTURE_2D,
2157 0, // level
[email protected]3a4d0c52011-06-29 23:11:582158 format,
[email protected]6217d392010-03-25 22:08:352159 0, 0,
2160 size.width(),
2161 size.height(),
2162 0); // border
2163}
2164
[email protected]ed9f9cd2013-02-27 21:12:352165void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352166 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302167 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362168 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352169 glDeleteTextures(1, &id_);
2170 id_ = 0;
2171 }
[email protected]68e81a4a62012-12-13 01:16:482172 memory_tracker_.TrackMemFree(bytes_allocated_);
2173 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352174}
2175
[email protected]ed9f9cd2013-02-27 21:12:352176void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052177 id_ = 0;
2178}
2179
[email protected]d5a28e452013-10-10 01:01:402180BackRenderbuffer::BackRenderbuffer(
2181 RenderbufferManager* renderbuffer_manager,
2182 MemoryTracker* memory_tracker,
2183 ContextState* state)
2184 : renderbuffer_manager_(renderbuffer_manager),
2185 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2186 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482187 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252188 id_(0) {
[email protected]6217d392010-03-25 22:08:352189}
2190
[email protected]ed9f9cd2013-02-27 21:12:352191BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352192 // This does not destroy the render buffer because that would require that
2193 // the associated GL context was current. Just check that it was explicitly
2194 // destroyed.
2195 DCHECK_EQ(id_, 0u);
2196}
2197
[email protected]ed9f9cd2013-02-27 21:12:352198void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302199 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402200 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352201 Destroy();
2202 glGenRenderbuffersEXT(1, &id_);
2203}
2204
[email protected]f42f05b2013-11-15 21:46:182205bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2206 const gfx::Size& size,
2207 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352208 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512209 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402210 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2211 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262212
2213 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402214 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232215 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262216 return false;
2217 }
2218
2219 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2220 return false;
2221 }
2222
[email protected]34ff8b0c2010-10-01 20:06:022223 if (samples <= 1) {
2224 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2225 format,
2226 size.width(),
2227 size.height());
2228 } else {
[email protected]f42f05b2013-11-15 21:46:182229 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2230 GL_RENDERBUFFER,
2231 samples,
2232 format,
2233 size.width(),
2234 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022235 }
[email protected]1078f912011-12-23 13:12:142236 bool success = glGetError() == GL_NO_ERROR;
2237 if (success) {
[email protected]d5a28e452013-10-10 01:01:402238 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482239 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262240 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402241 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482242 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142243 }
2244 return success;
[email protected]6217d392010-03-25 22:08:352245}
2246
[email protected]ed9f9cd2013-02-27 21:12:352247void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352248 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302249 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402250 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352251 glDeleteRenderbuffersEXT(1, &id_);
2252 id_ = 0;
2253 }
[email protected]68e81a4a62012-12-13 01:16:482254 memory_tracker_.TrackMemFree(bytes_allocated_);
2255 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352256}
2257
[email protected]ed9f9cd2013-02-27 21:12:352258void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052259 id_ = 0;
2260}
2261
[email protected]ed9f9cd2013-02-27 21:12:352262BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352263 : decoder_(decoder),
2264 id_(0) {
2265}
2266
[email protected]ed9f9cd2013-02-27 21:12:352267BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352268 // This does not destroy the frame buffer because that would require that
2269 // the associated GL context was current. Just check that it was explicitly
2270 // destroyed.
2271 DCHECK_EQ(id_, 0u);
2272}
2273
[email protected]ed9f9cd2013-02-27 21:12:352274void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302275 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2276 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352277 Destroy();
2278 glGenFramebuffersEXT(1, &id_);
2279}
2280
[email protected]ed9f9cd2013-02-27 21:12:352281void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352282 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512283 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302284 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352285 ScopedFrameBufferBinder binder(decoder_, id_);
2286 GLuint attach_id = texture ? texture->id() : 0;
2287 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2288 GL_COLOR_ATTACHMENT0,
2289 GL_TEXTURE_2D,
2290 attach_id,
2291 0);
2292}
2293
[email protected]ed9f9cd2013-02-27 21:12:352294void BackFramebuffer::AttachRenderBuffer(GLenum target,
2295 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352296 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512297 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302298 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352299 ScopedFrameBufferBinder binder(decoder_, id_);
2300 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2301 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152302 target,
[email protected]6217d392010-03-25 22:08:352303 GL_RENDERBUFFER,
2304 attach_id);
2305}
2306
[email protected]ed9f9cd2013-02-27 21:12:352307void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352308 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302309 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2310 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352311 glDeleteFramebuffersEXT(1, &id_);
2312 id_ = 0;
2313 }
2314}
2315
[email protected]ed9f9cd2013-02-27 21:12:352316void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052317 id_ = 0;
2318}
2319
[email protected]ed9f9cd2013-02-27 21:12:352320GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352321 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302322 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2323 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352324 ScopedFrameBufferBinder binder(decoder_, id_);
2325 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2326}
2327
[email protected]aa7666122011-09-02 19:45:522328GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2329 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322330}
2331
[email protected]aa7666122011-09-02 19:45:522332GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392333 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572334 group_(group),
[email protected]1d82e822013-04-10 21:32:322335 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132336 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282337 unpack_flip_y_(false),
2338 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172339 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242340 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492341 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242342 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402343 fixed_attrib_buffer_id_(0),
2344 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022345 offscreen_target_color_format_(0),
2346 offscreen_target_depth_format_(0),
2347 offscreen_target_stencil_format_(0),
2348 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562349 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052350 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132351 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462352 back_buffer_has_depth_(false),
2353 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422354 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582355 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562356 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052357 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112358 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002359 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432360 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302361 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512362 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222363 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432364 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042365 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102366 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492367 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132368 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062369 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282370 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132371 lose_context_when_out_of_memory_(false),
[email protected]cae20172012-12-07 00:06:192372 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2373 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022374 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102375 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002376 texture_state_(group_->feature_info()
2377 ->workarounds()
2378 .texsubimage2d_faster_than_teximage2d),
vmiura1c2b1de2014-09-19 19:03:242379 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2380 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
2381 gpu_trace_level_(2),
2382 gpu_trace_commands_(false),
2383 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102384 validation_texture_(0),
2385 validation_fbo_multisample_(0),
2386 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572387 DCHECK(group);
2388
[email protected]b1122982010-05-17 23:04:242389 attrib_0_value_.v[0] = 0.0f;
2390 attrib_0_value_.v[1] = 0.0f;
2391 attrib_0_value_.v[2] = 0.0f;
2392 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152393
[email protected]c2f8c8402010-12-06 18:07:242394 // The shader translator is used for WebGL even when running on EGL
2395 // because additional restrictions are needed (like only enabling
2396 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562397 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2398 // the empty string to CompileShader and this is not a valid shader.
2399 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002400 CommandLine::ForCurrentProcess()->HasSwitch(
2401 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152402 use_shader_translator_ = false;
2403 }
[email protected]96449d2c2009-11-25 00:01:322404}
2405
[email protected]80eb6b52012-01-19 00:14:412406GLES2DecoderImpl::~GLES2DecoderImpl() {
2407}
2408
[email protected]c410da802011-03-14 19:17:412409bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382410 const scoped_refptr<gfx::GLSurface>& surface,
2411 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232412 bool offscreen,
[email protected]c410da802011-03-14 19:17:412413 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292414 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242415 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322416 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382417 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302418 DCHECK(!context_.get());
2419
jbaumana7604692014-10-17 02:00:392420 surfaceless_ = surface->IsSurfaceless() && !offscreen;
achaulkcf5316f2014-09-26 19:28:422421
[email protected]55e136f2013-04-03 18:50:062422 set_initialized();
[email protected]b4af07d2014-08-20 00:11:572423 gpu_tracer_.reset(new GPUTracer(this));
[email protected]8f9b8dd2013-09-12 18:05:132424 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142425
[email protected]e844ae22012-01-14 03:36:262426 if (CommandLine::ForCurrentProcess()->HasSwitch(
2427 switches::kEnableGPUDebugging)) {
2428 set_debug(true);
2429 }
2430
[email protected]39ba4f02012-03-26 01:16:002431 if (CommandLine::ForCurrentProcess()->HasSwitch(
2432 switches::kEnableGPUCommandLogging)) {
2433 set_log_commands(true);
2434 }
2435
zmo84c08202014-11-23 15:28:402436 if (CommandLine::ForCurrentProcess()->HasSwitch(
2437 switches::kEnableUnsafeES3APIs)) {
2438 set_unsafe_es3_apis_enabled(true);
2439 }
2440
[email protected]062c38b2012-01-18 03:25:102441 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2442 switches::kCompileShaderAlwaysSucceeds);
2443
[email protected]63c9b052012-05-17 18:27:382444 // Take ownership of the context and surface. The surface can be replaced with
2445 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382446 context_ = context;
[email protected]63c9b052012-05-17 18:27:382447 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182448
[email protected]65f7efe2013-11-28 03:11:472449 ContextCreationAttribHelper attrib_parser;
2450 if (!attrib_parser.Parse(attribs))
2451 return false;
2452
[email protected]828a3932014-04-02 14:43:132453 // Save the loseContextWhenOutOfMemory context creation attribute.
2454 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402455 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132456
[email protected]65f7efe2013-11-28 03:11:472457 // If the failIfMajorPerformanceCaveat context creation attribute was true
2458 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402459 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472460 feature_info_->feature_flags().is_swiftshader) {
2461 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2462 Destroy(true);
2463 return false;
2464 }
2465
[email protected]956aec52013-09-05 15:41:192466 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222467 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392468 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422469 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382470 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032471 return false;
[email protected]a3ded6d2010-10-19 06:44:392472 }
[email protected]b64c24952012-04-19 03:20:272473 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282474
[email protected]e82fb792011-09-22 00:33:292475 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502476
[email protected]af6380962012-11-29 23:24:132477 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482478 vertex_array_manager_.reset(new VertexArrayManager());
2479
2480 GLuint default_vertex_attrib_service_id = 0;
2481 if (features().native_vertex_array_object) {
2482 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2483 glBindVertexArrayOES(default_vertex_attrib_service_id);
2484 }
2485
2486 state_.default_vertex_attrib_manager =
2487 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2488
[email protected]81f20a622014-04-18 01:54:522489 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002490 group_->max_vertex_attribs(),
2491 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462492
[email protected]81f20a622014-04-18 01:54:522493 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572494 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322495
[email protected]7cd76fd2013-06-02 21:11:112496 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532497
[email protected]b63f1d62014-07-18 15:40:592498 image_manager_.reset(new ImageManager);
2499
[email protected]302ce6d2011-07-07 23:28:112500 util_.set_num_compressed_texture_formats(
2501 validators_->compressed_texture_format.GetValues().size());
2502
[email protected]1071e572011-02-09 20:00:122503 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2504 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2505 // OpenGL ES 2.0 does not have this issue.
2506 glEnableVertexAttribArray(0);
2507 }
[email protected]b1122982010-05-17 23:04:242508 glGenBuffersARB(1, &attrib_0_buffer_id_);
2509 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2510 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2511 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402512 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082513
[email protected]1868a342012-11-07 15:56:022514 state_.texture_units.resize(group_->max_texture_units());
2515 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492516 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312517 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492518 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152519 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492520 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072521 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492522 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572523 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312524 }
[email protected]62e155e2012-10-23 22:43:152525 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492526 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072527 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492528 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572529 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462530 }
[email protected]370eaf12013-05-18 09:19:492531 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2532 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572533 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492534 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2535 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572536 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152537 }
[email protected]00f893d2010-08-24 18:55:492538 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502539 CHECK_GL_ERROR();
2540
[email protected]069944672012-04-25 20:52:232541 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402542 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542543 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022544 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432545 // max_sample_count must be initialized to a sane value. If
2546 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2547 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022548 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402549 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022550 max_sample_count);
2551 } else {
2552 offscreen_target_samples_ = 1;
2553 }
[email protected]845c4e32014-08-13 11:50:402554 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022555
2556 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2557 const bool rgb8_supported =
2558 context_->HasExtension("GL_OES_rgb8_rgba8");
2559 // The only available default render buffer formats in GLES2 have very
2560 // little precision. Don't enable multisampling unless 8-bit render
2561 // buffer formats are available--instead fall back to 8-bit textures.
2562 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402563 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022564 GL_RGBA8 : GL_RGB8;
2565 } else {
2566 offscreen_target_samples_ = 1;
[email protected]845c4e32014-08-13 11:50:402567 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022568 GL_RGBA : GL_RGB;
2569 }
2570
2571 // ANGLE only supports packed depth/stencil formats, so use it if it is
2572 // available.
2573 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182574 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272575 VLOG(1) << "GL_OES_packed_depth_stencil "
2576 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402577 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002578 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022579 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2580 offscreen_target_stencil_format_ = 0;
2581 } else {
2582 // It may be the case that this depth/stencil combination is not
2583 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402584 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022585 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402586 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022587 GL_STENCIL_INDEX8 : 0;
2588 }
2589 } else {
[email protected]845c4e32014-08-13 11:50:402590 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022591 GL_RGBA : GL_RGB;
2592
2593 // If depth is requested at all, use the packed depth stencil format if
2594 // it's available, as some desktop GL drivers don't support any non-packed
2595 // formats for depth attachments.
2596 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182597 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272598 VLOG(1) << "GL_EXT_packed_depth_stencil "
2599 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022600
[email protected]845c4e32014-08-13 11:50:402601 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002602 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022603 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2604 offscreen_target_stencil_format_ = 0;
2605 } else {
[email protected]845c4e32014-08-13 11:50:402606 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022607 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402608 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022609 GL_STENCIL_INDEX : 0;
2610 }
2611 }
2612
[email protected]845c4e32014-08-13 11:50:402613 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]97872062010-11-03 19:07:052614 GL_RGBA : GL_RGB;
2615
[email protected]6217d392010-03-25 22:08:352616 // Create the target frame buffer. This is the one that the client renders
2617 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352618 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352619 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022620 // Due to GLES2 format limitations, either the color texture (for
2621 // non-multisampling) or the color render buffer (for multisampling) will be
2622 // attached to the offscreen frame buffer. The render buffer has more
2623 // limited formats available to it, but the texture can't do multisampling.
2624 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402625 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2626 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022627 offscreen_target_color_render_buffer_->Create();
2628 } else {
[email protected]ce296892013-10-24 22:04:362629 offscreen_target_color_texture_.reset(new BackTexture(
2630 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022631 offscreen_target_color_texture_->Create();
2632 }
[email protected]d5a28e452013-10-10 01:01:402633 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2634 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152635 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402636 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2637 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152638 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352639
2640 // Create the saved offscreen texture. The target frame buffer is copied
2641 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352642 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022643 offscreen_saved_frame_buffer_->Create();
2644 //
[email protected]ce296892013-10-24 22:04:362645 offscreen_saved_color_texture_.reset(new BackTexture(
2646 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352647 offscreen_saved_color_texture_->Create();
2648
[email protected]6217d392010-03-25 22:08:352649 // Allocate the render buffers at their initial size and check the status
2650 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592651 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012652 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382653 Destroy(true);
[email protected]6217d392010-03-25 22:08:352654 return false;
2655 }
2656
[email protected]678a73f2012-12-19 19:22:092657 // Allocate the offscreen saved color texture.
2658 DCHECK(offscreen_saved_color_format_);
2659 offscreen_saved_color_texture_->AllocateStorage(
2660 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2661
2662 offscreen_saved_frame_buffer_->AttachRenderTexture(
2663 offscreen_saved_color_texture_.get());
2664 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2665 GL_FRAMEBUFFER_COMPLETE) {
2666 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2667 Destroy(true);
2668 return false;
2669 }
2670
[email protected]6217d392010-03-25 22:08:352671 // Bind to the new default frame buffer (the offscreen target frame buffer).
2672 // This should now be associated with ID zero.
2673 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102674 } else {
2675 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2676 // These are NOT if the back buffer has these proprorties. They are
2677 // if we want the command buffer to enforce them regardless of what
2678 // the real backbuffer is assuming the real back buffer gives us more than
2679 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2680 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2681 // can't do anything about that.
2682
achaulkcf5316f2014-09-26 19:28:422683 if (!surfaceless_) {
2684 GLint v = 0;
2685 glGetIntegerv(GL_ALPHA_BITS, &v);
2686 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2687 // the user requested RGB then RGB. If the user did not specify a
2688 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2689 back_buffer_color_format_ =
2690 (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
2691 glGetIntegerv(GL_DEPTH_BITS, &v);
2692 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
2693 glGetIntegerv(GL_STENCIL_BITS, &v);
2694 back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
2695 }
[email protected]6217d392010-03-25 22:08:352696 }
2697
[email protected]76a0ee102010-04-07 21:03:042698 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2699 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2700 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372701 // mailing list archives. It also implicitly enables the desktop GL
2702 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2703 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152704 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2705 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372706 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152707 }
[email protected]de17df392010-04-23 21:09:412708
[email protected]706b69f2012-07-27 04:59:302709 has_robustness_extension_ =
2710 context->HasExtension("GL_ARB_robustness") ||
oetuaho37cc50e2014-10-31 11:19:202711 context->HasExtension("GL_KHR_robustness") ||
[email protected]706b69f2012-07-27 04:59:302712 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432713
[email protected]c2f8c8402010-12-06 18:07:242714 if (!InitializeShaderTranslator()) {
2715 return false;
[email protected]de17df392010-04-23 21:09:412716 }
[email protected]76a0ee102010-04-07 21:03:042717
[email protected]e259eb412012-10-13 05:47:242718 state_.viewport_width = size.width();
2719 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282720
[email protected]5904806b2012-05-08 18:10:222721 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282722 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022723 viewport_max_width_ = viewport_params[0];
2724 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282725
[email protected]88a61bf2012-10-27 13:00:422726 state_.scissor_width = state_.viewport_width;
2727 state_.scissor_height = state_.viewport_height;
2728
[email protected]11f3e702012-06-19 19:00:012729 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342730 state_.InitCapabilities(NULL);
2731 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242732 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012733
2734 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2735 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2736 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2737 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
orglofchcad5a6742014-11-07 19:51:122738 DoBindValueBufferCHROMIUM(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, 0);
[email protected]11f3e702012-06-19 19:00:012739
achaulkcf5316f2014-09-26 19:28:422740 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002741#if defined(OS_ANDROID)
2742 // Temporary workaround for Android WebView because this clear ignores the
2743 // clip and corrupts that external UI of the App. Not calling glClear is ok
2744 // because the system already clears the buffer before each draw. Proper
2745 // fix might be setting the scissor clip properly before initialize. See
2746 // crbug.com/259023 for details.
2747 call_gl_clear = surface_->GetHandle();
2748#endif
2749 if (call_gl_clear) {
2750 // Clear the backbuffer.
2751 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2752 }
[email protected]561cc0a62013-05-07 18:34:452753
[email protected]b381ee32014-03-22 02:43:432754 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2755 if (feature_info_->workarounds()
2756 .disable_post_sub_buffers_for_onscreen_surfaces &&
2757 !surface->IsOffscreen())
2758 supports_post_sub_buffer_ = false;
2759
[email protected]62e155e2012-10-23 22:43:152760 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462761 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2762 }
[email protected]dd289a5d62012-06-30 22:05:462763
[email protected]9b753992013-04-27 02:04:412764 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2765 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242766 }
[email protected]85cb4682013-04-20 00:54:242767
[email protected]97419c02013-04-10 02:52:382768 // Only compositor contexts are known to use only the subset of GL
2769 // that can be safely migrated between the iGPU and the dGPU. Mark
2770 // those contexts as safe to forcibly transition between the GPUs.
2771 // http://crbug.com/180876, http://crbug.com/227228
2772 if (!offscreen)
2773 context_->SetSafeToForceGpuSwitch();
2774
[email protected]85a4ac22013-05-31 01:58:472775 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072776 AsyncPixelTransferManager::Create(context.get()));
2777 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592778
sievers2384f2b2014-11-18 02:10:352779 if (workarounds().gl_clear_broken) {
2780 DCHECK(!clear_framebuffer_blit_.get());
2781 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit");
2782 clear_framebuffer_blit_.reset(new ClearFramebufferResourceManager(this));
2783 if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR)
2784 return false;
2785 }
2786
[email protected]91c94eb2013-10-22 10:32:542787 framebuffer_manager()->AddObserver(this);
2788
[email protected]246a70452010-03-05 21:53:502789 return true;
[email protected]96449d2c2009-11-25 00:01:322790}
2791
[email protected]6d668892013-12-04 21:37:122792Capabilities GLES2DecoderImpl::GetCapabilities() {
2793 DCHECK(initialized());
2794
2795 Capabilities caps;
piman1c2e0a852014-11-12 05:17:552796 caps.VisitPrecisions([](GLenum shader, GLenum type,
2797 Capabilities::ShaderPrecision* shader_precision) {
2798 GLint range[2] = {0, 0};
2799 GLint precision = 0;
2800 GetShaderPrecisionFormatImpl(shader, type, range, &precision);
2801 shader_precision->min_range = range[0];
2802 shader_precision->max_range = range[1];
2803 shader_precision->precision = precision;
2804 });
2805 DoGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
2806 &caps.max_combined_texture_image_units);
2807 DoGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps.max_cube_map_texture_size);
2808 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
2809 &caps.max_fragment_uniform_vectors);
2810 DoGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps.max_renderbuffer_size);
2811 DoGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps.max_texture_image_units);
2812 DoGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.max_texture_size);
2813 DoGetIntegerv(GL_MAX_VARYING_VECTORS, &caps.max_varying_vectors);
2814 DoGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps.max_vertex_attribs);
2815 DoGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
2816 &caps.max_vertex_texture_image_units);
2817 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
2818 &caps.max_vertex_uniform_vectors);
2819 DoGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
2820 &caps.num_compressed_texture_formats);
2821 DoGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps.num_shader_binary_formats);
2822 DoGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM,
2823 &caps.bind_generates_resource_chromium);
[email protected]6d668892013-12-04 21:37:122824
[email protected]6d668892013-12-04 21:37:122825 caps.egl_image_external =
2826 feature_info_->feature_flags().oes_egl_image_external;
2827 caps.texture_format_bgra8888 =
2828 feature_info_->feature_flags().ext_texture_format_bgra8888;
2829 caps.texture_format_etc1 =
2830 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:202831 caps.texture_format_etc1_npot =
2832 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:122833 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2834 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2835 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2836 caps.discard_framebuffer =
2837 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352838 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122839
2840#if defined(OS_MACOSX)
2841 // This is unconditionally true on mac, no need to test for it at runtime.
2842 caps.iosurface = true;
2843#endif
2844
[email protected]b381ee32014-03-22 02:43:432845 caps.post_sub_buffer = supports_post_sub_buffer_;
reveman340109182014-09-30 15:36:452846 caps.image = true;
[email protected]6d668892013-12-04 21:37:122847
ed9198b422014-10-23 15:01:372848 caps.blend_equation_advanced =
2849 feature_info_->feature_flags().blend_equation_advanced;
2850 caps.blend_equation_advanced_coherent =
2851 feature_info_->feature_flags().blend_equation_advanced_coherent;
[email protected]6d668892013-12-04 21:37:122852 return caps;
2853}
2854
[email protected]302ce6d2011-07-07 23:28:112855void GLES2DecoderImpl::UpdateCapabilities() {
2856 util_.set_num_compressed_texture_formats(
2857 validators_->compressed_texture_format.GetValues().size());
2858 util_.set_num_shader_binary_formats(
2859 validators_->shader_binary_format.GetValues().size());
2860}
2861
[email protected]c2f8c8402010-12-06 18:07:242862bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442863 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2864
[email protected]c2f8c8402010-12-06 18:07:242865 if (!use_shader_translator_) {
2866 return true;
2867 }
2868 ShBuiltInResources resources;
2869 ShInitBuiltInResources(&resources);
2870 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2871 resources.MaxVertexUniformVectors =
2872 group_->max_vertex_uniform_vectors();
2873 resources.MaxVaryingVectors = group_->max_varying_vectors();
2874 resources.MaxVertexTextureImageUnits =
2875 group_->max_vertex_texture_image_units();
2876 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2877 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2878 resources.MaxFragmentUniformVectors =
2879 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492880 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242881 resources.MaxExpressionComplexity = 256;
2882 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042883
[email protected]46c86752013-05-21 05:08:392884 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212885 GLint precision = 0;
2886 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2887 range, &precision);
[email protected]448e459e2013-06-12 17:00:412888 resources.FragmentPrecisionHigh =
2889 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142890
[email protected]f0d74742011-10-03 16:31:042891 if (force_webgl_glsl_validation_) {
2892 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492893 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132894 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442895 if (!draw_buffers_explicitly_enabled_)
2896 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:062897 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
oetuaho0decd442014-10-13 08:40:462898 resources.NV_draw_buffers =
2899 draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
[email protected]f0d74742011-10-03 16:31:042900 } else {
2901 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152902 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462903 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152904 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062905 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152906 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492907 resources.EXT_draw_buffers =
2908 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492909 resources.EXT_frag_depth =
2910 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:062911 resources.EXT_shader_texture_lod =
2912 features().ext_shader_texture_lod ? 1 : 0;
oetuaho0decd442014-10-13 08:40:462913 resources.NV_draw_buffers =
2914 features().nv_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042915 }
2916
[email protected]26b61442013-03-17 16:12:012917 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2918 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052919 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022920 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:052921 else
2922 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122923 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2924 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2925 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212926 int driver_bug_workarounds = 0;
2927 if (workarounds().needs_glsl_built_in_function_emulation)
2928 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542929 if (workarounds().init_gl_position_in_vertex_shader)
2930 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112931 if (workarounds().unfold_short_circuit_as_ternary_operation)
2932 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:052933 if (workarounds().init_varyings_without_static_use)
2934 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:062935 if (workarounds().unroll_for_loop_with_sampler_array_index)
2936 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:252937 if (workarounds().scalarize_vec_and_mat_constructor_args)
2938 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:272939 if (workarounds().regenerate_struct_names)
2940 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
[email protected]87fb6ab2012-06-13 22:28:042941
[email protected]03cef9b2014-04-03 15:58:142942 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262943 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:142944 shader_spec,
2945 &resources,
[email protected]a6739bc2013-09-07 04:45:212946 implementation_type,
2947 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042948 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242949 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382950 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242951 return false;
2952 }
[email protected]87fb6ab2012-06-13 22:28:042953
[email protected]03cef9b2014-04-03 15:58:142954 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262955 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:142956 shader_spec,
2957 &resources,
[email protected]a6739bc2013-09-07 04:45:212958 implementation_type,
2959 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042960 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242961 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382962 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242963 return false;
2964 }
2965 return true;
2966}
2967
[email protected]ae51d192010-04-27 00:48:032968bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472969 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352970 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032971 return false;
2972 }
2973 }
[email protected]40d90a22013-04-09 03:39:552974 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032975 glGenBuffersARB(n, service_ids.get());
2976 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352977 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032978 }
2979 return true;
2980}
2981
2982bool GLES2DecoderImpl::GenFramebuffersHelper(
2983 GLsizei n, const GLuint* client_ids) {
2984 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352985 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032986 return false;
2987 }
2988 }
[email protected]40d90a22013-04-09 03:39:552989 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032990 glGenFramebuffersEXT(n, service_ids.get());
2991 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352992 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032993 }
2994 return true;
2995}
2996
2997bool GLES2DecoderImpl::GenRenderbuffersHelper(
2998 GLsizei n, const GLuint* client_ids) {
2999 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353000 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033001 return false;
3002 }
3003 }
[email protected]40d90a22013-04-09 03:39:553004 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033005 glGenRenderbuffersEXT(n, service_ids.get());
3006 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353007 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033008 }
3009 return true;
3010}
3011
orglofchcad5a6742014-11-07 19:51:123012bool GLES2DecoderImpl::GenValuebuffersCHROMIUMHelper(GLsizei n,
3013 const GLuint* client_ids) {
3014 for (GLsizei ii = 0; ii < n; ++ii) {
3015 if (GetValuebuffer(client_ids[ii])) {
3016 return false;
3017 }
3018 }
3019 for (GLsizei ii = 0; ii < n; ++ii) {
3020 CreateValuebuffer(client_ids[ii]);
3021 }
3022 return true;
3023}
3024
[email protected]ae51d192010-04-27 00:48:033025bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
3026 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353027 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033028 return false;
3029 }
3030 }
[email protected]40d90a22013-04-09 03:39:553031 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033032 glGenTextures(n, service_ids.get());
3033 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353034 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033035 }
3036 return true;
3037}
3038
3039void GLES2DecoderImpl::DeleteBuffersHelper(
3040 GLsizei n, const GLuint* client_ids) {
3041 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:213042 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103043 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:243044 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:113045 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:243046 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103047 }
[email protected]ed9f9cd2013-02-27 21:12:353048 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033049 }
[email protected]a93bb842010-02-16 23:03:473050 }
[email protected]07f54fcc2009-12-22 02:46:303051}
3052
[email protected]ae51d192010-04-27 00:48:033053void GLES2DecoderImpl::DeleteFramebuffersHelper(
3054 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453055 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153056 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:113057
[email protected]a25fa872010-03-25 02:57:583058 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353059 Framebuffer* framebuffer =
3060 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103061 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:343062 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
3063 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:443064 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:453065 GLenum target = supports_separate_framebuffer_binds ?
3066 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113067 glBindFramebufferEXT(target, GetBackbufferServiceId());
3068 }
[email protected]9d3b2e12013-10-02 01:04:343069 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
3070 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:453071 GLenum target = supports_separate_framebuffer_binds ?
3072 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113073 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:463074 }
[email protected]70d34263c2013-01-09 00:27:453075 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:353076 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033077 }
[email protected]a25fa872010-03-25 02:57:583078 }
[email protected]07f54fcc2009-12-22 02:46:303079}
3080
[email protected]ae51d192010-04-27 00:48:033081void GLES2DecoderImpl::DeleteRenderbuffersHelper(
3082 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453083 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153084 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:583085 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353086 Renderbuffer* renderbuffer =
3087 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103088 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:113089 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:243090 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103091 }
3092 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453093 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343094 if (framebuffer_state_.bound_read_framebuffer.get()) {
3095 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113096 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103097 }
[email protected]9d3b2e12013-10-02 01:04:343098 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3099 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113100 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103101 }
3102 } else {
[email protected]9d3b2e12013-10-02 01:04:343103 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3104 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113105 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103106 }
3107 }
[email protected]c986af502013-08-14 01:04:443108 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:353109 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033110 }
[email protected]a25fa872010-03-25 02:57:583111 }
[email protected]07f54fcc2009-12-22 02:46:303112}
3113
orglofchcad5a6742014-11-07 19:51:123114void GLES2DecoderImpl::DeleteValuebuffersCHROMIUMHelper(
3115 GLsizei n,
3116 const GLuint* client_ids) {
3117 for (GLsizei ii = 0; ii < n; ++ii) {
3118 Valuebuffer* valuebuffer = GetValuebuffer(client_ids[ii]);
3119 if (valuebuffer) {
3120 if (state_.bound_valuebuffer.get() == valuebuffer) {
3121 state_.bound_valuebuffer = NULL;
3122 }
3123 RemoveValuebuffer(client_ids[ii]);
3124 }
3125 }
3126}
3127
[email protected]ae51d192010-04-27 00:48:033128void GLES2DecoderImpl::DeleteTexturesHelper(
3129 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453130 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153131 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:473132 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:493133 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3134 if (texture_ref) {
3135 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103136 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443137 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463138 }
[email protected]370eaf12013-05-18 09:19:493139 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023140 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493141 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103142 }
3143 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453144 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343145 if (framebuffer_state_.bound_read_framebuffer.get()) {
3146 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113147 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103148 }
[email protected]9d3b2e12013-10-02 01:04:343149 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3150 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113151 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103152 }
3153 } else {
[email protected]9d3b2e12013-10-02 01:04:343154 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3155 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113156 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103157 }
3158 }
[email protected]e51bdf32011-11-23 22:21:463159#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073160 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463161 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3162 ReleaseIOSurfaceForTexture(service_id);
3163 }
3164#endif
[email protected]ed9f9cd2013-02-27 21:12:353165 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033166 }
[email protected]a93bb842010-02-16 23:03:473167 }
[email protected]07f54fcc2009-12-22 02:46:303168}
3169
[email protected]43f28f832010-02-03 02:28:483170// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323171
[email protected]eb54a562010-01-20 21:55:183172bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343173 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383174 return false;
3175
[email protected]177d1342013-12-07 04:20:343176 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:433177 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:293178
jbauman7a059312014-10-16 19:30:543179 MaybeExitOnContextLost();
[email protected]e9f0ca82013-04-01 23:52:293180
[email protected]63c9b052012-05-17 18:27:383181 return false;
[email protected]38d139d2011-07-14 00:38:433182 }
3183
[email protected]69a8701e2013-03-07 21:31:093184 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093185
[email protected]9b753992013-04-27 02:04:413186 // Rebind the FBO if it was unbound by the context.
3187 if (workarounds().unbind_fbo_on_context_switch)
3188 RestoreFramebufferBindings();
3189
[email protected]c986af502013-08-14 01:04:443190 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493191
[email protected]69a8701e2013-03-07 21:31:093192 return true;
3193}
3194
3195void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553196 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323197 if (engine() && query_manager_.get())
3198 query_manager_->ProcessPendingTransferQueries();
3199
[email protected]5b3a8e02013-03-13 05:36:443200 // TODO(epenner): Is there a better place to do this?
3201 // This needs to occur before we execute any batch of commands
3202 // from the client, as the client may have recieved an async
3203 // completion while issuing those commands.
3204 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483205 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183206}
3207
[email protected]8e3e0662010-08-23 18:46:303208static void RebindCurrentFramebuffer(
3209 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063210 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243211 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063212 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463213
[email protected]a3783712012-01-20 22:18:243214 if (framebuffer_id == 0) {
3215 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303216 }
[email protected]297ca1c2011-06-20 23:08:463217
[email protected]8e3e0662010-08-23 18:46:303218 glBindFramebufferEXT(target, framebuffer_id);
3219}
3220
3221void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443222 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463223
[email protected]62e155e2012-10-23 22:43:153224 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303225 RebindCurrentFramebuffer(
3226 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343227 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243228 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303229 } else {
3230 RebindCurrentFramebuffer(
3231 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343232 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243233 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303234 RebindCurrentFramebuffer(
3235 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343236 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243237 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303238 }
[email protected]70d34263c2013-01-09 00:27:453239 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303240}
3241
[email protected]0d6bfdc2011-11-02 01:32:203242bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353243 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203244 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103245 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423246 if (surfaceless_)
3247 return false;
[email protected]60f22d32012-12-12 00:31:583248 if (backbuffer_needs_clear_bits_) {
3249 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323250 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453251 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583252 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473253 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3254 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583255 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453256 state_.SetDeviceDepthMask(GL_TRUE);
3257 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423258 bool reset_draw_buffer = false;
brucedawson18249152014-10-31 23:02:323259 if ((backbuffer_needs_clear_bits_ & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]ee757922014-06-06 05:21:423260 group_->draw_buffer() == GL_NONE) {
3261 reset_draw_buffer = true;
3262 GLenum buf = GL_BACK;
3263 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3264 buf = GL_COLOR_ATTACHMENT0;
3265 glDrawBuffersARB(1, &buf);
3266 }
[email protected]60f22d32012-12-12 00:31:583267 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423268 if (reset_draw_buffer) {
3269 GLenum buf = GL_NONE;
3270 glDrawBuffersARB(1, &buf);
3271 }
[email protected]60f22d32012-12-12 00:31:583272 backbuffer_needs_clear_bits_ = 0;
3273 RestoreClearState();
3274 }
[email protected]0d6bfdc2011-11-02 01:32:203275 return true;
3276 }
3277
[email protected]968351b2011-12-20 08:26:513278 if (framebuffer_manager()->IsComplete(framebuffer)) {
3279 return true;
3280 }
3281
[email protected]0d6bfdc2011-11-02 01:32:203282 GLenum completeness = framebuffer->IsPossiblyComplete();
3283 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513284 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433285 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273286 return false;
3287 }
[email protected]0d6bfdc2011-11-02 01:32:203288
3289 // Are all the attachments cleared?
3290 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3291 texture_manager()->HaveUnclearedMips()) {
3292 if (!framebuffer->IsCleared()) {
3293 // Can we clear them?
[email protected]73276522012-11-09 05:50:203294 if (framebuffer->GetStatus(texture_manager(), target) !=
3295 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513296 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433297 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3298 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203299 return false;
3300 }
3301 ClearUnclearedAttachments(target, framebuffer);
3302 }
3303 }
3304
[email protected]968351b2011-12-20 08:26:513305 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203306 if (framebuffer->GetStatus(texture_manager(), target) !=
3307 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513308 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433309 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3310 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513311 return false;
3312 }
3313 framebuffer_manager()->MarkAsComplete(framebuffer);
3314 }
3315
[email protected]0d6bfdc2011-11-02 01:32:203316 // NOTE: At this point we don't know if the framebuffer is complete but
3317 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273318 return true;
3319}
3320
[email protected]0d6bfdc2011-11-02 01:32:203321bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153322 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513323 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343324 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3325 func_name);
[email protected]28718a92013-04-04 12:12:513326
3327 if (valid)
3328 OnUseFramebuffer();
3329
3330 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203331 }
[email protected]9d3b2e12013-10-02 01:04:343332 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113333 GL_DRAW_FRAMEBUFFER_EXT,
3334 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343335 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113336 GL_READ_FRAMEBUFFER_EXT,
3337 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203338}
3339
[email protected]2ea5950d2014-07-09 18:20:343340bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3341 const char* func_name) {
3342 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3343 framebuffer_state_.bound_read_framebuffer.get() :
3344 framebuffer_state_.bound_draw_framebuffer.get();
3345 if (!framebuffer)
3346 return true;
3347 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3348 LOCAL_SET_GL_ERROR(
3349 GL_INVALID_OPERATION, func_name, "no color image attached");
3350 return false;
3351 }
3352 return true;
3353}
3354
zmo383512cf2014-10-14 00:11:003355bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
3356 TextureRef* texture, GLint level) {
3357 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3358 framebuffer_state_.bound_read_framebuffer.get() :
3359 framebuffer_state_.bound_draw_framebuffer.get();
3360 if (!framebuffer)
3361 return false;
3362 const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
3363 GL_COLOR_ATTACHMENT0);
3364 if (!attachment)
3365 return false;
3366 return attachment->FormsFeedbackLoop(texture, level);
3367}
3368
[email protected]8e3e0662010-08-23 18:46:303369gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353370 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453371 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203372 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353373 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203374 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263375 if (attachment) {
3376 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503377 }
[email protected]9edc6b22010-12-23 02:00:263378 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023379 } else if (offscreen_target_frame_buffer_.get()) {
3380 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353381 } else {
[email protected]f62a5ab2011-05-23 20:34:153382 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023383 }
[email protected]246a70452010-03-05 21:53:503384}
3385
[email protected]68586372013-12-11 01:27:593386GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3387 Framebuffer* framebuffer =
3388 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3389 if (framebuffer != NULL) {
3390 return framebuffer->GetColorAttachmentTextureType();
3391 } else {
3392 return GL_UNSIGNED_BYTE;
3393 }
3394}
3395
[email protected]9edc6b22010-12-23 02:00:263396GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353397 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453398 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203399 if (framebuffer != NULL) {
3400 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463401 } else if (offscreen_target_frame_buffer_.get()) {
3402 return offscreen_target_color_format_;
3403 } else {
3404 return back_buffer_color_format_;
3405 }
3406}
3407
3408GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353409 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453410 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203411 if (framebuffer != NULL) {
3412 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263413 } else if (offscreen_target_frame_buffer_.get()) {
3414 return offscreen_target_color_format_;
3415 } else {
[email protected]32fe9aa2011-01-21 23:47:133416 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263417 }
3418}
3419
[email protected]9a5afa432011-07-22 18:16:393420void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513421 if (!offscreen_saved_color_texture_info_.get())
3422 return;
3423 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3424 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3425 texture_manager()->SetLevelInfo(
3426 offscreen_saved_color_texture_info_.get(),
3427 GL_TEXTURE_2D,
3428 0, // level
3429 GL_RGBA,
3430 offscreen_size_.width(),
3431 offscreen_size_.height(),
3432 1, // depth
3433 0, // border
3434 GL_RGBA,
3435 GL_UNSIGNED_BYTE,
3436 true);
[email protected]737191ee72014-03-09 08:02:423437 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513438 "UpdateParentTextureInfo",
3439 GetErrorState(),
3440 offscreen_saved_color_texture_info_.get(),
3441 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263442 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423443 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513444 "UpdateParentTextureInfo",
3445 GetErrorState(),
3446 offscreen_saved_color_texture_info_.get(),
3447 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263448 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423449 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513450 "UpdateParentTextureInfo",
3451 GetErrorState(),
3452 offscreen_saved_color_texture_info_.get(),
3453 GL_TEXTURE_WRAP_S,
3454 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423455 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513456 "UpdateParentTextureInfo",
3457 GetErrorState(),
3458 offscreen_saved_color_texture_info_.get(),
3459 GL_TEXTURE_WRAP_T,
3460 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443461 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3462 &state_, target);
[email protected]2ad674132013-06-05 07:48:513463 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353464}
3465
[email protected]799b4b22011-08-22 17:09:593466void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073467 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523468 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003469}
3470
[email protected]1d82e822013-04-10 21:32:323471Logger* GLES2DecoderImpl::GetLogger() {
3472 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523473}
3474
[email protected]cac16542014-01-15 17:53:513475void GLES2DecoderImpl::BeginDecoding() {
3476 gpu_tracer_->BeginDecoding();
3477 gpu_trace_commands_ = gpu_tracer_->IsTracing();
vmiura1c2b1de2014-09-19 19:03:243478 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3479 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513480}
3481
3482void GLES2DecoderImpl::EndDecoding() {
3483 gpu_tracer_->EndDecoding();
3484}
3485
[email protected]d3eba342013-04-18 21:11:503486ErrorState* GLES2DecoderImpl::GetErrorState() {
3487 return state_.GetErrorState();
3488}
3489
[email protected]e3932abb2013-03-13 00:01:373490void GLES2DecoderImpl::SetShaderCacheCallback(
3491 const ShaderCacheCallback& callback) {
3492 shader_cache_callback_ = callback;
3493}
3494
[email protected]840a7e462013-02-27 01:29:513495void GLES2DecoderImpl::SetWaitSyncPointCallback(
3496 const WaitSyncPointCallback& callback) {
3497 wait_sync_point_callback_ = callback;
3498}
3499
[email protected]85a4ac22013-05-31 01:58:473500AsyncPixelTransferManager*
3501 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3502 return async_pixel_transfer_manager_.get();
3503}
3504
3505void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3506 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593507}
3508
[email protected]498b5c072013-06-04 19:30:073509void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3510 AsyncPixelTransferManager* manager) {
3511 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3512}
3513
[email protected]1318e922010-09-17 22:03:163514bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3515 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493516 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3517 if (texture_ref) {
3518 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163519 return true;
3520 }
3521 return false;
3522}
3523
[email protected]63b465922012-09-06 02:04:523524uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443525 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483526 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523527}
3528
3529base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443530 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483531 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523532}
3533
3534base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3535 return total_processing_commands_time_;
3536}
3537
[email protected]dc25dda2012-09-27 21:36:303538void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3539 total_processing_commands_time_ += time;
3540}
3541
[email protected]63c9b052012-05-17 18:27:383542void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063543 if (!initialized())
3544 return;
3545
[email protected]63c9b052012-05-17 18:27:383546 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053547
[email protected]80eb6b52012-01-19 00:14:413548 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243549 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523550 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023551 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243552 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133553 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343554 framebuffer_state_.bound_read_framebuffer = NULL;
3555 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243556 state_.bound_renderbuffer = NULL;
orglofchcad5a6742014-11-07 19:51:123557 state_.bound_valuebuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413558
[email protected]cadac622013-06-11 16:46:363559 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513560 DCHECK(offscreen_target_color_texture_);
3561 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3562 offscreen_saved_color_texture_->id());
3563 offscreen_saved_color_texture_->Invalidate();
3564 offscreen_saved_color_texture_info_ = NULL;
3565 }
[email protected]eadc96792010-10-27 19:39:393566 if (have_context) {
[email protected]c322e882012-05-23 18:06:183567 if (copy_texture_CHROMIUM_.get()) {
3568 copy_texture_CHROMIUM_->Destroy();
3569 copy_texture_CHROMIUM_.reset();
3570 }
[email protected]43410e92012-04-20 17:06:283571
sievers2384f2b2014-11-18 02:10:353572 clear_framebuffer_blit_.reset();
3573
[email protected]7cd76fd2013-06-02 21:11:113574 if (state_.current_program.get()) {
3575 program_manager()->UnuseProgram(shader_manager(),
3576 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143577 }
3578
[email protected]b1122982010-05-17 23:04:243579 if (attrib_0_buffer_id_) {
3580 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3581 }
[email protected]8fbedc02010-11-18 18:43:403582 if (fixed_attrib_buffer_id_) {
3583 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3584 }
[email protected]b1122982010-05-17 23:04:243585
[email protected]4a4c18b2013-09-13 22:50:103586 if (validation_texture_) {
3587 glDeleteTextures(1, &validation_texture_);
3588 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3589 glDeleteFramebuffersEXT(1, &validation_fbo_);
3590 }
3591
[email protected]97872062010-11-03 19:07:053592 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543593 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053594 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543595 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053596 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023597 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053598 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153599 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053600 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153601 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053602 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023603 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053604 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543605 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273606 if (offscreen_resolved_frame_buffer_.get())
3607 offscreen_resolved_frame_buffer_->Destroy();
3608 if (offscreen_resolved_color_texture_.get())
3609 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053610 } else {
3611 if (offscreen_target_frame_buffer_.get())
3612 offscreen_target_frame_buffer_->Invalidate();
3613 if (offscreen_target_color_texture_.get())
3614 offscreen_target_color_texture_->Invalidate();
3615 if (offscreen_target_color_render_buffer_.get())
3616 offscreen_target_color_render_buffer_->Invalidate();
3617 if (offscreen_target_depth_render_buffer_.get())
3618 offscreen_target_depth_render_buffer_->Invalidate();
3619 if (offscreen_target_stencil_render_buffer_.get())
3620 offscreen_target_stencil_render_buffer_->Invalidate();
3621 if (offscreen_saved_frame_buffer_.get())
3622 offscreen_saved_frame_buffer_->Invalidate();
3623 if (offscreen_saved_color_texture_.get())
3624 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273625 if (offscreen_resolved_frame_buffer_.get())
3626 offscreen_resolved_frame_buffer_->Invalidate();
3627 if (offscreen_resolved_color_texture_.get())
3628 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023629 }
[email protected]83a52d032013-07-24 10:30:373630
3631 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3632 // Otherwise, we can leak objects. http://crbug.com/258772.
3633 // state_.current_program must be reset before group_ is reset because
3634 // the later deletes the ProgramManager object that referred by
3635 // state_.current_program object.
3636 state_.current_program = NULL;
3637
[email protected]43410e92012-04-20 17:06:283638 copy_texture_CHROMIUM_.reset();
sievers2384f2b2014-11-18 02:10:353639 clear_framebuffer_blit_.reset();
[email protected]97872062010-11-03 19:07:053640
[email protected]882ba1e22012-03-08 19:02:533641 if (query_manager_.get()) {
3642 query_manager_->Destroy(have_context);
3643 query_manager_.reset();
3644 }
3645
[email protected]944b62f32012-09-27 02:20:463646 if (vertex_array_manager_ .get()) {
3647 vertex_array_manager_->Destroy(have_context);
3648 vertex_array_manager_.reset();
3649 }
3650
[email protected]d2eaf52f2014-07-31 15:01:243651 if (image_manager_.get()) {
3652 image_manager_->Destroy(have_context);
3653 image_manager_.reset();
3654 }
3655
[email protected]97872062010-11-03 19:07:053656 offscreen_target_frame_buffer_.reset();
3657 offscreen_target_color_texture_.reset();
3658 offscreen_target_color_render_buffer_.reset();
3659 offscreen_target_depth_render_buffer_.reset();
3660 offscreen_target_stencil_render_buffer_.reset();
3661 offscreen_saved_frame_buffer_.reset();
3662 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273663 offscreen_resolved_frame_buffer_.reset();
3664 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463665
[email protected]03cef9b2014-04-03 15:58:143666 // Need to release these before releasing |group_| which may own the
3667 // ShaderTranslatorCache.
3668 fragment_translator_ = NULL;
3669 vertex_translator_ = NULL;
3670
[email protected]85a4ac22013-05-31 01:58:473671 // Should destroy the transfer manager before the texture manager held
3672 // by the context group.
3673 async_pixel_transfer_manager_.reset();
3674
[email protected]7cd76fd2013-06-02 21:11:113675 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393676 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233677 group_->Destroy(this, have_context);
3678 group_ = NULL;
3679 }
3680
3681 if (context_.get()) {
3682 context_->ReleaseCurrent(NULL);
3683 context_ = NULL;
3684 }
3685
[email protected]e51bdf32011-11-23 22:21:463686#if defined(OS_MACOSX)
3687 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3688 it != texture_to_io_surface_map_.end(); ++it) {
3689 CFRelease(it->second);
3690 }
3691 texture_to_io_surface_map_.clear();
3692#endif
[email protected]96449d2c2009-11-25 00:01:323693}
3694
[email protected]63c9b052012-05-17 18:27:383695void GLES2DecoderImpl::SetSurface(
3696 const scoped_refptr<gfx::GLSurface>& surface) {
3697 DCHECK(context_->IsCurrent(NULL));
3698 DCHECK(surface_.get());
3699 surface_ = surface;
3700 RestoreCurrentFramebufferBindings();
3701}
3702
[email protected]aba551b2014-02-08 03:38:323703void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3704 if (!offscreen_saved_color_texture_.get()) {
3705 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3706 return;
3707 }
[email protected]2ad674132013-06-05 07:48:513708 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243709 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073710 offscreen_saved_color_texture_info_ = TextureRef::Create(
3711 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513712 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3713 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393714 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243715 }
[email protected]aba551b2014-02-08 03:38:323716 mailbox_manager()->ProduceTexture(
sievers8b373ec52014-10-24 23:04:063717 mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243718}
3719
[email protected]799b4b22011-08-22 17:09:593720bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3721 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3722 if (!is_offscreen) {
3723 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3724 << " with an onscreen framebuffer.";
3725 return false;
3726 }
3727
3728 if (offscreen_size_ == size)
3729 return true;
3730
3731 offscreen_size_ = size;
3732 int w = offscreen_size_.width();
3733 int h = offscreen_size_.height();
3734 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3735 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3736 << "to allocate storage due to excessive dimensions.";
3737 return false;
3738 }
3739
3740 // Reallocate the offscreen target buffers.
3741 DCHECK(offscreen_target_color_format_);
3742 if (IsOffscreenBufferMultisampled()) {
3743 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253744 feature_info_.get(),
3745 offscreen_size_,
3746 offscreen_target_color_format_,
3747 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593748 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3749 << "to allocate storage for offscreen target color buffer.";
3750 return false;
3751 }
3752 } else {
3753 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093754 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593755 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3756 << "to allocate storage for offscreen target color texture.";
3757 return false;
3758 }
3759 }
3760 if (offscreen_target_depth_format_ &&
3761 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253762 feature_info_.get(),
3763 offscreen_size_,
3764 offscreen_target_depth_format_,
3765 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593766 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3767 << "to allocate storage for offscreen target depth buffer.";
3768 return false;
3769 }
3770 if (offscreen_target_stencil_format_ &&
3771 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253772 feature_info_.get(),
3773 offscreen_size_,
3774 offscreen_target_stencil_format_,
3775 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593776 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3777 << "to allocate storage for offscreen target stencil buffer.";
3778 return false;
3779 }
3780
3781 // Attach the offscreen target buffers to the target frame buffer.
3782 if (IsOffscreenBufferMultisampled()) {
3783 offscreen_target_frame_buffer_->AttachRenderBuffer(
3784 GL_COLOR_ATTACHMENT0,
3785 offscreen_target_color_render_buffer_.get());
3786 } else {
3787 offscreen_target_frame_buffer_->AttachRenderTexture(
3788 offscreen_target_color_texture_.get());
3789 }
3790 if (offscreen_target_depth_format_) {
3791 offscreen_target_frame_buffer_->AttachRenderBuffer(
3792 GL_DEPTH_ATTACHMENT,
3793 offscreen_target_depth_render_buffer_.get());
3794 }
3795 const bool packed_depth_stencil =
3796 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3797 if (packed_depth_stencil) {
3798 offscreen_target_frame_buffer_->AttachRenderBuffer(
3799 GL_STENCIL_ATTACHMENT,
3800 offscreen_target_depth_render_buffer_.get());
3801 } else if (offscreen_target_stencil_format_) {
3802 offscreen_target_frame_buffer_->AttachRenderBuffer(
3803 GL_STENCIL_ATTACHMENT,
3804 offscreen_target_stencil_render_buffer_.get());
3805 }
3806
3807 if (offscreen_target_frame_buffer_->CheckStatus() !=
3808 GL_FRAMEBUFFER_COMPLETE) {
3809 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3810 << "because offscreen FBO was incomplete.";
3811 return false;
3812 }
3813
3814 // Clear the target frame buffer.
3815 {
3816 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3817 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323818 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453819 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593820 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473821 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3822 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:593823 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:453824 state_.SetDeviceDepthMask(GL_TRUE);
3825 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:593826 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3827 RestoreClearState();
3828 }
[email protected]d85ef76d2011-09-08 22:21:433829
3830 // Destroy the offscreen resolved framebuffers.
3831 if (offscreen_resolved_frame_buffer_.get())
3832 offscreen_resolved_frame_buffer_->Destroy();
3833 if (offscreen_resolved_color_texture_.get())
3834 offscreen_resolved_color_texture_->Destroy();
3835 offscreen_resolved_color_texture_.reset();
3836 offscreen_resolved_frame_buffer_.reset();
3837
[email protected]799b4b22011-08-22 17:09:593838 return true;
[email protected]6217d392010-03-25 22:08:353839}
3840
vmiuracd108592014-09-08 14:36:343841error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
3842 const void* cmd_data) {
3843 const gles2::cmds::ResizeCHROMIUM& c =
3844 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:443845 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023846 return error::kDeferCommandUntilLater;
3847
[email protected]799b4b22011-08-22 17:09:593848 GLuint width = static_cast<GLuint>(c.width);
3849 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073850 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593851 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413852
3853 width = std::max(1U, width);
3854 height = std::max(1U, height);
3855
[email protected]a0d989162011-11-22 13:15:073856#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3857 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003858 // Make sure that we are done drawing to the back buffer before resizing.
3859 glFinish();
3860#endif
[email protected]799b4b22011-08-22 17:09:593861 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3862 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493863 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3864 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3865 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593866 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493867 }
[email protected]7ff86b92010-11-25 17:50:003868 }
[email protected]799b4b22011-08-22 17:09:593869
[email protected]9d37f062011-11-22 01:24:523870 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073871 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443872 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493873 if (!context_->IsCurrent(surface_.get())) {
3874 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3875 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053876 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493877 }
[email protected]658f7562011-09-09 05:24:053878 }
[email protected]799b4b22011-08-22 17:09:593879
3880 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393881}
3882
[email protected]96449d2c2009-11-25 00:01:323883const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3884 if (command_id > kStartPoint && command_id < kNumCommands) {
3885 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3886 }
3887 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3888}
3889
vmiura8266ca72014-09-09 21:37:003890// Decode a command, and call the corresponding GL functions.
3891// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
3892// of commands at once, and is now only used for tests that need to track
3893// individual commands.
3894error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
3895 unsigned int arg_count,
3896 const void* cmd_data) {
3897 return DoCommands(1, cmd_data, arg_count + 1, 0);
3898}
3899
3900// Decode multiple commands, and call the corresponding GL functions.
3901// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
3902// changed by a (malicious) client at any time, so if validation has to happen,
3903// it should operate on a copy of them.
3904// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
3905// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:243906template <bool DebugImpl>
3907error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
3908 const void* buffer,
3909 int num_entries,
3910 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:003911 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:143912 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:003913 const CommandBufferEntry* cmd_data =
3914 static_cast<const CommandBufferEntry*>(buffer);
3915 int process_pos = 0;
3916 unsigned int command = 0;
3917
3918 while (process_pos < num_entries && result == error::kNoError &&
3919 commands_to_process_--) {
3920 const unsigned int size = cmd_data->value_header.size;
3921 command = cmd_data->value_header.command;
3922
3923 if (size == 0) {
3924 result = error::kInvalidSize;
3925 break;
3926 }
3927
3928 if (static_cast<int>(size) + process_pos > num_entries) {
3929 result = error::kOutOfBounds;
3930 break;
3931 }
3932
vmiura1c2b1de2014-09-19 19:03:243933 if (DebugImpl) {
3934 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3935 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:003936
vmiura1c2b1de2014-09-19 19:03:243937 if (log_commands()) {
3938 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
3939 << "cmd: " << GetCommandName(command);
3940 }
vmiura8266ca72014-09-09 21:37:003941 }
3942
3943 const unsigned int arg_count = size - 1;
3944 unsigned int command_index = command - kStartPoint - 1;
3945 if (command_index < arraysize(command_info)) {
3946 const CommandInfo& info = command_info[command_index];
3947 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3948 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3949 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
3950 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:243951 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:003952 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3953 doing_gpu_trace = true;
3954 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3955 }
[email protected]cac16542014-01-15 17:53:513956 }
[email protected]cac16542014-01-15 17:53:513957
vmiura8266ca72014-09-09 21:37:003958 uint32 immediate_data_size = (arg_count - info_arg_count) *
3959 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323960
vmiura8266ca72014-09-09 21:37:003961 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:513962
vmiura1c2b1de2014-09-19 19:03:243963 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:003964 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:513965
vmiura1c2b1de2014-09-19 19:03:243966 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:003967 GLenum error;
3968 while ((error = glGetError()) != GL_NO_ERROR) {
3969 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
3970 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
3971 << " : " << GetCommandName(command);
3972 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
3973 }
[email protected]b9849abf2009-11-25 19:13:193974 }
vmiura8266ca72014-09-09 21:37:003975 } else {
3976 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323977 }
3978 } else {
vmiura8266ca72014-09-09 21:37:003979 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323980 }
vmiura1c2b1de2014-09-19 19:03:243981
3982 if (DebugImpl) {
3983 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3984 GetCommandName(command));
3985 }
3986
vmiura8266ca72014-09-09 21:37:003987 if (result == error::kNoError &&
3988 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:563989 result = current_decoder_error_;
3990 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:003991 }
3992
3993 if (result != error::kDeferCommandUntilLater) {
3994 process_pos += size;
3995 cmd_data += size;
3996 }
[email protected]a3a93e7b2010-08-28 00:48:563997 }
vmiura8266ca72014-09-09 21:37:003998
3999 if (entries_processed)
4000 *entries_processed = process_pos;
4001
4002 if (error::IsError(result)) {
4003 LOG(ERROR) << "Error: " << result << " for Command "
4004 << GetCommandName(command);
4005 }
4006
[email protected]b9849abf2009-11-25 19:13:194007 return result;
[email protected]96449d2c2009-11-25 00:01:324008}
4009
vmiura1c2b1de2014-09-19 19:03:244010error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
4011 const void* buffer,
4012 int num_entries,
4013 int* entries_processed) {
4014 if (gpu_debug_commands_) {
4015 return DoCommandsImpl<true>(
4016 num_commands, buffer, num_entries, entries_processed);
4017 } else {
4018 return DoCommandsImpl<false>(
4019 num_commands, buffer, num_entries, entries_processed);
4020 }
4021}
4022
[email protected]ed9f9cd2013-02-27 21:12:354023void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
4024 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:504025}
4026
[email protected]ae51d192010-04-27 00:48:034027bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:354028 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:034029 return false;
4030 }
[email protected]96449d2c2009-11-25 00:01:324031 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:034032 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:354033 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:324034 }
[email protected]ae51d192010-04-27 00:48:034035 return true;
[email protected]96449d2c2009-11-25 00:01:324036}
4037
[email protected]ae51d192010-04-27 00:48:034038bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:354039 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:034040 return false;
[email protected]96449d2c2009-11-25 00:01:324041 }
[email protected]ae51d192010-04-27 00:48:034042 GLuint service_id = glCreateShader(type);
4043 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:354044 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:034045 }
4046 return true;
[email protected]96449d2c2009-11-25 00:01:324047}
4048
[email protected]882ba1e22012-03-08 19:02:534049void GLES2DecoderImpl::DoFinish() {
4050 glFinish();
[email protected]5a36dc132013-07-23 23:17:554051 ProcessPendingReadPixels();
revemancc241eb2014-11-11 03:30:374052 ProcessPendingQueries(true);
[email protected]882ba1e22012-03-08 19:02:534053}
4054
4055void GLES2DecoderImpl::DoFlush() {
4056 glFlush();
revemancc241eb2014-11-11 03:30:374057 ProcessPendingQueries(false);
[email protected]882ba1e22012-03-08 19:02:534058}
4059
[email protected]3916c97e2010-02-25 03:20:504060void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:454061 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:024062 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:514063 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:534064 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:504065 return;
4066 }
[email protected]e259eb412012-10-13 05:47:244067 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:454068 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:504069}
4070
[email protected]051b1372010-04-12 02:42:084071void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:074072 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:084073 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034074 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:074075 buffer = GetBuffer(client_id);
4076 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:354077 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224078 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4079 "glBindBuffer",
4080 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:354081 return;
4082 }
4083
[email protected]b10492f2013-03-08 05:24:074084 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:034085 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354086 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:074087 buffer = GetBuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034088 }
[email protected]051b1372010-04-12 02:42:084089 }
[email protected]b10492f2013-03-08 05:24:074090 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
4091 if (buffer) {
4092 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:514093 LOCAL_SET_GL_ERROR(
4094 GL_INVALID_OPERATION,
4095 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:474096 return;
4097 }
[email protected]b10492f2013-03-08 05:24:074098 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:474099 }
[email protected]96449d2c2009-11-25 00:01:324100 switch (target) {
4101 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074102 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:324103 break;
4104 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074105 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:324106 break;
4107 default:
[email protected]a93bb842010-02-16 23:03:474108 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:324109 break;
4110 }
[email protected]051b1372010-04-12 02:42:084111 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:324112}
4113
[email protected]f3b191b2013-06-19 03:43:544114bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
4115 bool all_draw_buffers) {
4116 Framebuffer* framebuffer =
4117 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4118 if (!all_draw_buffers || !framebuffer) {
4119 return (GLES2Util::GetChannelsForFormat(
4120 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
4121 }
4122 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:464123}
4124
4125bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354126 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454127 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204128 if (framebuffer) {
4129 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:464130 }
4131 if (offscreen_target_frame_buffer_.get()) {
4132 return offscreen_target_depth_format_ != 0;
4133 }
4134 return back_buffer_has_depth_;
4135}
4136
4137bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354138 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454139 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204140 if (framebuffer) {
4141 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464142 }
4143 if (offscreen_target_frame_buffer_.get()) {
4144 return offscreen_target_stencil_format_ != 0 ||
4145 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4146 }
4147 return back_buffer_has_stencil_;
4148}
4149
4150void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444151 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454152 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4153 state_.SetDeviceColorMask(state_.color_mask_red,
4154 state_.color_mask_green,
4155 state_.color_mask_blue,
4156 state_.color_mask_alpha && have_alpha);
4157
[email protected]297ca1c2011-06-20 23:08:464158 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454159 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4160
[email protected]297ca1c2011-06-20 23:08:464161 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454162 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424163 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454164 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424165 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454166
4167 state_.SetDeviceCapabilityState(
4168 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4169 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224170 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444171 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464172 }
4173}
4174
[email protected]1868a342012-11-07 15:56:024175GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114176 return (offscreen_target_frame_buffer_.get())
4177 ? offscreen_target_frame_buffer_->id()
4178 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024179}
4180
[email protected]8875a5f2014-06-27 08:33:474181void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144182 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4183 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064184 // Restore the Framebuffer first because of bugs in Intel drivers.
4185 // Intel drivers incorrectly clip the viewport settings to
4186 // the size of the current framebuffer object.
4187 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164188 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064189}
4190
4191void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344192 GLuint service_id =
4193 framebuffer_state_.bound_draw_framebuffer.get()
4194 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4195 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064196 if (!features().chromium_framebuffer_multisample) {
4197 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4198 } else {
4199 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344200 service_id = framebuffer_state_.bound_read_framebuffer.get()
4201 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114202 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064203 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4204 }
[email protected]70d34263c2013-01-09 00:27:454205 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064206}
4207
[email protected]8875a5f2014-06-27 08:33:474208void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4209 state_.RestoreRenderbufferBindings();
4210}
4211
[email protected]29a4d902013-02-26 20:18:064212void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104213 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4214 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254215 GLenum target = texture->target();
4216 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064217 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254218 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064219 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254220 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064221 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254222 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064223 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254224 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064225 RestoreTextureUnitBindings(state_.active_texture_unit);
4226 }
[email protected]70d34263c2013-01-09 00:27:454227}
4228
[email protected]cd2ef752014-02-12 23:16:034229void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524230 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4231 // other VAOs.
4232 if (feature_info_->feature_flags().native_vertex_array_object)
4233 glBindVertexArrayOES(0);
4234
[email protected]cd2ef752014-02-12 23:16:034235 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
4236 if (i != 0) // Never disable attribute 0
4237 glDisableVertexAttribArray(i);
4238 if(features().angle_instanced_arrays)
4239 glVertexAttribDivisorANGLE(i, 0);
4240 }
4241}
4242
4243void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524244 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034245}
4246
[email protected]454157e2014-05-03 02:49:454247void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4248 state_.SetIgnoreCachedStateForTest(ignore);
4249}
4250
[email protected]70d34263c2013-01-09 00:27:454251void GLES2DecoderImpl::OnFboChanged() const {
4252 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:514253 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
4254}
4255
4256// Called after the FBO is checked for completeness.
4257void GLES2DecoderImpl::OnUseFramebuffer() const {
4258 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
4259 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:324260 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514261 glScissor(state_.scissor_x,
4262 state_.scissor_y,
4263 state_.scissor_width,
4264 state_.scissor_height);
4265
4266 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4267 // it's unclear how this bug works.
4268 glFlush();
4269 }
[email protected]b177ae22011-11-01 03:29:114270}
4271
[email protected]051b1372010-04-12 02:42:084272void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064273 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084274 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034275 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064276 framebuffer = GetFramebuffer(client_id);
4277 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354278 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224279 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4280 "glBindFramebuffer",
4281 "id not generated by glGenFramebuffers");
4282 return;
[email protected]bf5a8d132011-08-16 08:39:354283 }
4284
[email protected]4d8f0dd2013-03-09 14:37:064285 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034286 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354287 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064288 framebuffer = GetFramebuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034289 } else {
[email protected]4d8f0dd2013-03-09 14:37:064290 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084291 }
[email protected]4d8f0dd2013-03-09 14:37:064292 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084293 }
[email protected]4d8f0dd2013-03-09 14:37:064294 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304295
4296 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344297 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304298 }
[email protected]cac16542014-01-15 17:53:514299
4300 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304301 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344302 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304303 }
[email protected]6217d392010-03-25 22:08:354304
[email protected]c986af502013-08-14 01:04:444305 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464306
[email protected]b177ae22011-11-01 03:29:114307 // If we are rendering to the backbuffer get the FBO id for any simulated
4308 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064309 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114310 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464311 }
[email protected]6217d392010-03-25 22:08:354312
[email protected]051b1372010-04-12 02:42:084313 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454314 OnFboChanged();
[email protected]86093972010-03-11 00:13:564315}
4316
[email protected]051b1372010-04-12 02:42:084317void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274318 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084319 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034320 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274321 renderbuffer = GetRenderbuffer(client_id);
4322 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354323 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224324 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4325 "glBindRenderbuffer",
4326 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354327 return;
4328 }
4329
[email protected]8875a5f2014-06-27 08:33:474330 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034331 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354332 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274333 renderbuffer = GetRenderbuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034334 } else {
[email protected]ee2a79c32013-03-10 03:50:274335 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084336 }
[email protected]ee2a79c32013-03-10 03:50:274337 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084338 }
[email protected]caa13ed2014-02-17 11:29:204339 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274340 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474341 state_.bound_renderbuffer_valid = true;
4342 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564343}
4344
[email protected]051b1372010-04-12 02:42:084345void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494346 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084347 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034348 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494349 texture_ref = GetTexture(client_id);
4350 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354351 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224352 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4353 "glBindTexture",
4354 "id not generated by glGenTextures");
4355 return;
[email protected]bf5a8d132011-08-16 08:39:354356 }
4357
[email protected]02965c22013-03-09 02:40:074358 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034359 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414360 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354361 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494362 texture_ref = GetTexture(client_id);
[email protected]ae51d192010-04-27 00:48:034363 }
4364 } else {
[email protected]370eaf12013-05-18 09:19:494365 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084366 }
[email protected]ae51d192010-04-27 00:48:034367
[email protected]1958e0e2010-04-22 05:17:154368 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574369 if (texture_ref) {
4370 Texture* texture = texture_ref->texture();
4371 // Check that we are not trying to bind it to a different target.
4372 if (texture->target() != 0 && texture->target() != target) {
4373 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4374 "glBindTexture",
4375 "texture bound to more than 1 target.");
4376 return;
4377 }
4378 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4379 if (texture->target() == 0) {
4380 texture_manager()->SetTarget(texture_ref, target);
4381 }
4382 glBindTexture(target, texture->service_id());
4383 } else {
4384 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154385 }
[email protected]32145a92012-12-17 09:01:594386
[email protected]e259eb412012-10-13 05:47:244387 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504388 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474389 switch (target) {
4390 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494391 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474392 break;
4393 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494394 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474395 break;
[email protected]61eeb33f2011-07-26 15:30:314396 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494397 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314398 break;
[email protected]e51bdf32011-11-23 22:21:464399 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494400 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464401 break;
[email protected]a93bb842010-02-16 23:03:474402 default:
4403 NOTREACHED(); // Validation should prevent us getting here.
4404 break;
4405 }
4406}
4407
[email protected]07f54fcc2009-12-22 02:46:304408void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244409 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124410 if (index != 0 ||
4411 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244412 glDisableVertexAttribArray(index);
4413 }
[email protected]07f54fcc2009-12-22 02:46:304414 } else {
[email protected]ab09b612013-03-11 22:11:514415 LOCAL_SET_GL_ERROR(
4416 GL_INVALID_VALUE,
4417 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304418 }
4419}
4420
[email protected]60f22d32012-12-12 00:31:584421void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4422 GLsizei numAttachments,
4423 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:354424 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584425 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4426
4427 // Validates the attachments. If one of them fails
4428 // the whole command fails.
4429 for (GLsizei i = 0; i < numAttachments; ++i) {
4430 if ((framebuffer &&
4431 !validators_->attachment.IsValid(attachments[i])) ||
4432 (!framebuffer &&
4433 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514434 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4435 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584436 return;
4437 }
4438 }
4439
4440 // Marks each one of them as not cleared
4441 for (GLsizei i = 0; i < numAttachments; ++i) {
4442 if (framebuffer) {
4443 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4444 texture_manager(),
4445 attachments[i],
4446 false);
4447 } else {
4448 switch (attachments[i]) {
4449 case GL_COLOR_EXT:
4450 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4451 break;
4452 case GL_DEPTH_EXT:
4453 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4454 case GL_STENCIL_EXT:
4455 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4456 break;
4457 default:
4458 NOTREACHED();
4459 break;
4460 }
4461 }
4462 }
4463
[email protected]d49c5402013-09-11 15:39:024464 // If the default framebuffer is bound but we are still rendering to an
4465 // FBO, translate attachment names that refer to default framebuffer
4466 // channels to corresponding framebuffer attachments.
4467 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4468 for (GLsizei i = 0; i < numAttachments; ++i) {
4469 GLenum attachment = attachments[i];
4470 if (!framebuffer && GetBackbufferServiceId()) {
4471 switch (attachment) {
4472 case GL_COLOR_EXT:
4473 attachment = GL_COLOR_ATTACHMENT0;
4474 break;
4475 case GL_DEPTH_EXT:
4476 attachment = GL_DEPTH_ATTACHMENT;
4477 break;
4478 case GL_STENCIL_EXT:
4479 attachment = GL_STENCIL_ATTACHMENT;
4480 break;
4481 default:
4482 NOTREACHED();
4483 return;
4484 }
4485 }
4486 translated_attachments[i] = attachment;
4487 }
4488
boliu2e7d8a7a2014-10-16 20:35:204489 ScopedRenderTo do_render(framebuffer);
[email protected]d49c5402013-09-11 15:39:024490 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
[email protected]60f22d32012-12-12 00:31:584491}
4492
[email protected]07f54fcc2009-12-22 02:46:304493void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244494 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304495 glEnableVertexAttribArray(index);
4496 } else {
[email protected]ab09b612013-03-11 22:11:514497 LOCAL_SET_GL_ERROR(
4498 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304499 }
4500}
4501
[email protected]a93bb842010-02-16 23:03:474502void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444503 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4504 &state_, target);
[email protected]370eaf12013-05-18 09:19:494505 if (!texture_ref ||
4506 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514507 LOCAL_SET_GL_ERROR(
4508 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474509 return;
4510 }
[email protected]38c0a972012-05-12 00:48:024511
[email protected]12d95352012-12-14 07:23:544512 if (target == GL_TEXTURE_CUBE_MAP) {
4513 for (int i = 0; i < 6; ++i) {
4514 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494515 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514516 LOCAL_SET_GL_ERROR(
4517 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544518 return;
4519 }
4520 }
4521 } else {
[email protected]370eaf12013-05-18 09:19:494522 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514523 LOCAL_SET_GL_ERROR(
4524 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544525 return;
4526 }
[email protected]7687479c2012-05-14 23:54:044527 }
4528
[email protected]ab09b612013-03-11 22:11:514529 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194530 // Workaround for Mac driver bug. In the large scheme of things setting
4531 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564532 // hit so there's probably no need to make this conditional. The bug appears
4533 // to be that if the filtering mode is set to something that doesn't require
4534 // mipmaps for rendering, or is never set to something other than the default,
4535 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154536 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194537 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4538 }
[email protected]a93bb842010-02-16 23:03:474539 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154540 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494541 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4542 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194543 }
[email protected]ab09b612013-03-11 22:11:514544 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024545 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494546 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024547 }
[email protected]a93bb842010-02-16 23:03:474548}
4549
[email protected]b273e432010-04-12 17:23:584550bool GLES2DecoderImpl::GetHelper(
4551 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584552 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154553 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4554 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434555 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4556 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214557 // Return the GL implementation's preferred format and (see below type)
4558 // if we have the GL extension that exposes this. This allows the GPU
4559 // client to use the implementation's preferred format for glReadPixels
4560 // for optimisation.
4561 //
4562 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4563 // case when requested on integer/floating point buffers but which is
4564 // acceptable on GLES2 and with the GL_OES_read_format extension.
4565 //
4566 // Therefore if an error occurs we swallow the error and use the
4567 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434568 if (params) {
[email protected]c959a09a2014-03-27 11:44:214569 if (context_->HasExtension("GL_OES_read_format")) {
4570 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4571 GetErrorState());
4572 glGetIntegerv(pname, params);
4573 if (glGetError() == GL_NO_ERROR)
4574 return true;
4575 }
[email protected]68586372013-12-11 01:27:594576 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4577 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434578 }
4579 return true;
4580 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4581 *num_written = 1;
4582 if (params) {
[email protected]c959a09a2014-03-27 11:44:214583 if (context_->HasExtension("GL_OES_read_format")) {
4584 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4585 GetErrorState());
4586 glGetIntegerv(pname, params);
4587 if (glGetError() == GL_NO_ERROR)
4588 return true;
4589 }
[email protected]68586372013-12-11 01:27:594590 *params = GLES2Util::GetPreferredGLReadPixelsType(
4591 GetBoundReadFrameBufferInternalFormat(),
4592 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434593 }
4594 return true;
4595 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4596 *num_written = 1;
4597 if (params) {
4598 *params = group_->max_fragment_uniform_vectors();
4599 }
4600 return true;
4601 case GL_MAX_VARYING_VECTORS:
4602 *num_written = 1;
4603 if (params) {
4604 *params = group_->max_varying_vectors();
4605 }
4606 return true;
4607 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4608 *num_written = 1;
4609 if (params) {
4610 *params = group_->max_vertex_uniform_vectors();
4611 }
4612 return true;
[email protected]4e8a5b122010-05-08 22:00:104613 }
[email protected]5cb735d2011-10-13 01:37:234614 }
4615 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244616 case GL_MAX_VIEWPORT_DIMS:
4617 if (offscreen_target_frame_buffer_.get()) {
4618 *num_written = 2;
4619 if (params) {
4620 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4621 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4622 }
4623 return true;
4624 }
[email protected]5cb735d2011-10-13 01:37:234625 return false;
[email protected]84afefa2011-10-19 21:45:534626 case GL_MAX_SAMPLES:
4627 *num_written = 1;
4628 if (params) {
4629 params[0] = renderbuffer_manager()->max_samples();
4630 }
4631 return true;
4632 case GL_MAX_RENDERBUFFER_SIZE:
4633 *num_written = 1;
4634 if (params) {
4635 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4636 }
4637 return true;
[email protected]5cb735d2011-10-13 01:37:234638 case GL_MAX_TEXTURE_SIZE:
4639 *num_written = 1;
4640 if (params) {
4641 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4642 }
4643 return true;
4644 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4645 *num_written = 1;
4646 if (params) {
4647 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4648 }
4649 return true;
[email protected]2f143d482013-03-14 18:04:494650 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4651 *num_written = 1;
4652 if (params) {
4653 params[0] = group_->max_color_attachments();
4654 }
4655 return true;
4656 case GL_MAX_DRAW_BUFFERS_ARB:
4657 *num_written = 1;
4658 if (params) {
4659 params[0] = group_->max_draw_buffers();
4660 }
4661 return true;
[email protected]297ca1c2011-06-20 23:08:464662 case GL_ALPHA_BITS:
4663 *num_written = 1;
4664 if (params) {
4665 GLint v = 0;
4666 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544667 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464668 }
4669 return true;
4670 case GL_DEPTH_BITS:
4671 *num_written = 1;
4672 if (params) {
4673 GLint v = 0;
4674 glGetIntegerv(GL_DEPTH_BITS, &v);
4675 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4676 }
4677 return true;
4678 case GL_STENCIL_BITS:
4679 *num_written = 1;
4680 if (params) {
4681 GLint v = 0;
4682 glGetIntegerv(GL_STENCIL_BITS, &v);
4683 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4684 }
4685 return true;
[email protected]656dcaad2010-05-07 17:18:374686 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114687 *num_written = validators_->compressed_texture_format.GetValues().size();
4688 if (params) {
4689 for (GLint ii = 0; ii < *num_written; ++ii) {
4690 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4691 }
4692 }
[email protected]656dcaad2010-05-07 17:18:374693 return true;
[email protected]b273e432010-04-12 17:23:584694 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4695 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104696 if (params) {
[email protected]302ce6d2011-07-07 23:28:114697 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104698 }
[email protected]b273e432010-04-12 17:23:584699 return true;
4700 case GL_NUM_SHADER_BINARY_FORMATS:
4701 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104702 if (params) {
[email protected]302ce6d2011-07-07 23:28:114703 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104704 }
[email protected]b273e432010-04-12 17:23:584705 return true;
4706 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114707 *num_written = validators_->shader_binary_format.GetValues().size();
4708 if (params) {
4709 for (GLint ii = 0; ii < *num_written; ++ii) {
4710 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4711 }
4712 }
4713 return true;
[email protected]b273e432010-04-12 17:23:584714 case GL_SHADER_COMPILER:
4715 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104716 if (params) {
4717 *params = GL_TRUE;
4718 }
[email protected]b273e432010-04-12 17:23:584719 return true;
[email protected]6b8cf1a2010-05-06 16:13:584720 case GL_ARRAY_BUFFER_BINDING:
4721 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104722 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114723 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104724 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244725 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104726 &client_id);
4727 *params = client_id;
4728 } else {
4729 *params = 0;
4730 }
[email protected]6b8cf1a2010-05-06 16:13:584731 }
4732 return true;
4733 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4734 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104735 if (params) {
[email protected]e259eb412012-10-13 05:47:244736 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104737 GLuint client_id = 0;
4738 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254739 state_.vertex_attrib_manager->element_array_buffer()->
4740 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104741 *params = client_id;
4742 } else {
4743 *params = 0;
4744 }
[email protected]6b8cf1a2010-05-06 16:13:584745 }
4746 return true;
4747 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304748 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584749 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104750 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354751 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454752 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204753 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104754 GLuint client_id = 0;
4755 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204756 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304757 *params = client_id;
4758 } else {
4759 *params = 0;
4760 }
4761 }
4762 return true;
[email protected]ebfb73c2012-08-15 02:37:454763 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304764 *num_written = 1;
4765 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354766 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454767 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204768 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304769 GLuint client_id = 0;
4770 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204771 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104772 *params = client_id;
4773 } else {
4774 *params = 0;
4775 }
[email protected]6b8cf1a2010-05-06 16:13:584776 }
4777 return true;
4778 case GL_RENDERBUFFER_BINDING:
4779 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104780 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354781 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204782 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4783 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104784 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104785 } else {
4786 *params = 0;
4787 }
[email protected]6b8cf1a2010-05-06 16:13:584788 }
4789 return true;
4790 case GL_CURRENT_PROGRAM:
4791 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104792 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114793 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104794 GLuint client_id = 0;
4795 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244796 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104797 *params = client_id;
4798 } else {
4799 *params = 0;
4800 }
[email protected]6b8cf1a2010-05-06 16:13:584801 }
4802 return true;
[email protected]bf835842012-11-19 15:21:514803 case GL_VERTEX_ARRAY_BINDING_OES:
4804 *num_written = 1;
4805 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114806 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:524807 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:514808 GLuint client_id = 0;
4809 vertex_array_manager_->GetClientId(
4810 state_.vertex_attrib_manager->service_id(), &client_id);
4811 *params = client_id;
4812 } else {
4813 *params = 0;
4814 }
4815 }
4816 return true;
[email protected]4e8a5b122010-05-08 22:00:104817 case GL_TEXTURE_BINDING_2D:
4818 *num_written = 1;
4819 if (params) {
[email protected]e259eb412012-10-13 05:47:244820 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114821 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104822 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584823 } else {
4824 *params = 0;
4825 }
[email protected]6b8cf1a2010-05-06 16:13:584826 }
[email protected]4e8a5b122010-05-08 22:00:104827 return true;
4828 case GL_TEXTURE_BINDING_CUBE_MAP:
4829 *num_written = 1;
4830 if (params) {
[email protected]e259eb412012-10-13 05:47:244831 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114832 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104833 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584834 } else {
4835 *params = 0;
4836 }
[email protected]6b8cf1a2010-05-06 16:13:584837 }
[email protected]4e8a5b122010-05-08 22:00:104838 return true;
[email protected]61eeb33f2011-07-26 15:30:314839 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4840 *num_written = 1;
4841 if (params) {
[email protected]e259eb412012-10-13 05:47:244842 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114843 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104844 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314845 } else {
4846 *params = 0;
4847 }
4848 }
4849 return true;
[email protected]e51bdf32011-11-23 22:21:464850 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4851 *num_written = 1;
4852 if (params) {
[email protected]e259eb412012-10-13 05:47:244853 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114854 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104855 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464856 } else {
4857 *params = 0;
4858 }
4859 }
4860 return true;
[email protected]6c75c712012-06-19 15:43:174861 case GL_UNPACK_FLIP_Y_CHROMIUM:
4862 *num_written = 1;
4863 if (params) {
4864 params[0] = unpack_flip_y_;
4865 }
4866 return true;
4867 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4868 *num_written = 1;
4869 if (params) {
4870 params[0] = unpack_premultiply_alpha_;
4871 }
4872 return true;
4873 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4874 *num_written = 1;
4875 if (params) {
4876 params[0] = unpack_unpremultiply_alpha_;
4877 }
4878 return true;
[email protected]6eda6822014-04-03 23:00:504879 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4880 *num_written = 1;
4881 if (params) {
4882 params[0] = group_->bind_generates_resource() ? 1 : 0;
4883 }
4884 return true;
[email protected]b273e432010-04-12 17:23:584885 default:
[email protected]2f143d482013-03-14 18:04:494886 if (pname >= GL_DRAW_BUFFER0_ARB &&
4887 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4888 *num_written = 1;
4889 if (params) {
4890 Framebuffer* framebuffer =
4891 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4892 if (framebuffer) {
4893 params[0] = framebuffer->GetDrawBuffer(pname);
4894 } else { // backbuffer
4895 if (pname == GL_DRAW_BUFFER0_ARB)
4896 params[0] = group_->draw_buffer();
4897 else
4898 params[0] = GL_NONE;
4899 }
4900 }
4901 return true;
4902 }
[email protected]4e8a5b122010-05-08 22:00:104903 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534904 return false;
[email protected]b273e432010-04-12 17:23:584905 }
4906}
4907
[email protected]4e8a5b122010-05-08 22:00:104908bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4909 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264910 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534911 return true;
4912 }
[email protected]4e8a5b122010-05-08 22:00:104913 return GetHelper(pname, NULL, num_values);
4914}
4915
[email protected]7d3c36e2013-07-12 14:13:164916GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4917 if (GL_MAX_SAMPLES == pname &&
4918 features().use_img_for_multisampled_render_to_texture) {
4919 return GL_MAX_SAMPLES_IMG;
4920 }
4921 return pname;
4922}
4923
[email protected]b273e432010-04-12 17:23:584924void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4925 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104926 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534927 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554928 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264929 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534930 GetHelper(pname, values.get(), &num_written);
4931 }
[email protected]b273e432010-04-12 17:23:584932 for (GLsizei ii = 0; ii < num_written; ++ii) {
4933 params[ii] = static_cast<GLboolean>(values[ii]);
4934 }
4935 } else {
[email protected]7d3c36e2013-07-12 14:13:164936 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584937 glGetBooleanv(pname, params);
4938 }
4939}
4940
4941void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4942 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104943 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264944 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534945 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554946 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534947 GetHelper(pname, values.get(), &num_written);
4948 for (GLsizei ii = 0; ii < num_written; ++ii) {
4949 params[ii] = static_cast<GLfloat>(values[ii]);
4950 }
4951 } else {
[email protected]7d3c36e2013-07-12 14:13:164952 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534953 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584954 }
[email protected]b273e432010-04-12 17:23:584955 }
4956}
4957
4958void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4959 DCHECK(params);
4960 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264961 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534962 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164963 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584964 glGetIntegerv(pname, params);
4965 }
4966}
4967
[email protected]a0c3e972010-04-21 00:49:134968void GLES2DecoderImpl::DoGetProgramiv(
4969 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424970 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4971 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134972 return;
4973 }
[email protected]df37b9932013-03-08 05:21:424974 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134975}
4976
[email protected]17cfbe0e2013-03-07 01:26:084977void GLES2DecoderImpl::DoGetBufferParameteriv(
4978 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134979 // Just delegate it. Some validation is actually done before this.
4980 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4981 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084982}
4983
[email protected]258a3313f2011-10-18 20:13:574984void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424985 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574986 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514987 LOCAL_SET_GL_ERROR(
4988 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574989 return;
4990 }
[email protected]68dcb1f2012-04-07 00:14:564991 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514992 LOCAL_SET_GL_ERROR(
4993 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564994 return;
4995 }
4996 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514997 LOCAL_SET_GL_ERROR(
4998 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564999 return;
5000 }
[email protected]df37b9932013-03-08 05:21:425001 Program* program = GetProgramInfoNotShader(
5002 program_id, "glBindAttribLocation");
5003 if (!program) {
[email protected]258a3313f2011-10-18 20:13:575004 return;
[email protected]558847a2010-03-24 07:02:545005 }
zmo460b593e2014-10-13 23:07:455006 // At this point, the program's shaders may not be translated yet,
5007 // therefore, we may not find the hashed attribute name.
5008 // glBindAttribLocation call with original name is useless.
5009 // So instead, we should simply cache the binding, and then call
5010 // Program::ExecuteBindAttribLocationCalls() right before link.
[email protected]df37b9932013-03-08 05:21:425011 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
zmo460b593e2014-10-13 23:07:455012 // TODO(zmo): Get rid of the following glBindAttribLocation call.
[email protected]df37b9932013-03-08 05:21:425013 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:575014}
5015
[email protected]558847a2010-03-24 07:02:545016error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:345017 uint32 immediate_data_size,
5018 const void* cmd_data) {
5019 const gles2::cmds::BindAttribLocationBucket& c =
5020 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:585021 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:545022 GLuint index = static_cast<GLuint>(c.index);
5023 Bucket* bucket = GetBucket(c.name_bucket_id);
5024 if (!bucket || bucket->size() == 0) {
5025 return error::kInvalidArguments;
5026 }
5027 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:185028 if (!bucket->GetAsString(&name_str)) {
5029 return error::kInvalidArguments;
5030 }
[email protected]258a3313f2011-10-18 20:13:575031 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:545032 return error::kNoError;
5033}
5034
[email protected]2be6abf32012-06-26 00:28:335035void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:425036 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:335037 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515038 LOCAL_SET_GL_ERROR(
5039 GL_INVALID_VALUE,
5040 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:335041 return;
5042 }
5043 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515044 LOCAL_SET_GL_ERROR(
5045 GL_INVALID_OPERATION,
5046 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:335047 return;
5048 }
5049 if (location < 0 || static_cast<uint32>(location) >=
5050 (group_->max_fragment_uniform_vectors() +
5051 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:515052 LOCAL_SET_GL_ERROR(
5053 GL_INVALID_VALUE,
5054 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335055 return;
5056 }
[email protected]df37b9932013-03-08 05:21:425057 Program* program = GetProgramInfoNotShader(
5058 program_id, "glBindUniformLocationCHROMIUM");
5059 if (!program) {
[email protected]2be6abf32012-06-26 00:28:335060 return;
5061 }
[email protected]df37b9932013-03-08 05:21:425062 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:515063 LOCAL_SET_GL_ERROR(
5064 GL_INVALID_VALUE,
5065 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335066 }
5067}
5068
[email protected]2be6abf32012-06-26 00:28:335069error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
5070 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:345071 const void* cmd_data) {
5072 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
5073 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
5074 cmd_data);
[email protected]2be6abf32012-06-26 00:28:335075 GLuint program = static_cast<GLuint>(c.program);
5076 GLint location = static_cast<GLint>(c.location);
5077 Bucket* bucket = GetBucket(c.name_bucket_id);
5078 if (!bucket || bucket->size() == 0) {
5079 return error::kInvalidArguments;
5080 }
5081 std::string name_str;
5082 if (!bucket->GetAsString(&name_str)) {
5083 return error::kInvalidArguments;
5084 }
5085 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
5086 return error::kNoError;
5087}
5088
vmiuracd108592014-09-08 14:36:345089error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
5090 const void* cmd_data) {
5091 const gles2::cmds::DeleteShader& c =
5092 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035093 GLuint client_id = c.shader;
5094 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425095 Shader* shader = GetShader(client_id);
5096 if (shader) {
5097 if (!shader->IsDeleted()) {
5098 glDeleteShader(shader->service_id());
5099 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:145100 }
[email protected]ae51d192010-04-27 00:48:035101 } else {
[email protected]ab09b612013-03-11 22:11:515102 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:035103 }
[email protected]96449d2c2009-11-25 00:01:325104 }
[email protected]f7a64ee2010-02-01 22:24:145105 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325106}
5107
vmiuracd108592014-09-08 14:36:345108error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
5109 const void* cmd_data) {
5110 const gles2::cmds::DeleteProgram& c =
5111 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035112 GLuint client_id = c.program;
5113 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425114 Program* program = GetProgram(client_id);
5115 if (program) {
5116 if (!program->IsDeleted()) {
5117 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:145118 }
[email protected]ae51d192010-04-27 00:48:035119 } else {
[email protected]ab09b612013-03-11 22:11:515120 LOCAL_SET_GL_ERROR(
5121 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:035122 }
[email protected]96449d2c2009-11-25 00:01:325123 }
[email protected]f7a64ee2010-02-01 22:24:145124 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325125}
5126
[email protected]a7266a92012-06-28 02:11:085127error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:445128 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:205129 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:465130 ApplyDirtyState();
boliu2e7d8a7a2014-10-16 20:35:205131 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
sievers2384f2b2014-11-18 02:10:355132 if (workarounds().gl_clear_broken) {
5133 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround",
5134 GetErrorState());
5135 if (!BoundFramebufferHasDepthAttachment())
5136 mask &= ~GL_DEPTH_BUFFER_BIT;
5137 if (!BoundFramebufferHasStencilAttachment())
5138 mask &= ~GL_STENCIL_BUFFER_BIT;
5139 clear_framebuffer_blit_->ClearFramebuffer(
5140 this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red,
5141 state_.color_clear_green, state_.color_clear_blue,
5142 state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear);
5143 return error::kNoError;
5144 }
[email protected]3a03a8f2011-03-19 00:51:275145 glClear(mask);
5146 }
[email protected]a7266a92012-06-28 02:11:085147 return error::kNoError;
5148}
5149
[email protected]36cef8ce2010-03-16 07:34:455150void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5151 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035152 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065153 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5154 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515155 LOCAL_SET_GL_ERROR(
5156 GL_INVALID_OPERATION,
5157 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455158 return;
5159 }
[email protected]ae51d192010-04-27 00:48:035160 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275161 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035162 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275163 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5164 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515165 LOCAL_SET_GL_ERROR(
5166 GL_INVALID_OPERATION,
5167 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035168 return;
5169 }
[email protected]ee2a79c32013-03-10 03:50:275170 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035171 }
[email protected]ab09b612013-03-11 22:11:515172 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035173 glFramebufferRenderbufferEXT(
5174 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515175 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265176 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275177 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285178 }
[email protected]9d3b2e12013-10-02 01:04:345179 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445180 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465181 }
[email protected]81fc9d02013-03-14 23:53:325182 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285183}
5184
[email protected]3a2e7c7b2010-08-06 01:12:285185void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465186 if (SetCapabilityState(cap, false)) {
5187 glDisable(cap);
5188 }
[email protected]3a2e7c7b2010-08-06 01:12:285189}
5190
5191void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465192 if (SetCapabilityState(cap, true)) {
5193 glEnable(cap);
5194 }
[email protected]3a2e7c7b2010-08-06 01:12:285195}
5196
[email protected]88a61bf2012-10-27 13:00:425197void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5198 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5199 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5200 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285201}
5202
[email protected]b04e24c2013-01-08 18:35:255203void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425204 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5205 state_.sample_coverage_invert = (invert != 0);
5206 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285207}
5208
[email protected]0d6bfdc2011-11-02 01:32:205209// Assumes framebuffer is complete.
5210void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065211 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305212 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205213 // bind this to the DRAW point, clear then bind back to READ
5214 // TODO(gman): I don't think there is any guarantee that an FBO that
5215 // is complete on the READ attachment will be complete as a DRAW
5216 // attachment.
5217 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065218 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305219 }
[email protected]3a2e7c7b2010-08-06 01:12:285220 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425221 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465222 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205223 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465224 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065225 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5226 1.0f);
[email protected]454157e2014-05-03 02:49:455227 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285228 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535229 if (feature_info_->feature_flags().ext_draw_buffers)
5230 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285231 }
5232
[email protected]4d8f0dd2013-03-09 14:37:065233 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5234 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285235 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475236 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5237 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285238 clear_bits |= GL_STENCIL_BUFFER_BIT;
5239 }
5240
[email protected]4d8f0dd2013-03-09 14:37:065241 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5242 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285243 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455244 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285245 clear_bits |= GL_DEPTH_BUFFER_BIT;
5246 }
5247
[email protected]454157e2014-05-03 02:49:455248 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285249 glClear(clear_bits);
5250
brucedawson18249152014-10-31 23:02:325251 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]0e58af82014-08-08 14:02:535252 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425253 framebuffer->RestoreDrawBuffersAfterClear();
5254
[email protected]968351b2011-12-20 08:26:515255 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065256 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285257
[email protected]c007aa02010-09-02 22:22:405258 RestoreClearState();
5259
5260 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065261 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5262 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485263 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065264 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5265 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485266 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405267 }
5268}
5269
5270void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445271 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245272 glClearColor(
5273 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5274 state_.color_clear_alpha);
5275 glClearStencil(state_.stencil_clear);
5276 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225277 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455278 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285279 }
[email protected]36cef8ce2010-03-16 07:34:455280}
5281
5282GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355283 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305284 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205285 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455286 return GL_FRAMEBUFFER_COMPLETE;
5287 }
[email protected]0d6bfdc2011-11-02 01:32:205288 GLenum completeness = framebuffer->IsPossiblyComplete();
5289 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5290 return completeness;
5291 }
[email protected]73276522012-11-09 05:50:205292 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455293}
5294
5295void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035296 GLenum target, GLenum attachment, GLenum textarget,
5297 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165298 DoFramebufferTexture2DCommon(
5299 "glFramebufferTexture2D", target, attachment,
5300 textarget, client_texture_id, level, 0);
5301}
5302
5303void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5304 GLenum target, GLenum attachment, GLenum textarget,
5305 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165306 DoFramebufferTexture2DCommon(
5307 "glFramebufferTexture2DMultisample", target, attachment,
5308 textarget, client_texture_id, level, samples);
5309}
5310
5311void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5312 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5313 GLuint client_texture_id, GLint level, GLsizei samples) {
5314 if (samples > renderbuffer_manager()->max_samples()) {
5315 LOCAL_SET_GL_ERROR(
5316 GL_INVALID_VALUE,
5317 "glFramebufferTexture2DMultisample", "samples too large");
5318 return;
5319 }
[email protected]4d8f0dd2013-03-09 14:37:065320 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5321 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515322 LOCAL_SET_GL_ERROR(
5323 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165324 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455325 return;
5326 }
[email protected]ae51d192010-04-27 00:48:035327 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495328 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035329 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495330 texture_ref = GetTexture(client_texture_id);
5331 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515332 LOCAL_SET_GL_ERROR(
5333 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165334 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035335 return;
5336 }
[email protected]370eaf12013-05-18 09:19:495337 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035338 }
[email protected]0d6bfdc2011-11-02 01:32:205339
[email protected]80eb6b52012-01-19 00:14:415340 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515341 LOCAL_SET_GL_ERROR(
5342 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165343 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205344 return;
5345 }
5346
[email protected]91c94eb2013-10-22 10:32:545347 if (texture_ref)
5348 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5349
[email protected]7d3c36e2013-07-12 14:13:165350 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5351 if (0 == samples) {
5352 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5353 } else {
5354 if (features().use_img_for_multisampled_render_to_texture) {
5355 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5356 service_id, level, samples);
5357 } else {
5358 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5359 service_id, level, samples);
5360 }
5361 }
5362 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265363 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165364 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5365 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285366 }
[email protected]9d3b2e12013-10-02 01:04:345367 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445368 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465369 }
[email protected]91c94eb2013-10-22 10:32:545370
5371 if (texture_ref)
5372 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5373
[email protected]81fc9d02013-03-14 23:53:325374 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455375}
5376
zmo84c08202014-11-23 15:28:405377void GLES2DecoderImpl::DoFramebufferTextureLayer(
5378 GLenum target, GLenum attachment, GLuint client_texture_id,
5379 GLint level, GLint layer) {
5380 // TODO(zmo): Unsafe ES3 API, missing states update.
5381 GLuint service_id = 0;
5382 TextureRef* texture_ref = NULL;
5383 if (client_texture_id) {
5384 texture_ref = GetTexture(client_texture_id);
5385 if (!texture_ref) {
5386 LOCAL_SET_GL_ERROR(
5387 GL_INVALID_OPERATION,
5388 "glFramebufferTextureLayer", "unknown texture_ref");
5389 return;
5390 }
5391 service_id = texture_ref->service_id();
5392 }
5393 glFramebufferTextureLayer(target, attachment, service_id, level, layer);
5394}
5395
[email protected]36cef8ce2010-03-16 07:34:455396void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5397 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065398 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5399 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515400 LOCAL_SET_GL_ERROR(
5401 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205402 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455403 return;
5404 }
[email protected]74c1ec42010-08-12 01:55:575405 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105406 const Framebuffer::Attachment* attachment_object =
5407 framebuffer->GetAttachment(attachment);
5408 *params = attachment_object ? attachment_object->object_name() : 0;
5409 } else {
[email protected]7d3c36e2013-07-12 14:13:165410 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5411 features().use_img_for_multisampled_render_to_texture) {
5412 pname = GL_TEXTURE_SAMPLES_IMG;
5413 }
[email protected]62e65f02013-05-29 22:28:105414 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575415 }
[email protected]36cef8ce2010-03-16 07:34:455416}
5417
5418void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5419 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355420 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205421 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5422 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515423 LOCAL_SET_GL_ERROR(
5424 GL_INVALID_OPERATION,
5425 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455426 return;
5427 }
[email protected]8875a5f2014-06-27 08:33:475428
5429 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275430 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435431 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5432 *params = renderbuffer->internal_format();
5433 break;
5434 case GL_RENDERBUFFER_WIDTH:
5435 *params = renderbuffer->width();
5436 break;
5437 case GL_RENDERBUFFER_HEIGHT:
5438 *params = renderbuffer->height();
5439 break;
[email protected]7d3c36e2013-07-12 14:13:165440 case GL_RENDERBUFFER_SAMPLES_EXT:
5441 if (features().use_img_for_multisampled_render_to_texture) {
5442 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5443 params);
5444 } else {
5445 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5446 params);
5447 }
[email protected]ad84a3a2012-06-08 21:42:435448 default:
5449 glGetRenderbufferParameterivEXT(target, pname, params);
5450 break;
[email protected]b71f52c2010-06-18 22:20:205451 }
[email protected]36cef8ce2010-03-16 07:34:455452}
5453
[email protected]49cabed2013-11-13 18:15:185454void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305455 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5456 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5457 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445458 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165459
[email protected]49cabed2013-11-13 18:15:185460 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165461 return;
5462 }
5463
[email protected]454157e2014-05-03 02:49:455464 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
boliu2e7d8a7a2014-10-16 20:35:205465 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]f42f05b2013-11-15 21:46:185466 BlitFramebufferHelper(
5467 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455468 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5469 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185470}
5471
[email protected]8875a5f2014-06-27 08:33:475472void GLES2DecoderImpl::EnsureRenderbufferBound() {
5473 if (!state_.bound_renderbuffer_valid) {
5474 state_.bound_renderbuffer_valid = true;
5475 glBindRenderbufferEXT(GL_RENDERBUFFER,
5476 state_.bound_renderbuffer.get()
5477 ? state_.bound_renderbuffer->service_id()
5478 : 0);
5479 }
5480}
5481
[email protected]f42f05b2013-11-15 21:46:185482void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5483 const FeatureInfo* feature_info,
5484 GLenum target,
5485 GLsizei samples,
5486 GLenum internal_format,
5487 GLsizei width,
5488 GLsizei height) {
5489 // TODO(sievers): This could be resolved at the GL binding level, but the
5490 // binding process is currently a bit too 'brute force'.
5491 if (feature_info->feature_flags().is_angle) {
5492 glRenderbufferStorageMultisampleANGLE(
5493 target, samples, internal_format, width, height);
5494 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5495 glRenderbufferStorageMultisample(
5496 target, samples, internal_format, width, height);
5497 } else {
5498 glRenderbufferStorageMultisampleEXT(
5499 target, samples, internal_format, width, height);
5500 }
5501}
5502
5503void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5504 GLint srcY0,
5505 GLint srcX1,
5506 GLint srcY1,
5507 GLint dstX0,
5508 GLint dstY0,
5509 GLint dstX1,
5510 GLint dstY1,
5511 GLbitfield mask,
5512 GLenum filter) {
5513 // TODO(sievers): This could be resolved at the GL binding level, but the
5514 // binding process is currently a bit too 'brute force'.
5515 if (feature_info_->feature_flags().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245516 glBlitFramebufferANGLE(
5517 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185518 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5519 glBlitFramebuffer(
5520 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245521 } else {
5522 glBlitFramebufferEXT(
5523 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5524 }
[email protected]8e3e0662010-08-23 18:46:305525}
5526
[email protected]49cabed2013-11-13 18:15:185527bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5528 GLsizei samples,
5529 GLenum internalformat,
5530 GLsizei width,
5531 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535532 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515533 LOCAL_SET_GL_ERROR(
5534 GL_INVALID_VALUE,
5535 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185536 return false;
[email protected]84afefa2011-10-19 21:45:535537 }
5538
5539 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5540 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515541 LOCAL_SET_GL_ERROR(
5542 GL_INVALID_VALUE,
5543 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185544 return false;
[email protected]84afefa2011-10-19 21:45:535545 }
5546
[email protected]7989c9e2013-01-23 06:39:265547 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235548 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5549 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515550 LOCAL_SET_GL_ERROR(
5551 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205552 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185553 return false;
[email protected]8e3e0662010-08-23 18:46:305554 }
5555
[email protected]7989c9e2013-01-23 06:39:265556 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515557 LOCAL_SET_GL_ERROR(
5558 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205559 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185560 return false;
5561 }
5562
5563 return true;
5564}
5565
5566void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5567 GLenum target, GLsizei samples, GLenum internalformat,
5568 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185569 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5570 if (!renderbuffer) {
5571 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5572 "glRenderbufferStorageMultisampleCHROMIUM",
5573 "no renderbuffer bound");
5574 return;
5575 }
5576
5577 if (!ValidateRenderbufferStorageMultisample(
5578 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265579 return;
5580 }
5581
[email protected]8875a5f2014-06-27 08:33:475582 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235583 GLenum impl_format =
5584 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5585 internalformat);
[email protected]49cabed2013-11-13 18:15:185586 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5587 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185588 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:255589 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185590 GLenum error =
5591 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265592 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105593
5594 if (workarounds().validate_multisample_buffer_allocation) {
5595 if (!VerifyMultisampleRenderbufferIntegrity(
5596 renderbuffer->service_id(), impl_format)) {
5597 LOCAL_SET_GL_ERROR(
5598 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185599 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105600 return;
5601 }
5602 }
5603
[email protected]968351b2011-12-20 08:26:515604 // TODO(gman): If renderbuffers tracked which framebuffers they were
5605 // attached to we could just mark those framebuffers as not complete.
5606 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205607 renderbuffer_manager()->SetInfo(
5608 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265609 }
[email protected]8e3e0662010-08-23 18:46:305610}
5611
[email protected]49cabed2013-11-13 18:15:185612// This is the handler for multisampled_render_to_texture extensions.
5613void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5614 GLenum target, GLsizei samples, GLenum internalformat,
5615 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185616 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5617 if (!renderbuffer) {
5618 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5619 "glRenderbufferStorageMultisampleEXT",
5620 "no renderbuffer bound");
5621 return;
5622 }
5623
5624 if (!ValidateRenderbufferStorageMultisample(
5625 samples, internalformat, width, height)) {
5626 return;
5627 }
5628
[email protected]8875a5f2014-06-27 08:33:475629 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185630 GLenum impl_format =
5631 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5632 internalformat);
5633 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5634 if (features().use_img_for_multisampled_render_to_texture) {
5635 glRenderbufferStorageMultisampleIMG(
5636 target, samples, impl_format, width, height);
5637 } else {
5638 glRenderbufferStorageMultisampleEXT(
5639 target, samples, impl_format, width, height);
5640 }
5641 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5642 if (error == GL_NO_ERROR) {
5643 // TODO(gman): If renderbuffers tracked which framebuffers they were
5644 // attached to we could just mark those framebuffers as not complete.
5645 framebuffer_manager()->IncFramebufferStateChangeCount();
5646 renderbuffer_manager()->SetInfo(
5647 renderbuffer, samples, internalformat, width, height);
5648 }
5649}
5650
[email protected]4a4c18b2013-09-13 22:50:105651// This function validates the allocation of a multisampled renderbuffer
5652// by clearing it to a key color, blitting the contents to a texture, and
5653// reading back the color to ensure it matches the key.
5654bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5655 GLuint renderbuffer, GLenum format) {
5656
5657 // Only validate color buffers.
5658 // These formats have been selected because they are very common or are known
5659 // to be used by the WebGL backbuffer. If problems are observed with other
5660 // color formats they can be added here.
5661 switch(format) {
5662 case GL_RGB:
5663 case GL_RGB8:
5664 case GL_RGBA:
5665 case GL_RGBA8:
5666 break;
5667 default:
5668 return true;
5669 }
5670
5671 GLint draw_framebuffer, read_framebuffer;
5672
5673 // Cache framebuffer and texture bindings.
5674 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5675 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5676
5677 if (!validation_texture_) {
5678 GLint bound_texture;
5679 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5680
5681 // Create additional resources needed for the verification.
5682 glGenTextures(1, &validation_texture_);
5683 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5684 glGenFramebuffersEXT(1, &validation_fbo_);
5685
5686 // Texture only needs to be 1x1.
5687 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5688 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5689 GL_UNSIGNED_BYTE, NULL);
5690
5691 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5692 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5693 GL_TEXTURE_2D, validation_texture_, 0);
5694
5695 glBindTexture(GL_TEXTURE_2D, bound_texture);
5696 }
5697
5698 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5699 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5700 GL_RENDERBUFFER, renderbuffer);
5701
5702 // Cache current state and reset it to the values we require.
5703 GLboolean scissor_enabled = false;
5704 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5705 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455706 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105707
[email protected]454157e2014-05-03 02:49:455708 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105709 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455710 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105711
5712 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5713 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5714 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5715
5716 // Clear the buffer to the desired key color.
5717 glClear(GL_COLOR_BUFFER_BIT);
5718
5719 // Blit from the multisample buffer to a standard texture.
5720 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5721 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5722
[email protected]f42f05b2013-11-15 21:46:185723 BlitFramebufferHelper(
5724 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105725
5726 // Read a pixel from the buffer.
5727 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5728
5729 unsigned char pixel[3] = {0, 0, 0};
5730 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5731
5732 // Detach the renderbuffer.
5733 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5734 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5735 GL_RENDERBUFFER, 0);
5736
5737 // Restore cached state.
5738 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455739 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105740
[email protected]454157e2014-05-03 02:49:455741 state_.SetDeviceColorMask(
5742 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105743 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5744 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5745 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5746
5747 // Return true if the pixel matched the desired key color.
5748 return (pixel[0] == 0xFF &&
5749 pixel[1] == 0x00 &&
5750 pixel[2] == 0xFF);
5751}
5752
[email protected]36cef8ce2010-03-16 07:34:455753void GLES2DecoderImpl::DoRenderbufferStorage(
5754 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355755 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205756 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5757 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515758 LOCAL_SET_GL_ERROR(
5759 GL_INVALID_OPERATION,
5760 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455761 return;
5762 }
[email protected]876f6fee2010-08-02 23:10:325763
[email protected]84afefa2011-10-19 21:45:535764 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5765 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515766 LOCAL_SET_GL_ERROR(
5767 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535768 return;
5769 }
5770
[email protected]7989c9e2013-01-23 06:39:265771 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235772 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5773 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515774 LOCAL_SET_GL_ERROR(
5775 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265776 return;
5777 }
5778
5779 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515780 LOCAL_SET_GL_ERROR(
5781 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265782 return;
[email protected]b71f52c2010-06-18 22:20:205783 }
[email protected]876f6fee2010-08-02 23:10:325784
[email protected]8875a5f2014-06-27 08:33:475785 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:515786 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265787 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235788 target,
5789 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5790 internalformat),
5791 width,
5792 height);
[email protected]ab09b612013-03-11 22:11:515793 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265794 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515795 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5796 // we could just mark those framebuffers as not complete.
5797 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205798 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265799 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265800 }
[email protected]36cef8ce2010-03-16 07:34:455801}
5802
[email protected]df37b9932013-03-08 05:21:425803void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385804 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425805 Program* program = GetProgramInfoNotShader(
5806 program_id, "glLinkProgram");
5807 if (!program) {
[email protected]a93bb842010-02-16 23:03:475808 return;
5809 }
[email protected]05afda12011-01-20 00:17:345810
[email protected]df37b9932013-03-08 05:21:425811 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395812 ShaderTranslator* vertex_translator = NULL;
5813 ShaderTranslator* fragment_translator = NULL;
5814 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115815 vertex_translator = vertex_translator_.get();
5816 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395817 }
[email protected]df37b9932013-03-08 05:21:425818 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115819 vertex_translator,
5820 fragment_translator,
[email protected]008401532014-02-07 00:10:505821 workarounds().count_all_in_varyings_packing ?
5822 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115823 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425824 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185825 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425826 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185827 if (workarounds().clear_uniforms_before_first_program_use)
5828 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545829 }
5830 }
vmiura8266ca72014-09-09 21:37:005831
5832 // LinkProgram can be very slow. Exit command processing to allow for
5833 // context preemption and GPU watchdog checks.
5834 ExitCommandProcessingEarly();
[email protected]07f54fcc2009-12-22 02:46:305835};
5836
[email protected]3916c97e2010-02-25 03:20:505837void GLES2DecoderImpl::DoTexParameterf(
5838 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445839 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5840 &state_, target);
[email protected]02965c22013-03-09 02:40:075841 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515842 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245843 return;
[email protected]07f54fcc2009-12-22 02:46:305844 }
[email protected]cbb22e42011-05-12 23:36:245845
[email protected]737191ee72014-03-09 08:02:425846 texture_manager()->SetParameterf(
5847 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305848}
5849
[email protected]3916c97e2010-02-25 03:20:505850void GLES2DecoderImpl::DoTexParameteri(
5851 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445852 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5853 &state_, target);
[email protected]02965c22013-03-09 02:40:075854 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515855 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245856 return;
[email protected]3916c97e2010-02-25 03:20:505857 }
[email protected]cbb22e42011-05-12 23:36:245858
[email protected]737191ee72014-03-09 08:02:425859 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505860 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505861}
5862
5863void GLES2DecoderImpl::DoTexParameterfv(
5864 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445865 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5866 &state_, target);
[email protected]02965c22013-03-09 02:40:075867 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515868 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245869 return;
[email protected]3916c97e2010-02-25 03:20:505870 }
[email protected]cbb22e42011-05-12 23:36:245871
[email protected]737191ee72014-03-09 08:02:425872 texture_manager()->SetParameterf(
5873 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505874}
5875
5876void GLES2DecoderImpl::DoTexParameteriv(
5877 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445878 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5879 &state_, target);
[email protected]02965c22013-03-09 02:40:075880 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515881 LOCAL_SET_GL_ERROR(
5882 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245883 return;
[email protected]3916c97e2010-02-25 03:20:505884 }
[email protected]cbb22e42011-05-12 23:36:245885
[email protected]737191ee72014-03-09 08:02:425886 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505887 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505888}
5889
orglofchcad5a6742014-11-07 19:51:125890bool GLES2DecoderImpl::CheckCurrentValuebuffer(const char* function_name) {
5891 if (!state_.bound_valuebuffer.get()) {
5892 // There is no valuebuffer bound
5893 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5894 "no valuebuffer in use");
5895 return false;
5896 }
5897 return true;
5898}
5899
5900bool GLES2DecoderImpl::CheckCurrentValuebufferForSubscription(
5901 GLenum subscription,
5902 const char* function_name) {
5903 if (!CheckCurrentValuebuffer(function_name)) {
5904 return false;
5905 }
5906 if (!state_.bound_valuebuffer.get()->IsSubscribed(subscription)) {
5907 // The valuebuffer is not subscribed to the target
5908 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5909 "valuebuffer is not subscribed");
5910 return false;
5911 }
5912 return true;
5913}
5914
5915bool GLES2DecoderImpl::CheckSubscriptionTarget(GLint location,
5916 GLenum subscription,
5917 const char* function_name) {
5918 if (!CheckCurrentProgramForUniform(location, function_name)) {
5919 return false;
5920 }
5921 GLint real_location = -1;
5922 GLint array_index = -1;
5923 const Program::UniformInfo* info =
5924 state_.current_program->GetUniformInfoByFakeLocation(
5925 location, &real_location, &array_index);
5926 if (!info) {
5927 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "unknown location");
5928 return false;
5929 }
5930 if ((ValuebufferManager::ApiTypeForSubscriptionTarget(subscription) &
5931 info->accepts_api_type) == 0) {
5932 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5933 "wrong type for subscription");
5934 return false;
5935 }
5936 return true;
5937}
5938
[email protected]939e7362010-05-13 20:49:105939bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115940 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435941 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515942 LOCAL_SET_GL_ERROR(
5943 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435944 return false;
[email protected]939e7362010-05-13 20:49:105945 }
[email protected]e259eb412012-10-13 05:47:245946 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515947 LOCAL_SET_GL_ERROR(
5948 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105949 return false;
5950 }
5951 return true;
5952}
5953
5954bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5955 GLint location, const char* function_name) {
5956 if (!CheckCurrentProgram(function_name)) {
5957 return false;
5958 }
5959 return location != -1;
5960}
5961
zmof9a81360f2014-10-17 00:06:145962bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
5963 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
5964 if (!framebuffer)
5965 return false;
5966 const Framebuffer::Attachment* attachment =
5967 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
5968 if (!attachment)
5969 return false;
5970
5971 DCHECK(state_.current_program.get());
5972 const Program::SamplerIndices& sampler_indices =
5973 state_.current_program->sampler_indices();
5974 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5975 const Program::UniformInfo* uniform_info =
5976 state_.current_program->GetUniformInfo(sampler_indices[ii]);
5977 DCHECK(uniform_info);
5978 if (uniform_info->type != GL_SAMPLER_2D)
5979 continue;
5980 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5981 GLuint texture_unit_index = uniform_info->texture_units[jj];
5982 if (texture_unit_index >= state_.texture_units.size())
5983 continue;
5984 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
5985 TextureRef* texture_ref =
5986 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
5987 if (attachment->IsTexture(texture_ref))
5988 return true;
5989 }
5990 }
5991 return false;
5992}
5993
orglofchcad5a6742014-11-07 19:51:125994bool GLES2DecoderImpl::CheckUniformForApiType(
5995 const Program::UniformInfo* info,
5996 const char* function_name,
5997 Program::UniformApiType api_type) {
5998 DCHECK(info);
5999 if ((api_type & info->accepts_api_type) == 0) {
6000 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6001 "wrong uniform function for type");
6002 return false;
6003 }
6004 return true;
6005}
6006
[email protected]43c2f1f2011-03-25 18:35:366007bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:136008 GLint fake_location,
6009 const char* function_name,
6010 Program::UniformApiType api_type,
6011 GLint* real_location,
6012 GLenum* type,
6013 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:366014 DCHECK(type);
6015 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:126016 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:526017
[email protected]1b0a6752012-02-22 03:44:126018 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:106019 return false;
6020 }
[email protected]43c2f1f2011-03-25 18:35:366021 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:356022 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:246023 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:126024 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:366025 if (!info) {
[email protected]ab09b612013-03-11 22:11:516026 LOCAL_SET_GL_ERROR(
6027 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:106028 return false;
6029 }
orglofchcad5a6742014-11-07 19:51:126030 if (!CheckUniformForApiType(info, function_name, api_type)) {
[email protected]476ccb72012-12-06 15:52:526031 return false;
6032 }
[email protected]43c2f1f2011-03-25 18:35:366033 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:516034 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436035 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:366036 return false;
6037 }
6038 *count = std::min(info->size - array_index, *count);
6039 if (*count <= 0) {
6040 return false;
6041 }
6042 *type = info->type;
[email protected]939e7362010-05-13 20:49:106043 return true;
6044}
6045
[email protected]1b0a6752012-02-22 03:44:126046void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
6047 GLenum type = 0;
6048 GLsizei count = 1;
6049 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136050 if (!PrepForSetUniformByLocation(fake_location,
6051 "glUniform1i",
6052 Program::kUniform1i,
6053 &real_location,
6054 &type,
6055 &count)) {
[email protected]3916c97e2010-02-25 03:20:506056 return;
6057 }
[email protected]e259eb412012-10-13 05:47:246058 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026059 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:516060 LOCAL_SET_GL_ERROR(
6061 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466062 return;
6063 }
[email protected]1b0a6752012-02-22 03:44:126064 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:506065}
6066
6067void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:126068 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:366069 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126070 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136071 if (!PrepForSetUniformByLocation(fake_location,
6072 "glUniform1iv",
6073 Program::kUniform1i,
6074 &real_location,
6075 &type,
6076 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366077 return;
6078 }
[email protected]74727112012-06-13 21:18:086079 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
6080 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:246081 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026082 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:516083 LOCAL_SET_GL_ERROR(
6084 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466085 return;
6086 }
[email protected]43c2f1f2011-03-25 18:35:366087 }
[email protected]1b0a6752012-02-22 03:44:126088 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:506089}
6090
[email protected]939e7362010-05-13 20:49:106091void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:126092 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366093 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126094 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136095 if (!PrepForSetUniformByLocation(fake_location,
6096 "glUniform1fv",
6097 Program::kUniform1f,
6098 &real_location,
6099 &type,
6100 &count)) {
[email protected]939e7362010-05-13 20:49:106101 return;
6102 }
6103 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:556104 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:106105 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:536106 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106107 }
[email protected]1b0a6752012-02-22 03:44:126108 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106109 } else {
[email protected]1b0a6752012-02-22 03:44:126110 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106111 }
6112}
6113
6114void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:126115 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366116 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126117 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136118 if (!PrepForSetUniformByLocation(fake_location,
6119 "glUniform2fv",
6120 Program::kUniform2f,
6121 &real_location,
6122 &type,
6123 &count)) {
[email protected]939e7362010-05-13 20:49:106124 return;
6125 }
6126 if (type == GL_BOOL_VEC2) {
6127 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:556128 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106129 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536130 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106131 }
[email protected]1b0a6752012-02-22 03:44:126132 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106133 } else {
[email protected]1b0a6752012-02-22 03:44:126134 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106135 }
6136}
6137
6138void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:126139 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366140 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126141 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136142 if (!PrepForSetUniformByLocation(fake_location,
6143 "glUniform3fv",
6144 Program::kUniform3f,
6145 &real_location,
6146 &type,
6147 &count)) {
[email protected]939e7362010-05-13 20:49:106148 return;
6149 }
6150 if (type == GL_BOOL_VEC3) {
6151 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:556152 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106153 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536154 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106155 }
[email protected]1b0a6752012-02-22 03:44:126156 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106157 } else {
[email protected]1b0a6752012-02-22 03:44:126158 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106159 }
6160}
6161
6162void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:126163 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366164 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126165 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136166 if (!PrepForSetUniformByLocation(fake_location,
6167 "glUniform4fv",
6168 Program::kUniform4f,
6169 &real_location,
6170 &type,
6171 &count)) {
[email protected]939e7362010-05-13 20:49:106172 return;
6173 }
6174 if (type == GL_BOOL_VEC4) {
6175 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:556176 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106177 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536178 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106179 }
[email protected]1b0a6752012-02-22 03:44:126180 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106181 } else {
[email protected]1b0a6752012-02-22 03:44:126182 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106183 }
6184}
6185
[email protected]43c2f1f2011-03-25 18:35:366186void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:126187 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366188 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126189 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136190 if (!PrepForSetUniformByLocation(fake_location,
6191 "glUniform2iv",
6192 Program::kUniform2i,
6193 &real_location,
6194 &type,
6195 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366196 return;
6197 }
[email protected]1b0a6752012-02-22 03:44:126198 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366199}
6200
6201void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:126202 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366203 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126204 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136205 if (!PrepForSetUniformByLocation(fake_location,
6206 "glUniform3iv",
6207 Program::kUniform3i,
6208 &real_location,
6209 &type,
6210 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366211 return;
6212 }
[email protected]1b0a6752012-02-22 03:44:126213 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366214}
6215
6216void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:126217 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366218 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126219 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136220 if (!PrepForSetUniformByLocation(fake_location,
6221 "glUniform4iv",
6222 Program::kUniform4i,
6223 &real_location,
6224 &type,
6225 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366226 return;
6227 }
[email protected]1b0a6752012-02-22 03:44:126228 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366229}
6230
6231void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126232 GLint fake_location, GLsizei count, GLboolean transpose,
6233 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366234 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126235 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136236 if (!PrepForSetUniformByLocation(fake_location,
6237 "glUniformMatrix2fv",
6238 Program::kUniformMatrix2f,
6239 &real_location,
6240 &type,
6241 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366242 return;
6243 }
[email protected]1b0a6752012-02-22 03:44:126244 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366245}
6246
6247void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126248 GLint fake_location, GLsizei count, GLboolean transpose,
6249 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366250 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126251 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136252 if (!PrepForSetUniformByLocation(fake_location,
6253 "glUniformMatrix3fv",
6254 Program::kUniformMatrix3f,
6255 &real_location,
6256 &type,
6257 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366258 return;
6259 }
[email protected]1b0a6752012-02-22 03:44:126260 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366261}
6262
6263void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126264 GLint fake_location, GLsizei count, GLboolean transpose,
6265 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366266 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126267 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136268 if (!PrepForSetUniformByLocation(fake_location,
6269 "glUniformMatrix4fv",
6270 Program::kUniformMatrix4f,
6271 &real_location,
6272 &type,
6273 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366274 return;
6275 }
[email protected]1b0a6752012-02-22 03:44:126276 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366277}
6278
[email protected]df37b9932013-03-08 05:21:426279void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036280 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426281 Program* program = NULL;
6282 if (program_id) {
6283 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6284 if (!program) {
[email protected]ae51d192010-04-27 00:48:036285 return;
6286 }
[email protected]df37b9932013-03-08 05:21:426287 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506288 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516289 LOCAL_SET_GL_ERROR(
6290 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506291 return;
6292 }
[email protected]df37b9932013-03-08 05:21:426293 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506294 }
[email protected]7cd76fd2013-06-02 21:11:116295 if (state_.current_program.get()) {
6296 program_manager()->UnuseProgram(shader_manager(),
6297 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146298 }
[email protected]df37b9932013-03-08 05:21:426299 state_.current_program = program;
6300 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546301 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116302 if (state_.current_program.get()) {
6303 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186304 if (workarounds().clear_uniforms_before_first_program_use)
6305 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146306 }
[email protected]3916c97e2010-02-25 03:20:506307}
6308
[email protected]ab09b612013-03-11 22:11:516309void GLES2DecoderImpl::RenderWarning(
6310 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326311 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016312}
6313
[email protected]ab09b612013-03-11 22:11:516314void GLES2DecoderImpl::PerformanceWarning(
6315 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506316 logger_.LogMessage(filename, line,
6317 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016318}
6319
[email protected]91c94eb2013-10-22 10:32:546320void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6321 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546322 // Image is already in use if texture is attached to a framebuffer.
6323 if (texture && !texture->IsAttachedToFramebuffer()) {
6324 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6325 if (image) {
6326 ScopedGLErrorSuppressor suppressor(
6327 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6328 GetErrorState());
6329 glBindTexture(textarget, texture->service_id());
6330 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026331 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546332 }
6333 }
6334}
6335
6336void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6337 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546338 // Image is still in use if texture is attached to a framebuffer.
6339 if (texture && !texture->IsAttachedToFramebuffer()) {
6340 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6341 if (image) {
6342 ScopedGLErrorSuppressor suppressor(
6343 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6344 GetErrorState());
6345 glBindTexture(textarget, texture->service_id());
6346 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026347 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546348 }
6349 }
6350}
6351
[email protected]e56131d22013-07-28 16:14:116352bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116353 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546354 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556355 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116356 return true;
[email protected]ef526492010-06-02 23:12:256357 }
[email protected]e2367b42013-05-31 03:37:216358
[email protected]ef526492010-06-02 23:12:256359 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356360 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246361 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506362 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356363 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246364 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506365 DCHECK(uniform_info);
6366 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6367 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026368 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246369 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546370 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366371 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546372 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6373 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256374 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506375 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6376 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546377 textarget,
[email protected]00f893d2010-08-24 18:55:496378 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:516379 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:016380 std::string("texture bound to texture unit ") +
6381 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:296382 " is not renderable. It maybe non-power-of-2 and have"
6383 " incompatible texture filtering or is not"
6384 " 'texture complete'");
[email protected]91c94eb2013-10-22 10:32:546385 continue;
[email protected]3916c97e2010-02-25 03:20:506386 }
[email protected]91c94eb2013-10-22 10:32:546387
[email protected]4e7b89202014-01-28 01:44:066388 if (textarget != GL_TEXTURE_CUBE_MAP) {
6389 Texture* texture = texture_ref->texture();
6390 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6391 if (image && !texture->IsAttachedToFramebuffer()) {
6392 ScopedGLErrorSuppressor suppressor(
6393 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6394 textures_set = true;
6395 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6396 image->WillUseTexImage();
6397 continue;
6398 }
[email protected]91c94eb2013-10-22 10:32:546399 }
[email protected]3916c97e2010-02-25 03:20:506400 }
6401 // else: should this be an error?
6402 }
6403 }
[email protected]e56131d22013-07-28 16:14:116404 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506405}
6406
[email protected]91c94eb2013-10-22 10:32:546407void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116408 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356409 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116410 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506411 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356412 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246413 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506414 DCHECK(uniform_info);
6415 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6416 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026417 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246418 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116419 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546420 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496421 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506422 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496423 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116424 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6425 ? texture_unit.bound_texture_2d.get()
6426 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506427 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496428 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546429 continue;
6430 }
6431
[email protected]4e7b89202014-01-28 01:44:066432 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6433 Texture* texture = texture_ref->texture();
6434 gfx::GLImage* image =
6435 texture->GetLevelImage(texture_unit.bind_target, 0);
6436 if (image && !texture->IsAttachedToFramebuffer()) {
6437 ScopedGLErrorSuppressor suppressor(
6438 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6439 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6440 image->DidUseTexImage();
6441 continue;
6442 }
[email protected]3916c97e2010-02-25 03:20:506443 }
6444 }
6445 }
6446 }
6447 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246448 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306449}
6450
[email protected]0d6bfdc2011-11-02 01:32:206451bool GLES2DecoderImpl::ClearUnclearedTextures() {
6452 // Only check if there are some uncleared textures.
6453 if (!texture_manager()->HaveUnsafeTextures()) {
6454 return true;
6455 }
6456
6457 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116458 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356459 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116460 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206461 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356462 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246463 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206464 DCHECK(uniform_info);
6465 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6466 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026467 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246468 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496469 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366470 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496471 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6472 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206473 return false;
6474 }
6475 }
6476 }
6477 }
6478 }
6479 }
6480 return true;
6481}
6482
[email protected]c6aef902012-02-14 03:31:426483bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106484 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6485 GLsizei primcount) {
6486 DCHECK(instanced || primcount == 1);
6487
[email protected]689fa1c52010-06-09 18:35:036488 // NOTE: We specifically do not check current_program->IsValid() because
6489 // it could never be invalid since glUseProgram would have failed. While
6490 // glLinkProgram could later mark the program as invalid the previous
6491 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116492 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506493 // The program does not exist.
6494 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516495 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506496 return false;
6497 }
[email protected]c6aef902012-02-14 03:31:426498
zmof9a81360f2014-10-17 00:06:146499 if (CheckDrawingFeedbackLoops()) {
6500 LOCAL_SET_GL_ERROR(
6501 GL_INVALID_OPERATION, function_name,
6502 "Source and destination textures of the draw are the same.");
6503 return false;
6504 }
6505
[email protected]7cd76fd2013-06-02 21:11:116506 return state_.vertex_attrib_manager
6507 ->ValidateBindings(function_name,
6508 this,
6509 feature_info_.get(),
6510 state_.current_program.get(),
6511 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106512 instanced,
[email protected]7cd76fd2013-06-02 21:11:116513 primcount);
[email protected]b1122982010-05-17 23:04:246514}
6515
[email protected]c13e1da62011-09-09 21:48:306516bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436517 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306518 DCHECK(simulated);
6519 *simulated = false;
6520
[email protected]876f6fee2010-08-02 23:10:326521 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306522 return true;
[email protected]876f6fee2010-08-02 23:10:326523
[email protected]ac77603c72013-03-08 13:52:066524 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356525 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246526 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246527 bool attrib_0_used =
6528 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066529 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306530 return true;
[email protected]b1122982010-05-17 23:04:246531 }
6532
[email protected]b1122982010-05-17 23:04:246533 // Make a buffer with a single repeated vec4 value enough to
6534 // simulate the constant value that is supposed to be here.
6535 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306536 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476537 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306538
6539 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476540 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306541 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516542 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306543 return false;
6544 }
6545
[email protected]ab09b612013-03-11 22:11:516546 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016547 "Attribute 0 is disabled. This has signficant performance penalty");
6548
[email protected]ab09b612013-03-11 22:11:516549 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306550 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6551
[email protected]8f0b86c2f2012-04-10 05:48:286552 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6553 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496554 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306555 GLenum error = glGetError();
6556 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516557 LOCAL_SET_GL_ERROR(
6558 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306559 return false;
6560 }
[email protected]fc753442011-02-04 19:49:496561 }
[email protected]af6380962012-11-29 23:24:136562
6563 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286564 if (new_buffer ||
6565 (attrib_0_used &&
6566 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136567 (value.v[0] != attrib_0_value_.v[0] ||
6568 value.v[1] != attrib_0_value_.v[1] ||
6569 value.v[2] != attrib_0_value_.v[2] ||
6570 value.v[3] != attrib_0_value_.v[3])))) {
6571 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496572 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6573 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136574 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246575 attrib_0_size_ = size_needed;
6576 }
6577
6578 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6579
[email protected]ac77603c72013-03-08 13:52:066580 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426581 glVertexAttribDivisorANGLE(0, 0);
6582
[email protected]c13e1da62011-09-09 21:48:306583 *simulated = true;
[email protected]b1122982010-05-17 23:04:246584 return true;
[email protected]b1122982010-05-17 23:04:246585}
6586
[email protected]3fc38e22014-05-30 00:13:236587void GLES2DecoderImpl::RestoreStateForAttrib(
6588 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066589 const VertexAttrib* attrib =
6590 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236591 if (restore_array_binding) {
6592 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6593 Buffer* buffer = attrib->buffer();
6594 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6595 glVertexAttribPointer(
6596 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6597 attrib->gl_stride(), ptr);
6598 }
[email protected]ac77603c72013-03-08 13:52:066599 if (attrib->divisor())
6600 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246601 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236602 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6603 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286604
[email protected]265f8992012-07-20 01:03:146605 // Never touch vertex attribute 0's state (in particular, never
6606 // disable it) when running on desktop GL because it will never be
6607 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066608 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146609 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066610 if (attrib->enabled()) {
6611 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146612 } else {
[email protected]ac77603c72013-03-08 13:52:066613 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146614 }
[email protected]43410e92012-04-20 17:06:286615 }
[email protected]b1122982010-05-17 23:04:246616}
[email protected]07f54fcc2009-12-22 02:46:306617
[email protected]8fbedc02010-11-18 18:43:406618bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436619 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426620 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406621 DCHECK(simulated);
6622 *simulated = false;
6623 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6624 return true;
6625
[email protected]e259eb412012-10-13 05:47:246626 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406627 return true;
6628 }
6629
[email protected]ab09b612013-03-11 22:11:516630 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016631 "GL_FIXED attributes have a signficant performance penalty");
6632
[email protected]8fbedc02010-11-18 18:43:406633 // NOTE: we could be smart and try to check if a buffer is used
6634 // twice in 2 different attribs, find the overlapping parts and therefore
6635 // duplicate the minimum amount of data but this whole code path is not meant
6636 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6637 // tests so we just add to the buffer attrib used.
6638
[email protected]c13e1da62011-09-09 21:48:306639 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066640 const VertexAttribManager::VertexAttribList& enabled_attribs =
6641 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6642 for (VertexAttribManager::VertexAttribList::const_iterator it =
6643 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6644 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356645 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066646 state_.current_program->GetAttribInfoByLocation(attrib->index());
6647 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6648 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426649 GLuint num_vertices = max_accessed + 1;
6650 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516651 LOCAL_SET_GL_ERROR(
6652 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426653 return false;
6654 }
[email protected]8fbedc02010-11-18 18:43:406655 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066656 attrib->CanAccess(max_accessed) &&
6657 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476658 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066659 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476660 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516661 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436662 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406663 return false;
6664 }
6665 }
6666 }
6667
[email protected]3aad1a32012-09-07 20:54:476668 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6669 uint32 size_needed = 0;
6670 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306671 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516672 LOCAL_SET_GL_ERROR(
6673 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406674 return false;
6675 }
6676
[email protected]ab09b612013-03-11 22:11:516677 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406678
6679 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306680 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406681 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306682 GLenum error = glGetError();
6683 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516684 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436685 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306686 return false;
6687 }
[email protected]8fbedc02010-11-18 18:43:406688 }
6689
6690 // Copy the elements and convert to float
6691 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066692 for (VertexAttribManager::VertexAttribList::const_iterator it =
6693 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6694 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356695 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066696 state_.current_program->GetAttribInfoByLocation(attrib->index());
6697 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426698 max_vertex_accessed);
6699 GLuint num_vertices = max_accessed + 1;
6700 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516701 LOCAL_SET_GL_ERROR(
6702 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426703 return false;
6704 }
[email protected]8fbedc02010-11-18 18:43:406705 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066706 attrib->CanAccess(max_accessed) &&
6707 attrib->type() == GL_FIXED) {
penghuang5a3210b2014-10-29 18:24:366708 int num_elements = attrib->size() * num_vertices;
6709 const int src_size = num_elements * sizeof(int32);
6710 const int dst_size = num_elements * sizeof(float);
6711 scoped_ptr<float[]> data(new float[num_elements]);
[email protected]8fbedc02010-11-18 18:43:406712 const int32* src = reinterpret_cast<const int32 *>(
penghuang5a3210b2014-10-29 18:24:366713 attrib->buffer()->GetRange(attrib->offset(), src_size));
[email protected]8fbedc02010-11-18 18:43:406714 const int32* end = src + num_elements;
6715 float* dst = data.get();
6716 while (src != end) {
6717 *dst++ = static_cast<float>(*src++) / 65536.0f;
6718 }
penghuang5a3210b2014-10-29 18:24:366719 glBufferSubData(GL_ARRAY_BUFFER, offset, dst_size, data.get());
[email protected]8fbedc02010-11-18 18:43:406720 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066721 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406722 reinterpret_cast<GLvoid*>(offset));
penghuang5a3210b2014-10-29 18:24:366723 offset += dst_size;
[email protected]8fbedc02010-11-18 18:43:406724 }
6725 }
6726 *simulated = true;
6727 return true;
6728}
6729
6730void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6731 // There's no need to call glVertexAttribPointer because we shadow all the
6732 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246733 glBindBuffer(
6734 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116735 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6736 : 0);
[email protected]8fbedc02010-11-18 18:43:406737}
6738
[email protected]ad84a3a2012-06-08 21:42:436739error::Error GLES2DecoderImpl::DoDrawArrays(
6740 const char* function_name,
6741 bool instanced,
6742 GLenum mode,
6743 GLint first,
6744 GLsizei count,
6745 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226746 error::Error error = WillAccessBoundFramebufferForDraw();
6747 if (error != error::kNoError)
6748 return error;
[email protected]38d139d2011-07-14 00:38:436749 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516750 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436751 return error::kNoError;
6752 }
6753 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516754 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436755 return error::kNoError;
6756 }
[email protected]c6aef902012-02-14 03:31:426757 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516758 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426759 return error::kNoError;
6760 }
[email protected]ad84a3a2012-06-08 21:42:436761 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436762 return error::kNoError;
6763 }
6764 // We have to check this here because the prototype for glDrawArrays
6765 // is GLint not GLsizei.
6766 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516767 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436768 return error::kNoError;
6769 }
6770
[email protected]ac6904d62014-07-30 12:00:106771 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:516772 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436773 return error::kNoError;
6774 }
6775
6776 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:106777 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206778 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516779 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206780 return error::kNoError;
6781 }
[email protected]c13e1da62011-09-09 21:48:306782 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436783 if (!SimulateAttrib0(
6784 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306785 return error::kNoError;
6786 }
[email protected]38d139d2011-07-14 00:38:436787 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436788 if (SimulateFixedAttribs(
6789 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6790 primcount)) {
[email protected]e56131d22013-07-28 16:14:116791 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436792 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376793 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426794 if (!instanced) {
6795 glDrawArrays(mode, first, count);
6796 } else {
6797 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6798 }
[email protected]38d139d2011-07-14 00:38:436799 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546800 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436801 }
6802 if (simulated_fixed_attribs) {
6803 RestoreStateForSimulatedFixedAttribs();
6804 }
6805 }
6806 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236807 // We don't have to restore attrib 0 generic data at the end of this
6808 // function even if it is simulated. This is because we will simulate
6809 // it in each draw call, and attrib 0 generic data queries use cached
6810 // values instead of passing down to the underlying driver.
6811 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:436812 }
[email protected]38d139d2011-07-14 00:38:436813 }
6814 return error::kNoError;
6815}
6816
vmiuracd108592014-09-08 14:36:346817error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
6818 const void* cmd_data) {
6819 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436820 return DoDrawArrays("glDrawArrays",
6821 false,
[email protected]c6aef902012-02-14 03:31:426822 static_cast<GLenum>(c.mode),
6823 static_cast<GLint>(c.first),
6824 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:106825 1);
[email protected]c6aef902012-02-14 03:31:426826}
6827
6828error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:346829 uint32 immediate_data_size,
6830 const void* cmd_data) {
6831 const gles2::cmds::DrawArraysInstancedANGLE& c =
6832 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156833 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516834 LOCAL_SET_GL_ERROR(
6835 GL_INVALID_OPERATION,
6836 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426837 return error::kNoError;
6838 }
[email protected]ad84a3a2012-06-08 21:42:436839 return DoDrawArrays("glDrawArraysIntancedANGLE",
6840 true,
[email protected]c6aef902012-02-14 03:31:426841 static_cast<GLenum>(c.mode),
6842 static_cast<GLint>(c.first),
6843 static_cast<GLsizei>(c.count),
6844 static_cast<GLsizei>(c.primcount));
6845}
6846
[email protected]ad84a3a2012-06-08 21:42:436847error::Error GLES2DecoderImpl::DoDrawElements(
6848 const char* function_name,
6849 bool instanced,
6850 GLenum mode,
6851 GLsizei count,
6852 GLenum type,
6853 int32 offset,
6854 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226855 error::Error error = WillAccessBoundFramebufferForDraw();
6856 if (error != error::kNoError)
6857 return error;
[email protected]e259eb412012-10-13 05:47:246858 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516859 LOCAL_SET_GL_ERROR(
6860 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296861 return error::kNoError;
6862 }
6863
[email protected]8eee29c2010-04-29 03:38:296864 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516865 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296866 return error::kNoError;
6867 }
6868 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516869 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296870 return error::kNoError;
6871 }
[email protected]9438b012010-06-15 22:55:056872 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516873 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296874 return error::kNoError;
6875 }
[email protected]9438b012010-06-15 22:55:056876 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516877 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296878 return error::kNoError;
6879 }
[email protected]c6aef902012-02-14 03:31:426880 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516881 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426882 return error::kNoError;
6883 }
[email protected]8eee29c2010-04-29 03:38:296884
[email protected]ad84a3a2012-06-08 21:42:436885 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276886 return error::kNoError;
6887 }
6888
[email protected]ac6904d62014-07-30 12:00:106889 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:316890 return error::kNoError;
6891 }
6892
[email protected]8eee29c2010-04-29 03:38:296893 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086894 Buffer* element_array_buffer =
6895 state_.vertex_attrib_manager->element_array_buffer();
6896
6897 if (!element_array_buffer->GetMaxValueForRange(
6898 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516899 LOCAL_SET_GL_ERROR(
6900 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296901 return error::kNoError;
6902 }
6903
[email protected]ac6904d62014-07-30 12:00:106904 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206905 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516906 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206907 return error::kNoError;
6908 }
[email protected]c13e1da62011-09-09 21:48:306909 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436910 if (!SimulateAttrib0(
6911 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306912 return error::kNoError;
6913 }
[email protected]8fbedc02010-11-18 18:43:406914 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436915 if (SimulateFixedAttribs(
6916 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6917 primcount)) {
[email protected]e56131d22013-07-28 16:14:116918 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466919 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086920 // TODO(gman): Refactor to hide these details in BufferManager or
6921 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406922 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086923 bool used_client_side_array = false;
6924 if (element_array_buffer->IsClientSideArray()) {
6925 used_client_side_array = true;
6926 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6927 indices = element_array_buffer->GetRange(offset, 0);
6928 }
6929
[email protected]00c2cf92014-03-14 00:08:376930 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426931 if (!instanced) {
6932 glDrawElements(mode, count, type, indices);
6933 } else {
6934 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6935 }
[email protected]17cfbe0e2013-03-07 01:26:086936
6937 if (used_client_side_array) {
6938 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6939 element_array_buffer->service_id());
6940 }
6941
[email protected]8fbedc02010-11-18 18:43:406942 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546943 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406944 }
6945 if (simulated_fixed_attribs) {
6946 RestoreStateForSimulatedFixedAttribs();
6947 }
[email protected]ba3176a2009-12-16 18:19:466948 }
[email protected]b1122982010-05-17 23:04:246949 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236950 // We don't have to restore attrib 0 generic data at the end of this
6951 // function even if it is simulated. This is because we will simulate
6952 // it in each draw call, and attrib 0 generic data queries use cached
6953 // values instead of passing down to the underlying driver.
6954 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:246955 }
[email protected]96449d2c2009-11-25 00:01:326956 }
[email protected]f7a64ee2010-02-01 22:24:146957 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326958}
6959
vmiuracd108592014-09-08 14:36:346960error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
6961 const void* cmd_data) {
6962 const gles2::cmds::DrawElements& c =
6963 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436964 return DoDrawElements("glDrawElements",
6965 false,
[email protected]c6aef902012-02-14 03:31:426966 static_cast<GLenum>(c.mode),
6967 static_cast<GLsizei>(c.count),
6968 static_cast<GLenum>(c.type),
6969 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:106970 1);
[email protected]c6aef902012-02-14 03:31:426971}
6972
6973error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:346974 uint32 immediate_data_size,
6975 const void* cmd_data) {
6976 const gles2::cmds::DrawElementsInstancedANGLE& c =
6977 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156978 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516979 LOCAL_SET_GL_ERROR(
6980 GL_INVALID_OPERATION,
6981 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426982 return error::kNoError;
6983 }
[email protected]ad84a3a2012-06-08 21:42:436984 return DoDrawElements("glDrawElementsInstancedANGLE",
6985 true,
[email protected]c6aef902012-02-14 03:31:426986 static_cast<GLenum>(c.mode),
6987 static_cast<GLsizei>(c.count),
6988 static_cast<GLenum>(c.type),
6989 static_cast<int32>(c.index_offset),
6990 static_cast<GLsizei>(c.primcount));
6991}
6992
[email protected]269200b12010-11-18 22:53:066993GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236994 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6995 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076996 Buffer* buffer = GetBuffer(buffer_id);
6997 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036998 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516999 LOCAL_SET_GL_ERROR(
7000 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:237001 } else {
[email protected]b10492f2013-03-08 05:24:077002 if (!buffer->GetMaxValueForRange(
7003 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:037004 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517005 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:067006 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437007 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:237008 }
7009 }
7010 return max_vertex_accessed;
7011}
7012
[email protected]96449d2c2009-11-25 00:01:327013// Calls glShaderSource for the various versions of the ShaderSource command.
7014// Assumes that data / data_size points to a piece of memory that is in range
7015// of whatever context it came from (shared memory, immediate memory, bucket
7016// memory.)
[email protected]45bf5152010-02-12 00:11:317017error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:037018 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:577019 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:427020 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
7021 if (!shader) {
[email protected]45bf5152010-02-12 00:11:317022 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327023 }
[email protected]45bf5152010-02-12 00:11:317024 // Note: We don't actually call glShaderSource here. We wait until
7025 // the call to glCompileShader.
zmo576a0492014-09-13 01:12:327026 shader->set_source(str);
[email protected]f7a64ee2010-02-01 22:24:147027 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327028}
7029
[email protected]558847a2010-03-24 07:02:547030error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
vmiuracd108592014-09-08 14:36:347031 uint32 immediate_data_size,
7032 const void* cmd_data) {
7033 const gles2::cmds::ShaderSourceBucket& c =
7034 *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data);
[email protected]558847a2010-03-24 07:02:547035 Bucket* bucket = GetBucket(c.data_bucket_id);
7036 if (!bucket || bucket->size() == 0) {
7037 return error::kInvalidArguments;
7038 }
7039 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:037040 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:547041 bucket->size() - 1);
7042}
7043
[email protected]ae51d192010-04-27 00:48:037044void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:387045 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:427046 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
7047 if (!shader) {
[email protected]45bf5152010-02-12 00:11:317048 return;
7049 }
[email protected]f57bb282010-11-12 00:51:347050 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:187051 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:427052 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:457053 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:417054 }
[email protected]de17df392010-04-23 21:09:417055
zmo576a0492014-09-13 01:12:327056 shader->DoCompile(
[email protected]b05955552014-02-06 18:41:187057 translator,
7058 feature_info_->feature_flags().angle_translated_shader_source ?
zmo576a0492014-09-13 01:12:327059 Shader::kANGLE : Shader::kGL);
vmiura8266ca72014-09-09 21:37:007060
7061 // CompileShader can be very slow. Exit command processing to allow for
7062 // context preemption and GPU watchdog checks.
7063 ExitCommandProcessingEarly();
7064}
[email protected]45bf5152010-02-12 00:11:317065
[email protected]ddd968b82010-03-02 00:44:297066void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:427067 GLuint shader_id, GLenum pname, GLint* params) {
7068 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
7069 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:297070 return;
7071 }
[email protected]8f1ccdac2010-05-19 21:01:487072 switch (pname) {
7073 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:327074 *params = shader->source().size();
7075 if (*params)
7076 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:487077 return;
7078 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:327079 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:417080 return;
[email protected]8f1ccdac2010-05-19 21:01:487081 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:327082 *params = shader->log_info().size();
7083 if (*params)
7084 ++(*params);
[email protected]e5186162010-06-14 18:54:417085 return;
[email protected]d6a53e42011-10-05 00:09:367086 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:327087 *params = shader->translated_source().size();
7088 if (*params)
7089 ++(*params);
[email protected]d6a53e42011-10-05 00:09:367090 return;
[email protected]8f1ccdac2010-05-19 21:01:487091 default:
7092 break;
[email protected]ddd968b82010-03-02 00:44:297093 }
[email protected]df37b9932013-03-08 05:21:427094 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:297095}
7096
vmiuracd108592014-09-08 14:36:347097error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
7098 const void* cmd_data) {
7099 const gles2::cmds::GetShaderSource& c =
7100 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427101 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:037102 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7103 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427104 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:327105 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:297106 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:297107 return error::kNoError;
7108 }
zmo576a0492014-09-13 01:12:327109 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:037110 return error::kNoError;
7111}
7112
[email protected]d6a53e42011-10-05 00:09:367113error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
7114 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347115 const void* cmd_data) {
7116 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
7117 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
7118 cmd_data);
[email protected]df37b9932013-03-08 05:21:427119 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:367120 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7121 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427122 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:207123 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:427124 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:367125 bucket->SetSize(0);
7126 return error::kNoError;
7127 }
7128
zmo576a0492014-09-13 01:12:327129 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:367130 return error::kNoError;
7131}
7132
[email protected]ae51d192010-04-27 00:48:037133error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:347134 uint32 immediate_data_size,
7135 const void* cmd_data) {
7136 const gles2::cmds::GetProgramInfoLog& c =
7137 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427138 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:587139 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7140 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427141 Program* program = GetProgramInfoNotShader(
7142 program_id, "glGetProgramInfoLog");
7143 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:467144 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037145 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:317146 }
[email protected]df37b9932013-03-08 05:21:427147 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:037148 return error::kNoError;
7149}
7150
7151error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:347152 uint32 immediate_data_size,
7153 const void* cmd_data) {
7154 const gles2::cmds::GetShaderInfoLog& c =
7155 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427156 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:587157 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7158 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427159 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:327160 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:467161 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037162 return error::kNoError;
7163 }
zmo576a0492014-09-13 01:12:327164 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:037165 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327166}
7167
[email protected]d058bca2012-11-26 10:27:267168bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
7169 return state_.GetEnabled(cap);
7170}
7171
[email protected]1958e0e2010-04-22 05:17:157172bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:217173 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107174 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157175}
7176
7177bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357178 const Framebuffer* framebuffer =
7179 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107180 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157181}
7182
7183bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367184 // IsProgram is true for programs as soon as they are created, until they are
7185 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:357186 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:107187 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157188}
7189
7190bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357191 const Renderbuffer* renderbuffer =
7192 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107193 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157194}
7195
7196bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367197 // IsShader is true for shaders as soon as they are created, until they
7198 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:357199 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:107200 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157201}
7202
7203bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:497204 const TextureRef* texture_ref = GetTexture(client_id);
7205 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:037206}
7207
7208void GLES2DecoderImpl::DoAttachShader(
7209 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427210 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587211 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:427212 if (!program) {
[email protected]ae51d192010-04-27 00:48:037213 return;
[email protected]1958e0e2010-04-22 05:17:157214 }
[email protected]df37b9932013-03-08 05:21:427215 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
7216 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037217 return;
7218 }
[email protected]df37b9932013-03-08 05:21:427219 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517220 LOCAL_SET_GL_ERROR(
7221 GL_INVALID_OPERATION,
7222 "glAttachShader",
7223 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:317224 return;
7225 }
[email protected]df37b9932013-03-08 05:21:427226 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037227}
7228
7229void GLES2DecoderImpl::DoDetachShader(
7230 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427231 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587232 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427233 if (!program) {
[email protected]ae51d192010-04-27 00:48:037234 return;
7235 }
[email protected]df37b9932013-03-08 05:21:427236 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7237 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037238 return;
7239 }
[email protected]df37b9932013-03-08 05:21:427240 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517241 LOCAL_SET_GL_ERROR(
7242 GL_INVALID_OPERATION,
7243 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227244 return;
7245 }
[email protected]df37b9932013-03-08 05:21:427246 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037247}
7248
7249void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427250 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587251 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427252 if (!program) {
[email protected]ae51d192010-04-27 00:48:037253 return;
7254 }
[email protected]df37b9932013-03-08 05:21:427255 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157256}
7257
[email protected]ac77603c72013-03-08 13:52:067258void GLES2DecoderImpl::GetVertexAttribHelper(
7259 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247260 switch (pname) {
7261 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067262 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247263 if (buffer && !buffer->IsDeleted()) {
7264 GLuint client_id;
7265 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7266 *params = client_id;
7267 }
7268 break;
7269 }
7270 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067271 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247272 break;
7273 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067274 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247275 break;
7276 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067277 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247278 break;
7279 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067280 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247281 break;
7282 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067283 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247284 break;
[email protected]c6aef902012-02-14 03:31:427285 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067286 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427287 break;
[email protected]ac77603c72013-03-08 13:52:067288 default:
7289 NOTREACHED();
7290 break;
7291 }
7292}
7293
[email protected]4c6f5462014-03-05 00:26:567294void GLES2DecoderImpl::DoGetTexParameterfv(
7295 GLenum target, GLenum pname, GLfloat* params) {
7296 InitTextureMaxAnisotropyIfNeeded(target, pname);
7297 glGetTexParameterfv(target, pname, params);
7298}
7299
7300void GLES2DecoderImpl::DoGetTexParameteriv(
7301 GLenum target, GLenum pname, GLint* params) {
7302 InitTextureMaxAnisotropyIfNeeded(target, pname);
7303 glGetTexParameteriv(target, pname, params);
7304}
7305
7306void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7307 GLenum target, GLenum pname) {
7308 if (!workarounds().init_texture_max_anisotropy)
7309 return;
7310 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7311 !validators_->texture_parameter.IsValid(pname)) {
7312 return;
7313 }
7314
7315 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7316 &state_, target);
7317 if (!texture_ref) {
7318 LOCAL_SET_GL_ERROR(
7319 GL_INVALID_OPERATION,
7320 "glGetTexParamter{fi}v", "unknown texture for target");
7321 return;
7322 }
7323 Texture* texture = texture_ref->texture();
7324 texture->InitTextureMaxAnisotropyIfNeeded(target);
7325}
7326
[email protected]ac77603c72013-03-08 13:52:067327void GLES2DecoderImpl::DoGetVertexAttribfv(
7328 GLuint index, GLenum pname, GLfloat* params) {
7329 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7330 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517331 LOCAL_SET_GL_ERROR(
7332 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067333 return;
7334 }
7335 switch (pname) {
7336 case GL_CURRENT_VERTEX_ATTRIB: {
7337 const Vec4& value = state_.attrib_values[index];
7338 params[0] = value.v[0];
7339 params[1] = value.v[1];
7340 params[2] = value.v[2];
7341 params[3] = value.v[3];
7342 break;
7343 }
7344 default: {
7345 GLint value = 0;
7346 GetVertexAttribHelper(attrib, pname, &value);
7347 *params = static_cast<GLfloat>(value);
7348 break;
7349 }
7350 }
7351}
7352
7353void GLES2DecoderImpl::DoGetVertexAttribiv(
7354 GLuint index, GLenum pname, GLint* params) {
7355 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7356 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517357 LOCAL_SET_GL_ERROR(
7358 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067359 return;
7360 }
7361 switch (pname) {
[email protected]af6380962012-11-29 23:24:137362 case GL_CURRENT_VERTEX_ATTRIB: {
7363 const Vec4& value = state_.attrib_values[index];
7364 params[0] = static_cast<GLint>(value.v[0]);
7365 params[1] = static_cast<GLint>(value.v[1]);
7366 params[2] = static_cast<GLint>(value.v[2]);
7367 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247368 break;
[email protected]af6380962012-11-29 23:24:137369 }
[email protected]b1122982010-05-17 23:04:247370 default:
[email protected]ac77603c72013-03-08 13:52:067371 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247372 break;
7373 }
7374}
7375
[email protected]af6380962012-11-29 23:24:137376bool GLES2DecoderImpl::SetVertexAttribValue(
7377 const char* function_name, GLuint index, const GLfloat* value) {
7378 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517379 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137380 return false;
[email protected]b1122982010-05-17 23:04:247381 }
[email protected]af6380962012-11-29 23:24:137382 Vec4& v = state_.attrib_values[index];
7383 v.v[0] = value[0];
7384 v.v[1] = value[1];
7385 v.v[2] = value[2];
7386 v.v[3] = value[3];
7387 return true;
7388}
7389
7390void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7391 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7392 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7393 glVertexAttrib1f(index, v0);
7394 }
[email protected]b1122982010-05-17 23:04:247395}
7396
7397void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137398 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7399 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7400 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247401 }
[email protected]b1122982010-05-17 23:04:247402}
7403
7404void GLES2DecoderImpl::DoVertexAttrib3f(
7405 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137406 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7407 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7408 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247409 }
[email protected]b1122982010-05-17 23:04:247410}
7411
7412void GLES2DecoderImpl::DoVertexAttrib4f(
7413 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137414 GLfloat v[4] = { v0, v1, v2, v3, };
7415 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7416 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247417 }
[email protected]b1122982010-05-17 23:04:247418}
7419
7420void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137421 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7422 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7423 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247424 }
[email protected]b1122982010-05-17 23:04:247425}
7426
7427void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137428 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7429 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7430 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247431 }
[email protected]b1122982010-05-17 23:04:247432}
7433
7434void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137435 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7436 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7437 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247438 }
[email protected]b1122982010-05-17 23:04:247439}
7440
7441void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137442 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7443 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247444 }
[email protected]b1122982010-05-17 23:04:247445}
7446
[email protected]f7a64ee2010-02-01 22:24:147447error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347448 uint32 immediate_data_size,
7449 const void* cmd_data) {
7450 const gles2::cmds::VertexAttribPointer& c =
7451 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467452
[email protected]7cd76fd2013-06-02 21:11:117453 if (!state_.bound_array_buffer.get() ||
7454 state_.bound_array_buffer->IsDeleted()) {
7455 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527456 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517457 LOCAL_SET_GL_ERROR(
7458 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467459 return error::kNoError;
7460 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517461 LOCAL_SET_GL_ERROR(
7462 GL_INVALID_VALUE,
7463 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467464 return error::kNoError;
7465 }
[email protected]96449d2c2009-11-25 00:01:327466 }
[email protected]8eee29c2010-04-29 03:38:297467
7468 GLuint indx = c.indx;
7469 GLint size = c.size;
7470 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327471 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:297472 GLsizei stride = c.stride;
7473 GLsizei offset = c.offset;
7474 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057475 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517476 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297477 return error::kNoError;
7478 }
[email protected]9438b012010-06-15 22:55:057479 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517480 LOCAL_SET_GL_ERROR(
7481 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297482 return error::kNoError;
7483 }
7484 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517485 LOCAL_SET_GL_ERROR(
7486 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297487 return error::kNoError;
7488 }
7489 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517490 LOCAL_SET_GL_ERROR(
7491 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297492 return error::kNoError;
7493 }
7494 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517495 LOCAL_SET_GL_ERROR(
7496 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297497 return error::kNoError;
7498 }
7499 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517500 LOCAL_SET_GL_ERROR(
7501 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297502 return error::kNoError;
7503 }
7504 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317505 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127506 // component_size must be a power of two to use & as optimized modulo.
7507 DCHECK(GLES2Util::IsPOT(component_size));
7508 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517509 LOCAL_SET_GL_ERROR(
7510 GL_INVALID_OPERATION,
7511 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317512 return error::kNoError;
7513 }
[email protected]a07a23602014-08-05 11:36:127514 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517515 LOCAL_SET_GL_ERROR(
7516 GL_INVALID_OPERATION,
7517 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297518 return error::kNoError;
7519 }
[email protected]7cd76fd2013-06-02 21:11:117520 state_.vertex_attrib_manager
7521 ->SetAttribInfo(indx,
7522 state_.bound_array_buffer.get(),
7523 size,
7524 type,
7525 normalized,
7526 stride,
7527 stride != 0 ? stride : component_size * size,
7528 offset);
[email protected]8fbedc02010-11-18 18:43:407529 if (type != GL_FIXED) {
7530 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7531 }
[email protected]f7a64ee2010-02-01 22:24:147532 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327533}
7534
[email protected]43410e92012-04-20 17:06:287535void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7536 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247537 state_.viewport_x = x;
7538 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027539 state_.viewport_width = std::min(width, viewport_max_width_);
7540 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287541 glViewport(x, y, width, height);
7542}
7543
[email protected]c6aef902012-02-14 03:31:427544error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347545 uint32 immediate_data_size,
7546 const void* cmd_data) {
7547 const gles2::cmds::VertexAttribDivisorANGLE& c =
7548 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157549 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517550 LOCAL_SET_GL_ERROR(
7551 GL_INVALID_OPERATION,
7552 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537553 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427554 }
7555 GLuint index = c.index;
7556 GLuint divisor = c.divisor;
7557 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517558 LOCAL_SET_GL_ERROR(
7559 GL_INVALID_VALUE,
7560 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427561 return error::kNoError;
7562 }
7563
[email protected]e259eb412012-10-13 05:47:247564 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427565 index,
7566 divisor);
7567 glVertexAttribDivisorANGLE(index, divisor);
7568 return error::kNoError;
7569}
7570
[email protected]68586372013-12-11 01:27:597571template <typename pixel_data_type>
7572static void WriteAlphaData(
7573 void *pixels, uint32 row_count, uint32 channel_count,
7574 uint32 alpha_channel_index, uint32 unpadded_row_size,
7575 uint32 padded_row_size, pixel_data_type alpha_value) {
7576 DCHECK_GT(channel_count, 0U);
7577 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7578 uint32 unpadded_row_size_in_elements =
7579 unpadded_row_size / sizeof(pixel_data_type);
7580 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7581 uint32 padded_row_size_in_elements =
7582 padded_row_size / sizeof(pixel_data_type);
7583 pixel_data_type* dst =
7584 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7585 for (uint32 yy = 0; yy < row_count; ++yy) {
7586 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7587 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7588 *d = alpha_value;
7589 }
7590 dst += padded_row_size_in_elements;
7591 }
7592}
7593
[email protected]5a36dc132013-07-23 23:17:557594void GLES2DecoderImpl::FinishReadPixels(
7595 const cmds::ReadPixels& c,
7596 GLuint buffer) {
7597 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7598 GLsizei width = c.width;
7599 GLsizei height = c.height;
7600 GLenum format = c.format;
7601 GLenum type = c.type;
7602 typedef cmds::ReadPixels::Result Result;
7603 uint32 pixels_size;
7604 Result* result = NULL;
7605 if (c.result_shm_id != 0) {
7606 result = GetSharedMemoryAs<Result*>(
7607 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7608 if (!result) {
7609 if (buffer != 0) {
7610 glDeleteBuffersARB(1, &buffer);
7611 }
7612 return;
7613 }
7614 }
7615 GLES2Util::ComputeImageDataSizes(
7616 width, height, format, type, state_.pack_alignment, &pixels_size,
7617 NULL, NULL);
7618 void* pixels = GetSharedMemoryAs<void*>(
7619 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7620 if (!pixels) {
7621 if (buffer != 0) {
7622 glDeleteBuffersARB(1, &buffer);
7623 }
7624 return;
7625 }
7626
7627 if (buffer != 0) {
7628 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337629 void* data;
7630 if (features().map_buffer_range) {
7631 data = glMapBufferRange(
7632 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7633 } else {
7634 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7635 }
miub70d78592014-11-15 03:53:477636 if (!data) {
7637 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer",
7638 "Unable to map memory for readback.");
7639 return;
7640 }
[email protected]5a36dc132013-07-23 23:17:557641 memcpy(pixels, data, pixels_size);
7642 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7643 // have to restore the state.
7644 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7645 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7646 glDeleteBuffersARB(1, &buffer);
7647 }
7648
7649 if (result != NULL) {
7650 *result = true;
7651 }
7652
7653 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7654 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7655 if ((channels_exist & 0x0008) == 0 &&
7656 workarounds().clear_alpha_in_readpixels) {
7657 // Set the alpha to 255 because some drivers are buggy in this regard.
7658 uint32 temp_size;
7659
7660 uint32 unpadded_row_size;
7661 uint32 padded_row_size;
7662 if (!GLES2Util::ComputeImageDataSizes(
7663 width, 2, format, type, state_.pack_alignment, &temp_size,
7664 &unpadded_row_size, &padded_row_size)) {
7665 return;
7666 }
[email protected]68586372013-12-11 01:27:597667
7668 uint32 channel_count = 0;
7669 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557670 switch (format) {
7671 case GL_RGBA:
7672 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597673 channel_count = 4;
7674 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557675 break;
[email protected]68586372013-12-11 01:27:597676 case GL_ALPHA:
7677 channel_count = 1;
7678 alpha_channel = 0;
7679 break;
7680 }
7681
7682 if (channel_count > 0) {
7683 switch (type) {
7684 case GL_UNSIGNED_BYTE:
7685 WriteAlphaData<uint8>(
7686 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7687 padded_row_size, 0xFF);
7688 break;
7689 case GL_FLOAT:
7690 WriteAlphaData<float>(
7691 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7692 padded_row_size, 1.0f);
7693 break;
7694 case GL_HALF_FLOAT:
7695 WriteAlphaData<uint16>(
7696 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7697 padded_row_size, 0x3C00);
7698 break;
[email protected]5a36dc132013-07-23 23:17:557699 }
[email protected]5a36dc132013-07-23 23:17:557700 }
7701 }
7702}
7703
vmiuracd108592014-09-08 14:36:347704error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7705 const void* cmd_data) {
7706 const gles2::cmds::ReadPixels& c =
7707 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:217708 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227709 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7710 if (fbo_error != error::kNoError)
7711 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317712 GLint x = c.x;
7713 GLint y = c.y;
7714 GLsizei width = c.width;
7715 GLsizei height = c.height;
7716 GLenum format = c.format;
7717 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327718 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:567719 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517720 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567721 return error::kNoError;
7722 }
[email protected]ed9f9cd2013-02-27 21:12:357723 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187724 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347725 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247726 width, height, format, type, state_.pack_alignment, &pixels_size,
7727 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187728 return error::kOutOfBounds;
7729 }
[email protected]612d2f82009-12-08 20:49:317730 void* pixels = GetSharedMemoryAs<void*>(
7731 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107732 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147733 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467734 }
[email protected]de43f082013-04-02 01:16:107735 Result* result = NULL;
7736 if (c.result_shm_id != 0) {
7737 result = GetSharedMemoryAs<Result*>(
7738 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7739 if (!result) {
7740 return error::kOutOfBounds;
7741 }
7742 }
[email protected]a51788e2010-02-24 21:54:257743
[email protected]9438b012010-06-15 22:55:057744 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517745 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297746 return error::kNoError;
7747 }
[email protected]68586372013-12-11 01:27:597748 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517749 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127750 return error::kNoError;
7751 }
[email protected]68586372013-12-11 01:27:597752 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7753 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7754 // format and type are acceptable enums but not guaranteed to be supported
7755 // for this framebuffer. Have to ask gl if they are valid.
7756 GLint preferred_format = 0;
7757 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7758 GLint preferred_type = 0;
7759 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7760 if (format != static_cast<GLenum>(preferred_format) ||
7761 type != static_cast<GLenum>(preferred_type)) {
7762 LOCAL_SET_GL_ERROR(
7763 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7764 "with the current read framebuffer");
7765 return error::kNoError;
7766 }
7767 }
[email protected]57f223832010-03-19 01:57:567768 if (width == 0 || height == 0) {
7769 return error::kNoError;
7770 }
7771
[email protected]57f223832010-03-19 01:57:567772 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307773 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567774
[email protected]3aad1a32012-09-07 20:54:477775 int32 max_x;
7776 int32 max_y;
7777 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517778 LOCAL_SET_GL_ERROR(
7779 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147780 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317781 }
[email protected]57f223832010-03-19 01:57:567782
[email protected]2ea5950d2014-07-09 18:20:347783 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
7784 return error::kNoError;
7785 }
7786
[email protected]0d6bfdc2011-11-02 01:32:207787 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7788 return error::kNoError;
7789 }
7790
[email protected]caa13ed2014-02-17 11:29:207791 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107792
7793 ScopedResolvedFrameBufferBinder binder(this, false, true);
7794
[email protected]d37231fa2010-04-09 21:16:027795 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567796 // The user requested an out of range area. Get the results 1 line
7797 // at a time.
7798 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347799 uint32 unpadded_row_size;
7800 uint32 padded_row_size;
7801 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247802 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347803 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517804 LOCAL_SET_GL_ERROR(
7805 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567806 return error::kNoError;
7807 }
7808
7809 GLint dest_x_offset = std::max(-x, 0);
7810 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347811 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247812 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7813 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517814 LOCAL_SET_GL_ERROR(
7815 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567816 return error::kNoError;
7817 }
7818
7819 // Copy each row into the larger dest rect.
7820 int8* dst = static_cast<int8*>(pixels);
7821 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027822 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567823 GLint read_width = read_end_x - read_x;
7824 for (GLint yy = 0; yy < height; ++yy) {
7825 GLint ry = y + yy;
7826
7827 // Clear the row.
7828 memset(dst, 0, unpadded_row_size);
7829
7830 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027831 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567832 glReadPixels(
7833 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7834 }
7835 dst += padded_row_size;
7836 }
7837 } else {
[email protected]5a36dc132013-07-23 23:17:557838 if (async && features().use_async_readpixels) {
miu50cef602014-11-11 01:35:417839 GLuint buffer = 0;
[email protected]5a36dc132013-07-23 23:17:557840 glGenBuffersARB(1, &buffer);
7841 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
miub70d78592014-11-15 03:53:477842 // For ANGLE client version 2, GL_STREAM_READ is not available.
7843 const GLenum usage_hint =
7844 features().is_angle ? GL_STATIC_DRAW : GL_STREAM_READ;
7845 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint);
[email protected]5a36dc132013-07-23 23:17:557846 GLenum error = glGetError();
7847 if (error == GL_NO_ERROR) {
7848 glReadPixels(x, y, width, height, format, type, 0);
7849 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7850 new FenceCallback()));
7851 WaitForReadPixels(base::Bind(
7852 &GLES2DecoderImpl::FinishReadPixels,
7853 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7854 <GLES2DecoderImpl>(this),
7855 c, buffer));
7856 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7857 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597858 } else {
7859 // On error, unbind pack buffer and fall through to sync readpixels
7860 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
miu50cef602014-11-11 01:35:417861 glDeleteBuffersARB(1, &buffer);
[email protected]5a36dc132013-07-23 23:17:557862 }
7863 }
[email protected]57f223832010-03-19 01:57:567864 glReadPixels(x, y, width, height, format, type, pixels);
7865 }
[email protected]ab09b612013-03-11 22:11:517866 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257867 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107868 if (result != NULL) {
7869 *result = true;
7870 }
[email protected]5a36dc132013-07-23 23:17:557871 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257872 }
[email protected]4848b9f82011-03-10 18:37:567873
[email protected]f7a64ee2010-02-01 22:24:147874 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327875}
7876
vmiuracd108592014-09-08 14:36:347877error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
7878 const void* cmd_data) {
7879 const gles2::cmds::PixelStorei& c =
7880 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:197881 GLenum pname = c.pname;
7882 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057883 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517884 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127885 return error::kNoError;
7886 }
[email protected]222471d2011-11-30 18:06:397887 switch (pname) {
7888 case GL_PACK_ALIGNMENT:
7889 case GL_UNPACK_ALIGNMENT:
7890 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517891 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207892 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397893 return error::kNoError;
7894 }
[email protected]164d6d52012-05-05 00:55:037895 break;
[email protected]0a1e9ad2012-05-04 21:13:037896 case GL_UNPACK_FLIP_Y_CHROMIUM:
7897 unpack_flip_y_ = (param != 0);
7898 return error::kNoError;
7899 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7900 unpack_premultiply_alpha_ = (param != 0);
7901 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177902 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7903 unpack_unpremultiply_alpha_ = (param != 0);
7904 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397905 default:
7906 break;
[email protected]b9849abf2009-11-25 19:13:197907 }
7908 glPixelStorei(pname, param);
7909 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437910 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247911 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437912 break;
7913 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427914 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437915 break;
7916 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247917 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437918 break;
7919 default:
7920 // Validation should have prevented us from getting here.
7921 NOTREACHED();
7922 break;
[email protected]b9849abf2009-11-25 19:13:197923 }
[email protected]f7a64ee2010-02-01 22:24:147924 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197925}
7926
[email protected]1c75a3702011-11-11 14:15:287927error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:347928 uint32 immediate_data_size,
7929 const void* cmd_data) {
7930 const gles2::cmds::PostSubBufferCHROMIUM& c =
7931 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:387932 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:277933 {
7934 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
7935 }
[email protected]b381ee32014-03-22 02:43:437936 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:517937 LOCAL_SET_GL_ERROR(
7938 GL_INVALID_OPERATION,
7939 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287940 return error::kNoError;
7941 }
[email protected]8f9b8dd2013-09-12 18:05:137942 bool is_tracing;
7943 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7944 &is_tracing);
7945 if (is_tracing) {
7946 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7947 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7948 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7949 is_offscreen ? offscreen_size_ : surface_->GetSize());
7950 }
[email protected]7794d512012-04-17 20:36:497951 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287952 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497953 } else {
7954 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287955 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497956 }
[email protected]1c75a3702011-11-11 14:15:287957}
7958
[email protected]957f0642014-04-09 16:50:017959error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
7960 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347961 const void* cmd_data) {
7962 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
7963 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:107964 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
7965 if (!ref) {
7966 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7967 "glScheduleOverlayPlaneCHROMIUM",
7968 "unknown texture");
7969 return error::kNoError;
7970 }
7971 gfx::GLImage* image =
7972 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
7973 if (!image) {
7974 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7975 "glScheduleOverlayPlaneCHROMIUM",
7976 "unsupported texture format");
7977 return error::kNoError;
7978 }
7979 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
7980 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
7981 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
7982 "glScheduleOverlayPlaneCHROMIUM",
7983 "invalid transform enum");
7984 return error::kNoError;
7985 }
7986 if (!surface_->ScheduleOverlayPlane(
7987 c.plane_z_order,
7988 transform,
7989 image,
7990 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
7991 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
7992 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
7993 "glScheduleOverlayPlaneCHROMIUM",
7994 "failed to schedule overlay");
7995 }
[email protected]957f0642014-04-09 16:50:017996 return error::kNoError;
7997}
7998
[email protected]558847a2010-03-24 07:02:547999error::Error GLES2DecoderImpl::GetAttribLocationHelper(
8000 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8001 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578002 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518003 LOCAL_SET_GL_ERROR(
8004 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578005 return error::kNoError;
8006 }
[email protected]df37b9932013-03-08 05:21:428007 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:588008 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:428009 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148010 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198011 }
[email protected]df37b9932013-03-08 05:21:428012 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518013 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438014 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258015 return error::kNoError;
8016 }
[email protected]b9849abf2009-11-25 19:13:198017 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548018 location_shm_id, location_shm_offset, sizeof(GLint));
8019 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148020 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198021 }
[email protected]558847a2010-03-24 07:02:548022 // Require the client to init this incase the context is lost and we are no
8023 // longer executing commands.
8024 if (*location != -1) {
8025 return error::kGenericError;
8026 }
[email protected]df37b9932013-03-08 05:21:428027 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148028 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198029}
8030
[email protected]558847a2010-03-24 07:02:548031error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:348032 uint32 immediate_data_size,
8033 const void* cmd_data) {
8034 const gles2::cmds::GetAttribLocation& c =
8035 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548036 Bucket* bucket = GetBucket(c.name_bucket_id);
8037 if (!bucket) {
8038 return error::kInvalidArguments;
8039 }
8040 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188041 if (!bucket->GetAsString(&name_str)) {
8042 return error::kInvalidArguments;
8043 }
[email protected]558847a2010-03-24 07:02:548044 return GetAttribLocationHelper(
8045 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8046}
8047
8048error::Error GLES2DecoderImpl::GetUniformLocationHelper(
8049 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8050 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578051 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518052 LOCAL_SET_GL_ERROR(
8053 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578054 return error::kNoError;
8055 }
[email protected]df37b9932013-03-08 05:21:428056 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:208057 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:428058 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148059 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198060 }
[email protected]df37b9932013-03-08 05:21:428061 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518062 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438063 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258064 return error::kNoError;
8065 }
[email protected]b9849abf2009-11-25 19:13:198066 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548067 location_shm_id, location_shm_offset, sizeof(GLint));
8068 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148069 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198070 }
[email protected]558847a2010-03-24 07:02:548071 // Require the client to init this incase the context is lost an we are no
8072 // longer executing commands.
8073 if (*location != -1) {
8074 return error::kGenericError;
8075 }
[email protected]df37b9932013-03-08 05:21:428076 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148077 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198078}
8079
[email protected]f7a64ee2010-02-01 22:24:148080error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:348081 uint32 immediate_data_size,
8082 const void* cmd_data) {
8083 const gles2::cmds::GetUniformLocation& c =
8084 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548085 Bucket* bucket = GetBucket(c.name_bucket_id);
8086 if (!bucket) {
8087 return error::kInvalidArguments;
8088 }
8089 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188090 if (!bucket->GetAsString(&name_str)) {
8091 return error::kInvalidArguments;
8092 }
[email protected]558847a2010-03-24 07:02:548093 return GetUniformLocationHelper(
8094 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:198095}
8096
vmiuracd108592014-09-08 14:36:348097error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
8098 const void* cmd_data) {
8099 const gles2::cmds::GetString& c =
8100 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:298101 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:058102 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:518103 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:298104 return error::kNoError;
8105 }
[email protected]959e9072013-09-20 16:58:388106 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:048107 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:158108 switch (name) {
8109 case GL_VERSION:
8110 str = "OpenGL ES 2.0 Chromium";
8111 break;
8112 case GL_SHADING_LANGUAGE_VERSION:
8113 str = "OpenGL ES GLSL ES 1.0 Chromium";
8114 break;
[email protected]32939602012-05-09 06:25:168115 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:168116 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:388117 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
8118 // They are used by WEBGL_debug_renderer_info.
8119 if (!force_webgl_glsl_validation_)
8120 str = "Chromium";
[email protected]32939602012-05-09 06:25:168121 break;
[email protected]1958e0e2010-04-22 05:17:158122 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:048123 {
[email protected]70dc60932013-06-04 03:33:498124 // For WebGL contexts, strip out the OES derivatives and
8125 // EXT frag depth extensions if they have not been enabled.
8126 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:048127 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:498128 if (!derivatives_explicitly_enabled_) {
8129 size_t offset = extensions.find(kOESDerivativeExtension);
8130 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098131 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:498132 std::string());
8133 }
8134 }
8135 if (!frag_depth_explicitly_enabled_) {
8136 size_t offset = extensions.find(kEXTFragDepthExtension);
8137 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098138 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:498139 std::string());
8140 }
[email protected]f0d74742011-10-03 16:31:048141 }
[email protected]aff39ac82013-06-08 04:53:138142 if (!draw_buffers_explicitly_enabled_) {
8143 size_t offset = extensions.find(kEXTDrawBuffersExtension);
8144 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098145 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:138146 std::string());
8147 }
8148 }
[email protected]93c2fd82014-04-16 02:46:068149 if (!shader_texture_lod_explicitly_enabled_) {
8150 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
8151 if (std::string::npos != offset) {
8152 extensions.replace(offset,
8153 arraysize(kEXTShaderTextureLodExtension),
8154 std::string());
8155 }
8156 }
[email protected]f0d74742011-10-03 16:31:048157 } else {
[email protected]6f5fac9d12012-06-26 21:02:458158 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:048159 }
[email protected]b381ee32014-03-22 02:43:438160 if (supports_post_sub_buffer_)
8161 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:458162 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:048163 }
[email protected]1958e0e2010-04-22 05:17:158164 break;
8165 default:
[email protected]1958e0e2010-04-22 05:17:158166 break;
8167 }
[email protected]ddd968b82010-03-02 00:44:298168 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:158169 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:298170 return error::kNoError;
8171}
8172
vmiuracd108592014-09-08 14:36:348173error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
8174 const void* cmd_data) {
8175 const gles2::cmds::BufferData& c =
8176 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:118177 GLenum target = static_cast<GLenum>(c.target);
8178 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
8179 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8180 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8181 GLenum usage = static_cast<GLenum>(c.usage);
8182 const void* data = NULL;
8183 if (data_shm_id != 0 || data_shm_offset != 0) {
8184 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
8185 if (!data) {
8186 return error::kOutOfBounds;
8187 }
8188 }
[email protected]0fbba3732013-07-17 15:40:138189 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:148190 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198191}
8192
[email protected]0c86dbf2010-03-05 08:14:118193void GLES2DecoderImpl::DoBufferSubData(
8194 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:138195 // Just delegate it. Some validation is actually done before this.
8196 buffer_manager()->ValidateAndDoBufferSubData(
8197 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:198198}
8199
[email protected]0d6bfdc2011-11-02 01:32:208200bool GLES2DecoderImpl::ClearLevel(
8201 unsigned service_id,
8202 unsigned bind_target,
8203 unsigned target,
8204 int level,
[email protected]d8e6c9242014-02-20 16:56:258205 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:208206 unsigned format,
8207 unsigned type,
8208 int width,
[email protected]4502e6492011-12-14 19:39:158209 int height,
8210 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:008211 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:008212 if (feature_info_->feature_flags().angle_depth_texture &&
8213 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:008214 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
8215 // on depth formats.
8216 GLuint fb = 0;
8217 glGenFramebuffersEXT(1, &fb);
8218 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
8219
8220 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
8221 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
8222 GL_DEPTH_ATTACHMENT;
8223
8224 glFramebufferTexture2DEXT(
8225 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
8226 // ANGLE promises a depth only attachment ok.
8227 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8228 GL_FRAMEBUFFER_COMPLETE) {
8229 return false;
8230 }
8231 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:478232 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8233 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008234 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458235 state_.SetDeviceDepthMask(GL_TRUE);
8236 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:008237 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8238
8239 RestoreClearState();
8240
8241 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358242 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008243 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8244 GLuint fb_service_id =
8245 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8246 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8247 return true;
8248 }
8249
[email protected]45d15a62012-04-18 14:33:178250 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8251
8252 uint32 size;
8253 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348254 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248255 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178256 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208257 return false;
8258 }
[email protected]45d15a62012-04-18 14:33:178259
[email protected]a5d3dad2012-05-26 04:34:448260 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8261
[email protected]45d15a62012-04-18 14:33:178262 int tile_height;
8263
8264 if (size > kMaxZeroSize) {
8265 if (kMaxZeroSize < padded_row_size) {
8266 // That'd be an awfully large texture.
8267 return false;
8268 }
8269 // We should never have a large total size with a zero row size.
8270 DCHECK_GT(padded_row_size, 0U);
8271 tile_height = kMaxZeroSize / padded_row_size;
8272 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248273 width, tile_height, format, type, state_.unpack_alignment, &size,
8274 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178275 return false;
8276 }
[email protected]4502e6492011-12-14 19:39:158277 } else {
[email protected]45d15a62012-04-18 14:33:178278 tile_height = height;
8279 }
8280
8281 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558282 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178283 memset(zero.get(), 0, size);
8284 glBindTexture(bind_target, service_id);
8285
8286 GLint y = 0;
8287 while (y < height) {
8288 GLint h = y + tile_height > height ? height - y : tile_height;
8289 if (is_texture_immutable || h != height) {
8290 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8291 } else {
[email protected]8f1d2aa2013-05-10 23:45:388292 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258293 target, level, internal_format, width, h, 0, format, type,
8294 zero.get());
[email protected]45d15a62012-04-18 14:33:178295 }
8296 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158297 }
[email protected]c986af502013-08-14 01:04:448298 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
8299 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:078300 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208301 return true;
8302}
8303
[email protected]ad84a3a2012-06-08 21:42:438304namespace {
8305
8306const int kS3TCBlockWidth = 4;
8307const int kS3TCBlockHeight = 4;
8308const int kS3TCDXT1BlockSize = 8;
8309const int kS3TCDXT3AndDXT5BlockSize = 16;
8310
8311bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518312 return (size == 1) ||
8313 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438314}
8315
[email protected]8aec81ec2014-04-29 01:04:518316bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128317 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518318}
8319
[email protected]ad84a3a2012-06-08 21:42:438320} // anonymous namespace.
8321
8322bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8323 const char* function_name,
8324 GLsizei width, GLsizei height, GLenum format, size_t size) {
8325 unsigned int bytes_required = 0;
8326
8327 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518328 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438329 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518330 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8331 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438332 int num_blocks_across =
8333 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8334 int num_blocks_down =
8335 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8336 int num_blocks = num_blocks_across * num_blocks_down;
8337 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8338 break;
8339 }
[email protected]8aec81ec2014-04-29 01:04:518340 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8341 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438342 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8343 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8344 int num_blocks_across =
8345 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8346 int num_blocks_down =
8347 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8348 int num_blocks = num_blocks_across * num_blocks_down;
8349 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8350 break;
8351 }
[email protected]8aec81ec2014-04-29 01:04:518352 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8353 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8354 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8355 break;
8356 }
8357 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8358 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8359 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078360 break;
8361 }
[email protected]ad84a3a2012-06-08 21:42:438362 default:
[email protected]ab09b612013-03-11 22:11:518363 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438364 return false;
8365 }
8366
8367 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518368 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438369 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8370 return false;
8371 }
8372
8373 return true;
8374}
8375
8376bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8377 const char* function_name,
8378 GLint level, GLsizei width, GLsizei height, GLenum format) {
8379 switch (format) {
8380 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8381 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8382 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8383 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8384 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518385 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438386 GL_INVALID_OPERATION, function_name,
8387 "width or height invalid for level");
8388 return false;
8389 }
8390 return true;
8391 }
[email protected]8aec81ec2014-04-29 01:04:518392 case GL_ATC_RGB_AMD:
8393 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8394 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8395 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078396 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518397 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078398 GL_INVALID_OPERATION, function_name,
8399 "width or height invalid for level");
8400 return false;
8401 }
8402 return true;
[email protected]8aec81ec2014-04-29 01:04:518403 }
8404 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8405 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8406 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8407 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8408 if (!IsValidPVRTCSize(level, width) ||
8409 !IsValidPVRTCSize(level, height)) {
8410 LOCAL_SET_GL_ERROR(
8411 GL_INVALID_OPERATION, function_name,
8412 "width or height invalid for level");
8413 return false;
8414 }
8415 return true;
8416 }
[email protected]ad84a3a2012-06-08 21:42:438417 default:
8418 return false;
8419 }
8420}
8421
8422bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8423 const char* function_name,
8424 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8425 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358426 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438427 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518428 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438429 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8430 return false;
8431 }
8432
8433 switch (format) {
8434 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8435 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8436 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8437 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8438 const int kBlockWidth = 4;
8439 const int kBlockHeight = 4;
8440 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518441 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438442 GL_INVALID_OPERATION, function_name,
8443 "xoffset or yoffset not multiple of 4");
8444 return false;
8445 }
8446 GLsizei tex_width = 0;
8447 GLsizei tex_height = 0;
8448 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8449 width - xoffset > tex_width ||
8450 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518451 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438452 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8453 return false;
8454 }
8455 return ValidateCompressedTexDimensions(
8456 function_name, level, width, height, format);
8457 }
[email protected]8aec81ec2014-04-29 01:04:518458 case GL_ATC_RGB_AMD:
8459 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8460 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8461 LOCAL_SET_GL_ERROR(
8462 GL_INVALID_OPERATION, function_name,
8463 "not supported for ATC textures");
8464 return false;
8465 }
[email protected]2d3765b2012-10-03 00:31:078466 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518467 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078468 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208469 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078470 return false;
8471 }
[email protected]8aec81ec2014-04-29 01:04:518472 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8473 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8474 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8475 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8476 if ((xoffset != 0) || (yoffset != 0)) {
8477 LOCAL_SET_GL_ERROR(
8478 GL_INVALID_OPERATION, function_name,
8479 "xoffset and yoffset must be zero");
8480 return false;
8481 }
8482 GLsizei tex_width = 0;
8483 GLsizei tex_height = 0;
8484 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8485 width != tex_width ||
8486 height != tex_height) {
8487 LOCAL_SET_GL_ERROR(
8488 GL_INVALID_OPERATION, function_name,
8489 "dimensions must match existing texture level dimensions");
8490 return false;
8491 }
8492 return ValidateCompressedTexDimensions(
8493 function_name, level, width, height, format);
8494 }
[email protected]ad84a3a2012-06-08 21:42:438495 default:
8496 return false;
8497 }
8498}
8499
[email protected]a93bb842010-02-16 23:03:478500error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8501 GLenum target,
8502 GLint level,
8503 GLenum internal_format,
8504 GLsizei width,
8505 GLsizei height,
8506 GLint border,
8507 GLsizei image_size,
8508 const void* data) {
[email protected]a93bb842010-02-16 23:03:478509 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058510 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518511 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8512 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298513 return error::kNoError;
8514 }
[email protected]9438b012010-06-15 22:55:058515 if (!validators_->compressed_texture_format.IsValid(
8516 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518517 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538518 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478519 return error::kNoError;
8520 }
[email protected]80eb6b52012-01-19 00:14:418521 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478522 border != 0) {
[email protected]ab09b612013-03-11 22:11:518523 LOCAL_SET_GL_ERROR(
8524 GL_INVALID_VALUE,
8525 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478526 return error::kNoError;
8527 }
[email protected]c986af502013-08-14 01:04:448528 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8529 &state_, target);
[email protected]370eaf12013-05-18 09:19:498530 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518531 LOCAL_SET_GL_ERROR(
8532 GL_INVALID_VALUE,
8533 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478534 return error::kNoError;
8535 }
[email protected]370eaf12013-05-18 09:19:498536 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078537 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518538 LOCAL_SET_GL_ERROR(
8539 GL_INVALID_OPERATION,
8540 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438541 return error::kNoError;
8542 }
8543
8544 if (!ValidateCompressedTexDimensions(
8545 "glCompressedTexImage2D", level, width, height, internal_format) ||
8546 !ValidateCompressedTexFuncData(
8547 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178548 return error::kNoError;
8549 }
[email protected]968351b2011-12-20 08:26:518550
[email protected]7989c9e2013-01-23 06:39:268551 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518552 LOCAL_SET_GL_ERROR(
8553 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268554 return error::kNoError;
8555 }
8556
[email protected]02965c22013-03-09 02:40:078557 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448558 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518559 }
8560
[email protected]40d90a22013-04-09 03:39:558561 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478562 if (!data) {
8563 zero.reset(new int8[image_size]);
8564 memset(zero.get(), 0, image_size);
8565 data = zero.get();
8566 }
[email protected]ab09b612013-03-11 22:11:518567 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478568 glCompressedTexImage2D(
8569 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518570 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438571 if (error == GL_NO_ERROR) {
8572 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498573 texture_ref, target, level, internal_format,
8574 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438575 }
vmiura8266ca72014-09-09 21:37:008576
8577 // This may be a slow command. Exit command processing to allow for
8578 // context preemption and GPU watchdog checks.
8579 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:478580 return error::kNoError;
8581}
8582
[email protected]f7a64ee2010-02-01 22:24:148583error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:348584 uint32 immediate_data_size,
8585 const void* cmd_data) {
8586 const gles2::cmds::CompressedTexImage2D& c =
8587 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198588 GLenum target = static_cast<GLenum>(c.target);
8589 GLint level = static_cast<GLint>(c.level);
8590 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8591 GLsizei width = static_cast<GLsizei>(c.width);
8592 GLsizei height = static_cast<GLsizei>(c.height);
8593 GLint border = static_cast<GLint>(c.border);
8594 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8595 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8596 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8597 const void* data = NULL;
8598 if (data_shm_id != 0 || data_shm_offset != 0) {
8599 data = GetSharedMemoryAs<const void*>(
8600 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468601 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148602 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198603 }
8604 }
[email protected]a93bb842010-02-16 23:03:478605 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198606 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198607}
8608
[email protected]b6140d02010-05-17 14:47:168609error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:348610 uint32 immediate_data_size,
8611 const void* cmd_data) {
8612 const gles2::cmds::CompressedTexImage2DBucket& c =
8613 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168614 GLenum target = static_cast<GLenum>(c.target);
8615 GLint level = static_cast<GLint>(c.level);
8616 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8617 GLsizei width = static_cast<GLsizei>(c.width);
8618 GLsizei height = static_cast<GLsizei>(c.height);
8619 GLint border = static_cast<GLint>(c.border);
8620 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288621 if (!bucket) {
8622 return error::kInvalidArguments;
8623 }
8624 uint32 data_size = bucket->size();
8625 GLsizei imageSize = data_size;
8626 const void* data = bucket->GetData(0, data_size);
8627 if (!data) {
8628 return error::kInvalidArguments;
8629 }
[email protected]b6140d02010-05-17 14:47:168630 return DoCompressedTexImage2D(
8631 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288632 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168633}
8634
8635error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8636 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348637 const void* cmd_data) {
8638 const gles2::cmds::CompressedTexSubImage2DBucket& c =
8639 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168640 GLenum target = static_cast<GLenum>(c.target);
8641 GLint level = static_cast<GLint>(c.level);
8642 GLint xoffset = static_cast<GLint>(c.xoffset);
8643 GLint yoffset = static_cast<GLint>(c.yoffset);
8644 GLsizei width = static_cast<GLsizei>(c.width);
8645 GLsizei height = static_cast<GLsizei>(c.height);
8646 GLenum format = static_cast<GLenum>(c.format);
8647 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288648 if (!bucket) {
8649 return error::kInvalidArguments;
8650 }
[email protected]b6140d02010-05-17 14:47:168651 uint32 data_size = bucket->size();
8652 GLsizei imageSize = data_size;
8653 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288654 if (!data) {
8655 return error::kInvalidArguments;
8656 }
[email protected]9438b012010-06-15 22:55:058657 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518658 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538659 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168660 return error::kNoError;
8661 }
[email protected]9438b012010-06-15 22:55:058662 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518663 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8664 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058665 return error::kNoError;
8666 }
[email protected]b6140d02010-05-17 14:47:168667 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518668 LOCAL_SET_GL_ERROR(
8669 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168670 return error::kNoError;
8671 }
8672 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518673 LOCAL_SET_GL_ERROR(
8674 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168675 return error::kNoError;
8676 }
8677 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518678 LOCAL_SET_GL_ERROR(
8679 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168680 return error::kNoError;
8681 }
[email protected]cadde4a2010-07-31 17:10:438682 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168683 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8684 return error::kNoError;
8685}
8686
vmiuracd108592014-09-08 14:36:348687error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
8688 const void* cmd_data) {
8689 const gles2::cmds::TexImage2D& c =
8690 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138691 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8692 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:448693 // Set as failed for now, but if it successed, this will be set to not failed.
8694 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198695 GLenum target = static_cast<GLenum>(c.target);
8696 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448697 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8698 // for internalformat.
8699 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198700 GLsizei width = static_cast<GLsizei>(c.width);
8701 GLsizei height = static_cast<GLsizei>(c.height);
8702 GLint border = static_cast<GLint>(c.border);
8703 GLenum format = static_cast<GLenum>(c.format);
8704 GLenum type = static_cast<GLenum>(c.type);
8705 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8706 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188707 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348708 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248709 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:348710 NULL)) {
[email protected]a76b0052010-03-05 00:33:188711 return error::kOutOfBounds;
8712 }
[email protected]b9849abf2009-11-25 19:13:198713 const void* pixels = NULL;
8714 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8715 pixels = GetSharedMemoryAs<const void*>(
8716 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468717 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148718 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198719 }
8720 }
[email protected]f598f422012-12-07 08:30:038721
[email protected]c986af502013-08-14 01:04:448722 TextureManager::DoTextImage2DArguments args = {
8723 target, level, internal_format, width, height, border, format, type,
8724 pixels, pixels_size};
8725 texture_manager()->ValidateAndDoTexImage2D(
8726 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:008727
8728 // This may be a slow command. Exit command processing to allow for
8729 // context preemption and GPU watchdog checks.
8730 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038731 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198732}
8733
[email protected]cadde4a2010-07-31 17:10:438734void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8735 GLenum target,
8736 GLint level,
8737 GLint xoffset,
8738 GLint yoffset,
8739 GLsizei width,
8740 GLsizei height,
8741 GLenum format,
8742 GLsizei image_size,
8743 const void * data) {
[email protected]c986af502013-08-14 01:04:448744 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8745 &state_, target);
[email protected]370eaf12013-05-18 09:19:498746 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518747 LOCAL_SET_GL_ERROR(
8748 GL_INVALID_OPERATION,
8749 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438750 return;
8751 }
[email protected]370eaf12013-05-18 09:19:498752 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438753 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528754 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078755 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518756 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528757 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438758 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528759 return;
8760 }
8761 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518762 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528763 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438764 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528765 return;
8766 }
[email protected]02965c22013-03-09 02:40:078767 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528768 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518769 LOCAL_SET_GL_ERROR(
8770 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438771 return;
8772 }
[email protected]ad84a3a2012-06-08 21:42:438773
8774 if (!ValidateCompressedTexFuncData(
8775 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8776 !ValidateCompressedTexSubDimensions(
8777 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078778 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438779 return;
8780 }
8781
8782
[email protected]0d6bfdc2011-11-02 01:32:208783 // Note: There is no need to deal with texture cleared tracking here
8784 // because the validation above means you can only get here if the level
8785 // is already a matching compressed format and in that case
8786 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438787 glCompressedTexSubImage2D(
8788 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:008789
8790 // This may be a slow command. Exit command processing to allow for
8791 // context preemption and GPU watchdog checks.
8792 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438793}
8794
[email protected]6e288612010-12-21 20:45:038795static void Clip(
8796 GLint start, GLint range, GLint sourceRange,
8797 GLint* out_start, GLint* out_range) {
8798 DCHECK(out_start);
8799 DCHECK(out_range);
8800 if (start < 0) {
8801 range += start;
8802 start = 0;
8803 }
8804 GLint end = start + range;
8805 if (end > sourceRange) {
8806 range -= end - sourceRange;
8807 }
8808 *out_start = start;
8809 *out_range = range;
8810}
8811
[email protected]cadde4a2010-07-31 17:10:438812void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448813 GLenum target,
8814 GLint level,
8815 GLenum internal_format,
8816 GLint x,
8817 GLint y,
8818 GLsizei width,
8819 GLsizei height,
8820 GLint border) {
[email protected]09e17272012-11-30 10:30:448821 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448822 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8823 &state_, target);
[email protected]370eaf12013-05-18 09:19:498824 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518825 LOCAL_SET_GL_ERROR(
8826 GL_INVALID_OPERATION,
8827 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438828 return;
8829 }
[email protected]370eaf12013-05-18 09:19:498830 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078831 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518832 LOCAL_SET_GL_ERROR(
8833 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:538834 return;
[email protected]97dc7cbe2011-12-06 17:26:178835 }
[email protected]80eb6b52012-01-19 00:14:418836 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188837 border != 0) {
[email protected]ab09b612013-03-11 22:11:518838 LOCAL_SET_GL_ERROR(
8839 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188840 return;
8841 }
[email protected]17a961192014-02-14 15:20:528842 if (!texture_manager()->ValidateFormatAndTypeCombination(
8843 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
8844 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:008845 return;
8846 }
[email protected]f5719fb2010-08-04 18:27:188847
[email protected]9edc6b22010-12-23 02:00:268848 // Check we have compatible formats.
8849 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8850 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8851 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8852
8853 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518854 LOCAL_SET_GL_ERROR(
8855 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268856 return;
8857 }
8858
[email protected]81375742012-06-08 00:04:008859 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518860 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008861 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268862 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8863 return;
8864 }
8865
8866 uint32 estimated_size = 0;
8867 if (!GLES2Util::ComputeImageDataSizes(
8868 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8869 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518870 LOCAL_SET_GL_ERROR(
8871 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268872 return;
8873 }
8874
8875 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518876 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008877 return;
8878 }
8879
[email protected]2ea5950d2014-07-09 18:20:348880 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
8881 return;
8882 }
8883
zmo383512cf2014-10-14 00:11:008884 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
8885 LOCAL_SET_GL_ERROR(
8886 GL_INVALID_OPERATION,
8887 "glCopyTexImage2D", "source and destination textures are the same");
8888 return;
8889 }
8890
[email protected]a0b78dc2011-11-11 10:43:108891 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8892 return;
8893 }
8894
[email protected]ab09b612013-03-11 22:11:518895 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278896 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038897 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268898
[email protected]02965c22013-03-09 02:40:078899 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448900 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:468901 }
8902
[email protected]9edc6b22010-12-23 02:00:268903 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038904 GLint copyX = 0;
8905 GLint copyY = 0;
8906 GLint copyWidth = 0;
8907 GLint copyHeight = 0;
8908 Clip(x, width, size.width(), &copyX, &copyWidth);
8909 Clip(y, height, size.height(), &copyY, &copyHeight);
8910
8911 if (copyX != x ||
8912 copyY != y ||
8913 copyWidth != width ||
8914 copyHeight != height) {
8915 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208916 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078917 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:258918 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
8919 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518920 LOCAL_SET_GL_ERROR(
8921 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038922 return;
8923 }
[email protected]6e288612010-12-21 20:45:038924 if (copyHeight > 0 && copyWidth > 0) {
8925 GLint dx = copyX - x;
8926 GLint dy = copyY - y;
8927 GLint destX = dx;
8928 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:378929 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038930 glCopyTexSubImage2D(target, level,
8931 destX, destY, copyX, copyY,
8932 copyWidth, copyHeight);
8933 }
8934 } else {
[email protected]00c2cf92014-03-14 00:08:378935 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038936 glCopyTexImage2D(target, level, internal_format,
8937 copyX, copyY, copyWidth, copyHeight, border);
8938 }
[email protected]ab09b612013-03-11 22:11:518939 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438940 if (error == GL_NO_ERROR) {
8941 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498942 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208943 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438944 }
vmiura8266ca72014-09-09 21:37:008945
8946 // This may be a slow command. Exit command processing to allow for
8947 // context preemption and GPU watchdog checks.
8948 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438949}
8950
8951void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448952 GLenum target,
8953 GLint level,
8954 GLint xoffset,
8955 GLint yoffset,
8956 GLint x,
8957 GLint y,
8958 GLsizei width,
8959 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448960 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448961 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8962 &state_, target);
[email protected]370eaf12013-05-18 09:19:498963 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518964 LOCAL_SET_GL_ERROR(
8965 GL_INVALID_OPERATION,
8966 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438967 return;
8968 }
[email protected]370eaf12013-05-18 09:19:498969 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438970 GLenum type = 0;
8971 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078972 if (!texture->GetLevelType(target, level, &type, &format) ||
8973 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528974 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518975 LOCAL_SET_GL_ERROR(
8976 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438977 return;
8978 }
[email protected]85a4ac22013-05-31 01:58:478979 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518980 LOCAL_SET_GL_ERROR(
8981 GL_INVALID_OPERATION,
8982 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598983 return;
8984 }
[email protected]9edc6b22010-12-23 02:00:268985
8986 // Check we have compatible formats.
8987 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8988 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8989 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8990
[email protected]2d3765b2012-10-03 00:31:078991 if (!channels_needed ||
8992 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518993 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438994 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268995 return;
8996 }
8997
[email protected]81375742012-06-08 00:04:008998 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518999 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009000 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439001 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:009002 return;
9003 }
9004
[email protected]2ea5950d2014-07-09 18:20:349005 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
9006 return;
9007 }
9008
zmo383512cf2014-10-14 00:11:009009 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9010 LOCAL_SET_GL_ERROR(
9011 GL_INVALID_OPERATION,
9012 "glCopyTexSubImage2D", "source and destination textures are the same");
9013 return;
9014 }
9015
[email protected]a0b78dc2011-11-11 10:43:109016 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
9017 return;
9018 }
9019
[email protected]de26b3c2011-08-03 21:54:279020 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039021 gfx::Size size = GetBoundReadFrameBufferSize();
9022 GLint copyX = 0;
9023 GLint copyY = 0;
9024 GLint copyWidth = 0;
9025 GLint copyHeight = 0;
9026 Clip(x, width, size.width(), &copyX, &copyWidth);
9027 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:209028
[email protected]370eaf12013-05-18 09:19:499029 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:519030 LOCAL_SET_GL_ERROR(
9031 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:209032 return;
9033 }
9034
[email protected]6e288612010-12-21 20:45:039035 if (copyX != x ||
9036 copyY != y ||
9037 copyWidth != width ||
9038 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:209039 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:039040 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:349041 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:249042 width, height, format, type, state_.unpack_alignment, &pixels_size,
9043 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519044 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439045 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:039046 return;
9047 }
[email protected]40d90a22013-04-09 03:39:559048 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:039049 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:379050 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039051 glTexSubImage2D(
9052 target, level, xoffset, yoffset, width, height,
9053 format, type, zero.get());
9054 }
[email protected]0d6bfdc2011-11-02 01:32:209055
[email protected]6e288612010-12-21 20:45:039056 if (copyHeight > 0 && copyWidth > 0) {
9057 GLint dx = copyX - x;
9058 GLint dy = copyY - y;
9059 GLint destX = xoffset + dx;
9060 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:379061 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039062 glCopyTexSubImage2D(target, level,
9063 destX, destY, copyX, copyY,
9064 copyWidth, copyHeight);
9065 }
vmiura8266ca72014-09-09 21:37:009066
9067 // This may be a slow command. Exit command processing to allow for
9068 // context preemption and GPU watchdog checks.
9069 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439070}
9071
[email protected]f598f422012-12-07 08:30:039072bool GLES2DecoderImpl::ValidateTexSubImage2D(
9073 error::Error* error,
9074 const char* function_name,
9075 GLenum target,
9076 GLint level,
9077 GLint xoffset,
9078 GLint yoffset,
9079 GLsizei width,
9080 GLsizei height,
9081 GLenum format,
9082 GLenum type,
9083 const void * data) {
9084 (*error) = error::kNoError;
9085 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:519086 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:039087 return false;
9088 }
9089 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:519090 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:039091 return false;
9092 }
9093 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:519094 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:039095 return false;
9096 }
[email protected]c986af502013-08-14 01:04:449097 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9098 &state_, target);
[email protected]370eaf12013-05-18 09:19:499099 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519100 LOCAL_SET_GL_ERROR(
9101 GL_INVALID_OPERATION,
9102 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:039103 return false;
[email protected]cadde4a2010-07-31 17:10:439104 }
[email protected]370eaf12013-05-18 09:19:499105 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:529106 GLenum current_type = 0;
9107 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079108 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519109 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:039110 GL_INVALID_OPERATION, function_name, "level does not exist.");
9111 return false;
[email protected]df6cf1ad2011-01-29 01:20:529112 }
[email protected]17a961192014-02-14 15:20:529113 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
9114 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:039115 return false;
[email protected]df6cf1ad2011-01-29 01:20:529116 }
9117 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:519118 LOCAL_SET_GL_ERROR(
9119 GL_INVALID_OPERATION,
9120 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:039121 return false;
[email protected]df6cf1ad2011-01-29 01:20:529122 }
[email protected]85a4ac22013-05-31 01:58:479123 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519124 LOCAL_SET_GL_ERROR(
9125 GL_INVALID_OPERATION,
9126 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599127 return false;
9128 }
[email protected]02965c22013-03-09 02:40:079129 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529130 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519131 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:039132 return false;
[email protected]cadde4a2010-07-31 17:10:439133 }
[email protected]81375742012-06-08 00:04:009134 if ((GLES2Util::GetChannelsForFormat(format) &
9135 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519136 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009137 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:039138 function_name, "can not supply data for depth or stencil textures");
9139 return false;
[email protected]81375742012-06-08 00:04:009140 }
[email protected]f598f422012-12-07 08:30:039141 if (data == NULL) {
9142 (*error) = error::kOutOfBounds;
9143 return false;
9144 }
9145 return true;
9146}
[email protected]81375742012-06-08 00:04:009147
[email protected]f598f422012-12-07 08:30:039148error::Error GLES2DecoderImpl::DoTexSubImage2D(
9149 GLenum target,
9150 GLint level,
9151 GLint xoffset,
9152 GLint yoffset,
9153 GLsizei width,
9154 GLsizei height,
9155 GLenum format,
9156 GLenum type,
9157 const void * data) {
9158 error::Error error = error::kNoError;
9159 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
9160 xoffset, yoffset, width, height, format, type, data)) {
9161 return error;
9162 }
[email protected]c986af502013-08-14 01:04:449163 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9164 &state_, target);
[email protected]370eaf12013-05-18 09:19:499165 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:159166 GLsizei tex_width = 0;
9167 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:079168 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:159169 DCHECK(ok);
9170 if (xoffset != 0 || yoffset != 0 ||
9171 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:499172 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
9173 target, level)) {
[email protected]ab09b612013-03-11 22:11:519174 LOCAL_SET_GL_ERROR(
9175 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:039176 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:309177 }
[email protected]c986af502013-08-14 01:04:449178 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159179 glTexSubImage2D(
9180 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:039181 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:209182 }
[email protected]4502e6492011-12-14 19:39:159183
[email protected]345ba902013-11-14 21:39:009184 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:449185 !texture->IsImmutable()) {
9186 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:259187 GLenum internal_format;
9188 GLenum tex_type;
9189 texture->GetLevelType(target, level, &tex_type, &internal_format);
9190 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
9191 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:389192 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:259193 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:159194 } else {
[email protected]c986af502013-08-14 01:04:449195 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159196 glTexSubImage2D(
9197 target, level, xoffset, yoffset, width, height, format, type, data);
9198 }
[email protected]370eaf12013-05-18 09:19:499199 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:009200
9201 // This may be a slow command. Exit command processing to allow for
9202 // context preemption and GPU watchdog checks.
9203 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039204 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:439205}
9206
vmiuracd108592014-09-08 14:36:349207error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
9208 const void* cmd_data) {
9209 const gles2::cmds::TexSubImage2D& c =
9210 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139211 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
9212 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:009213 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:449214 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:009215 return error::kNoError;
9216
9217 GLenum target = static_cast<GLenum>(c.target);
9218 GLint level = static_cast<GLint>(c.level);
9219 GLint xoffset = static_cast<GLint>(c.xoffset);
9220 GLint yoffset = static_cast<GLint>(c.yoffset);
9221 GLsizei width = static_cast<GLsizei>(c.width);
9222 GLsizei height = static_cast<GLsizei>(c.height);
9223 GLenum format = static_cast<GLenum>(c.format);
9224 GLenum type = static_cast<GLenum>(c.type);
9225 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:349226 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:249227 width, height, format, type, state_.unpack_alignment, &data_size,
9228 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:009229 return error::kOutOfBounds;
9230 }
9231 const void* pixels = GetSharedMemoryAs<const void*>(
9232 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:039233 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:009234 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:009235}
9236
[email protected]f7a64ee2010-02-01 22:24:149237error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349238 uint32 immediate_data_size,
9239 const void* cmd_data) {
9240 const gles2::cmds::GetVertexAttribPointerv& c =
9241 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369242 GLuint index = static_cast<GLuint>(c.index);
9243 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359244 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259245 Result* result = GetSharedMemoryAs<Result*>(
9246 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369247 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149248 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369249 }
[email protected]07d0cc82010-02-17 04:51:409250 // Check that the client initialized the result.
9251 if (result->size != 0) {
9252 return error::kInvalidArguments;
9253 }
[email protected]9438b012010-06-15 22:55:059254 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519255 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9256 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149257 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369258 }
[email protected]3916c97e2010-02-25 03:20:509259 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519260 LOCAL_SET_GL_ERROR(
9261 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149262 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369263 }
[email protected]0bfd9882010-02-05 23:02:259264 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089265 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359266 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149267 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329268}
9269
[email protected]f7b85372010-02-03 01:11:379270bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:429271 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:379272 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:129273 error::Error* error, GLint* real_location,
9274 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:109275 DCHECK(error);
9276 DCHECK(service_id);
9277 DCHECK(result_pointer);
9278 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129279 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379280 *error = error::kNoError;
9281 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259282 SizedResult<GLint>* result;
9283 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9284 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9285 if (!result) {
[email protected]f7b85372010-02-03 01:11:379286 *error = error::kOutOfBounds;
9287 return false;
9288 }
[email protected]0bfd9882010-02-05 23:02:259289 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379290 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259291 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429292 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9293 if (!program) {
[email protected]ae51d192010-04-27 00:48:039294 return false;
9295 }
[email protected]df37b9932013-03-08 05:21:429296 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379297 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519298 LOCAL_SET_GL_ERROR(
9299 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379300 return false;
9301 }
[email protected]df37b9932013-03-08 05:21:429302 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369303 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359304 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429305 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129306 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369307 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379308 // No such location.
[email protected]ab09b612013-03-11 22:11:519309 LOCAL_SET_GL_ERROR(
9310 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379311 return false;
9312 }
[email protected]43c2f1f2011-03-25 18:35:369313 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509314 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379315 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519316 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379317 return false;
9318 }
[email protected]0bfd9882010-02-05 23:02:259319 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9320 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9321 if (!result) {
[email protected]f7b85372010-02-03 01:11:379322 *error = error::kOutOfBounds;
9323 return false;
9324 }
[email protected]0bfd9882010-02-05 23:02:259325 result->size = size;
[email protected]939e7362010-05-13 20:49:109326 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379327 return true;
9328}
9329
vmiuracd108592014-09-08 14:36:349330error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9331 const void* cmd_data) {
9332 const gles2::cmds::GetUniformiv& c =
9333 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379334 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339335 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379336 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109337 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:129338 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379339 Error error;
[email protected]0bfd9882010-02-05 23:02:259340 void* result;
[email protected]f7b85372010-02-03 01:11:379341 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129342 program, fake_location, c.params_shm_id, c.params_shm_offset,
9343 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:259344 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129345 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359346 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379347 }
9348 return error;
[email protected]96449d2c2009-11-25 00:01:329349}
9350
vmiuracd108592014-09-08 14:36:349351error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9352 const void* cmd_data) {
9353 const gles2::cmds::GetUniformfv& c =
9354 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379355 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339356 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379357 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129358 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379359 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359360 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109361 Result* result;
9362 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:379363 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129364 program, fake_location, c.params_shm_id, c.params_shm_offset,
9365 &error, &real_location, &service_id,
9366 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:109367 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9368 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
9369 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:559370 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129371 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109372 GLfloat* dst = result->GetData();
9373 for (GLsizei ii = 0; ii < num_values; ++ii) {
9374 dst[ii] = (temp[ii] != 0);
9375 }
9376 } else {
[email protected]1b0a6752012-02-22 03:44:129377 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109378 }
[email protected]f7b85372010-02-03 01:11:379379 }
9380 return error;
[email protected]96449d2c2009-11-25 00:01:329381}
9382
[email protected]f7a64ee2010-02-01 22:24:149383error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349384 uint32 immediate_data_size,
9385 const void* cmd_data) {
9386 const gles2::cmds::GetShaderPrecisionFormat& c =
9387 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259388 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9389 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359390 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259391 Result* result = GetSharedMemoryAs<Result*>(
9392 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9393 if (!result) {
9394 return error::kOutOfBounds;
9395 }
[email protected]07d0cc82010-02-17 04:51:409396 // Check that the client initialized the result.
9397 if (result->success != 0) {
9398 return error::kInvalidArguments;
9399 }
[email protected]9438b012010-06-15 22:55:059400 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519401 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539402 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299403 return error::kNoError;
9404 }
[email protected]9438b012010-06-15 22:55:059405 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519406 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539407 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299408 return error::kNoError;
9409 }
9410
9411 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409412
[email protected]46c86752013-05-21 05:08:399413 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409414 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219415 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409416
9417 result->min_range = range[0];
9418 result->max_range = range[1];
9419 result->precision = precision;
9420
[email protected]f7a64ee2010-02-01 22:24:149421 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329422}
9423
[email protected]f7a64ee2010-02-01 22:24:149424error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349425 uint32 immediate_data_size,
9426 const void* cmd_data) {
9427 const gles2::cmds::GetAttachedShaders& c =
9428 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259429 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429430 GLuint program_id = static_cast<GLuint>(c.program);
9431 Program* program = GetProgramInfoNotShader(
9432 program_id, "glGetAttachedShaders");
9433 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259434 return error::kNoError;
9435 }
[email protected]ed9f9cd2013-02-27 21:12:359436 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259437 uint32 max_count = Result::ComputeMaxResults(result_size);
9438 Result* result = GetSharedMemoryAs<Result*>(
9439 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9440 if (!result) {
9441 return error::kOutOfBounds;
9442 }
[email protected]07d0cc82010-02-17 04:51:409443 // Check that the client initialized the result.
9444 if (result->size != 0) {
9445 return error::kInvalidArguments;
9446 }
[email protected]0bfd9882010-02-05 23:02:259447 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039448 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429449 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259450 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039451 if (!shader_manager()->GetClientId(result->GetData()[ii],
9452 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259453 NOTREACHED();
9454 return error::kGenericError;
9455 }
9456 }
9457 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149458 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329459}
9460
[email protected]f7a64ee2010-02-01 22:24:149461error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349462 uint32 immediate_data_size,
9463 const void* cmd_data) {
9464 const gles2::cmds::GetActiveUniform& c =
9465 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429466 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259467 GLuint index = c.index;
9468 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359469 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259470 Result* result = GetSharedMemoryAs<Result*>(
9471 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9472 if (!result) {
9473 return error::kOutOfBounds;
9474 }
[email protected]07d0cc82010-02-17 04:51:409475 // Check that the client initialized the result.
9476 if (result->success != 0) {
9477 return error::kInvalidArguments;
9478 }
[email protected]df37b9932013-03-08 05:21:429479 Program* program = GetProgramInfoNotShader(
9480 program_id, "glGetActiveUniform");
9481 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259482 return error::kNoError;
9483 }
[email protected]ed9f9cd2013-02-27 21:12:359484 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429485 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:259486 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:519487 LOCAL_SET_GL_ERROR(
9488 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259489 return error::kNoError;
9490 }
9491 result->success = 1; // true.
9492 result->size = uniform_info->size;
9493 result->type = uniform_info->type;
9494 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299495 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149496 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329497}
9498
vmiuracd108592014-09-08 14:36:349499error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
9500 const void* cmd_data) {
9501 const gles2::cmds::GetActiveAttrib& c =
9502 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429503 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259504 GLuint index = c.index;
9505 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359506 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:259507 Result* result = GetSharedMemoryAs<Result*>(
9508 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9509 if (!result) {
9510 return error::kOutOfBounds;
9511 }
[email protected]07d0cc82010-02-17 04:51:409512 // Check that the client initialized the result.
9513 if (result->success != 0) {
9514 return error::kInvalidArguments;
9515 }
[email protected]df37b9932013-03-08 05:21:429516 Program* program = GetProgramInfoNotShader(
9517 program_id, "glGetActiveAttrib");
9518 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259519 return error::kNoError;
9520 }
[email protected]ed9f9cd2013-02-27 21:12:359521 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:429522 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:259523 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:519524 LOCAL_SET_GL_ERROR(
9525 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259526 return error::kNoError;
9527 }
9528 result->success = 1; // true.
9529 result->size = attrib_info->size;
9530 result->type = attrib_info->type;
9531 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299532 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149533 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329534}
9535
vmiuracd108592014-09-08 14:36:349536error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
9537 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:589538#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:519539 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:589540 return error::kNoError;
9541#else
9542 GLsizei n = static_cast<GLsizei>(c.n);
9543 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:519544 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:589545 return error::kNoError;
9546 }
9547 GLsizei length = static_cast<GLsizei>(c.length);
9548 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:519549 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:589550 return error::kNoError;
9551 }
9552 uint32 data_size;
9553 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
9554 return error::kOutOfBounds;
9555 }
9556 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
9557 c.shaders_shm_id, c.shaders_shm_offset, data_size);
9558 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
9559 const void* binary = GetSharedMemoryAs<const void*>(
9560 c.binary_shm_id, c.binary_shm_offset, length);
9561 if (shaders == NULL || binary == NULL) {
9562 return error::kOutOfBounds;
9563 }
[email protected]0782b14b2014-05-24 13:04:169564 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:589565 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:429566 Shader* shader = GetShader(shaders[ii]);
9567 if (!shader) {
[email protected]ab09b612013-03-11 22:11:519568 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:589569 return error::kNoError;
9570 }
[email protected]df37b9932013-03-08 05:21:429571 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:589572 }
9573 // TODO(gman): call glShaderBinary
9574 return error::kNoError;
9575#endif
9576}
9577
[email protected]6d792ee12013-05-15 00:40:569578void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:499579 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:089580
[email protected]64ace852011-05-19 21:49:499581 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:429582 // TRACE_EVENT for gpu tests:
9583 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:429584 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:429585 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
9586 "width", (is_offscreen ? offscreen_size_.width() :
9587 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:569588 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:499589 "offscreen", is_offscreen,
9590 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:159591 {
[email protected]a36ed4832014-04-24 16:40:279592 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:159593 }
9594
[email protected]8f9b8dd2013-09-12 18:05:139595 bool is_tracing;
9596 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
9597 &is_tracing);
9598 if (is_tracing) {
9599 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
9600 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
9601 is_offscreen ? offscreen_size_ : surface_->GetSize());
9602 }
9603
[email protected]6217d392010-03-25 22:08:359604 // If offscreen then don't actually SwapBuffers to the display. Just copy
9605 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:499606 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:319607 TRACE_EVENT2("gpu", "Offscreen",
9608 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:539609 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
9610 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9611 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9612 // fix this.
[email protected]62e155e2012-10-23 22:43:159613 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:539614 offscreen_saved_frame_buffer_->Create();
9615 glFinish();
9616 }
9617
9618 // Allocate the offscreen saved color texture.
9619 DCHECK(offscreen_saved_color_format_);
9620 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:099621 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:539622
9623 offscreen_saved_frame_buffer_->AttachRenderTexture(
9624 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:059625 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9626 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9627 GL_FRAMEBUFFER_COMPLETE) {
9628 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9629 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:569630 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9631 return;
[email protected]f0cfe752013-01-14 01:09:059632 }
[email protected]1fb8c482011-08-31 01:01:539633
[email protected]f0cfe752013-01-14 01:09:059634 // Clear the offscreen color texture.
9635 // TODO(piman): Is this still necessary?
9636 {
9637 ScopedFrameBufferBinder binder(this,
9638 offscreen_saved_frame_buffer_->id());
9639 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:459640 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9641 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:059642 glClear(GL_COLOR_BUFFER_BIT);
9643 RestoreClearState();
9644 }
[email protected]1fb8c482011-08-31 01:01:539645 }
9646
9647 UpdateParentTextureInfo();
9648 }
9649
[email protected]f0cfe752013-01-14 01:09:059650 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:569651 return;
[email protected]ab09b612013-03-11 22:11:519652 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:309653 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:359654
[email protected]34ff8b0c2010-10-01 20:06:029655 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:139656 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:279657 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:489658 } else {
[email protected]069944672012-04-25 20:52:239659 ScopedFrameBufferBinder binder(this,
9660 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:139661
[email protected]069944672012-04-25 20:52:239662 if (offscreen_target_buffer_preserved_) {
9663 // Copy the target frame buffer to the saved offscreen texture.
9664 offscreen_saved_color_texture_->Copy(
9665 offscreen_saved_color_texture_->size(),
9666 offscreen_saved_color_format_);
9667 } else {
9668 // Flip the textures in the parent context via the texture manager.
9669 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:499670 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:239671 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:569672
[email protected]069944672012-04-25 20:52:239673 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9674 offscreen_target_frame_buffer_->AttachRenderTexture(
9675 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:489676 }
[email protected]069944672012-04-25 20:52:239677
9678 // Ensure the side effects of the copy are visible to the parent
9679 // context. There is no need to do this for ANGLE because it uses a
9680 // single D3D device for all contexts.
[email protected]f42f05b2013-11-15 21:46:189681 if (!feature_info_->feature_flags().is_angle)
[email protected]069944672012-04-25 20:52:239682 glFlush();
[email protected]0c8c9d22010-06-25 17:36:399683 }
[email protected]6217d392010-03-25 22:08:359684 } else {
[email protected]f62a5ab2011-05-23 20:34:159685 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019686 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:569687 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:019688 }
[email protected]6217d392010-03-25 22:08:359689 }
vmiura8266ca72014-09-09 21:37:009690
9691 // This may be a slow command. Exit command processing to allow for
9692 // context preemption and GPU watchdog checks.
9693 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:359694}
9695
[email protected]d4239852011-08-12 04:51:229696error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:349697 uint32 immediate_data_size,
9698 const void* cmd_data) {
9699 const gles2::cmds::EnableFeatureCHROMIUM& c =
9700 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:189701 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289702 if (!bucket || bucket->size() == 0) {
9703 return error::kInvalidArguments;
9704 }
[email protected]ed9f9cd2013-02-27 21:12:359705 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189706 Result* result = GetSharedMemoryAs<Result*>(
9707 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9708 if (!result) {
9709 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109710 }
[email protected]b1d2dcb2010-05-17 19:24:189711 // Check that the client initialized the result.
9712 if (*result != 0) {
9713 return error::kInvalidArguments;
9714 }
9715 std::string feature_str;
9716 if (!bucket->GetAsString(&feature_str)) {
9717 return error::kInvalidArguments;
9718 }
9719
9720 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229721 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189722 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229723 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:409724 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9725 // TODO(gman): decide how to remove the need for this const_cast.
9726 // I could make validators_ non const but that seems bad as this is the only
9727 // place it is needed. I could make some special friend class of validators
9728 // just to allow this to set them. That seems silly. I could refactor this
9729 // code to use the extension mechanism or the initialization attributes to
9730 // turn this feature on. Given that the only real point of this is to make
9731 // the conformance tests pass and given that there is lots of real work that
9732 // needs to be done it seems like refactoring for one to one of those
9733 // methods is a very low priority.
9734 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049735 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9736 force_webgl_glsl_validation_ = true;
9737 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189738 } else {
9739 return error::kNoError;
9740 }
9741
9742 *result = 1; // true.
9743 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109744}
9745
[email protected]c2f8c8402010-12-06 18:07:249746error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9747 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:349748 const void* cmd_data) {
9749 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
9750 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
9751 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249752 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359753 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:199754 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:249755 bucket->SetFromString(info->extensions().c_str());
9756 return error::kNoError;
9757}
9758
9759error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:349760 uint32 immediate_data_size,
9761 const void* cmd_data) {
9762 const gles2::cmds::RequestExtensionCHROMIUM& c =
9763 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249764 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289765 if (!bucket || bucket->size() == 0) {
9766 return error::kInvalidArguments;
9767 }
[email protected]c2f8c8402010-12-06 18:07:249768 std::string feature_str;
9769 if (!bucket->GetAsString(&feature_str)) {
9770 return error::kInvalidArguments;
9771 }
9772
[email protected]4b7eba92013-01-08 02:23:569773 bool desire_webgl_glsl_validation =
9774 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9775 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:499776 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:139777 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:069778 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:569779 if (force_webgl_glsl_validation_) {
9780 desire_standard_derivatives =
9781 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:499782 desire_frag_depth =
9783 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:139784 desire_draw_buffers =
9785 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:069786 desire_shader_texture_lod =
9787 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049788 }
9789
[email protected]4b7eba92013-01-08 02:23:569790 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:499791 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:139792 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9793 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:499794 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9795 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9796 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:139797 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:069798 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:249799 InitializeShaderTranslator();
9800 }
9801
[email protected]302ce6d2011-07-07 23:28:119802 UpdateCapabilities();
9803
[email protected]c2f8c8402010-12-06 18:07:249804 return error::kNoError;
9805}
9806
[email protected]2318d342011-07-11 22:27:429807error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:349808 uint32 immediate_data_size,
9809 const void* cmd_data) {
9810 const gles2::cmds::GetProgramInfoCHROMIUM& c =
9811 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429812 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429813 uint32 bucket_id = c.bucket_id;
9814 Bucket* bucket = CreateBucket(bucket_id);
9815 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429816 Program* program = NULL;
9817 program = GetProgram(program_id);
9818 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469819 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429820 }
[email protected]df37b9932013-03-08 05:21:429821 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429822 return error::kNoError;
9823}
9824
[email protected]38d139d2011-07-14 00:38:439825error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9826 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439827 case GL_NO_ERROR:
9828 // TODO(kbr): improve the precision of the error code in this case.
9829 // Consider delegating to context for error code if MakeCurrent fails.
9830 return error::kUnknown;
9831 case GL_GUILTY_CONTEXT_RESET_ARB:
9832 return error::kGuilty;
9833 case GL_INNOCENT_CONTEXT_RESET_ARB:
9834 return error::kInnocent;
9835 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9836 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439837 }
9838
9839 NOTREACHED();
9840 return error::kUnknown;
9841}
9842
jbauman7a059312014-10-16 19:30:549843void GLES2DecoderImpl::MaybeExitOnContextLost() {
9844 // Some D3D drivers cannot recover from device lost in the GPU process
9845 // sandbox. Allow a new GPU process to launch.
9846 if (workarounds().exit_on_context_lost) {
9847 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
9848 << " a D3D device in the Chrome GPU process sandbox.";
9849#if defined(OS_WIN)
9850 base::win::SetShouldCrashOnProcessDetach(false);
9851#endif
9852 exit(0);
9853 }
9854}
9855
[email protected]38d139d2011-07-14 00:38:439856bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099857 if (reset_status_ != GL_NO_ERROR) {
jbauman7a059312014-10-16 19:30:549858 MaybeExitOnContextLost();
[email protected]c4485aad62012-12-17 10:19:099859 return true;
9860 }
[email protected]706b69f2012-07-27 04:59:309861 if (context_->WasAllocatedUsingRobustnessExtension()) {
9862 GLenum status = GL_NO_ERROR;
9863 if (has_robustness_extension_)
9864 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439865 if (status != GL_NO_ERROR) {
9866 // The graphics card was reset. Signal a lost context to the application.
9867 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229868 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439869 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099870 << " context lost via ARB/EXT_robustness. Reset status = "
9871 << GLES2Util::GetStringEnum(status);
jbauman7a059312014-10-16 19:30:549872 MaybeExitOnContextLost();
[email protected]38d139d2011-07-14 00:38:439873 return true;
9874 }
9875 }
9876 return false;
9877}
9878
[email protected]93a7d98f2013-07-11 00:04:229879bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9880 return WasContextLost() && reset_by_robustness_extension_;
9881}
9882
[email protected]c4485aad62012-12-17 10:19:099883void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9884 // Only loses the context once.
9885 if (reset_status_ != GL_NO_ERROR) {
9886 return;
9887 }
9888
oetuaho37cc50e2014-10-31 11:19:209889 if (workarounds().use_virtualized_gl_contexts) {
9890 // If the context is virtual, the real context being guilty does not ensure
9891 // that the virtual context is guilty.
9892 if (reset_status == GL_GUILTY_CONTEXT_RESET_ARB) {
9893 reset_status = GL_UNKNOWN_CONTEXT_RESET_ARB;
9894 }
9895 } else if (reset_status == GL_UNKNOWN_CONTEXT_RESET_ARB &&
9896 has_robustness_extension_) {
9897 // If the reason for the call was a GL error, we can try to determine the
9898 // reset status more accurately.
9899 GLenum driver_status = glGetGraphicsResetStatusARB();
9900 if (driver_status == GL_GUILTY_CONTEXT_RESET_ARB ||
9901 driver_status == GL_INNOCENT_CONTEXT_RESET_ARB) {
9902 reset_status = driver_status;
9903 }
9904 }
9905
[email protected]c4485aad62012-12-17 10:19:099906 // Marks this context as lost.
9907 reset_status_ = reset_status;
9908 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099909}
9910
[email protected]b096d032013-03-08 03:08:019911error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:349912 uint32 immediate_data_size,
9913 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:019914 return error::kUnknownCommand;
9915}
9916
[email protected]840a7e462013-02-27 01:29:519917error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:349918 uint32 immediate_data_size,
9919 const void* cmd_data) {
9920 const gles2::cmds::WaitSyncPointCHROMIUM& c =
9921 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
sievers173a20d2014-10-22 18:19:329922 uint32 sync_point = c.sync_point;
[email protected]840a7e462013-02-27 01:29:519923 if (wait_sync_point_callback_.is_null())
9924 return error::kNoError;
9925
sievers173a20d2014-10-22 18:19:329926 return wait_sync_point_callback_.Run(sync_point) ?
[email protected]840a7e462013-02-27 01:29:519927 error::kNoError : error::kDeferCommandUntilLater;
9928}
9929
[email protected]5dfc457b2013-12-13 11:13:079930error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:349931 uint32 immediate_data_size,
9932 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:079933 if (surface_->DeferDraws())
9934 return error::kDeferCommandUntilLater;
9935 if (!surface_->SetBackbufferAllocation(false))
9936 return error::kLostContext;
9937 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
9938 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
9939 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
9940 return error::kNoError;
9941}
9942
[email protected]882ba1e22012-03-08 19:02:539943bool GLES2DecoderImpl::GenQueriesEXTHelper(
9944 GLsizei n, const GLuint* client_ids) {
9945 for (GLsizei ii = 0; ii < n; ++ii) {
9946 if (query_manager_->GetQuery(client_ids[ii])) {
9947 return false;
9948 }
9949 }
[email protected]4eea7e62014-04-22 21:14:439950 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:539951 return true;
9952}
9953
9954void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9955 GLsizei n, const GLuint* client_ids) {
9956 for (GLsizei ii = 0; ii < n; ++ii) {
9957 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9958 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:139959 ContextState::QueryMap::iterator it =
9960 state_.current_queries.find(query->target());
9961 if (it != state_.current_queries.end())
9962 state_.current_queries.erase(it);
9963
[email protected]c45f1972012-03-14 07:27:369964 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539965 }
[email protected]4eea7e62014-04-22 21:14:439966 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:539967 }
9968}
9969
revemancc241eb2014-11-11 03:30:379970bool GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
[email protected]22e3f552012-03-13 01:54:199971 if (query_manager_.get() == NULL) {
9972 return false;
9973 }
revemancc241eb2014-11-11 03:30:379974 if (!query_manager_->ProcessPendingQueries(did_finish)) {
[email protected]22e3f552012-03-13 01:54:199975 current_decoder_error_ = error::kOutOfBounds;
9976 }
9977 return query_manager_->HavePendingQueries();
9978}
9979
[email protected]5a36dc132013-07-23 23:17:559980// Note that if there are no pending readpixels right now,
9981// this function will call the callback immediately.
9982void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9983 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9984 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9985 } else {
9986 callback.Run();
9987 }
9988}
9989
9990void GLES2DecoderImpl::ProcessPendingReadPixels() {
9991 while (!pending_readpixel_fences_.empty() &&
9992 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9993 std::vector<base::Closure> callbacks =
9994 pending_readpixel_fences_.front()->callbacks;
9995 pending_readpixel_fences_.pop();
9996 for (size_t i = 0; i < callbacks.size(); i++) {
9997 callbacks[i].Run();
9998 }
9999 }
10000}
10001
[email protected]2b1767cf2013-03-16 09:25:0510002bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510003 return !pending_readpixel_fences_.empty() ||
10004 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510005}
10006
10007void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510008 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:4810009 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:0510010 return;
[email protected]b68b100752013-06-05 08:34:4810011 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510012 ProcessFinishedAsyncTransfers();
10013}
10014
vmiuracd108592014-09-08 14:36:3410015error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
10016 const void* cmd_data) {
10017 const gles2::cmds::BeginQueryEXT& c =
10018 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310019 GLenum target = static_cast<GLenum>(c.target);
10020 GLuint client_id = static_cast<GLuint>(c.id);
10021 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
10022 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10023
[email protected]c45f1972012-03-14 07:27:3610024 switch (target) {
10025 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:5510026 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:3110027 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
10028 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:0010029 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:3610030 break;
[email protected]6a25ae422014-04-17 23:48:2710031 case GL_COMMANDS_COMPLETED_CHROMIUM:
10032 if (!features().chromium_sync_query) {
10033 LOCAL_SET_GL_ERROR(
10034 GL_INVALID_OPERATION, "glBeginQueryEXT",
10035 "not enabled for commands completed queries");
10036 return error::kNoError;
10037 }
10038 break;
[email protected]c45f1972012-03-14 07:27:3610039 default:
[email protected]62e155e2012-10-23 22:43:1510040 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:5110041 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:0010042 GL_INVALID_OPERATION, "glBeginQueryEXT",
10043 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:3610044 return error::kNoError;
10045 }
10046 break;
[email protected]882ba1e22012-03-08 19:02:5310047 }
10048
[email protected]8ebd46c2014-01-08 12:06:1310049 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110050 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310051 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:5310052 return error::kNoError;
10053 }
10054
10055 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:5110056 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:5310057 return error::kNoError;
10058 }
10059
10060 QueryManager::Query* query = query_manager_->GetQuery(client_id);
10061 if (!query) {
[email protected]4eea7e62014-04-22 21:14:4310062 if (!query_manager_->IsValidQuery(client_id)) {
10063 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10064 "glBeginQueryEXT",
10065 "id not made by glGenQueriesEXT");
10066 return error::kNoError;
10067 }
[email protected]c45f1972012-03-14 07:27:3610068 query = query_manager_->CreateQuery(
10069 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:5310070 }
10071
[email protected]c45f1972012-03-14 07:27:3610072 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110073 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310074 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:5310075 return error::kNoError;
10076 } else if (query->shm_id() != sync_shm_id ||
10077 query->shm_offset() != sync_shm_offset) {
10078 DLOG(ERROR) << "Shared memory used by query not the same as before";
10079 return error::kInvalidArguments;
10080 }
10081
[email protected]c45f1972012-03-14 07:27:3610082 if (!query_manager_->BeginQuery(query)) {
10083 return error::kOutOfBounds;
10084 }
[email protected]882ba1e22012-03-08 19:02:5310085
[email protected]8ebd46c2014-01-08 12:06:1310086 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:5310087 return error::kNoError;
10088}
10089
vmiuracd108592014-09-08 14:36:3410090error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
10091 const void* cmd_data) {
10092 const gles2::cmds::EndQueryEXT& c =
10093 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310094 GLenum target = static_cast<GLenum>(c.target);
10095 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:1310096 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:5310097
[email protected]8ebd46c2014-01-08 12:06:1310098 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110099 LOCAL_SET_GL_ERROR(
10100 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:5310101 return error::kNoError;
10102 }
[email protected]882ba1e22012-03-08 19:02:5310103
[email protected]8ebd46c2014-01-08 12:06:1310104 QueryManager::Query* query = it->second.get();
10105 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:3610106 return error::kOutOfBounds;
10107 }
10108
[email protected]fe8d73c2013-02-16 22:37:3210109 query_manager_->ProcessPendingTransferQueries();
10110
[email protected]8ebd46c2014-01-08 12:06:1310111 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:5310112 return error::kNoError;
10113}
10114
[email protected]944b62f32012-09-27 02:20:4610115bool GLES2DecoderImpl::GenVertexArraysOESHelper(
10116 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610117 for (GLsizei ii = 0; ii < n; ++ii) {
10118 if (GetVertexAttribManager(client_ids[ii])) {
10119 return false;
10120 }
10121 }
[email protected]ab4fd7282012-10-12 16:25:5710122
[email protected]62e155e2012-10-23 22:43:1510123 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710124 // Emulated VAO
10125 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810126 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:5710127 }
10128 } else {
[email protected]40d90a22013-04-09 03:39:5510129 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:5710130
10131 glGenVertexArraysOES(n, service_ids.get());
10132 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810133 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:5710134 }
[email protected]944b62f32012-09-27 02:20:4610135 }
[email protected]ab4fd7282012-10-12 16:25:5710136
[email protected]944b62f32012-09-27 02:20:4610137 return true;
10138}
10139
10140void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
10141 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610142 for (GLsizei ii = 0; ii < n; ++ii) {
10143 VertexAttribManager* vao =
10144 GetVertexAttribManager(client_ids[ii]);
10145 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:1110146 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:1110147 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:4610148 }
10149 RemoveVertexAttribManager(client_ids[ii]);
10150 }
10151 }
10152}
10153
10154void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610155 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:4610156 if (client_id != 0) {
10157 vao = GetVertexAttribManager(client_id);
10158 if (!vao) {
10159 // Unlike most Bind* methods, the spec explicitly states that VertexArray
10160 // only allows names that have been previously generated. As such, we do
10161 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:5110162 LOCAL_SET_GL_ERROR(
10163 GL_INVALID_OPERATION,
10164 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:4610165 current_decoder_error_ = error::kNoError;
10166 return;
[email protected]944b62f32012-09-27 02:20:4610167 }
[email protected]944b62f32012-09-27 02:20:4610168 } else {
[email protected]81f20a622014-04-18 01:54:5210169 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4610170 }
10171
[email protected]ab4fd7282012-10-12 16:25:5710172 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110173 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2410174 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1510175 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710176 EmulateVertexArrayState();
10177 } else {
[email protected]da364812014-05-09 21:39:4810178 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5710179 glBindVertexArrayOES(service_id);
10180 }
10181 }
10182}
10183
10184// Used when OES_vertex_array_object isn't natively supported
10185void GLES2DecoderImpl::EmulateVertexArrayState() {
10186 // Setup the Vertex attribute state
10187 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2310188 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5710189 }
10190
10191 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2110192 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2410193 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5710194 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
10195 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4610196}
10197
10198bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610199 const VertexAttribManager* vao =
10200 GetVertexAttribManager(client_id);
10201 return vao && vao->IsValid() && !vao->IsDeleted();
10202}
10203
[email protected]e51bdf32011-11-23 22:21:4610204#if defined(OS_MACOSX)
10205void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
10206 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
10207 texture_id);
10208 if (it != texture_to_io_surface_map_.end()) {
10209 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5310210 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4610211 CFRelease(surface);
10212 texture_to_io_surface_map_.erase(it);
10213 }
10214}
10215#endif
10216
10217void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
10218 GLenum target, GLsizei width, GLsizei height,
10219 GLuint io_surface_id, GLuint plane) {
10220#if defined(OS_MACOSX)
10221 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5110222 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310223 GL_INVALID_OPERATION,
10224 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4610225 return;
10226 }
10227
[email protected]e51bdf32011-11-23 22:21:4610228 if (target != GL_TEXTURE_RECTANGLE_ARB) {
10229 // This might be supported in the future, and if we could require
10230 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
10231 // could delete a lot of code. For now, perform strict validation so we
10232 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5110233 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610234 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310235 "glTexImageIOSurface2DCHROMIUM",
10236 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4610237 return;
10238 }
10239
[email protected]09d50362012-10-18 20:54:3710240 // Default target might be conceptually valid, but disallow it to avoid
10241 // accidents.
[email protected]c986af502013-08-14 01:04:4410242 TextureRef* texture_ref =
10243 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910244 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110245 LOCAL_SET_GL_ERROR(
10246 GL_INVALID_OPERATION,
10247 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4610248 return;
10249 }
[email protected]e51bdf32011-11-23 22:21:4610250
10251 // Look up the new IOSurface. Note that because of asynchrony
10252 // between processes this might fail; during live resizing the
10253 // plugin process might allocate and release an IOSurface before
10254 // this process gets a chance to look it up. Hold on to any old
10255 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5310256 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4610257 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5110258 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310259 GL_INVALID_OPERATION,
10260 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4610261 return;
10262 }
10263
10264 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4910265 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4610266
10267 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
10268 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4910269 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4610270
10271 CGLContextObj context =
10272 static_cast<CGLContextObj>(context_->GetHandle());
10273
[email protected]c3a6b4a2014-06-04 09:25:5310274 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4610275 context,
10276 target,
10277 GL_RGBA,
10278 width,
10279 height,
10280 GL_BGRA,
10281 GL_UNSIGNED_INT_8_8_8_8_REV,
10282 surface,
10283 plane);
10284
10285 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5110286 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610287 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310288 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4610289 return;
10290 }
10291
10292 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910293 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4610294 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
10295
10296#else
[email protected]ab09b612013-03-11 22:11:5110297 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310298 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4610299#endif
10300}
10301
[email protected]97dc7cbe2011-12-06 17:26:1710302static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
10303 switch (internalformat) {
10304 case GL_RGB565:
10305 return GL_RGB;
10306 case GL_RGBA4:
10307 return GL_RGBA;
10308 case GL_RGB5_A1:
10309 return GL_RGBA;
10310 case GL_RGB8_OES:
10311 return GL_RGB;
10312 case GL_RGBA8_OES:
10313 return GL_RGBA;
10314 case GL_LUMINANCE8_ALPHA8_EXT:
10315 return GL_LUMINANCE_ALPHA;
10316 case GL_LUMINANCE8_EXT:
10317 return GL_LUMINANCE;
10318 case GL_ALPHA8_EXT:
10319 return GL_ALPHA;
10320 case GL_RGBA32F_EXT:
10321 return GL_RGBA;
10322 case GL_RGB32F_EXT:
10323 return GL_RGB;
10324 case GL_ALPHA32F_EXT:
10325 return GL_ALPHA;
10326 case GL_LUMINANCE32F_EXT:
10327 return GL_LUMINANCE;
10328 case GL_LUMINANCE_ALPHA32F_EXT:
10329 return GL_LUMINANCE_ALPHA;
10330 case GL_RGBA16F_EXT:
10331 return GL_RGBA;
10332 case GL_RGB16F_EXT:
10333 return GL_RGB;
10334 case GL_ALPHA16F_EXT:
10335 return GL_ALPHA;
10336 case GL_LUMINANCE16F_EXT:
10337 return GL_LUMINANCE;
10338 case GL_LUMINANCE_ALPHA16F_EXT:
10339 return GL_LUMINANCE_ALPHA;
10340 case GL_BGRA8_EXT:
10341 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5910342 case GL_SRGB8_ALPHA8_EXT:
10343 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1710344 default:
10345 return GL_NONE;
10346 }
10347}
10348
[email protected]43410e92012-04-20 17:06:2810349void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:0310350 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:5410351 GLenum internal_format, GLenum dest_type) {
[email protected]1e24dc7f2014-04-14 02:40:0810352 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
10353
[email protected]370eaf12013-05-18 09:19:4910354 TextureRef* dest_texture_ref = GetTexture(dest_id);
10355 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:2810356
[email protected]370eaf12013-05-18 09:19:4910357 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110358 LOCAL_SET_GL_ERROR(
10359 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:2810360 return;
10361 }
10362
10363 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110364 LOCAL_SET_GL_ERROR(
10365 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:2810366 return;
10367 }
10368
[email protected]370eaf12013-05-18 09:19:4910369 Texture* source_texture = source_texture_ref->texture();
10370 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710371 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2510372 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3410373 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
10374 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:0010375 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10376 "glCopyTextureCHROMIUM",
10377 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:0310378 return;
10379 }
10380
[email protected]43410e92012-04-20 17:06:2810381 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:2810382
[email protected]3e0dfd72014-02-21 06:28:4110383 gfx::GLImage* image =
10384 source_texture->GetLevelImage(source_texture->target(), 0);
10385 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5510386 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5610387 source_width = size.width();
10388 source_height = size.height();
10389 if (source_width <= 0 || source_height <= 0) {
10390 LOCAL_SET_GL_ERROR(
10391 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5510392 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5610393 return;
10394 }
[email protected]3ecc1052013-09-26 08:59:0010395 } else {
10396 if (!source_texture->GetLevelSize(
10397 source_texture->target(), 0, &source_width, &source_height)) {
10398 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10399 "glCopyTextureChromium",
10400 "source texture has no level 0");
10401 return;
10402 }
10403
10404 // Check that this type of texture is allowed.
10405 if (!texture_manager()->ValidForTarget(
10406 source_texture->target(), level, source_width, source_height, 1)) {
10407 LOCAL_SET_GL_ERROR(
10408 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
10409 return;
10410 }
[email protected]377976552013-05-14 23:32:5610411 }
10412
[email protected]04b5b37d2014-02-07 02:11:5110413 // Clear the source texture if necessary.
10414 if (!texture_manager()->ClearTextureLevel(
10415 this, source_texture_ref, source_texture->target(), 0)) {
10416 LOCAL_SET_GL_ERROR(
10417 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
10418 return;
10419 }
10420
[email protected]a6e3d282014-08-22 22:20:4410421 GLenum source_type = 0;
10422 GLenum source_internal_format = 0;
10423 source_texture->GetLevelType(
10424 source_texture->target(), 0, &source_type, &source_internal_format);
10425
10426 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
10427 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
10428 // renderable on some platforms.
reveman6b0fbe42014-09-04 00:55:0310429 bool valid_dest_format = internal_format == GL_RGB ||
10430 internal_format == GL_RGBA ||
10431 internal_format == GL_BGRA_EXT;
[email protected]a6e3d282014-08-22 22:20:4410432 bool valid_source_format = source_internal_format == GL_ALPHA ||
10433 source_internal_format == GL_RGB ||
10434 source_internal_format == GL_RGBA ||
10435 source_internal_format == GL_LUMINANCE ||
10436 source_internal_format == GL_LUMINANCE_ALPHA ||
10437 source_internal_format == GL_BGRA_EXT;
10438 if (!valid_source_format || !valid_dest_format) {
10439 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10440 "glCopyTextureCHROMIUM",
10441 "invalid internal format");
10442 return;
10443 }
10444
[email protected]cf6b8f62012-05-25 21:43:3710445 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
10446 // needed because it takes 10s of milliseconds to initialize.
10447 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5110448 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3710449 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2710450 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3710451 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5110452 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3710453 return;
10454 }
10455
[email protected]efc87712014-07-09 00:22:4710456 GLenum dest_type_previous = dest_type;
10457 GLenum dest_internal_format = internal_format;
[email protected]02965c22013-03-09 02:40:0710458 bool dest_level_defined = dest_texture->GetLevelSize(
10459 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2810460
[email protected]0a1e9ad2012-05-04 21:13:0310461 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:5410462 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0710463 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0310464 }
10465
10466 // Resize the destination texture to the dimensions of the source texture.
10467 if (!dest_level_defined || dest_width != source_width ||
10468 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5410469 dest_internal_format != internal_format ||
10470 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2810471 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5110472 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0710473 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:3810474 glTexImage2D(
[email protected]43410e92012-04-20 17:06:2810475 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:0310476 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5110477 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0310478 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0210479 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2810480 return;
[email protected]0a1e9ad2012-05-04 21:13:0310481 }
[email protected]43410e92012-04-20 17:06:2810482
10483 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910484 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0310485 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2510486 } else {
[email protected]02965c22013-03-09 02:40:0710487 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:4910488 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:2810489 }
10490
[email protected]00c2cf92014-03-14 00:08:3710491 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5410492
revemance8fbe82014-09-05 02:19:5210493 // Try using GLImage::CopyTexImage when possible.
10494 bool unpack_premultiply_alpha_change =
10495 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
10496 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
10497 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
10498 if (image->CopyTexImage(GL_TEXTURE_2D))
10499 return;
10500 }
10501
10502 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
10503
[email protected]5394a4102013-04-18 05:41:3710504 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
10505 // before presenting.
10506 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
10507 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
10508 // instead of using default matrix crbug.com/226218.
10509 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
10510 0.0f, 1.0f, 0.0f, 0.0f,
10511 0.0f, 0.0f, 1.0f, 0.0f,
10512 0.0f, 0.0f, 0.0f, 1.0f};
10513 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
10514 this,
10515 source_texture->target(),
[email protected]5394a4102013-04-18 05:41:3710516 source_texture->service_id(),
[email protected]90f7d30d2014-08-13 02:51:5710517 dest_texture->service_id(),
10518 level,
10519 source_width,
10520 source_height,
[email protected]5394a4102013-04-18 05:41:3710521 unpack_flip_y_,
10522 unpack_premultiply_alpha_,
10523 unpack_unpremultiply_alpha_,
10524 default_matrix);
10525 } else {
[email protected]90f7d30d2014-08-13 02:51:5710526 copy_texture_CHROMIUM_->DoCopyTexture(this,
10527 source_texture->target(),
10528 source_texture->service_id(),
10529 source_internal_format,
10530 dest_texture->service_id(),
10531 level,
10532 internal_format,
10533 source_width,
10534 source_height,
10535 unpack_flip_y_,
10536 unpack_premultiply_alpha_,
10537 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3710538 }
[email protected]91c94eb2013-10-22 10:32:5410539
10540 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2810541}
10542
[email protected]97dc7cbe2011-12-06 17:26:1710543static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
10544 switch (internalformat) {
10545 case GL_RGB565:
10546 return GL_UNSIGNED_SHORT_5_6_5;
10547 case GL_RGBA4:
10548 return GL_UNSIGNED_SHORT_4_4_4_4;
10549 case GL_RGB5_A1:
10550 return GL_UNSIGNED_SHORT_5_5_5_1;
10551 case GL_RGB8_OES:
10552 return GL_UNSIGNED_BYTE;
10553 case GL_RGBA8_OES:
10554 return GL_UNSIGNED_BYTE;
10555 case GL_LUMINANCE8_ALPHA8_EXT:
10556 return GL_UNSIGNED_BYTE;
10557 case GL_LUMINANCE8_EXT:
10558 return GL_UNSIGNED_BYTE;
10559 case GL_ALPHA8_EXT:
10560 return GL_UNSIGNED_BYTE;
10561 case GL_RGBA32F_EXT:
10562 return GL_FLOAT;
10563 case GL_RGB32F_EXT:
10564 return GL_FLOAT;
10565 case GL_ALPHA32F_EXT:
10566 return GL_FLOAT;
10567 case GL_LUMINANCE32F_EXT:
10568 return GL_FLOAT;
10569 case GL_LUMINANCE_ALPHA32F_EXT:
10570 return GL_FLOAT;
10571 case GL_RGBA16F_EXT:
10572 return GL_HALF_FLOAT_OES;
10573 case GL_RGB16F_EXT:
10574 return GL_HALF_FLOAT_OES;
10575 case GL_ALPHA16F_EXT:
10576 return GL_HALF_FLOAT_OES;
10577 case GL_LUMINANCE16F_EXT:
10578 return GL_HALF_FLOAT_OES;
10579 case GL_LUMINANCE_ALPHA16F_EXT:
10580 return GL_HALF_FLOAT_OES;
10581 case GL_BGRA8_EXT:
10582 return GL_UNSIGNED_BYTE;
10583 default:
10584 return GL_NONE;
10585 }
10586}
10587
10588void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4410589 GLenum target,
10590 GLint levels,
10591 GLenum internal_format,
10592 GLsizei width,
10593 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1310594 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
10595 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4110596 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0010597 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5110598 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310599 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1710600 return;
10601 }
[email protected]c986af502013-08-14 01:04:4410602 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10603 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910604 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110605 LOCAL_SET_GL_ERROR(
10606 GL_INVALID_OPERATION,
10607 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1710608 return;
10609 }
[email protected]370eaf12013-05-18 09:19:4910610 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710611 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4410612 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1710613 }
[email protected]02965c22013-03-09 02:40:0710614 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5110615 LOCAL_SET_GL_ERROR(
10616 GL_INVALID_OPERATION,
10617 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1710618 return;
10619 }
[email protected]7989c9e2013-01-23 06:39:2610620
10621 GLenum format = ExtractFormatFromStorageFormat(internal_format);
10622 GLenum type = ExtractTypeFromStorageFormat(internal_format);
10623
10624 {
10625 GLsizei level_width = width;
10626 GLsizei level_height = height;
10627 uint32 estimated_size = 0;
10628 for (int ii = 0; ii < levels; ++ii) {
10629 uint32 level_size = 0;
10630 if (!GLES2Util::ComputeImageDataSizes(
10631 level_width, level_height, format, type, state_.unpack_alignment,
10632 &estimated_size, NULL, NULL) ||
10633 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110634 LOCAL_SET_GL_ERROR(
10635 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2610636 return;
10637 }
10638 level_width = std::max(1, level_width >> 1);
10639 level_height = std::max(1, level_height >> 1);
10640 }
10641 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110642 LOCAL_SET_GL_ERROR(
10643 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610644 return;
10645 }
10646 }
10647
[email protected]ab09b612013-03-11 22:11:5110648 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3810649 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5110650 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1710651 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1510652 GLsizei level_width = width;
10653 GLsizei level_height = height;
10654 for (int ii = 0; ii < levels; ++ii) {
10655 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910656 texture_ref, target, ii, format,
10657 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1510658 level_width = std::max(1, level_width >> 1);
10659 level_height = std::max(1, level_height >> 1);
10660 }
[email protected]02965c22013-03-09 02:40:0710661 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1710662 }
[email protected]97dc7cbe2011-12-06 17:26:1710663}
[email protected]e51bdf32011-11-23 22:21:4610664
[email protected]78b514b2012-05-01 21:50:5910665error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3410666 uint32 immediate_data_size,
10667 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3510668 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5910669}
10670
10671void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710672 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210673 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210674 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710675 "mailbox[0]", static_cast<unsigned char>(data[0]));
10676
[email protected]43f253da2014-06-10 17:51:2210677 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10678 &state_, target);
10679 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
10680}
10681
10682void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
10683 GLenum target, const GLbyte* data) {
10684 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
10685 "context", logger_.GetLogPrefix(),
10686 "mailbox[0]", static_cast<unsigned char>(data[0]));
10687
10688 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
10689 target, data);
10690}
10691
10692void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
10693 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3710694 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2210695 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3710696 "mailbox that was not generated by "
10697 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210698
[email protected]370eaf12013-05-18 09:19:4910699 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110700 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210701 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910702 return;
10703 }
10704
[email protected]62e65f02013-05-29 22:28:1010705 Texture* produced = texture_manager()->Produce(texture_ref);
10706 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5110707 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210708 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
10709 return;
10710 }
10711
10712 if (produced->target() != target) {
10713 LOCAL_SET_GL_ERROR(
10714 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5910715 return;
10716 }
10717
sievers8b373ec52014-10-24 23:04:0610718 group_->mailbox_manager()->ProduceTexture(mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5910719}
10720
10721void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710722 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210723 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210724 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710725 "mailbox[0]", static_cast<unsigned char>(data[0]));
10726 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10727 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
10728 "mailbox that was not generated by "
10729 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210730
[email protected]62e65f02013-05-29 22:28:1010731 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4410732 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1110733 if (!texture_ref.get()) {
10734 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10735 "glConsumeTextureCHROMIUM",
10736 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910737 return;
10738 }
[email protected]62e65f02013-05-29 22:28:1010739 GLuint client_id = texture_ref->client_id();
10740 if (!client_id) {
10741 LOCAL_SET_GL_ERROR(
10742 GL_INVALID_OPERATION,
10743 "glConsumeTextureCHROMIUM", "unknown texture for target");
10744 return;
10745 }
sievers8b373ec52014-10-24 23:04:0610746 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]62e65f02013-05-29 22:28:1010747 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110748 LOCAL_SET_GL_ERROR(
10749 GL_INVALID_OPERATION,
10750 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910751 return;
10752 }
[email protected]62e65f02013-05-29 22:28:1010753 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110754 LOCAL_SET_GL_ERROR(
10755 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1010756 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5910757 return;
10758 }
[email protected]62e65f02013-05-29 22:28:1010759
10760 DeleteTexturesHelper(1, &client_id);
10761 texture_ref = texture_manager()->Consume(client_id, texture);
10762 glBindTexture(target, texture_ref->service_id());
10763
10764 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10765 unit.bind_target = target;
10766 switch (target) {
10767 case GL_TEXTURE_2D:
10768 unit.bound_texture_2d = texture_ref;
10769 break;
10770 case GL_TEXTURE_CUBE_MAP:
10771 unit.bound_texture_cube_map = texture_ref;
10772 break;
10773 case GL_TEXTURE_EXTERNAL_OES:
10774 unit.bound_texture_external_oes = texture_ref;
10775 break;
10776 case GL_TEXTURE_RECTANGLE_ARB:
10777 unit.bound_texture_rectangle_arb = texture_ref;
10778 break;
10779 default:
10780 NOTREACHED(); // Validation should prevent us getting here.
10781 break;
10782 }
[email protected]78b514b2012-05-01 21:50:5910783}
10784
[email protected]43f253da2014-06-10 17:51:2210785error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
10786 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3410787 const void* cmd_data) {
10788 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
10789 *static_cast<
10790 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
10791 cmd_data);
[email protected]43f253da2014-06-10 17:51:2210792 GLenum target = static_cast<GLenum>(c.target);
10793 uint32_t data_size;
10794 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
10795 return error::kOutOfBounds;
10796 }
10797 if (data_size > immediate_data_size) {
10798 return error::kOutOfBounds;
10799 }
10800 const GLbyte* mailbox =
10801 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
10802 if (!validators_->texture_bind_target.IsValid(target)) {
10803 LOCAL_SET_GL_ERROR_INVALID_ENUM(
10804 "glCreateAndConsumeTextureCHROMIUM", target, "target");
10805 return error::kNoError;
10806 }
10807 if (mailbox == NULL) {
10808 return error::kOutOfBounds;
10809 }
10810 uint32_t client_id = c.client_id;
10811 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
10812 return error::kNoError;
10813}
10814
10815void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
10816 const GLbyte* data, GLuint client_id) {
10817 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
10818 "context", logger_.GetLogPrefix(),
10819 "mailbox[0]", static_cast<unsigned char>(data[0]));
10820 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10821 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
10822 "passed a mailbox that was not "
10823 "generated by GenMailboxCHROMIUM.";
10824
10825 TextureRef* texture_ref = GetTexture(client_id);
10826 if (texture_ref) {
10827 LOCAL_SET_GL_ERROR(
10828 GL_INVALID_OPERATION,
10829 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
10830 return;
10831 }
sievers8b373ec52014-10-24 23:04:0610832 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]43f253da2014-06-10 17:51:2210833 if (!texture) {
10834 LOCAL_SET_GL_ERROR(
10835 GL_INVALID_OPERATION,
10836 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
10837 return;
10838 }
10839 if (texture->target() != target) {
10840 LOCAL_SET_GL_ERROR(
10841 GL_INVALID_OPERATION,
10842 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
10843 return;
10844 }
10845
[email protected]43f253da2014-06-10 17:51:2210846 texture_ref = texture_manager()->Consume(client_id, texture);
10847}
10848
orglofchcad5a6742014-11-07 19:51:1210849bool GLES2DecoderImpl::DoIsValuebufferCHROMIUM(GLuint client_id) {
10850 const Valuebuffer* valuebuffer = GetValuebuffer(client_id);
10851 return valuebuffer && valuebuffer->IsValid();
10852}
10853
10854void GLES2DecoderImpl::DoBindValueBufferCHROMIUM(GLenum target,
10855 GLuint client_id) {
10856 Valuebuffer* valuebuffer = NULL;
10857 if (client_id != 0) {
10858 valuebuffer = GetValuebuffer(client_id);
10859 if (!valuebuffer) {
10860 if (!group_->bind_generates_resource()) {
10861 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindValuebufferCHROMIUM",
10862 "id not generated by glBindValuebufferCHROMIUM");
10863 return;
10864 }
10865
10866 // It's a new id so make a valuebuffer for it.
10867 CreateValuebuffer(client_id);
10868 valuebuffer = GetValuebuffer(client_id);
10869 }
10870 valuebuffer->MarkAsValid();
10871 }
10872 state_.bound_valuebuffer = valuebuffer;
10873}
10874
10875void GLES2DecoderImpl::DoSubscribeValueCHROMIUM(GLenum target,
10876 GLenum subscription) {
10877 if (!CheckCurrentValuebuffer("glSubscribeValueCHROMIUM")) {
10878 return;
10879 }
10880 state_.bound_valuebuffer.get()->AddSubscription(subscription);
10881}
10882
10883void GLES2DecoderImpl::DoPopulateSubscribedValuesCHROMIUM(GLenum target) {
10884 if (!CheckCurrentValuebuffer("glPopulateSubscribedValuesCHROMIUM")) {
10885 return;
10886 }
10887 valuebuffer_manager()->UpdateValuebufferState(state_.bound_valuebuffer.get());
10888}
10889
10890void GLES2DecoderImpl::DoUniformValueBufferCHROMIUM(GLint location,
10891 GLenum target,
10892 GLenum subscription) {
10893 if (!CheckCurrentValuebufferForSubscription(
10894 subscription, "glPopulateSubscribedValuesCHROMIUM")) {
10895 return;
10896 }
10897 if (!CheckSubscriptionTarget(location, subscription,
10898 "glPopulateSubscribedValuesCHROMIUM")) {
10899 return;
10900 }
10901 const ValueState* state =
10902 state_.bound_valuebuffer.get()->GetState(subscription);
10903 if (state) {
10904 switch (subscription) {
10905 case GL_MOUSE_POSITION_CHROMIUM:
10906 DoUniform2iv(location, 1, state->int_value);
10907 break;
10908 default:
10909 NOTREACHED() << "Unhandled uniform subscription target "
10910 << subscription;
10911 break;
10912 }
10913 }
10914}
10915
[email protected]d2a0e1a2012-08-12 02:25:0110916void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10917 GLsizei length, const GLchar* marker) {
10918 if (!marker) {
10919 marker = "";
10920 }
10921 debug_marker_manager_.SetMarker(
10922 length ? std::string(marker, length) : std::string(marker));
10923}
10924
10925void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10926 GLsizei length, const GLchar* marker) {
10927 if (!marker) {
10928 marker = "";
10929 }
[email protected]cac16542014-01-15 17:53:5110930 std::string name = length ? std::string(marker, length) : std::string(marker);
10931 debug_marker_manager_.PushGroup(name);
10932 gpu_tracer_->Begin(name, kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110933}
10934
10935void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10936 debug_marker_manager_.PopGroup();
[email protected]cac16542014-01-15 17:53:5110937 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110938}
10939
[email protected]09d50362012-10-18 20:54:3710940void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10941 GLenum target, GLint image_id) {
10942 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710943
[email protected]bc26e8d2014-01-29 00:40:3010944 if (target == GL_TEXTURE_CUBE_MAP) {
10945 LOCAL_SET_GL_ERROR(
10946 GL_INVALID_ENUM,
10947 "glBindTexImage2DCHROMIUM", "invalid target");
10948 return;
10949 }
10950
[email protected]09d50362012-10-18 20:54:3710951 // Default target might be conceptually valid, but disallow it to avoid
10952 // accidents.
[email protected]c986af502013-08-14 01:04:4410953 TextureRef* texture_ref =
10954 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910955 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110956 LOCAL_SET_GL_ERROR(
10957 GL_INVALID_OPERATION,
10958 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710959 return;
10960 }
10961
10962 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10963 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110964 LOCAL_SET_GL_ERROR(
10965 GL_INVALID_OPERATION,
10966 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710967 return;
10968 }
10969
[email protected]b8160812013-04-09 00:41:0410970 {
10971 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010972 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610973 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0410974 LOCAL_SET_GL_ERROR(
10975 GL_INVALID_OPERATION,
10976 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10977 return;
10978 }
[email protected]09d50362012-10-18 20:54:3710979 }
10980
10981 gfx::Size size = gl_image->GetSize();
10982 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910983 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710984 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910985 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710986}
10987
10988void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10989 GLenum target, GLint image_id) {
10990 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710991
10992 // Default target might be conceptually valid, but disallow it to avoid
10993 // accidents.
[email protected]c986af502013-08-14 01:04:4410994 TextureRef* texture_ref =
10995 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910996 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110997 LOCAL_SET_GL_ERROR(
10998 GL_INVALID_OPERATION,
10999 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711000 return;
11001 }
11002
11003 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11004 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111005 LOCAL_SET_GL_ERROR(
11006 GL_INVALID_OPERATION,
11007 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711008 return;
11009 }
11010
11011 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4911012 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3711013 return;
11014
[email protected]b8160812013-04-09 00:41:0411015 {
11016 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011017 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611018 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0411019 }
[email protected]09d50362012-10-18 20:54:3711020
11021 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911022 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3711023 GL_RGBA, GL_UNSIGNED_BYTE, false);
11024}
[email protected]d2a0e1a2012-08-12 02:25:0111025
[email protected]94307712012-11-16 23:26:1111026error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3411027 uint32 immediate_data_size,
11028 const void* cmd_data) {
11029 const gles2::cmds::TraceBeginCHROMIUM& c =
11030 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
[email protected]94307712012-11-16 23:26:1111031 Bucket* bucket = GetBucket(c.bucket_id);
11032 if (!bucket || bucket->size() == 0) {
11033 return error::kInvalidArguments;
11034 }
11035 std::string command_name;
11036 if (!bucket->GetAsString(&command_name)) {
11037 return error::kInvalidArguments;
11038 }
[email protected]fb97b662013-02-20 23:02:1411039 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
[email protected]cac16542014-01-15 17:53:5111040 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5111041 LOCAL_SET_GL_ERROR(
11042 GL_INVALID_OPERATION,
11043 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1411044 return error::kNoError;
11045 }
[email protected]94307712012-11-16 23:26:1111046 return error::kNoError;
11047}
11048
11049void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1411050 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5111051 LOCAL_SET_GL_ERROR(
11052 GL_INVALID_OPERATION,
11053 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1111054 return;
11055 }
[email protected]fb97b662013-02-20 23:02:1411056 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
[email protected]cac16542014-01-15 17:53:5111057 gpu_tracer_->End(kTraceCHROMIUM);
[email protected]94307712012-11-16 23:26:1111058}
11059
[email protected]2f143d482013-03-14 18:04:4911060void GLES2DecoderImpl::DoDrawBuffersEXT(
11061 GLsizei count, const GLenum* bufs) {
11062 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
11063 LOCAL_SET_GL_ERROR(
11064 GL_INVALID_VALUE,
11065 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
11066 return;
11067 }
11068
11069 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
11070 if (framebuffer) {
11071 for (GLsizei i = 0; i < count; ++i) {
11072 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
11073 bufs[i] != GL_NONE) {
11074 LOCAL_SET_GL_ERROR(
11075 GL_INVALID_OPERATION,
11076 "glDrawBuffersEXT",
11077 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
11078 return;
11079 }
11080 }
11081 glDrawBuffersARB(count, bufs);
11082 framebuffer->SetDrawBuffers(count, bufs);
11083 } else { // backbuffer
11084 if (count > 1 ||
11085 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
11086 LOCAL_SET_GL_ERROR(
11087 GL_INVALID_OPERATION,
11088 "glDrawBuffersEXT",
11089 "more than one buffer or bufs not GL_NONE or GL_BACK");
11090 return;
11091 }
11092 GLenum mapped_buf = bufs[0];
11093 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
11094 bufs[0] == GL_BACK) {
11095 mapped_buf = GL_COLOR_ATTACHMENT0;
11096 }
11097 glDrawBuffersARB(count, &mapped_buf);
11098 group_->set_draw_buffer(bufs[0]);
11099 }
11100}
11101
[email protected]a6a09f852014-05-23 13:05:0311102void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
11103 group_->LoseContexts(other);
11104 reset_status_ = current;
11105 current_decoder_error_ = error::kLostContext;
11106}
11107
kkinnunen337d59632014-08-26 10:19:5711108void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
11109 const GLfloat* matrix) {
11110 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11111 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11112 if (!features().chromium_path_rendering) {
11113 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11114 "glMatrixLoadfCHROMIUM",
11115 "function not available");
11116 return;
11117 }
11118
11119 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11120 ? state_.projection_matrix
11121 : state_.modelview_matrix;
11122 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
11123 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11124 // since the values of the _NV and _CHROMIUM tokens match.
11125 glMatrixLoadfEXT(matrix_mode, matrix);
11126}
11127
11128void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
11129 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11130 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11131
11132 if (!features().chromium_path_rendering) {
11133 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11134 "glMatrixLoadIdentityCHROMIUM",
11135 "function not available");
11136 return;
11137 }
11138
11139 static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
11140 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
11141 0.0f, 0.0f, 0.0f, 1.0f};
11142
11143 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11144 ? state_.projection_matrix
11145 : state_.modelview_matrix;
11146 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
11147 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11148 // since the values of the _NV and _CHROMIUM tokens match.
11149 glMatrixLoadIdentityEXT(matrix_mode);
11150}
11151
[email protected]32145a92012-12-17 09:01:5911152bool GLES2DecoderImpl::ValidateAsyncTransfer(
11153 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4711154 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5911155 GLenum target,
11156 GLint level,
11157 const void * data) {
11158 // We only support async uploads to 2D textures for now.
11159 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111160 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5911161 return false;
11162 }
11163 // We only support uploads to level zero for now.
11164 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5111165 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5911166 return false;
11167 }
11168 // A transfer buffer must be bound, even for asyncTexImage2D.
11169 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5111170 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5911171 return false;
11172 }
11173 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4711174 if (!texture_ref ||
11175 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5111176 LOCAL_SET_GL_ERROR(
11177 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911178 function_name, "transfer already in progress");
11179 return false;
11180 }
11181 return true;
11182}
11183
[email protected]e3c4a9ab2014-03-31 09:07:0211184base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
11185 uint32 async_upload_token,
11186 uint32 sync_data_shm_id,
11187 uint32 sync_data_shm_offset) {
11188 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2511189 if (!buffer.get() ||
11190 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0211191 return base::Closure();
11192
11193 AsyncMemoryParams mem_params(buffer,
11194 sync_data_shm_offset,
11195 sizeof(AsyncUploadSync));
11196
11197 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
11198 new AsyncUploadTokenCompletionObserver(async_upload_token));
11199
11200 return base::Bind(
11201 &AsyncPixelTransferManager::AsyncNotifyCompletion,
11202 base::Unretained(GetAsyncPixelTransferManager()),
11203 mem_params,
11204 observer);
11205}
11206
[email protected]69023942012-11-30 19:57:1611207error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411208 uint32 immediate_data_size,
11209 const void* cmd_data) {
11210 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
11211 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611212 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611213 GLenum target = static_cast<GLenum>(c.target);
11214 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4411215 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1611216 GLsizei width = static_cast<GLsizei>(c.width);
11217 GLsizei height = static_cast<GLsizei>(c.height);
11218 GLint border = static_cast<GLint>(c.border);
11219 GLenum format = static_cast<GLenum>(c.format);
11220 GLenum type = static_cast<GLenum>(c.type);
11221 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
11222 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
11223 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0211224 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11225 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11226 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11227
11228 base::ScopedClosureRunner scoped_completion_callback;
11229 if (async_upload_token) {
11230 base::Closure completion_closure =
11231 AsyncUploadTokenCompletionClosure(async_upload_token,
11232 sync_data_shm_id,
11233 sync_data_shm_offset);
11234 if (completion_closure.is_null())
11235 return error::kInvalidArguments;
11236
11237 scoped_completion_callback.Reset(completion_closure);
11238 }
[email protected]32145a92012-12-17 09:01:5911239
11240 // TODO(epenner): Move this and copies of this memory validation
11241 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1611242 if (!GLES2Util::ComputeImageDataSizes(
11243 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
11244 NULL)) {
11245 return error::kOutOfBounds;
11246 }
11247 const void* pixels = NULL;
11248 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
11249 pixels = GetSharedMemoryAs<const void*>(
11250 pixels_shm_id, pixels_shm_offset, pixels_size);
11251 if (!pixels) {
11252 return error::kOutOfBounds;
11253 }
11254 }
11255
[email protected]c986af502013-08-14 01:04:4411256 TextureManager::DoTextImage2DArguments args = {
11257 target, level, internal_format, width, height, border, format, type,
11258 pixels, pixels_size};
11259 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5911260 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4411261 if (!texture_manager()->ValidateTexImage2D(
11262 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5911263 return error::kNoError;
11264 }
11265
11266 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4911267 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911268 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711269 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911270 return error::kNoError;
11271
11272 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0711273 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5111274 LOCAL_SET_GL_ERROR(
11275 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911276 "glAsyncTexImage2DCHROMIUM", "already defined");
11277 return error::kNoError;
11278 }
11279
[email protected]7989c9e2013-01-23 06:39:2611280 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5111281 LOCAL_SET_GL_ERROR(
11282 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611283 return error::kNoError;
11284 }
11285
[email protected]5b3a8e02013-03-13 05:36:4411286 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3811287 AsyncTexImage2DParams tex_params = {
11288 target, level, static_cast<GLenum>(internal_format),
11289 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1211290 AsyncMemoryParams mem_params(
11291 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5911292
[email protected]5b3a8e02013-03-13 05:36:4411293 // Set up the async state if needed, and make the texture
11294 // immutable so the async state stays valid. The level info
11295 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1811296 AsyncPixelTransferDelegate* delegate =
11297 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
11298 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4411299 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5911300
[email protected]896425e2013-06-12 17:27:1811301 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4411302 tex_params,
11303 mem_params,
11304 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4911305 // The callback is only invoked if the transfer delegate still
11306 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4411307 // ownership that both of these pointers are valid.
11308 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4911309 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4411310 tex_params));
[email protected]f598f422012-12-07 08:30:0311311 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611312}
11313
11314error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411315 uint32 immediate_data_size,
11316 const void* cmd_data) {
11317 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
11318 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611319 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611320 GLenum target = static_cast<GLenum>(c.target);
11321 GLint level = static_cast<GLint>(c.level);
11322 GLint xoffset = static_cast<GLint>(c.xoffset);
11323 GLint yoffset = static_cast<GLint>(c.yoffset);
11324 GLsizei width = static_cast<GLsizei>(c.width);
11325 GLsizei height = static_cast<GLsizei>(c.height);
11326 GLenum format = static_cast<GLenum>(c.format);
11327 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0211328 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11329 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11330 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11331
11332 base::ScopedClosureRunner scoped_completion_callback;
11333 if (async_upload_token) {
11334 base::Closure completion_closure =
11335 AsyncUploadTokenCompletionClosure(async_upload_token,
11336 sync_data_shm_id,
11337 sync_data_shm_offset);
11338 if (completion_closure.is_null())
11339 return error::kInvalidArguments;
11340
11341 scoped_completion_callback.Reset(completion_closure);
11342 }
[email protected]32145a92012-12-17 09:01:5911343
11344 // TODO(epenner): Move this and copies of this memory validation
11345 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1611346 uint32 data_size;
11347 if (!GLES2Util::ComputeImageDataSizes(
11348 width, height, format, type, state_.unpack_alignment, &data_size,
11349 NULL, NULL)) {
11350 return error::kOutOfBounds;
11351 }
11352 const void* pixels = GetSharedMemoryAs<const void*>(
11353 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5911354
11355 // All the normal glTexSubImage2D validation.
11356 error::Error error = error::kNoError;
11357 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
11358 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
11359 return error;
[email protected]69023942012-11-30 19:57:1611360 }
11361
[email protected]32145a92012-12-17 09:01:5911362 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4411363 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11364 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911365 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911366 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711367 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911368 return error::kNoError;
11369
11370 // Guarantee async textures are always 'cleared' as follows:
11371 // - AsyncTexImage2D can not redefine an existing texture
11372 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
11373 // - AsyncTexSubImage2D clears synchronously if not already cleared.
11374 // - Textures become immutable after an async call.
11375 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0711376 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4911377 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
11378 target, level)) {
[email protected]ab09b612013-03-11 22:11:5111379 LOCAL_SET_GL_ERROR(
11380 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2511381 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5911382 return error::kNoError;
11383 }
11384 }
11385
[email protected]5b3a8e02013-03-13 05:36:4411386 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0311387 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5911388 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1211389 AsyncMemoryParams mem_params(
11390 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1811391 AsyncPixelTransferDelegate* delegate =
11392 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11393 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4411394 // TODO(epenner): We may want to enforce exclusive use
11395 // of async APIs in which case this should become an error,
11396 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0311397 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4411398 0, 0, 0, 0, 0, 0};
11399 texture->GetLevelSize(target, level, &define_params.width,
11400 &define_params.height);
11401 texture->GetLevelType(target, level, &define_params.type,
11402 &define_params.internal_format);
11403 // Set up the async state if needed, and make the texture
11404 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1811405 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4711406 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4411407 texture->SetImmutable(true);
11408 }
11409
[email protected]896425e2013-06-12 17:27:1811410 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5911411 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611412}
11413
[email protected]a00c1f742013-03-05 17:02:1611414error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411415 uint32 immediate_data_size,
11416 const void* cmd_data) {
11417 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
11418 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1611419 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11420 GLenum target = static_cast<GLenum>(c.target);
11421
11422 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111423 LOCAL_SET_GL_ERROR(
11424 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1611425 return error::kNoError;
11426 }
[email protected]c986af502013-08-14 01:04:4411427 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11428 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911429 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111430 LOCAL_SET_GL_ERROR(
11431 GL_INVALID_OPERATION,
11432 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1611433 return error::kNoError;
11434 }
[email protected]896425e2013-06-12 17:27:1811435 AsyncPixelTransferDelegate* delegate =
11436 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11437 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4911438 LOCAL_SET_GL_ERROR(
11439 GL_INVALID_OPERATION,
11440 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
11441 return error::kNoError;
11442 }
[email protected]896425e2013-06-12 17:27:1811443 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0911444 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1611445 return error::kNoError;
11446}
11447
[email protected]e3c4a9ab2014-03-31 09:07:0211448error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411449 uint32 immediate_data_size,
11450 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0211451 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11452
11453 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
11454 ProcessFinishedAsyncTransfers();
11455 return error::kNoError;
11456}
11457
[email protected]91c94eb2013-10-22 10:32:5411458void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
11459 TextureRef* texture_ref) {
11460 Texture* texture = texture_ref->texture();
11461 DoDidUseTexImageIfNeeded(texture, texture->target());
11462}
11463
oetuaho37cc50e2014-10-31 11:19:2011464void GLES2DecoderImpl::OnContextLostError() {
11465 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
11466}
11467
[email protected]828a3932014-04-02 14:43:1311468void GLES2DecoderImpl::OnOutOfMemoryError() {
11469 if (lose_context_when_out_of_memory_) {
11470 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]828a3932014-04-02 14:43:1311471 }
11472}
11473
[email protected]96449d2c2009-11-25 00:01:3211474// Include the auto-generated part of this file. We split this because it means
11475// we can easily edit the non-auto generated parts right here in this file
11476// instead of having to edit some template or the code generator.
11477#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
11478
11479} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2511480} // namespace gpu