blob: d119e7f26810cb62e7a685975eb155e1b103df6d [file] [log] [blame]
[email protected]529c6672012-01-04 02:18:261// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]96449d2c2009-11-25 00:01:322// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]8a837bb2010-01-05 00:21:245#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
[email protected]74470702010-01-06 18:51:166
7#include <stdio.h>
8
[email protected]1aef98132010-02-23 18:00:079#include <algorithm>
mateuszs3371ab02015-04-24 13:20:2310#include <cmath>
[email protected]f39f4b3f2010-05-12 17:04:0811#include <list>
[email protected]96449d2c2009-11-25 00:01:3212#include <map>
dcastagna504d45c2015-04-06 19:30:3913#include <queue>
[email protected]94307712012-11-16 23:26:1114#include <stack>
[email protected]f39f4b3f2010-05-12 17:04:0815#include <string>
16#include <vector>
[email protected]5a6db6c2010-04-22 18:32:0617
[email protected]00eb49a2010-08-12 20:46:5718#include "base/at_exit.h"
[email protected]9d37f062011-11-22 01:24:5219#include "base/bind.h"
[email protected]e3c4a9ab2014-03-31 09:07:0220#include "base/callback_helpers.h"
[email protected]e844ae22012-01-14 03:36:2621#include "base/command_line.h"
[email protected]3b63f8f42011-03-28 01:54:1522#include "base/memory/scoped_ptr.h"
[email protected]e3c4a9ab2014-03-31 09:07:0223#include "base/numerics/safe_math.h"
[email protected]f4390962013-06-11 07:29:2224#include "base/strings/string_number_conversions.h"
[email protected]6d668892013-12-04 21:37:1225#include "base/strings/string_split.h"
primiano05dadf012015-01-28 13:10:3226#include "base/trace_event/trace_event.h"
27#include "base/trace_event/trace_event_synthetic_delay.h"
[email protected]d37231fa2010-04-09 21:16:0228#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3229#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2230#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3231#include "gpu/command_buffer/common/gles2_cmd_format.h"
32#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1033#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5134#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2235#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
36#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5037#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3238#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5039#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2440#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5041#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1142#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5843#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3244#include "gpu/command_buffer/service/gl_utils.h"
sievers2384f2b2014-11-18 02:10:3545#include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h"
[email protected]43410e92012-04-20 17:06:2846#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4647#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1348#include "gpu/command_buffer/service/gpu_state_tracer.h"
[email protected]e844ae22012-01-14 03:36:2649#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1450#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3751#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5952#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2553#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4754#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5355#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5856#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4757#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4558#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0459#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]a93bb842010-02-16 23:03:4760#include "gpu/command_buffer/service/texture_manager.h"
orglofchcad5a6742014-11-07 19:51:1261#include "gpu/command_buffer/service/valuebuffer_manager.h"
[email protected]944b62f32012-09-27 02:20:4662#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2263#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]6896d7f2014-04-28 20:24:1564#include "third_party/smhasher/src/City.h"
[email protected]5a36dc132013-07-23 23:17:5565#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3766#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2767#include "ui/gl/gl_implementation.h"
68#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2769
[email protected]e51bdf32011-11-23 22:21:4670#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:5371#include <IOSurface/IOSurfaceAPI.h>
72// Note that this must be included after gl_bindings.h to avoid conflicts.
73#include <OpenGL/CGLIOSurface.h>
[email protected]e51bdf32011-11-23 22:21:4674#endif
[email protected]de17df392010-04-23 21:09:4175
[email protected]6eb775352013-08-27 05:57:1676#if defined(OS_WIN)
77#include "base/win/win_util.h"
78#endif
79
[email protected]a7a27ace2009-12-12 00:11:2580namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3281namespace gles2 {
82
[email protected]f0d74742011-10-03 16:31:0483namespace {
[email protected]693ca512012-11-13 18:09:1384
dongseong.hwang46305b12015-03-05 18:28:0485const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
86const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
87const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
88const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
89
90const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
91 0.0f, 1.0f, 0.0f, 0.0f,
92 0.0f, 0.0f, 1.0f, 0.0f,
93 0.0f, 0.0f, 0.0f, 1.0f};
[email protected]693ca512012-11-13 18:09:1394
[email protected]448e459e2013-06-12 17:00:4195static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
96 GLint rangeMax,
97 GLint precision) {
98 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
99}
100
[email protected]8dc1bf92013-03-12 03:58:21101static void GetShaderPrecisionFormatImpl(GLenum shader_type,
102 GLenum precision_type,
dcastagna504d45c2015-04-06 19:30:39103 GLint* range, GLint* precision) {
[email protected]8dc1bf92013-03-12 03:58:21104 switch (precision_type) {
105 case GL_LOW_INT:
106 case GL_MEDIUM_INT:
107 case GL_HIGH_INT:
108 // These values are for a 32-bit twos-complement integer format.
109 range[0] = 31;
110 range[1] = 30;
111 *precision = 0;
112 break;
113 case GL_LOW_FLOAT:
114 case GL_MEDIUM_FLOAT:
115 case GL_HIGH_FLOAT:
116 // These values are for an IEEE single-precision floating-point format.
117 range[0] = 127;
118 range[1] = 127;
119 *precision = 23;
120 break;
121 default:
122 NOTREACHED();
123 break;
124 }
125
[email protected]8af4d5e2013-03-15 23:55:33126 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
127 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21128 // This function is sometimes defined even though it's really just
129 // a stub, so we need to set range and precision as if it weren't
130 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44131 // On Mac OS with some GPUs, calling this generates a
132 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
133 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21134 glGetShaderPrecisionFormat(shader_type, precision_type,
135 range, precision);
[email protected]448e459e2013-06-12 17:00:41136
137 // TODO(brianderson): Make the following official workarounds.
138
139 // Some drivers have bugs where they report the ranges as a negative number.
140 // Taking the absolute value here shouldn't hurt because negative numbers
141 // aren't expected anyway.
142 range[0] = abs(range[0]);
143 range[1] = abs(range[1]);
144
145 // If the driver reports a precision for highp float that isn't actually
146 // highp, don't pretend like it's supported because shader compilation will
147 // fail anyway.
148 if (precision_type == GL_HIGH_FLOAT &&
149 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
150 range[0] = 0;
151 range[1] = 0;
152 *precision = 0;
153 }
[email protected]8dc1bf92013-03-12 03:58:21154 }
155}
156
[email protected]d286ebbc2014-07-03 17:19:10157static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
158 switch (plane_transform) {
159 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
160 return gfx::OVERLAY_TRANSFORM_NONE;
161 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
162 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
163 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
164 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
165 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
166 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
167 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
168 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
169 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
170 return gfx::OVERLAY_TRANSFORM_ROTATE_270;
171 default:
172 return gfx::OVERLAY_TRANSFORM_INVALID;
173 }
174}
175
[email protected]b04e24c2013-01-08 18:35:25176} // namespace
[email protected]f0d74742011-10-03 16:31:04177
[email protected]6217d392010-03-25 22:08:35178class GLES2DecoderImpl;
179
[email protected]ab09b612013-03-11 22:11:51180// Local versions of the SET_GL_ERROR macros
181#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50182 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51183#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50184 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
185 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51186#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50187 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
188 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51189#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50190 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
191 function_name)
[email protected]ab09b612013-03-11 22:11:51192#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50193 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51194#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50195 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51196#define LOCAL_PERFORMANCE_WARNING(msg) \
197 PerformanceWarning(__FILE__, __LINE__, msg)
198#define LOCAL_RENDER_WARNING(msg) \
199 RenderWarning(__FILE__, __LINE__, msg)
200
[email protected]07f54fcc2009-12-22 02:46:30201// Check that certain assumptions the code makes are true. There are places in
202// the code where shared memory is passed direclty to GL. Example, glUniformiv,
203// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
204// a few others) are 32bits. If they are not 32bits the code will have to change
205// to call those GL functions with service side memory and then copy the results
206// to shared memory, converting the sizes.
mostynb7f032092014-12-20 00:36:44207static_assert(sizeof(GLint) == sizeof(uint32), // NOLINT
208 "GLint should be the same size as uint32");
209static_assert(sizeof(GLsizei) == sizeof(uint32), // NOLINT
210 "GLsizei should be the same size as uint32");
211static_assert(sizeof(GLfloat) == sizeof(float), // NOLINT
212 "GLfloat should be the same size as float");
[email protected]07f54fcc2009-12-22 02:46:30213
[email protected]43f28f832010-02-03 02:28:48214// TODO(kbr): the use of this anonymous namespace core dumps the
215// linker on Mac OS X 10.6 when the symbol ordering file is used
216// namespace {
[email protected]96449d2c2009-11-25 00:01:32217
218// Returns the address of the first byte after a struct.
219template <typename T>
220const void* AddressAfterStruct(const T& pod) {
221 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
222}
223
[email protected]07f54fcc2009-12-22 02:46:30224// Returns the address of the frst byte after the struct or NULL if size >
225// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32226template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30227RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
228 uint32 size,
229 uint32 immediate_data_size) {
230 return (size <= immediate_data_size) ?
231 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
232 NULL;
[email protected]96449d2c2009-11-25 00:01:32233}
234
[email protected]07f54fcc2009-12-22 02:46:30235// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18236bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32237 GLuint count,
238 size_t size,
[email protected]a76b0052010-03-05 00:33:18239 unsigned int elements_per_unit,
240 uint32* dst) {
241 uint32 value;
242 if (!SafeMultiplyUint32(count, size, &value)) {
243 return false;
244 }
245 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
246 return false;
247 }
248 *dst = value;
249 return true;
[email protected]96449d2c2009-11-25 00:01:32250}
251
[email protected]258a3313f2011-10-18 20:13:57252// Return true if a character belongs to the ASCII subset as defined in
253// GLSL ES 1.0 spec section 3.1.
254static bool CharacterIsValidForGLES(unsigned char c) {
255 // Printing characters are valid except " $ ` @ \ ' DEL.
256 if (c >= 32 && c <= 126 &&
257 c != '"' &&
258 c != '$' &&
259 c != '`' &&
260 c != '@' &&
261 c != '\\' &&
262 c != '\'') {
263 return true;
264 }
265 // Horizontal tab, line feed, vertical tab, form feed, carriage return
266 // are also valid.
267 if (c >= 9 && c <= 13) {
268 return true;
269 }
270
271 return false;
272}
273
274static bool StringIsValidForGLES(const char* str) {
275 for (; *str; ++str) {
276 if (!CharacterIsValidForGLES(*str)) {
277 return false;
278 }
279 }
280 return true;
281}
282
[email protected]6217d392010-03-25 22:08:35283// This class prevents any GL errors that occur when it is in scope from
284// being reported to the client.
285class ScopedGLErrorSuppressor {
286 public:
[email protected]ab09b612013-03-11 22:11:51287 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30288 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35289 ~ScopedGLErrorSuppressor();
290 private:
[email protected]ab09b612013-03-11 22:11:51291 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30292 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35293 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
294};
295
[email protected]2b10c02d2014-01-29 16:43:02296// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35297// object goes out of scope. Also temporarily switches to using active texture
298// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02299class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35300 public:
[email protected]00c2cf92014-03-14 00:08:37301 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02302 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35303
304 private:
[email protected]ce296892013-10-24 22:04:36305 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02306 GLenum target_;
307 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35308};
309
310// Temporarily changes a decoder's bound render buffer and restore it when this
311// object goes out of scope.
312class ScopedRenderBufferBinder {
313 public:
[email protected]00c2cf92014-03-14 00:08:37314 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35315 ~ScopedRenderBufferBinder();
316
317 private:
[email protected]18e785a2013-10-09 03:29:41318 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35319 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
320};
321
322// Temporarily changes a decoder's bound frame buffer and restore it when this
323// object goes out of scope.
324class ScopedFrameBufferBinder {
325 public:
[email protected]00c2cf92014-03-14 00:08:37326 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35327 ~ScopedFrameBufferBinder();
328
329 private:
330 GLES2DecoderImpl* decoder_;
331 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
332};
333
[email protected]34ff8b0c2010-10-01 20:06:02334// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52335// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27336// if it is bound or enforce_internal_framebuffer is true. If internal is
337// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02338class ScopedResolvedFrameBufferBinder {
339 public:
[email protected]00c2cf92014-03-14 00:08:37340 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
341 bool enforce_internal_framebuffer,
342 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02343 ~ScopedResolvedFrameBufferBinder();
344
345 private:
346 GLES2DecoderImpl* decoder_;
347 bool resolve_and_bind_;
348 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
349};
350
[email protected]00c2cf92014-03-14 00:08:37351class ScopedModifyPixels {
352 public:
353 explicit ScopedModifyPixels(TextureRef* ref);
354 ~ScopedModifyPixels();
355
356 private:
357 TextureRef* ref_;
358};
359
360ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
361 if (ref_)
362 ref_->texture()->OnWillModifyPixels();
363}
364
365ScopedModifyPixels::~ScopedModifyPixels() {
366 if (ref_)
367 ref_->texture()->OnDidModifyPixels();
368}
369
370class ScopedRenderTo {
371 public:
372 explicit ScopedRenderTo(Framebuffer* framebuffer);
373 ~ScopedRenderTo();
374
375 private:
376 const Framebuffer* framebuffer_;
377};
378
379ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
380 : framebuffer_(framebuffer) {
381 if (framebuffer)
382 framebuffer_->OnWillRenderTo();
383}
384
385ScopedRenderTo::~ScopedRenderTo() {
386 if (framebuffer_)
387 framebuffer_->OnDidRenderTo();
388}
389
[email protected]6217d392010-03-25 22:08:35390// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35391class BackTexture {
[email protected]6217d392010-03-25 22:08:35392 public:
[email protected]ce296892013-10-24 22:04:36393 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35394 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35395
396 // Create a new render texture.
397 void Create();
398
399 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09400 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35401
402 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58403 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35404
405 // Destroy the render texture. This must be explicitly called before
406 // destroying this object.
407 void Destroy();
408
[email protected]97872062010-11-03 19:07:05409 // Invalidate the texture. This can be used when a context is lost and it is
410 // not possible to make it current in order to free the resource.
411 void Invalidate();
412
[email protected]6217d392010-03-25 22:08:35413 GLuint id() const {
414 return id_;
415 }
416
[email protected]d37231fa2010-04-09 21:16:02417 gfx::Size size() const {
418 return size_;
419 }
420
[email protected]6217d392010-03-25 22:08:35421 private:
[email protected]ff6493f2012-07-31 19:52:25422 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36423 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48424 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35425 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02426 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35427 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35428};
429
430// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35431class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35432 public:
[email protected]d5a28e452013-10-10 01:01:40433 explicit BackRenderbuffer(
434 RenderbufferManager* renderbuffer_manager,
435 MemoryTracker* memory_tracker,
436 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35437 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35438
439 // Create a new render buffer.
440 void Create();
441
442 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18443 bool AllocateStorage(const FeatureInfo* feature_info,
444 const gfx::Size& size,
445 GLenum format,
446 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35447
448 // Destroy the render buffer. This must be explicitly called before destroying
449 // this object.
450 void Destroy();
451
[email protected]97872062010-11-03 19:07:05452 // Invalidate the render buffer. This can be used when a context is lost and
453 // it is not possible to make it current in order to free the resource.
454 void Invalidate();
455
[email protected]6217d392010-03-25 22:08:35456 GLuint id() const {
457 return id_;
458 }
459
460 private:
[email protected]d5a28e452013-10-10 01:01:40461 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25462 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40463 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48464 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35465 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35466 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35467};
468
469// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35470class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35471 public:
[email protected]ed9f9cd2013-02-27 21:12:35472 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
473 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35474
475 // Create a new frame buffer.
476 void Create();
477
478 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35479 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35480
[email protected]b9363b22010-06-09 22:06:15481 // Attach a render buffer to a frame buffer. Note that this unbinds any
482 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35483 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35484
[email protected]6217d392010-03-25 22:08:35485 // Destroy the frame buffer. This must be explicitly called before destroying
486 // this object.
487 void Destroy();
488
[email protected]97872062010-11-03 19:07:05489 // Invalidate the frame buffer. This can be used when a context is lost and it
490 // is not possible to make it current in order to free the resource.
491 void Invalidate();
492
[email protected]6217d392010-03-25 22:08:35493 // See glCheckFramebufferStatusEXT.
494 GLenum CheckStatus();
495
496 GLuint id() const {
497 return id_;
498 }
499
500 private:
501 GLES2DecoderImpl* decoder_;
502 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35503 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35504};
[email protected]34ff8b0c2010-10-01 20:06:02505
[email protected]5a36dc132013-07-23 23:17:55506struct FenceCallback {
dcastagna504d45c2015-04-06 19:30:39507 FenceCallback()
[email protected]5a36dc132013-07-23 23:17:55508 : fence(gfx::GLFence::Create()) {
509 DCHECK(fence);
510 }
[email protected]5a36dc132013-07-23 23:17:55511 std::vector<base::Closure> callbacks;
512 scoped_ptr<gfx::GLFence> fence;
513};
514
[email protected]e3c4a9ab2014-03-31 09:07:02515class AsyncUploadTokenCompletionObserver
516 : public AsyncPixelTransferCompletionObserver {
517 public:
518 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
519 : async_upload_token_(async_upload_token) {
520 }
521
dcheng1f4d1d72014-10-21 16:21:58522 void DidComplete(const AsyncMemoryParams& mem_params) override {
dcheng6ef3c5552014-08-30 05:34:19523 DCHECK(mem_params.buffer().get());
[email protected]e3c4a9ab2014-03-31 09:07:02524 void* data = mem_params.GetDataAddress();
525 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
526 sync->SetAsyncUploadToken(async_upload_token_);
527 }
528
529 private:
dcheng1f4d1d72014-10-21 16:21:58530 ~AsyncUploadTokenCompletionObserver() override {}
[email protected]e3c4a9ab2014-03-31 09:07:02531
532 uint32 async_upload_token_;
533
534 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
535};
536
[email protected]43f28f832010-02-03 02:28:48537// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32538
[email protected]efc87712014-07-09 00:22:47539// static
540const unsigned int GLES2Decoder::kDefaultStencilMask =
541 static_cast<unsigned int>(-1);
542
[email protected]ddb1e5a2010-12-13 20:10:45543bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
544 uint32* service_texture_id) {
545 return false;
546}
547
[email protected]a3ded6d2010-10-19 06:44:39548GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06549 : initialized_(false),
550 debug_(false),
zmo84c08202014-11-23 15:28:40551 log_commands_(false),
552 unsafe_es3_apis_enabled_(false) {
[email protected]96449d2c2009-11-25 00:01:32553}
554
[email protected]3916c97e2010-02-25 03:20:50555GLES2Decoder::~GLES2Decoder() {
556}
557
[email protected]cac16542014-01-15 17:53:51558void GLES2Decoder::BeginDecoding() {}
559
560void GLES2Decoder::EndDecoding() {}
561
[email protected]f39f4b3f2010-05-12 17:04:08562// This class implements GLES2Decoder so we don't have to expose all the GLES2
563// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54564class GLES2DecoderImpl : public GLES2Decoder,
[email protected]828a3932014-04-02 14:43:13565 public FramebufferManager::TextureDetachObserver,
566 public ErrorStateClient {
[email protected]f39f4b3f2010-05-12 17:04:08567 public:
[email protected]aa7666122011-09-02 19:45:52568 explicit GLES2DecoderImpl(ContextGroup* group);
dcheng1f4d1d72014-10-21 16:21:58569 ~GLES2DecoderImpl() override;
[email protected]f39f4b3f2010-05-12 17:04:08570
[email protected]96449d2c2009-11-25 00:01:32571 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58572 Error DoCommand(unsigned int command,
573 unsigned int arg_count,
574 const void* args) override;
[email protected]96449d2c2009-11-25 00:01:32575
dcheng1f4d1d72014-10-21 16:21:58576 error::Error DoCommands(unsigned int num_commands,
577 const void* buffer,
578 int num_entries,
579 int* entries_processed) override;
vmiura8266ca72014-09-09 21:37:00580
vmiura1c2b1de2014-09-19 19:03:24581 template <bool DebugImpl>
582 error::Error DoCommandsImpl(unsigned int num_commands,
583 const void* buffer,
584 int num_entries,
585 int* entries_processed);
586
[email protected]96449d2c2009-11-25 00:01:32587 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58588 const char* GetCommandName(unsigned int command_id) const override;
[email protected]96449d2c2009-11-25 00:01:32589
590 // Overridden from GLES2Decoder.
dcheng1f4d1d72014-10-21 16:21:58591 bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
592 const scoped_refptr<gfx::GLContext>& context,
593 bool offscreen,
dongseong.hwang4c04a162015-03-04 07:27:33594 const gfx::Size& offscreen_size,
dcheng1f4d1d72014-10-21 16:21:58595 const DisallowedFeatures& disallowed_features,
596 const std::vector<int32>& attribs) override;
597 void Destroy(bool have_context) override;
598 void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
599 void ProduceFrontBuffer(const Mailbox& mailbox) override;
600 bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
[email protected]9a5afa432011-07-22 18:16:39601 void UpdateParentTextureInfo();
dcheng1f4d1d72014-10-21 16:21:58602 bool MakeCurrent() override;
603 GLES2Util* GetGLES2Util() override { return &util_; }
604 gfx::GLContext* GetGLContext() override { return context_.get(); }
605 ContextGroup* GetContextGroup() override { return group_.get(); }
606 Capabilities GetCapabilities() override;
607 void RestoreState(const ContextState* prev_state) override;
[email protected]29a4d902013-02-26 20:18:06608
dcheng1f4d1d72014-10-21 16:21:58609 void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); }
610 void RestoreAllTextureUnitBindings(
mohan.reddy5e1b8952014-10-08 01:38:17611 const ContextState* prev_state) const override {
[email protected]5baa86bc2014-01-16 04:33:16612 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55613 }
dcheng1f4d1d72014-10-21 16:21:58614 void RestoreActiveTextureUnitBinding(unsigned int target) const override {
[email protected]4b2d2b262014-03-21 22:05:27615 state_.RestoreActiveTextureUnitBinding(target);
616 }
dcheng1f4d1d72014-10-21 16:21:58617 void RestoreBufferBindings() const override {
[email protected]29a4d902013-02-26 20:18:06618 state_.RestoreBufferBindings();
619 }
dcheng1f4d1d72014-10-21 16:21:58620 void RestoreGlobalState() const override { state_.RestoreGlobalState(NULL); }
621 void RestoreProgramBindings() const override {
[email protected]29a4d902013-02-26 20:18:06622 state_.RestoreProgramBindings();
623 }
dcheng1f4d1d72014-10-21 16:21:58624 void RestoreTextureUnitBindings(unsigned unit) const override {
[email protected]5baa86bc2014-01-16 04:33:16625 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06626 }
dcheng1f4d1d72014-10-21 16:21:58627 void RestoreFramebufferBindings() const override;
628 void RestoreRenderbufferBindings() override;
629 void RestoreTextureState(unsigned service_id) const override;
[email protected]29a4d902013-02-26 20:18:06630
dcheng1f4d1d72014-10-21 16:21:58631 void ClearAllAttributes() const override;
632 void RestoreAllAttributes() const override;
[email protected]cd2ef752014-02-12 23:16:03633
dcheng1f4d1d72014-10-21 16:21:58634 QueryManager* GetQueryManager() override { return query_manager_.get(); }
635 VertexArrayManager* GetVertexArrayManager() override {
[email protected]944b62f32012-09-27 02:20:46636 return vertex_array_manager_.get();
637 }
dcheng1f4d1d72014-10-21 16:21:58638 ImageManager* GetImageManager() override { return image_manager_.get(); }
orglofch33edd842014-12-03 05:32:15639
640 ValuebufferManager* GetValuebufferManager() override {
641 return valuebuffer_manager();
642 }
643
revemancc241eb2014-11-11 03:30:37644 bool ProcessPendingQueries(bool did_finish) override;
orglofch33edd842014-12-03 05:32:15645
dcheng1f4d1d72014-10-21 16:21:58646 bool HasMoreIdleWork() override;
647 void PerformIdleWork() override;
[email protected]43f28f832010-02-03 02:28:48648
dcheng1f4d1d72014-10-21 16:21:58649 void WaitForReadPixels(base::Closure callback) override;
[email protected]5a36dc132013-07-23 23:17:55650
dcheng1f4d1d72014-10-21 16:21:58651 void SetResizeCallback(
mohan.reddy5e1b8952014-10-08 01:38:17652 const base::Callback<void(gfx::Size, float)>& callback) override;
[email protected]22f320a2011-08-30 01:17:00653
dcheng1f4d1d72014-10-21 16:21:58654 Logger* GetLogger() override;
[email protected]cac16542014-01-15 17:53:51655
dcheng1f4d1d72014-10-21 16:21:58656 void BeginDecoding() override;
657 void EndDecoding() override;
[email protected]cac16542014-01-15 17:53:51658
dcheng1f4d1d72014-10-21 16:21:58659 ErrorState* GetErrorState() override;
660 const ContextState* GetContextState() override { return &state_; }
[email protected]1d82e822013-04-10 21:32:32661
dcheng1f4d1d72014-10-21 16:21:58662 void SetShaderCacheCallback(const ShaderCacheCallback& callback) override;
663 void SetWaitSyncPointCallback(const WaitSyncPointCallback& callback) override;
[email protected]22f320a2011-08-30 01:17:00664
dcheng1f4d1d72014-10-21 16:21:58665 AsyncPixelTransferManager* GetAsyncPixelTransferManager() override;
666 void ResetAsyncPixelTransferManagerForTest() override;
667 void SetAsyncPixelTransferManagerForTest(
mohan.reddy5e1b8952014-10-08 01:38:17668 AsyncPixelTransferManager* manager) override;
dcheng1f4d1d72014-10-21 16:21:58669 void SetIgnoreCachedStateForTest(bool ignore) override;
[email protected]69a8701e2013-03-07 21:31:09670 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59671
dcheng1f4d1d72014-10-21 16:21:58672 bool GetServiceTextureId(uint32 client_texture_id,
673 uint32* service_texture_id) override;
[email protected]43f28f832010-02-03 02:28:48674
dcheng1f4d1d72014-10-21 16:21:58675 uint32 GetTextureUploadCount() override;
676 base::TimeDelta GetTotalTextureUploadTime() override;
677 base::TimeDelta GetTotalProcessingCommandsTime() override;
678 void AddProcessingCommandsTime(base::TimeDelta) override;
[email protected]63b465922012-09-06 02:04:52679
[email protected]8e3e0662010-08-23 18:46:30680 // Restores the current state to the user's settings.
681 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30682
[email protected]297ca1c2011-06-20 23:08:46683 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
684 void ApplyDirtyState();
685
686 // These check the state of the currently bound framebuffer or the
687 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54688 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
689 // check with all attached and enabled color attachments.
690 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46691 bool BoundFramebufferHasDepthAttachment();
692 bool BoundFramebufferHasStencilAttachment();
693
dcheng1f4d1d72014-10-21 16:21:58694 error::ContextLostReason GetContextLostReason() override;
[email protected]38d139d2011-07-14 00:38:43695
[email protected]91c94eb2013-10-22 10:32:54696 // Overridden from FramebufferManager::TextureDetachObserver:
dcheng1f4d1d72014-10-21 16:21:58697 void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) override;
[email protected]91c94eb2013-10-22 10:32:54698
[email protected]828a3932014-04-02 14:43:13699 // Overriden from ErrorStateClient.
oetuaho37cc50e2014-10-31 11:19:20700 void OnContextLostError() override;
dcheng1f4d1d72014-10-21 16:21:58701 void OnOutOfMemoryError() override;
[email protected]828a3932014-04-02 14:43:13702
[email protected]8875a5f2014-06-27 08:33:47703 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
704 void EnsureRenderbufferBound();
705
[email protected]f42f05b2013-11-15 21:46:18706 // Helpers to facilitate calling into compatible extensions.
707 static void RenderbufferStorageMultisampleHelper(
708 const FeatureInfo* feature_info,
709 GLenum target,
710 GLsizei samples,
711 GLenum internal_format,
712 GLsizei width,
713 GLsizei height);
714
715 void BlitFramebufferHelper(GLint srcX0,
716 GLint srcY0,
717 GLint srcX1,
718 GLint srcY1,
719 GLint dstX0,
720 GLint dstY0,
721 GLint dstX1,
722 GLint dstY1,
723 GLbitfield mask,
724 GLenum filter);
[email protected]345ba902013-11-14 21:39:00725
[email protected]96449d2c2009-11-25 00:01:32726 private:
[email protected]70d34263c2013-01-09 00:27:45727 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02728 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35729 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35730
[email protected]c2f8c8402010-12-06 18:07:24731 // Initialize or re-initialize the shader translator.
732 bool InitializeShaderTranslator();
733
[email protected]302ce6d2011-07-07 23:28:11734 void UpdateCapabilities();
735
[email protected]ae51d192010-04-27 00:48:03736 // Helpers for the glGen and glDelete functions.
737 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
738 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
739 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
740 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
741 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
742 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
743 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
744 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
orglofchcad5a6742014-11-07 19:51:12745 bool GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
746 void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53747 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
748 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46749 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
750 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47751
[email protected]e3c4a9ab2014-03-31 09:07:02752 // Helper for async upload token completion notification callback.
753 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
754 uint32 sync_data_shm_id,
755 uint32 sync_data_shm_offset);
756
757
758
[email protected]70d34263c2013-01-09 00:27:45759 // Workarounds
760 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51761 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45762
sieversfbaa5dc2015-04-28 00:45:31763 error::ContextLostReason GetContextLostReasonFromResetStatus(
764 GLenum reset_status) const;
765
[email protected]3916c97e2010-02-25 03:20:50766 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50767 BufferManager* buffer_manager() {
768 return group_->buffer_manager();
769 }
770
[email protected]a25fa872010-03-25 02:57:58771 RenderbufferManager* renderbuffer_manager() {
772 return group_->renderbuffer_manager();
773 }
774
775 FramebufferManager* framebuffer_manager() {
776 return group_->framebuffer_manager();
777 }
778
orglofchcad5a6742014-11-07 19:51:12779 ValuebufferManager* valuebuffer_manager() {
780 return group_->valuebuffer_manager();
781 }
782
[email protected]3916c97e2010-02-25 03:20:50783 ProgramManager* program_manager() {
784 return group_->program_manager();
785 }
786
787 ShaderManager* shader_manager() {
788 return group_->shader_manager();
789 }
790
[email protected]03cef9b2014-04-03 15:58:14791 ShaderTranslatorCache* shader_translator_cache() {
792 return group_->shader_translator_cache();
793 }
794
[email protected]29a4d902013-02-26 20:18:06795 const TextureManager* texture_manager() const {
796 return group_->texture_manager();
797 }
798
[email protected]3916c97e2010-02-25 03:20:50799 TextureManager* texture_manager() {
800 return group_->texture_manager();
801 }
802
[email protected]78b514b2012-05-01 21:50:59803 MailboxManager* mailbox_manager() {
804 return group_->mailbox_manager();
805 }
806
[email protected]b63f1d62014-07-18 15:40:59807 ImageManager* image_manager() { return image_manager_.get(); }
[email protected]09d50362012-10-18 20:54:37808
[email protected]944b62f32012-09-27 02:20:46809 VertexArrayManager* vertex_array_manager() {
810 return vertex_array_manager_.get();
811 }
812
[email protected]7989c9e2013-01-23 06:39:26813 MemoryTracker* memory_tracker() {
814 return group_->memory_tracker();
815 }
816
817 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
818 MemoryTracker* tracker = memory_tracker();
819 if (tracker) {
820 return tracker->EnsureGPUMemoryAvailable(estimated_size);
821 }
822 return true;
823 }
824
[email protected]34ff8b0c2010-10-01 20:06:02825 bool IsOffscreenBufferMultisampled() const {
826 return offscreen_target_samples_ > 1;
827 }
828
[email protected]ed9f9cd2013-02-27 21:12:35829 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49830 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03831 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35832 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47833 }
834
835 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49836 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07837 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47838 }
839
840 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35841 void RemoveTexture(GLuint client_id) {
842 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50843 }
[email protected]a93bb842010-02-16 23:03:47844
[email protected]d37231fa2010-04-09 21:16:02845 // Get the size (in pixels) of the currently bound frame buffer (either FBO
846 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30847 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02848
[email protected]9edc6b22010-12-23 02:00:26849 // Get the format of the currently bound frame buffer (either FBO or regular
850 // back buffer)
[email protected]68586372013-12-11 01:27:59851 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26852 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46853 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26854
[email protected]a93bb842010-02-16 23:03:47855 // Wrapper for CompressedTexImage2D commands.
856 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37857 GLenum target,
858 GLint level,
859 GLenum internal_format,
860 GLsizei width,
861 GLsizei height,
862 GLint border,
863 GLsizei image_size,
864 const void* data);
[email protected]a93bb842010-02-16 23:03:47865
[email protected]cadde4a2010-07-31 17:10:43866 // Wrapper for CompressedTexSubImage2D.
867 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37868 GLenum target,
869 GLint level,
870 GLint xoffset,
871 GLint yoffset,
872 GLsizei width,
873 GLsizei height,
874 GLenum format,
875 GLsizei imageSize,
876 const void * data);
[email protected]cadde4a2010-07-31 17:10:43877
878 // Wrapper for CopyTexImage2D.
879 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37880 GLenum target,
881 GLint level,
882 GLenum internal_format,
883 GLint x,
884 GLint y,
885 GLsizei width,
886 GLsizei height,
887 GLint border);
[email protected]cadde4a2010-07-31 17:10:43888
[email protected]6d792ee12013-05-15 00:40:56889 // Wrapper for SwapBuffers.
890 void DoSwapBuffers();
891
bajones2345c1f2014-12-09 04:45:51892 // Wrapper for SwapInterval.
893 void DoSwapInterval(int interval);
894
[email protected]cadde4a2010-07-31 17:10:43895 // Wrapper for CopyTexSubImage2D.
896 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37897 GLenum target,
898 GLint level,
899 GLint xoffset,
900 GLint yoffset,
901 GLint x,
902 GLint y,
903 GLsizei width,
904 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43905
[email protected]f598f422012-12-07 08:30:03906 // Validation for TexSubImage2D.
907 bool ValidateTexSubImage2D(
908 error::Error* error,
909 const char* function_name,
910 GLenum target,
911 GLint level,
912 GLint xoffset,
913 GLint yoffset,
914 GLsizei width,
915 GLsizei height,
916 GLenum format,
917 GLenum type,
918 const void * data);
919
[email protected]cadde4a2010-07-31 17:10:43920 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03921 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37922 GLenum target,
923 GLint level,
924 GLint xoffset,
925 GLint yoffset,
926 GLsizei width,
927 GLsizei height,
928 GLenum format,
929 GLenum type,
930 const void * data);
[email protected]cadde4a2010-07-31 17:10:43931
[email protected]32145a92012-12-17 09:01:59932 // Extra validation for async tex(Sub)Image2D.
933 bool ValidateAsyncTransfer(
934 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47935 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59936 GLenum target,
937 GLint level,
938 const void * data);
939
[email protected]e51bdf32011-11-23 22:21:46940 // Wrapper for TexImageIOSurface2DCHROMIUM.
941 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37942 GLenum target,
943 GLsizei width,
944 GLsizei height,
945 GLuint io_surface_id,
946 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46947
dongseong.hwang46305b12015-03-05 18:28:04948 void DoCopyTextureCHROMIUM(GLenum target,
949 GLuint source_id,
950 GLuint dest_id,
951 GLenum internal_format,
952 GLenum dest_type);
953
954 void DoCopySubTextureCHROMIUM(GLenum target,
955 GLuint source_id,
956 GLuint dest_id,
957 GLint xoffset,
958 GLint yoffset);
[email protected]43410e92012-04-20 17:06:28959
[email protected]97dc7cbe2011-12-06 17:26:17960 // Wrapper for TexStorage2DEXT.
961 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37962 GLenum target,
963 GLint levels,
964 GLenum internal_format,
965 GLsizei width,
966 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17967
[email protected]78b514b2012-05-01 21:50:59968 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22969 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
970 const GLbyte* key);
971 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
972 GLenum target, const GLbyte* data);
973
bajonesd8388be02015-04-04 00:15:43974 void EnsureTextureForClientId(GLenum target, GLuint client_id);
[email protected]78b514b2012-05-01 21:50:59975 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22976 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
977 GLuint client_id);
[email protected]78b514b2012-05-01 21:50:59978
orglofchcad5a6742014-11-07 19:51:12979 bool DoIsValuebufferCHROMIUM(GLuint client_id);
980 void DoBindValueBufferCHROMIUM(GLenum target, GLuint valuebuffer);
981 void DoSubscribeValueCHROMIUM(GLenum target, GLenum subscription);
982 void DoPopulateSubscribedValuesCHROMIUM(GLenum target);
983 void DoUniformValueBufferCHROMIUM(GLint location,
984 GLenum target,
985 GLenum subscription);
986
[email protected]09d50362012-10-18 20:54:37987 void DoBindTexImage2DCHROMIUM(
988 GLenum target,
989 GLint image_id);
990 void DoReleaseTexImage2DCHROMIUM(
991 GLenum target,
992 GLint image_id);
993
[email protected]94307712012-11-16 23:26:11994 void DoTraceEndCHROMIUM(void);
995
[email protected]2f143d482013-03-14 18:04:49996 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
997
[email protected]a6a09f852014-05-23 13:05:03998 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
999
kkinnunen337d59632014-08-26 10:19:571000 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
1001 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
1002
[email protected]ed9f9cd2013-02-27 21:12:351003 // Creates a Program for the given program.
1004 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:571005 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:351006 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471007 }
1008
[email protected]07f54fcc2009-12-22 02:46:301009 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351010 Program* GetProgram(GLuint client_id) {
1011 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:461012 }
[email protected]07f54fcc2009-12-22 02:46:301013
[email protected]cae20172012-12-07 00:06:191014#if defined(NDEBUG)
1015 void LogClientServiceMapping(
1016 const char* /* function_name */,
1017 GLuint /* client_id */,
1018 GLuint /* service_id */) {
1019 }
1020 template<typename T>
1021 void LogClientServiceForInfo(
1022 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
1023 }
1024#else
1025 void LogClientServiceMapping(
1026 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:261027 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:471028 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
1029 << ": client_id = " << client_id
1030 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:261031 }
[email protected]cae20172012-12-07 00:06:191032 }
1033 template<typename T>
1034 void LogClientServiceForInfo(
1035 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:261036 if (info) {
[email protected]cae20172012-12-07 00:06:191037 LogClientServiceMapping(function_name, client_id, info->service_id());
1038 }
1039 }
1040#endif
1041
[email protected]6b8cf1a2010-05-06 16:13:581042 // Gets the program info for the given program. If it's not a program
1043 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:351044 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:581045 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421046 Program* program = GetProgram(client_id);
1047 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351048 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511049 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431050 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581051 } else {
[email protected]ab09b612013-03-11 22:11:511052 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581053 }
1054 }
[email protected]df37b9932013-03-08 05:21:421055 LogClientServiceForInfo(program, client_id, function_name);
1056 return program;
[email protected]6b8cf1a2010-05-06 16:13:581057 }
1058
1059
[email protected]ed9f9cd2013-02-27 21:12:351060 // Creates a Shader for the given shader.
1061 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571062 GLuint client_id,
1063 GLuint service_id,
1064 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351065 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571066 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311067 }
1068
1069 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351070 Shader* GetShader(GLuint client_id) {
1071 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311072 }
1073
[email protected]6b8cf1a2010-05-06 16:13:581074 // Gets the shader info for the given shader. If it's not a shader generates a
1075 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351076 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581077 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421078 Shader* shader = GetShader(client_id);
1079 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351080 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511081 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431082 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581083 } else {
[email protected]ab09b612013-03-11 22:11:511084 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431085 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581086 }
1087 }
[email protected]df37b9932013-03-08 05:21:421088 LogClientServiceForInfo(shader, client_id, function_name);
1089 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581090 }
1091
[email protected]a93bb842010-02-16 23:03:471092 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351093 void CreateBuffer(GLuint client_id, GLuint service_id) {
1094 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471095 }
1096
[email protected]07f54fcc2009-12-22 02:46:301097 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211098 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071099 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1100 return buffer;
[email protected]1d32bc82010-01-13 22:06:461101 }
[email protected]07f54fcc2009-12-22 02:46:301102
[email protected]a93bb842010-02-16 23:03:471103 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1104 // on glDeleteBuffers so we can make sure the user does not try to render
1105 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351106 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471107
[email protected]a25fa872010-03-25 02:57:581108 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351109 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1110 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581111 }
1112
1113 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061114 Framebuffer* GetFramebuffer(GLuint client_id) {
1115 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581116 }
1117
1118 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351119 void RemoveFramebuffer(GLuint client_id) {
1120 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581121 }
1122
1123 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351124 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1125 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031126 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581127 }
1128
1129 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271130 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1131 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581132 }
1133
1134 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351135 void RemoveRenderbuffer(GLuint client_id) {
1136 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581137 }
1138
orglofchcad5a6742014-11-07 19:51:121139 // Creates a valuebuffer info for the given valuebuffer.
1140 void CreateValuebuffer(GLuint client_id) {
1141 return valuebuffer_manager()->CreateValuebuffer(client_id);
1142 }
1143
1144 // Gets the valuebuffer info for a given valuebuffer.
1145 Valuebuffer* GetValuebuffer(GLuint client_id) {
1146 return valuebuffer_manager()->GetValuebuffer(client_id);
1147 }
1148
1149 // Removes the valuebuffer info for the given valuebuffer.
1150 void RemoveValuebuffer(GLuint client_id) {
1151 valuebuffer_manager()->RemoveValuebuffer(client_id);
1152 }
1153
[email protected]944b62f32012-09-27 02:20:461154 // Gets the vertex attrib manager for the given vertex array.
1155 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1156 VertexAttribManager* info =
1157 vertex_array_manager()->GetVertexAttribManager(client_id);
1158 return info;
1159 }
1160
1161 // Removes the vertex attrib manager for the given vertex array.
1162 void RemoveVertexAttribManager(GLuint client_id) {
1163 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1164 }
1165
1166 // Creates a vertex attrib manager for the given vertex array.
[email protected]da364812014-05-09 21:39:481167 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1168 GLuint client_id,
1169 GLuint service_id,
1170 bool client_visible) {
1171 return vertex_array_manager()->CreateVertexAttribManager(
1172 client_id, service_id, group_->max_vertex_attribs(), client_visible);
[email protected]944b62f32012-09-27 02:20:461173 }
1174
[email protected]258a3313f2011-10-18 20:13:571175 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331176 void DoBindUniformLocationCHROMIUM(
1177 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571178
[email protected]558847a2010-03-24 07:02:541179 error::Error GetAttribLocationHelper(
zmo4a16ff992015-02-05 22:18:411180 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1181 const std::string& name_str);
[email protected]558847a2010-03-24 07:02:541182
1183 error::Error GetUniformLocationHelper(
zmo4a16ff992015-02-05 22:18:411184 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1185 const std::string& name_str);
[email protected]558847a2010-03-24 07:02:541186
zmo5393fb52015-01-27 01:50:481187 error::Error GetFragDataLocationHelper(
zmo4a16ff992015-02-05 22:18:411188 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1189 const std::string& name_str);
zmo5393fb52015-01-27 01:50:481190
zmo1bb3d1d2015-01-21 20:29:431191 // Wrapper for glShaderSource.
1192 void DoShaderSource(
1193 GLuint client_id, GLsizei count, const char** data, const GLint* length);
[email protected]07f54fcc2009-12-22 02:46:301194
zmo38923562015-01-29 20:17:391195 // Wrapper for glTransformFeedbackVaryings.
1196 void DoTransformFeedbackVaryings(
1197 GLuint client_program_id, GLsizei count, const char* const* varyings,
1198 GLenum buffer_mode);
1199
[email protected]0d6bfdc2011-11-02 01:32:201200 // Clear any textures used by the current program.
1201 bool ClearUnclearedTextures();
1202
[email protected]0d6bfdc2011-11-02 01:32:201203 // Clears any uncleared attachments attached to the given frame buffer.
1204 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061205 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281206
[email protected]0d6bfdc2011-11-02 01:32:201207 // overridden from GLES2Decoder
boliu45dc77a2015-02-25 23:26:311208 bool ClearLevel(Texture* texture,
dcheng1f4d1d72014-10-21 16:21:581209 unsigned target,
1210 int level,
1211 unsigned internal_format,
1212 unsigned format,
1213 unsigned type,
1214 int width,
1215 int height,
1216 bool is_texture_immutable) override;
[email protected]0d6bfdc2011-11-02 01:32:201217
[email protected]c007aa02010-09-02 22:22:401218 // Restore all GL state that affects clearing.
1219 void RestoreClearState();
1220
[email protected]3a2e7c7b2010-08-06 01:12:281221 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461222 // Returns: true if glEnable/glDisable should actually be called.
1223 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281224
[email protected]0d6bfdc2011-11-02 01:32:201225 // Check that the currently bound framebuffers are valid.
1226 // Generates GL error if not.
1227 bool CheckBoundFramebuffersValid(const char* func_name);
1228
[email protected]2ea5950d2014-07-09 18:20:341229 // Check that the currently bound read framebuffer has a color image
1230 // attached. Generates GL error if not.
1231 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1232
zmo383512cf2014-10-14 00:11:001233 // Check that the currently bound read framebuffer's color image
1234 // isn't the target texture of the glCopyTex{Sub}Image2D.
1235 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
1236
[email protected]0d6bfdc2011-11-02 01:32:201237 // Check if a framebuffer meets our requirements.
1238 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351239 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201240 GLenum target,
1241 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271242
orglofchcad5a6742014-11-07 19:51:121243 // Check if the current valuebuffer exists and is valid. If not generates
1244 // the appropriate GL error. Returns true if the current valuebuffer is in
1245 // a usable state.
1246 bool CheckCurrentValuebuffer(const char* function_name);
1247
1248 // Check if the current valuebuffer exists and is valiud and that the
1249 // value buffer is actually subscribed to the given subscription
1250 bool CheckCurrentValuebufferForSubscription(GLenum subscription,
1251 const char* function_name);
1252
1253 // Check if the location can be used for the given subscription target. If not
1254 // generates the appropriate GL error. Returns true if the location is usable
1255 bool CheckSubscriptionTarget(GLint location,
1256 GLenum subscription,
1257 const char* function_name);
1258
[email protected]939e7362010-05-13 20:49:101259 // Checks if the current program exists and is valid. If not generates the
1260 // appropriate GL error. Returns true if the current program is in a usable
1261 // state.
1262 bool CheckCurrentProgram(const char* function_name);
1263
1264 // Checks if the current program exists and is valid and that location is not
1265 // -1. If the current program is not valid generates the appropriate GL
1266 // error. Returns true if the current program is in a usable state and
1267 // location is not -1.
1268 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1269
zmof9a81360f2014-10-17 00:06:141270 // Checks if the current program samples a texture that is also the color
1271 // image of the current bound framebuffer, i.e., the source and destination
1272 // of the draw operation are the same.
1273 bool CheckDrawingFeedbackLoops();
1274
orglofchcad5a6742014-11-07 19:51:121275 // Checks if |api_type| is valid for the given uniform
1276 // If the api type is not valid generates the appropriate GL
1277 // error. Returns true if |api_type| is valid for the uniform
1278 bool CheckUniformForApiType(const Program::UniformInfo* info,
1279 const char* function_name,
1280 Program::UniformApiType api_type);
1281
[email protected]939e7362010-05-13 20:49:101282 // Gets the type of a uniform for a location in the current program. Sets GL
1283 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361284 // program is valid and the location exists. Adjusts count so it
1285 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131286 bool PrepForSetUniformByLocation(GLint fake_location,
1287 const char* function_name,
1288 Program::UniformApiType api_type,
1289 GLint* real_location,
1290 GLenum* type,
1291 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101292
[email protected]b177ae22011-11-01 03:29:111293 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021294 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111295
[email protected]b273e432010-04-12 17:23:581296 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1297 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1298
[email protected]ac77603c72013-03-08 13:52:061299 // Helper for glGetVertexAttrib
1300 void GetVertexAttribHelper(
1301 const VertexAttrib* attrib, GLenum pname, GLint* param);
1302
[email protected]3916c97e2010-02-25 03:20:501303 // Wrapper for glActiveTexture
1304 void DoActiveTexture(GLenum texture_unit);
1305
[email protected]ae51d192010-04-27 00:48:031306 // Wrapper for glAttachShader
1307 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1308
[email protected]96449d2c2009-11-25 00:01:321309 // Wrapper for glBindBuffer since we need to track the current targets.
1310 void DoBindBuffer(GLenum target, GLuint buffer);
1311
[email protected]86093972010-03-11 00:13:561312 // Wrapper for glBindFramebuffer since we need to track the current targets.
1313 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1314
1315 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1316 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1317
[email protected]a93bb842010-02-16 23:03:471318 // Wrapper for glBindTexture since we need to track the current targets.
1319 void DoBindTexture(GLenum target, GLuint texture);
1320
[email protected]944b62f32012-09-27 02:20:461321 // Wrapper for glBindVertexArrayOES
1322 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571323 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461324
[email protected]49cabed2013-11-13 18:15:181325 // Wrapper for glBlitFramebufferCHROMIUM.
1326 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301327 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1328 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1329 GLbitfield mask, GLenum filter);
1330
[email protected]36cef8ce2010-03-16 07:34:451331 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111332 void DoBufferSubData(
1333 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1334
[email protected]36cef8ce2010-03-16 07:34:451335 // Wrapper for glCheckFramebufferStatus
1336 GLenum DoCheckFramebufferStatus(GLenum target);
1337
[email protected]3a03a8f2011-03-19 00:51:271338 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081339 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271340
[email protected]88a61bf2012-10-27 13:00:421341 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421342 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251343 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281344
[email protected]45bf5152010-02-12 00:11:311345 // Wrapper for glCompileShader.
1346 void DoCompileShader(GLuint shader);
1347
[email protected]ae51d192010-04-27 00:48:031348 // Wrapper for glDetachShader
1349 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1350
[email protected]3a2e7c7b2010-08-06 01:12:281351 // Wrapper for glDisable
1352 void DoDisable(GLenum cap);
1353
[email protected]07f54fcc2009-12-22 02:46:301354 // Wrapper for glDisableVertexAttribArray.
1355 void DoDisableVertexAttribArray(GLuint index);
1356
[email protected]60f22d32012-12-12 00:31:581357 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1358 // attachments.
1359 void DoDiscardFramebufferEXT(GLenum target,
1360 GLsizei numAttachments,
1361 const GLenum* attachments);
1362
[email protected]3a2e7c7b2010-08-06 01:12:281363 // Wrapper for glEnable
1364 void DoEnable(GLenum cap);
1365
[email protected]07f54fcc2009-12-22 02:46:301366 // Wrapper for glEnableVertexAttribArray.
1367 void DoEnableVertexAttribArray(GLuint index);
1368
[email protected]882ba1e22012-03-08 19:02:531369 // Wrapper for glFinish.
1370 void DoFinish();
1371
1372 // Wrapper for glFlush.
1373 void DoFlush();
1374
[email protected]36cef8ce2010-03-16 07:34:451375 // Wrapper for glFramebufferRenderbufffer.
1376 void DoFramebufferRenderbuffer(
1377 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1378 GLuint renderbuffer);
1379
1380 // Wrapper for glFramebufferTexture2D.
1381 void DoFramebufferTexture2D(
1382 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1383 GLint level);
1384
[email protected]7d3c36e2013-07-12 14:13:161385 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1386 void DoFramebufferTexture2DMultisample(
1387 GLenum target, GLenum attachment, GLenum textarget,
1388 GLuint texture, GLint level, GLsizei samples);
1389
1390 // Common implementation for both DoFramebufferTexture2D wrappers.
1391 void DoFramebufferTexture2DCommon(const char* name,
1392 GLenum target, GLenum attachment, GLenum textarget,
1393 GLuint texture, GLint level, GLsizei samples);
1394
zmo84c08202014-11-23 15:28:401395 // Wrapper for glFramebufferTextureLayer.
1396 void DoFramebufferTextureLayer(
1397 GLenum target, GLenum attachment, GLuint texture, GLint level,
1398 GLint layer);
1399
[email protected]a93bb842010-02-16 23:03:471400 // Wrapper for glGenerateMipmap
1401 void DoGenerateMipmap(GLenum target);
1402
[email protected]7d3c36e2013-07-12 14:13:161403 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1404 // to account for different pname values defined in different extension
1405 // variants.
1406 GLenum AdjustGetPname(GLenum pname);
1407
[email protected]b273e432010-04-12 17:23:581408 // Wrapper for DoGetBooleanv.
1409 void DoGetBooleanv(GLenum pname, GLboolean* params);
1410
1411 // Wrapper for DoGetFloatv.
1412 void DoGetFloatv(GLenum pname, GLfloat* params);
1413
[email protected]36cef8ce2010-03-16 07:34:451414 // Wrapper for glGetFramebufferAttachmentParameteriv.
1415 void DoGetFramebufferAttachmentParameteriv(
1416 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1417
zmo8ac3bab2015-04-18 02:30:581418 // Wrapper for glGetInteger64v.
1419 void DoGetInteger64v(GLenum pname, GLint64* params);
1420
[email protected]a0c3e972010-04-21 00:49:131421 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581422 void DoGetIntegerv(GLenum pname, GLint* params);
1423
[email protected]29a9eb52010-04-13 09:04:231424 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061425 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231426 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1427
[email protected]17cfbe0e2013-03-07 01:26:081428 // Wrapper for glGetBufferParameteriv.
1429 void DoGetBufferParameteriv(
1430 GLenum target, GLenum pname, GLint* params);
1431
[email protected]a0c3e972010-04-21 00:49:131432 // Wrapper for glGetProgramiv.
1433 void DoGetProgramiv(
1434 GLuint program_id, GLenum pname, GLint* params);
1435
[email protected]36cef8ce2010-03-16 07:34:451436 // Wrapper for glRenderbufferParameteriv.
1437 void DoGetRenderbufferParameteriv(
1438 GLenum target, GLenum pname, GLint* params);
1439
[email protected]ddd968b82010-03-02 00:44:291440 // Wrapper for glGetShaderiv
1441 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1442
[email protected]4c6f5462014-03-05 00:26:561443 // Wrappers for glGetTexParameter.
1444 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1445 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1446 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1447
[email protected]b1122982010-05-17 23:04:241448 // Wrappers for glGetVertexAttrib.
1449 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1450 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1451
[email protected]1958e0e2010-04-22 05:17:151452 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241453 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151454 bool DoIsBuffer(GLuint client_id);
1455 bool DoIsFramebuffer(GLuint client_id);
1456 bool DoIsProgram(GLuint client_id);
1457 bool DoIsRenderbuffer(GLuint client_id);
1458 bool DoIsShader(GLuint client_id);
1459 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461460 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151461
[email protected]07f54fcc2009-12-22 02:46:301462 // Wrapper for glLinkProgram
1463 void DoLinkProgram(GLuint program);
1464
[email protected]36cef8ce2010-03-16 07:34:451465 // Wrapper for glRenderbufferStorage.
1466 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031467 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451468
[email protected]49cabed2013-11-13 18:15:181469 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1470 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301471 GLenum target, GLsizei samples, GLenum internalformat,
1472 GLsizei width, GLsizei height);
1473
[email protected]49cabed2013-11-13 18:15:181474 // Handler for glRenderbufferStorageMultisampleEXT
1475 // (multisampled_render_to_texture).
1476 void DoRenderbufferStorageMultisampleEXT(
1477 GLenum target, GLsizei samples, GLenum internalformat,
1478 GLsizei width, GLsizei height);
1479
1480 // Common validation for multisample extensions.
1481 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1482 GLenum internalformat,
1483 GLsizei width,
1484 GLsizei height);
1485
[email protected]4a4c18b2013-09-13 22:50:101486 // Verifies that the currently bound multisample renderbuffer is valid
1487 // Very slow! Only done on platforms with driver bugs that return invalid
1488 // buffers under memory pressure
1489 bool VerifyMultisampleRenderbufferIntegrity(
1490 GLuint renderbuffer, GLenum format);
1491
[email protected]b273e432010-04-12 17:23:581492 // Wrapper for glReleaseShaderCompiler.
1493 void DoReleaseShaderCompiler() { }
1494
zmobcb3fdd62014-12-11 00:49:031495 // Wrappers for glSamplerParameter*v functions.
1496 void DoSamplerParameterfv(
1497 GLuint sampler, GLenum pname, const GLfloat* params);
1498 void DoSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* params);
1499
[email protected]3916c97e2010-02-25 03:20:501500 // Wrappers for glTexParameter functions.
1501 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1502 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1503 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1504 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1505
1506 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1507 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121508 void DoUniform1i(GLint fake_location, GLint v0);
1509 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1510 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1511 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1512 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101513
1514 // Wrappers for glUniformfv because some drivers don't correctly accept
1515 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121516 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1517 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1518 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1519 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501520
[email protected]43c2f1f2011-03-25 18:35:361521 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121522 GLint fake_location, GLsizei count, GLboolean transpose,
1523 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361524 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121525 GLint fake_location, GLsizei count, GLboolean transpose,
1526 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361527 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121528 GLint fake_location, GLsizei count, GLboolean transpose,
1529 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361530
[email protected]af6380962012-11-29 23:24:131531 bool SetVertexAttribValue(
1532 const char* function_name, GLuint index, const GLfloat* value);
1533
[email protected]b1122982010-05-17 23:04:241534 // Wrappers for glVertexAttrib??
1535 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1536 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1537 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1538 void DoVertexAttrib4f(
1539 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1540 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1541 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1542 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1543 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1544
[email protected]43410e92012-04-20 17:06:281545 // Wrapper for glViewport
1546 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1547
[email protected]07f54fcc2009-12-22 02:46:301548 // Wrapper for glUseProgram
1549 void DoUseProgram(GLuint program);
1550
[email protected]ae51d192010-04-27 00:48:031551 // Wrapper for glValidateProgram.
1552 void DoValidateProgram(GLuint program_client_id);
1553
[email protected]d2a0e1a2012-08-12 02:25:011554 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1555 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1556 void DoPopGroupMarkerEXT(void);
1557
[email protected]4e8a5b122010-05-08 22:00:101558 // Gets the number of values that will be returned by glGetXXX. Returns
1559 // false if pname is unknown.
1560 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1561
[email protected]07f54fcc2009-12-22 02:46:301562 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431563 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101564 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1565 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301566
[email protected]c13e1da62011-09-09 21:48:301567 // Returns true if successful, simulated will be true if attrib0 was
1568 // simulated.
[email protected]c6aef902012-02-14 03:31:421569 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431570 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231571 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241572
[email protected]91c94eb2013-10-22 10:32:541573 // If an image is bound to texture, this will call Will/DidUseTexImage
1574 // if needed.
1575 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1576 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1577
1578 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111579 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541580 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501581
[email protected]8fbedc02010-11-18 18:43:401582 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421583 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431584 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421585 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401586 void RestoreStateForSimulatedFixedAttribs();
1587
[email protected]c6aef902012-02-14 03:31:421588 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101589 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421590 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431591 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421592 bool instanced, GLenum mode, GLint first, GLsizei count,
1593 GLsizei primcount);
1594 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431595 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421596 bool instanced, GLenum mode, GLsizei count, GLenum type,
1597 int32 offset, GLsizei primcount);
1598
[email protected]61eeb33f2011-07-26 15:30:311599 GLenum GetBindTargetForSamplerType(GLenum type) {
1600 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461601 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1602 switch (type) {
1603 case GL_SAMPLER_2D:
1604 return GL_TEXTURE_2D;
1605 case GL_SAMPLER_CUBE:
1606 return GL_TEXTURE_CUBE_MAP;
1607 case GL_SAMPLER_EXTERNAL_OES:
1608 return GL_TEXTURE_EXTERNAL_OES;
1609 case GL_SAMPLER_2D_RECT_ARB:
1610 return GL_TEXTURE_RECTANGLE_ARB;
1611 }
1612
1613 NOTREACHED();
1614 return 0;
[email protected]61eeb33f2011-07-26 15:30:311615 }
1616
[email protected]8e3e0662010-08-23 18:46:301617 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061618 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1619 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301620 switch (target) {
1621 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451622 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341623 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301624 break;
[email protected]ebfb73c2012-08-15 02:37:451625 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341626 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301627 break;
1628 default:
1629 NOTREACHED();
1630 break;
1631 }
[email protected]4d8f0dd2013-03-09 14:37:061632 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301633 }
1634
[email protected]ed9f9cd2013-02-27 21:12:351635 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201636 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271637 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201638 switch (target) {
1639 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111640 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201641 break;
1642 default:
1643 NOTREACHED();
1644 break;
1645 }
[email protected]ee2a79c32013-03-10 03:50:271646 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201647 }
1648
[email protected]f7b85372010-02-03 01:11:371649 // Validates the program and location for a glGetUniform call and returns
1650 // a SizeResult setup to receive the result. Returns true if glGetUniform
1651 // should be called.
vmiura181c74002015-03-20 01:32:511652 bool GetUniformSetup(GLuint program,
1653 GLint fake_location,
1654 uint32 shm_id,
1655 uint32 shm_offset,
1656 error::Error* error,
1657 GLint* real_location,
1658 GLuint* service_id,
1659 void** result,
1660 GLenum* result_type,
1661 GLsizei* result_size);
[email protected]f7b85372010-02-03 01:11:371662
sieversfbaa5dc2015-04-28 00:45:311663 bool WasContextLost() const override;
1664 bool WasContextLostByRobustnessExtension() const override;
1665 void MarkContextLost(error::ContextLostReason reason) override;
1666 bool CheckResetStatus();
[email protected]38d139d2011-07-14 00:38:431667
[email protected]e51bdf32011-11-23 22:21:461668#if defined(OS_MACOSX)
1669 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1670#endif
1671
[email protected]ad84a3a2012-06-08 21:42:431672 bool ValidateCompressedTexDimensions(
1673 const char* function_name,
1674 GLint level, GLsizei width, GLsizei height, GLenum format);
1675 bool ValidateCompressedTexFuncData(
1676 const char* function_name,
1677 GLsizei width, GLsizei height, GLenum format, size_t size);
1678 bool ValidateCompressedTexSubDimensions(
1679 const char* function_name,
1680 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1681 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351682 Texture* texture);
dongseong.hwang46305b12015-03-05 18:28:041683 bool ValidateCopyTextureCHROMIUM(const char* function_name,
1684 GLenum target,
1685 TextureRef* source_texture_ref,
1686 TextureRef* dest_texture_ref,
1687 GLenum dest_internal_format);
[email protected]ad84a3a2012-06-08 21:42:431688
[email protected]ab09b612013-03-11 22:11:511689 void RenderWarning(const char* filename, int line, const std::string& msg);
1690 void PerformanceWarning(
1691 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011692
[email protected]62e155e2012-10-23 22:43:151693 const FeatureInfo::FeatureFlags& features() const {
1694 return feature_info_->feature_flags();
1695 }
1696
1697 const FeatureInfo::Workarounds& workarounds() const {
1698 return feature_info_->workarounds();
1699 }
1700
[email protected]a7266a92012-06-28 02:11:081701 bool ShouldDeferDraws() {
1702 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341703 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081704 surface_->DeferDraws();
1705 }
1706
[email protected]09e17272012-11-30 10:30:441707 bool ShouldDeferReads() {
1708 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341709 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441710 surface_->DeferDraws();
1711 }
1712
dongseong.hwange1cb2aa2015-02-11 09:33:331713 bool IsRobustnessSupported() {
1714 return has_robustness_extension_ &&
1715 context_->WasAllocatedUsingRobustnessExtension();
1716 }
1717
[email protected]c76fe672013-12-13 23:30:221718 error::Error WillAccessBoundFramebufferForDraw() {
1719 if (ShouldDeferDraws())
1720 return error::kDeferCommandUntilLater;
1721 if (!offscreen_target_frame_buffer_.get() &&
1722 !framebuffer_state_.bound_draw_framebuffer.get() &&
1723 !surface_->SetBackbufferAllocation(true))
1724 return error::kLostContext;
1725 return error::kNoError;
1726 }
1727
1728 error::Error WillAccessBoundFramebufferForRead() {
1729 if (ShouldDeferReads())
1730 return error::kDeferCommandUntilLater;
1731 if (!offscreen_target_frame_buffer_.get() &&
1732 !framebuffer_state_.bound_read_framebuffer.get() &&
1733 !surface_->SetBackbufferAllocation(true))
1734 return error::kLostContext;
1735 return error::kNoError;
1736 }
1737
vmiura8266ca72014-09-09 21:37:001738 // Set remaining commands to process to 0 to force DoCommands to return
1739 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1740 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1741
[email protected]5a36dc132013-07-23 23:17:551742 void ProcessPendingReadPixels();
1743 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1744
[email protected]96449d2c2009-11-25 00:01:321745 // Generate a member function prototype for each command in an automated and
1746 // typesafe way.
vmiuracd108592014-09-08 14:36:341747#define GLES2_CMD_OP(name) \
1748 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321749
1750 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1751
1752 #undef GLES2_CMD_OP
1753
[email protected]2f2d7042010-04-14 21:45:581754 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381755 scoped_refptr<gfx::GLSurface> surface_;
1756 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021757
[email protected]a3ded6d2010-10-19 06:44:391758 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351759 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391760
[email protected]1d82e822013-04-10 21:32:321761 DebugMarkerManager debug_marker_manager_;
1762 Logger logger_;
1763
[email protected]e259eb412012-10-13 05:47:241764 // All the state for this context.
1765 ContextState state_;
1766
[email protected]34ff8b0c2010-10-01 20:06:021767 // Current width and height of the offscreen frame buffer.
1768 gfx::Size offscreen_size_;
1769
[email protected]96449d2c2009-11-25 00:01:321770 // Util to help with GL.
1771 GLES2Util util_;
1772
[email protected]43410e92012-04-20 17:06:281773 // unpack flip y as last set by glPixelStorei
1774 bool unpack_flip_y_;
1775
[email protected]6c75c712012-06-19 15:43:171776 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281777 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171778 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281779
[email protected]b1122982010-05-17 23:04:241780 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1781 GLuint attrib_0_buffer_id_;
1782
1783 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131784 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241785
[email protected]fc753442011-02-04 19:49:491786 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1787 bool attrib_0_buffer_matches_value_;
1788
[email protected]b1122982010-05-17 23:04:241789 // The size of attrib 0.
1790 GLsizei attrib_0_size_;
1791
[email protected]8fbedc02010-11-18 18:43:401792 // The buffer used to simulate GL_FIXED attribs.
1793 GLuint fixed_attrib_buffer_id_;
1794
1795 // The size of fiixed attrib buffer.
1796 GLsizei fixed_attrib_buffer_size_;
1797
[email protected]b9363b22010-06-09 22:06:151798 // The offscreen frame buffer that the client renders to. With EGL, the
1799 // depth and stencil buffers are separate. With regular GL there is a single
1800 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1801 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351802 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1803 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1804 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1805 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1806 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021807 GLenum offscreen_target_color_format_;
1808 GLenum offscreen_target_depth_format_;
1809 GLenum offscreen_target_stencil_format_;
1810 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561811 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351812
[email protected]de26b3c2011-08-03 21:54:271813 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351814 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1815 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491816 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351817 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271818
1819 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351820 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1821 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051822 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351823
[email protected]882ba1e22012-03-08 19:02:531824 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531825
[email protected]944b62f32012-09-27 02:20:461826 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1827
[email protected]b63f1d62014-07-18 15:40:591828 scoped_ptr<ImageManager> image_manager_;
1829
[email protected]729c0b42013-05-26 02:05:071830 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001831
[email protected]840a7e462013-02-27 01:29:511832 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481833
[email protected]e3932abb2013-03-13 00:01:371834 ShaderCacheCallback shader_cache_callback_;
1835
[email protected]85a4ac22013-05-31 01:58:471836 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421837
[email protected]32fe9aa2011-01-21 23:47:131838 // The format of the back buffer_
1839 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461840 bool back_buffer_has_depth_;
1841 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131842
achaulkcf5316f2014-09-26 19:28:421843 bool surfaceless_;
1844
[email protected]60f22d32012-12-12 00:31:581845 // Backbuffer attachments that are currently undefined.
1846 uint32 backbuffer_needs_clear_bits_;
1847
[email protected]a6a09f852014-05-23 13:05:031848 // The current decoder error communicates the decoder error through command
1849 // processing functions that do not return the error value. Should be set only
1850 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561851 error::Error current_decoder_error_;
1852
[email protected]b1d2dcb2010-05-17 19:24:181853 bool use_shader_translator_;
dyen0ff9e4402015-02-12 22:27:431854 scoped_refptr<ShaderTranslatorInterface> vertex_translator_;
1855 scoped_refptr<ShaderTranslatorInterface> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181856
[email protected]e82fb792011-09-22 00:33:291857 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411858
[email protected]915a59a12010-09-30 21:29:111859 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051860 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351861 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051862
[email protected]65225772011-05-12 21:10:241863 int frame_number_;
1864
vmiura8266ca72014-09-09 21:37:001865 // Number of commands remaining to be processed in DoCommands().
1866 int commands_to_process_;
1867
[email protected]706b69f2012-07-27 04:59:301868 bool has_robustness_extension_;
sieversfbaa5dc2015-04-28 00:45:311869 error::ContextLostReason context_lost_reason_;
1870 bool context_was_lost_;
[email protected]93a7d98f2013-07-11 00:04:221871 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431872 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431873
[email protected]f0d74742011-10-03 16:31:041874 // These flags are used to override the state of the shared feature_info_
1875 // member. Because the same FeatureInfo instance may be shared among many
1876 // contexts, the assumptions on the availablity of extensions in WebGL
1877 // contexts may be broken. These flags override the shared state to preserve
1878 // WebGL semantics.
1879 bool force_webgl_glsl_validation_;
1880 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491881 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131882 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061883 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041884
[email protected]062c38b2012-01-18 03:25:101885 bool compile_shader_always_succeeds_;
1886
[email protected]828a3932014-04-02 14:43:131887 // An optional behaviour to lose the context and group when OOM.
1888 bool lose_context_when_out_of_memory_;
1889
[email protected]cae20172012-12-07 00:06:191890 // Log extra info.
1891 bool service_logging_;
1892
[email protected]e51bdf32011-11-23 22:21:461893#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531894 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461895 TextureToIOSurfaceMap texture_to_io_surface_map_;
1896#endif
1897
[email protected]43410e92012-04-20 17:06:281898 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
sievers2384f2b2014-11-18 02:10:351899 scoped_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_;
[email protected]43410e92012-04-20 17:06:281900
[email protected]1868a342012-11-07 15:56:021901 // Cached values of the currently assigned viewport dimensions.
1902 GLsizei viewport_max_width_;
1903 GLsizei viewport_max_height_;
1904
[email protected]63b465922012-09-06 02:04:521905 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521906 base::TimeDelta total_processing_commands_time_;
1907
[email protected]c986af502013-08-14 01:04:441908 // States related to each manager.
1909 DecoderTextureState texture_state_;
1910 DecoderFramebufferState framebuffer_state_;
1911
[email protected]fb97b662013-02-20 23:02:141912 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131913 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:241914 const unsigned char* cb_command_trace_category_;
dyencb86f2f2014-12-09 18:35:411915 const unsigned char* gpu_decoder_category_;
[email protected]cac16542014-01-15 17:53:511916 int gpu_trace_level_;
1917 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:241918 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:111919
[email protected]5a36dc132013-07-23 23:17:551920 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1921
[email protected]4a4c18b2013-09-13 22:50:101922 // Used to validate multisample renderbuffers if needed
1923 GLuint validation_texture_;
1924 GLuint validation_fbo_multisample_;
1925 GLuint validation_fbo_;
1926
vmiuracd108592014-09-08 14:36:341927 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1928 uint32 immediate_data_size,
1929 const void* data);
1930
1931 // A struct to hold info about each command.
1932 struct CommandInfo {
1933 CmdHandler cmd_handler;
1934 uint8 arg_flags; // How to handle the arguments for this command
1935 uint8 cmd_flags; // How to handle this command
1936 uint16 arg_count; // How many arguments are expected for this command.
1937 };
1938
1939 // A table of CommandInfo for all the commands.
1940 static const CommandInfo command_info[kNumCommands - kStartPoint];
1941
[email protected]96449d2c2009-11-25 00:01:321942 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1943};
1944
vmiuracd108592014-09-08 14:36:341945const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1946#define GLES2_CMD_OP(name) \
1947 { \
1948 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
1949 cmds::name::cmd_flags, \
1950 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1951 } \
1952 , /* NOLINT */
1953 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1954#undef GLES2_CMD_OP
1955};
1956
[email protected]ab09b612013-03-11 22:11:511957ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301958 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511959 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301960 error_state_(error_state) {
1961 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351962}
1963
1964ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301965 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351966}
1967
[email protected]2b10c02d2014-01-29 16:43:021968static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361969 TextureUnit& info = state->texture_units[0];
1970 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021971 scoped_refptr<TextureRef> texture_ref;
1972 switch (target) {
1973 case GL_TEXTURE_2D:
1974 texture_ref = info.bound_texture_2d;
1975 break;
1976 case GL_TEXTURE_CUBE_MAP:
1977 texture_ref = info.bound_texture_cube_map;
1978 break;
1979 case GL_TEXTURE_EXTERNAL_OES:
1980 texture_ref = info.bound_texture_external_oes;
1981 break;
1982 case GL_TEXTURE_RECTANGLE_ARB:
1983 texture_ref = info.bound_texture_rectangle_arb;
1984 break;
1985 default:
1986 NOTREACHED();
1987 break;
1988 }
1989 if (texture_ref.get()) {
1990 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361991 } else {
1992 last_id = 0;
1993 }
1994
[email protected]2b10c02d2014-01-29 16:43:021995 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361996 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1997}
1998
[email protected]2b10c02d2014-01-29 16:43:021999ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
2000 GLuint id,
2001 GLenum target)
2002 : state_(state),
2003 target_(target) {
[email protected]ab09b612013-03-11 22:11:512004 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:022005 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352006
2007 // TODO(apatrick): Check if there are any other states that need to be reset
2008 // before binding a new texture.
2009 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:022010 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:352011}
2012
[email protected]2b10c02d2014-01-29 16:43:022013ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:512014 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:022015 "ScopedTextureBinder::dtor", state_->GetErrorState());
2016 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:352017}
2018
[email protected]18e785a2013-10-09 03:29:412019ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:352020 GLuint id)
[email protected]18e785a2013-10-09 03:29:412021 : state_(state) {
[email protected]ab09b612013-03-11 22:11:512022 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:412023 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352024 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
2025}
2026
2027ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512028 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:412029 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
2030 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:352031}
2032
2033ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
2034 GLuint id)
2035 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:512036 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302037 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352038 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:452039 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:352040}
2041
2042ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512043 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302044 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:302045 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:352046}
2047
[email protected]34ff8b0c2010-10-01 20:06:022048ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:272049 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:522050 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:342051 resolve_and_bind_ = (
2052 decoder_->offscreen_target_frame_buffer_.get() &&
2053 decoder_->IsOffscreenBufferMultisampled() &&
2054 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
2055 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:022056 if (!resolve_and_bind_)
2057 return;
2058
[email protected]ab09b612013-03-11 22:11:512059 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302060 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022061 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
2062 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:272063 GLuint targetid;
2064 if (internal) {
2065 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
2066 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:352067 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:272068 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352069 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:362070 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:272071 decoder_->offscreen_resolved_color_texture_->Create();
2072
2073 DCHECK(decoder_->offscreen_saved_color_format_);
2074 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:092075 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
2076 false);
[email protected]de26b3c2011-08-03 21:54:272077 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
2078 decoder_->offscreen_resolved_color_texture_.get());
2079 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
2080 GL_FRAMEBUFFER_COMPLETE) {
2081 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
2082 << "because offscreen resolved FBO was incomplete.";
2083 return;
2084 }
2085 }
2086 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
2087 } else {
2088 targetid = decoder_->offscreen_saved_frame_buffer_->id();
2089 }
2090 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022091 const int width = decoder_->offscreen_size_.width();
2092 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:452093 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:182094 decoder->BlitFramebufferHelper(0,
2095 0,
2096 width,
2097 height,
2098 0,
2099 0,
2100 width,
2101 height,
2102 GL_COLOR_BUFFER_BIT,
2103 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:272104 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022105}
2106
2107ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
2108 if (!resolve_and_bind_)
2109 return;
2110
[email protected]ab09b612013-03-11 22:11:512111 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302112 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022113 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222114 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452115 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182116 }
[email protected]34ff8b0c2010-10-01 20:06:022117}
2118
[email protected]ce296892013-10-24 22:04:362119BackTexture::BackTexture(
2120 MemoryTracker* memory_tracker,
2121 ContextState* state)
2122 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2123 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482124 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252125 id_(0) {
[email protected]6217d392010-03-25 22:08:352126}
2127
[email protected]ed9f9cd2013-02-27 21:12:352128BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352129 // This does not destroy the render texture because that would require that
2130 // the associated GL context was current. Just check that it was explicitly
2131 // destroyed.
2132 DCHECK_EQ(id_, 0u);
2133}
2134
[email protected]ed9f9cd2013-02-27 21:12:352135void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302136 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362137 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352138 Destroy();
2139 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022140 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2142 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582143 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162145
2146 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2147 // never called on an offscreen context, no data will ever be uploaded to the
2148 // saved offscreen color texture (it is deferred until to when SwapBuffers
2149 // is called). My idea is that some nvidia drivers might have a bug where
2150 // deleting a texture that has never been populated might cause a
2151 // crash.
2152 glTexImage2D(
2153 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482154
2155 bytes_allocated_ = 16u * 16u * 4u;
2156 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352157}
2158
[email protected]ed9f9cd2013-02-27 21:12:352159bool BackTexture::AllocateStorage(
2160 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352161 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302162 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362163 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022164 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092165 uint32 image_size = 0;
2166 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:422167 size.width(), size.height(), 1, format, GL_UNSIGNED_BYTE, 8, &image_size,
[email protected]678a73f2012-12-19 19:22:092168 NULL, NULL);
2169
[email protected]7989c9e2013-01-23 06:39:262170 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2171 return false;
2172 }
2173
[email protected]40d90a22013-04-09 03:39:552174 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092175 if (zero) {
2176 zero_data.reset(new char[image_size]);
2177 memset(zero_data.get(), 0, image_size);
2178 }
[email protected]6217d392010-03-25 22:08:352179
[email protected]8f1d2aa2013-05-10 23:45:382180 glTexImage2D(GL_TEXTURE_2D,
2181 0, // mip level
2182 format,
2183 size.width(),
2184 size.height(),
2185 0, // border
2186 format,
2187 GL_UNSIGNED_BYTE,
2188 zero_data.get());
[email protected]6217d392010-03-25 22:08:352189
[email protected]d37231fa2010-04-09 21:16:022190 size_ = size;
2191
[email protected]1078f912011-12-23 13:12:142192 bool success = glGetError() == GL_NO_ERROR;
2193 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482194 memory_tracker_.TrackMemFree(bytes_allocated_);
2195 bytes_allocated_ = image_size;
2196 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142197 }
2198 return success;
[email protected]6217d392010-03-25 22:08:352199}
2200
[email protected]ed9f9cd2013-02-27 21:12:352201void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352202 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302203 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362204 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022205 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352206 glCopyTexImage2D(GL_TEXTURE_2D,
2207 0, // level
[email protected]3a4d0c52011-06-29 23:11:582208 format,
[email protected]6217d392010-03-25 22:08:352209 0, 0,
2210 size.width(),
2211 size.height(),
2212 0); // border
2213}
2214
[email protected]ed9f9cd2013-02-27 21:12:352215void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352216 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302217 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362218 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352219 glDeleteTextures(1, &id_);
2220 id_ = 0;
2221 }
[email protected]68e81a4a62012-12-13 01:16:482222 memory_tracker_.TrackMemFree(bytes_allocated_);
2223 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352224}
2225
[email protected]ed9f9cd2013-02-27 21:12:352226void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052227 id_ = 0;
2228}
2229
[email protected]d5a28e452013-10-10 01:01:402230BackRenderbuffer::BackRenderbuffer(
2231 RenderbufferManager* renderbuffer_manager,
2232 MemoryTracker* memory_tracker,
2233 ContextState* state)
2234 : renderbuffer_manager_(renderbuffer_manager),
2235 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2236 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482237 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252238 id_(0) {
[email protected]6217d392010-03-25 22:08:352239}
2240
[email protected]ed9f9cd2013-02-27 21:12:352241BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352242 // This does not destroy the render buffer because that would require that
2243 // the associated GL context was current. Just check that it was explicitly
2244 // destroyed.
2245 DCHECK_EQ(id_, 0u);
2246}
2247
[email protected]ed9f9cd2013-02-27 21:12:352248void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302249 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402250 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352251 Destroy();
2252 glGenRenderbuffersEXT(1, &id_);
2253}
2254
[email protected]f42f05b2013-11-15 21:46:182255bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2256 const gfx::Size& size,
2257 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352258 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512259 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402260 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2261 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262262
2263 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402264 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232265 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262266 return false;
2267 }
2268
2269 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2270 return false;
2271 }
2272
[email protected]34ff8b0c2010-10-01 20:06:022273 if (samples <= 1) {
2274 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2275 format,
2276 size.width(),
2277 size.height());
2278 } else {
[email protected]f42f05b2013-11-15 21:46:182279 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2280 GL_RENDERBUFFER,
2281 samples,
2282 format,
2283 size.width(),
2284 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022285 }
[email protected]1078f912011-12-23 13:12:142286 bool success = glGetError() == GL_NO_ERROR;
2287 if (success) {
[email protected]d5a28e452013-10-10 01:01:402288 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482289 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262290 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402291 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482292 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142293 }
2294 return success;
[email protected]6217d392010-03-25 22:08:352295}
2296
[email protected]ed9f9cd2013-02-27 21:12:352297void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352298 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302299 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402300 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352301 glDeleteRenderbuffersEXT(1, &id_);
2302 id_ = 0;
2303 }
[email protected]68e81a4a62012-12-13 01:16:482304 memory_tracker_.TrackMemFree(bytes_allocated_);
2305 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352306}
2307
[email protected]ed9f9cd2013-02-27 21:12:352308void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052309 id_ = 0;
2310}
2311
[email protected]ed9f9cd2013-02-27 21:12:352312BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352313 : decoder_(decoder),
2314 id_(0) {
2315}
2316
[email protected]ed9f9cd2013-02-27 21:12:352317BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352318 // This does not destroy the frame buffer because that would require that
2319 // the associated GL context was current. Just check that it was explicitly
2320 // destroyed.
2321 DCHECK_EQ(id_, 0u);
2322}
2323
[email protected]ed9f9cd2013-02-27 21:12:352324void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302325 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2326 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352327 Destroy();
2328 glGenFramebuffersEXT(1, &id_);
2329}
2330
[email protected]ed9f9cd2013-02-27 21:12:352331void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352332 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512333 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302334 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352335 ScopedFrameBufferBinder binder(decoder_, id_);
2336 GLuint attach_id = texture ? texture->id() : 0;
2337 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2338 GL_COLOR_ATTACHMENT0,
2339 GL_TEXTURE_2D,
2340 attach_id,
2341 0);
2342}
2343
[email protected]ed9f9cd2013-02-27 21:12:352344void BackFramebuffer::AttachRenderBuffer(GLenum target,
2345 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352346 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512347 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302348 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352349 ScopedFrameBufferBinder binder(decoder_, id_);
2350 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2351 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152352 target,
[email protected]6217d392010-03-25 22:08:352353 GL_RENDERBUFFER,
2354 attach_id);
2355}
2356
[email protected]ed9f9cd2013-02-27 21:12:352357void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352358 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302359 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2360 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352361 glDeleteFramebuffersEXT(1, &id_);
2362 id_ = 0;
2363 }
2364}
2365
[email protected]ed9f9cd2013-02-27 21:12:352366void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052367 id_ = 0;
2368}
2369
[email protected]ed9f9cd2013-02-27 21:12:352370GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352371 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302372 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2373 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352374 ScopedFrameBufferBinder binder(decoder_, id_);
2375 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2376}
2377
[email protected]aa7666122011-09-02 19:45:522378GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2379 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322380}
2381
[email protected]aa7666122011-09-02 19:45:522382GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392383 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572384 group_(group),
[email protected]1d82e822013-04-10 21:32:322385 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132386 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282387 unpack_flip_y_(false),
2388 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172389 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242390 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492391 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242392 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402393 fixed_attrib_buffer_id_(0),
2394 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022395 offscreen_target_color_format_(0),
2396 offscreen_target_depth_format_(0),
2397 offscreen_target_stencil_format_(0),
2398 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562399 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052400 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132401 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462402 back_buffer_has_depth_(false),
2403 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422404 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582405 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562406 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052407 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112408 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002409 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432410 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302411 has_robustness_extension_(false),
sieversfbaa5dc2015-04-28 00:45:312412 context_lost_reason_(error::kUnknown),
2413 context_was_lost_(false),
[email protected]93a7d98f2013-07-11 00:04:222414 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432415 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042416 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102417 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492418 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132419 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062420 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282421 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132422 lose_context_when_out_of_memory_(false),
avi9ab037202014-12-22 23:49:532423 service_logging_(base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]cae20172012-12-07 00:06:192424 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022425 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102426 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002427 texture_state_(group_->feature_info()
2428 ->workarounds()
2429 .texsubimage2d_faster_than_teximage2d),
vmiura1c2b1de2014-09-19 19:03:242430 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2431 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
dyencb86f2f2014-12-09 18:35:412432 gpu_decoder_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2433 TRACE_DISABLED_BY_DEFAULT("gpu_decoder"))),
vmiura1c2b1de2014-09-19 19:03:242434 gpu_trace_level_(2),
2435 gpu_trace_commands_(false),
2436 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102437 validation_texture_(0),
2438 validation_fbo_multisample_(0),
2439 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572440 DCHECK(group);
2441
[email protected]b1122982010-05-17 23:04:242442 attrib_0_value_.v[0] = 0.0f;
2443 attrib_0_value_.v[1] = 0.0f;
2444 attrib_0_value_.v[2] = 0.0f;
2445 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152446
[email protected]c2f8c8402010-12-06 18:07:242447 // The shader translator is used for WebGL even when running on EGL
2448 // because additional restrictions are needed (like only enabling
2449 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562450 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2451 // the empty string to CompileShader and this is not a valid shader.
2452 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
avi9ab037202014-12-22 23:49:532453 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]39ba4f02012-03-26 01:16:002454 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152455 use_shader_translator_ = false;
2456 }
[email protected]96449d2c2009-11-25 00:01:322457}
2458
[email protected]80eb6b52012-01-19 00:14:412459GLES2DecoderImpl::~GLES2DecoderImpl() {
2460}
2461
[email protected]c410da802011-03-14 19:17:412462bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382463 const scoped_refptr<gfx::GLSurface>& surface,
2464 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232465 bool offscreen,
dongseong.hwang4c04a162015-03-04 07:27:332466 const gfx::Size& offscreen_size,
[email protected]e82fb792011-09-22 00:33:292467 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242468 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322469 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382470 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302471 DCHECK(!context_.get());
hendrikw2e3b5c8c2015-04-27 23:52:252472 DCHECK(!offscreen || !offscreen_size.IsEmpty());
[email protected]66791e382010-07-14 20:48:302473
zmo0ee15862015-03-04 03:50:182474 ContextCreationAttribHelper attrib_parser;
2475 if (!attrib_parser.Parse(attribs))
2476 return false;
2477
jbaumana7604692014-10-17 02:00:392478 surfaceless_ = surface->IsSurfaceless() && !offscreen;
achaulkcf5316f2014-09-26 19:28:422479
[email protected]55e136f2013-04-03 18:50:062480 set_initialized();
[email protected]8f9b8dd2013-09-12 18:05:132481 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142482
avi9ab037202014-12-22 23:49:532483 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2484 switches::kEnableGPUDebugging)) {
[email protected]e844ae22012-01-14 03:36:262485 set_debug(true);
2486 }
2487
avi9ab037202014-12-22 23:49:532488 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2489 switches::kEnableGPUCommandLogging)) {
[email protected]39ba4f02012-03-26 01:16:002490 set_log_commands(true);
2491 }
2492
avi9ab037202014-12-22 23:49:532493 compile_shader_always_succeeds_ =
2494 base::CommandLine::ForCurrentProcess()->HasSwitch(
2495 switches::kCompileShaderAlwaysSucceeds);
[email protected]062c38b2012-01-18 03:25:102496
[email protected]63c9b052012-05-17 18:27:382497 // Take ownership of the context and surface. The surface can be replaced with
2498 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382499 context_ = context;
[email protected]63c9b052012-05-17 18:27:382500 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182501
dyen5b1c02ff2015-02-26 01:54:002502 // Create GPU Tracer for timing values.
2503 gpu_tracer_.reset(new GPUTracer(this));
2504
[email protected]828a3932014-04-02 14:43:132505 // Save the loseContextWhenOutOfMemory context creation attribute.
2506 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402507 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132508
[email protected]65f7efe2013-11-28 03:11:472509 // If the failIfMajorPerformanceCaveat context creation attribute was true
2510 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402511 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472512 feature_info_->feature_flags().is_swiftshader) {
2513 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2514 Destroy(true);
2515 return false;
2516 }
2517
[email protected]956aec52013-09-05 15:41:192518 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222519 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392520 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422521 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382522 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032523 return false;
[email protected]a3ded6d2010-10-19 06:44:392524 }
[email protected]b64c24952012-04-19 03:20:272525 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282526
zmoac89bdd2015-03-10 02:09:052527 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2528 switches::kEnableUnsafeES3APIs) &&
2529 attrib_parser.es3_context_required &&
2530 feature_info_->IsES3Capable()) {
2531 feature_info_->EnableES3Validators();
2532 set_unsafe_es3_apis_enabled(true);
2533 }
2534
[email protected]e82fb792011-09-22 00:33:292535 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502536
[email protected]af6380962012-11-29 23:24:132537 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482538 vertex_array_manager_.reset(new VertexArrayManager());
2539
2540 GLuint default_vertex_attrib_service_id = 0;
2541 if (features().native_vertex_array_object) {
2542 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2543 glBindVertexArrayOES(default_vertex_attrib_service_id);
2544 }
2545
2546 state_.default_vertex_attrib_manager =
2547 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2548
[email protected]81f20a622014-04-18 01:54:522549 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002550 group_->max_vertex_attribs(),
2551 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462552
[email protected]81f20a622014-04-18 01:54:522553 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572554 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322555
[email protected]7cd76fd2013-06-02 21:11:112556 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532557
[email protected]b63f1d62014-07-18 15:40:592558 image_manager_.reset(new ImageManager);
2559
[email protected]302ce6d2011-07-07 23:28:112560 util_.set_num_compressed_texture_formats(
2561 validators_->compressed_texture_format.GetValues().size());
2562
[email protected]1071e572011-02-09 20:00:122563 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2564 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2565 // OpenGL ES 2.0 does not have this issue.
2566 glEnableVertexAttribArray(0);
2567 }
[email protected]b1122982010-05-17 23:04:242568 glGenBuffersARB(1, &attrib_0_buffer_id_);
2569 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2570 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2571 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402572 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082573
[email protected]1868a342012-11-07 15:56:022574 state_.texture_units.resize(group_->max_texture_units());
2575 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492576 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312577 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492578 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152579 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492580 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072581 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492582 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572583 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312584 }
[email protected]62e155e2012-10-23 22:43:152585 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492586 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072587 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492588 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572589 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462590 }
[email protected]370eaf12013-05-18 09:19:492591 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2592 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572593 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492594 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2595 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572596 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152597 }
[email protected]00f893d2010-08-24 18:55:492598 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502599 CHECK_GL_ERROR();
2600
[email protected]069944672012-04-25 20:52:232601 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402602 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542603 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022604 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432605 // max_sample_count must be initialized to a sane value. If
2606 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2607 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022608 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402609 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022610 max_sample_count);
2611 } else {
2612 offscreen_target_samples_ = 1;
2613 }
[email protected]845c4e32014-08-13 11:50:402614 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022615
2616 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2617 const bool rgb8_supported =
2618 context_->HasExtension("GL_OES_rgb8_rgba8");
2619 // The only available default render buffer formats in GLES2 have very
2620 // little precision. Don't enable multisampling unless 8-bit render
2621 // buffer formats are available--instead fall back to 8-bit textures.
2622 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402623 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022624 GL_RGBA8 : GL_RGB8;
2625 } else {
2626 offscreen_target_samples_ = 1;
[email protected]845c4e32014-08-13 11:50:402627 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022628 GL_RGBA : GL_RGB;
2629 }
2630
2631 // ANGLE only supports packed depth/stencil formats, so use it if it is
2632 // available.
2633 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182634 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272635 VLOG(1) << "GL_OES_packed_depth_stencil "
2636 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402637 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002638 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022639 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2640 offscreen_target_stencil_format_ = 0;
2641 } else {
2642 // It may be the case that this depth/stencil combination is not
2643 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402644 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022645 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402646 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022647 GL_STENCIL_INDEX8 : 0;
2648 }
2649 } else {
[email protected]845c4e32014-08-13 11:50:402650 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022651 GL_RGBA : GL_RGB;
2652
2653 // If depth is requested at all, use the packed depth stencil format if
2654 // it's available, as some desktop GL drivers don't support any non-packed
2655 // formats for depth attachments.
2656 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182657 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272658 VLOG(1) << "GL_EXT_packed_depth_stencil "
2659 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022660
[email protected]845c4e32014-08-13 11:50:402661 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002662 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022663 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2664 offscreen_target_stencil_format_ = 0;
2665 } else {
[email protected]845c4e32014-08-13 11:50:402666 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022667 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402668 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022669 GL_STENCIL_INDEX : 0;
2670 }
2671 }
2672
[email protected]845c4e32014-08-13 11:50:402673 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]97872062010-11-03 19:07:052674 GL_RGBA : GL_RGB;
2675
[email protected]6217d392010-03-25 22:08:352676 // Create the target frame buffer. This is the one that the client renders
2677 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352678 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352679 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022680 // Due to GLES2 format limitations, either the color texture (for
2681 // non-multisampling) or the color render buffer (for multisampling) will be
2682 // attached to the offscreen frame buffer. The render buffer has more
2683 // limited formats available to it, but the texture can't do multisampling.
2684 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402685 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2686 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022687 offscreen_target_color_render_buffer_->Create();
2688 } else {
[email protected]ce296892013-10-24 22:04:362689 offscreen_target_color_texture_.reset(new BackTexture(
2690 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022691 offscreen_target_color_texture_->Create();
2692 }
[email protected]d5a28e452013-10-10 01:01:402693 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2694 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152695 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402696 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2697 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152698 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352699
2700 // Create the saved offscreen texture. The target frame buffer is copied
2701 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352702 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022703 offscreen_saved_frame_buffer_->Create();
2704 //
[email protected]ce296892013-10-24 22:04:362705 offscreen_saved_color_texture_.reset(new BackTexture(
2706 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352707 offscreen_saved_color_texture_->Create();
2708
[email protected]6217d392010-03-25 22:08:352709 // Allocate the render buffers at their initial size and check the status
2710 // of the frame buffers is okay.
dongseong.hwang4c04a162015-03-04 07:27:332711 if (!ResizeOffscreenFrameBuffer(offscreen_size)) {
[email protected]d0498742010-09-20 20:27:012712 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382713 Destroy(true);
[email protected]6217d392010-03-25 22:08:352714 return false;
2715 }
2716
dongseong.hwang4c04a162015-03-04 07:27:332717 state_.viewport_width = offscreen_size.width();
2718 state_.viewport_height = offscreen_size.height();
2719
[email protected]678a73f2012-12-19 19:22:092720 // Allocate the offscreen saved color texture.
2721 DCHECK(offscreen_saved_color_format_);
2722 offscreen_saved_color_texture_->AllocateStorage(
2723 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2724
2725 offscreen_saved_frame_buffer_->AttachRenderTexture(
2726 offscreen_saved_color_texture_.get());
2727 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2728 GL_FRAMEBUFFER_COMPLETE) {
2729 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2730 Destroy(true);
2731 return false;
2732 }
2733
[email protected]6217d392010-03-25 22:08:352734 // Bind to the new default frame buffer (the offscreen target frame buffer).
2735 // This should now be associated with ID zero.
2736 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102737 } else {
2738 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2739 // These are NOT if the back buffer has these proprorties. They are
2740 // if we want the command buffer to enforce them regardless of what
2741 // the real backbuffer is assuming the real back buffer gives us more than
2742 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2743 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2744 // can't do anything about that.
2745
achaulkcf5316f2014-09-26 19:28:422746 if (!surfaceless_) {
kbrc9f0e10c2015-03-31 19:49:122747 GLint alpha_bits = 0;
2748 GLint depth_bits = 0;
2749 GLint stencil_bits = 0;
2750
2751 bool default_fb = (GetBackbufferServiceId() == 0);
2752
marcheu1856f5d52015-04-04 01:42:532753 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:122754 glGetFramebufferAttachmentParameterivEXT(
2755 GL_FRAMEBUFFER,
2756 default_fb ? GL_BACK_LEFT : GL_COLOR_ATTACHMENT0,
2757 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits);
2758 glGetFramebufferAttachmentParameterivEXT(
2759 GL_FRAMEBUFFER,
2760 default_fb ? GL_DEPTH : GL_DEPTH_ATTACHMENT,
2761 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits);
2762 glGetFramebufferAttachmentParameterivEXT(
2763 GL_FRAMEBUFFER,
2764 default_fb ? GL_STENCIL : GL_STENCIL_ATTACHMENT,
2765 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits);
2766 } else {
2767 glGetIntegerv(GL_ALPHA_BITS, &alpha_bits);
2768 glGetIntegerv(GL_DEPTH_BITS, &depth_bits);
2769 glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
2770 }
2771
achaulkcf5316f2014-09-26 19:28:422772 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2773 // the user requested RGB then RGB. If the user did not specify a
2774 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2775 back_buffer_color_format_ =
kbrc9f0e10c2015-03-31 19:49:122776 (attrib_parser.alpha_size != 0 && alpha_bits > 0) ? GL_RGBA : GL_RGB;
2777 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && depth_bits > 0;
2778 back_buffer_has_stencil_ =
2779 attrib_parser.stencil_size != 0 && stencil_bits > 0;
achaulkcf5316f2014-09-26 19:28:422780 }
dongseong.hwang4c04a162015-03-04 07:27:332781
2782 state_.viewport_width = surface->GetSize().width();
2783 state_.viewport_height = surface->GetSize().height();
[email protected]6217d392010-03-25 22:08:352784 }
2785
[email protected]76a0ee102010-04-07 21:03:042786 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2787 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2788 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372789 // mailing list archives. It also implicitly enables the desktop GL
2790 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2791 // variable in fragment shaders.
marcheu1856f5d52015-04-04 01:42:532792 if (!feature_info_->gl_version_info().BehavesLikeGLES()) {
[email protected]b9363b22010-06-09 22:06:152793 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372794 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152795 }
[email protected]de17df392010-04-23 21:09:412796
[email protected]706b69f2012-07-27 04:59:302797 has_robustness_extension_ =
2798 context->HasExtension("GL_ARB_robustness") ||
oetuaho37cc50e2014-10-31 11:19:202799 context->HasExtension("GL_KHR_robustness") ||
[email protected]706b69f2012-07-27 04:59:302800 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432801
[email protected]c2f8c8402010-12-06 18:07:242802 if (!InitializeShaderTranslator()) {
2803 return false;
[email protected]de17df392010-04-23 21:09:412804 }
[email protected]76a0ee102010-04-07 21:03:042805
[email protected]5904806b2012-05-08 18:10:222806 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282807 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022808 viewport_max_width_ = viewport_params[0];
2809 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282810
[email protected]88a61bf2012-10-27 13:00:422811 state_.scissor_width = state_.viewport_width;
2812 state_.scissor_height = state_.viewport_height;
2813
[email protected]11f3e702012-06-19 19:00:012814 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342815 state_.InitCapabilities(NULL);
2816 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242817 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012818
2819 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2820 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2821 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2822 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
orglofchcad5a6742014-11-07 19:51:122823 DoBindValueBufferCHROMIUM(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, 0);
[email protected]11f3e702012-06-19 19:00:012824
achaulkcf5316f2014-09-26 19:28:422825 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002826#if defined(OS_ANDROID)
2827 // Temporary workaround for Android WebView because this clear ignores the
2828 // clip and corrupts that external UI of the App. Not calling glClear is ok
2829 // because the system already clears the buffer before each draw. Proper
2830 // fix might be setting the scissor clip properly before initialize. See
2831 // crbug.com/259023 for details.
2832 call_gl_clear = surface_->GetHandle();
2833#endif
2834 if (call_gl_clear) {
2835 // Clear the backbuffer.
2836 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2837 }
[email protected]561cc0a62013-05-07 18:34:452838
[email protected]b381ee32014-03-22 02:43:432839 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2840 if (feature_info_->workarounds()
2841 .disable_post_sub_buffers_for_onscreen_surfaces &&
2842 !surface->IsOffscreen())
2843 supports_post_sub_buffer_ = false;
2844
[email protected]62e155e2012-10-23 22:43:152845 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462846 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2847 }
[email protected]dd289a5d62012-06-30 22:05:462848
[email protected]9b753992013-04-27 02:04:412849 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2850 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242851 }
[email protected]85cb4682013-04-20 00:54:242852
[email protected]97419c02013-04-10 02:52:382853 // Only compositor contexts are known to use only the subset of GL
2854 // that can be safely migrated between the iGPU and the dGPU. Mark
2855 // those contexts as safe to forcibly transition between the GPUs.
2856 // http://crbug.com/180876, http://crbug.com/227228
2857 if (!offscreen)
2858 context_->SetSafeToForceGpuSwitch();
2859
[email protected]85a4ac22013-05-31 01:58:472860 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072861 AsyncPixelTransferManager::Create(context.get()));
2862 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592863
sievers2384f2b2014-11-18 02:10:352864 if (workarounds().gl_clear_broken) {
2865 DCHECK(!clear_framebuffer_blit_.get());
2866 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit");
2867 clear_framebuffer_blit_.reset(new ClearFramebufferResourceManager(this));
2868 if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR)
2869 return false;
2870 }
2871
[email protected]91c94eb2013-10-22 10:32:542872 framebuffer_manager()->AddObserver(this);
2873
[email protected]246a70452010-03-05 21:53:502874 return true;
[email protected]96449d2c2009-11-25 00:01:322875}
2876
[email protected]6d668892013-12-04 21:37:122877Capabilities GLES2DecoderImpl::GetCapabilities() {
2878 DCHECK(initialized());
2879
2880 Capabilities caps;
piman1c2e0a852014-11-12 05:17:552881 caps.VisitPrecisions([](GLenum shader, GLenum type,
2882 Capabilities::ShaderPrecision* shader_precision) {
2883 GLint range[2] = {0, 0};
2884 GLint precision = 0;
2885 GetShaderPrecisionFormatImpl(shader, type, range, &precision);
2886 shader_precision->min_range = range[0];
2887 shader_precision->max_range = range[1];
2888 shader_precision->precision = precision;
2889 });
2890 DoGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
2891 &caps.max_combined_texture_image_units);
2892 DoGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps.max_cube_map_texture_size);
2893 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
2894 &caps.max_fragment_uniform_vectors);
2895 DoGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps.max_renderbuffer_size);
2896 DoGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps.max_texture_image_units);
2897 DoGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.max_texture_size);
2898 DoGetIntegerv(GL_MAX_VARYING_VECTORS, &caps.max_varying_vectors);
2899 DoGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps.max_vertex_attribs);
2900 DoGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
2901 &caps.max_vertex_texture_image_units);
2902 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
2903 &caps.max_vertex_uniform_vectors);
2904 DoGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
2905 &caps.num_compressed_texture_formats);
2906 DoGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps.num_shader_binary_formats);
2907 DoGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM,
2908 &caps.bind_generates_resource_chromium);
heejin.r.chung8f143292015-02-05 02:44:002909 if (unsafe_es3_apis_enabled()) {
zmoba1fe9d22015-04-15 21:42:512910 // TODO(zmo): Note that some parameter values could be more than 32-bit,
2911 // but for now we clamp them to 32-bit max.
2912 DoGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &caps.max_3d_texture_size);
2913 DoGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &caps.max_array_texture_layers);
2914 DoGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &caps.max_color_attachments);
2915 DoGetIntegerv(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,
2916 &caps.max_combined_fragment_uniform_components);
2917 DoGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS,
2918 &caps.max_combined_uniform_blocks);
2919 DoGetIntegerv(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,
2920 &caps.max_combined_vertex_uniform_components);
2921 DoGetIntegerv(GL_MAX_DRAW_BUFFERS, &caps.max_draw_buffers);
2922 DoGetIntegerv(GL_MAX_ELEMENT_INDEX, &caps.max_element_index);
2923 DoGetIntegerv(GL_MAX_ELEMENTS_INDICES, &caps.max_elements_indices);
2924 DoGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &caps.max_elements_vertices);
2925 DoGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS,
2926 &caps.max_fragment_input_components);
2927 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS,
2928 &caps.max_fragment_uniform_blocks);
2929 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,
2930 &caps.max_fragment_uniform_components);
2931 DoGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET,
2932 &caps.max_program_texel_offset);
2933 DoGetIntegerv(GL_MAX_SAMPLES, &caps.max_samples);
2934 DoGetIntegerv(GL_MAX_SERVER_WAIT_TIMEOUT, &caps.max_server_wait_timeout);
2935 DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
2936 &caps.max_transform_feedback_interleaved_components);
heejin.r.chung8f143292015-02-05 02:44:002937 DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
2938 &caps.max_transform_feedback_separate_attribs);
zmoba1fe9d22015-04-15 21:42:512939 DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
2940 &caps.max_transform_feedback_separate_components);
2941 DoGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &caps.max_uniform_block_size);
heejin.r.chung8f143292015-02-05 02:44:002942 DoGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
2943 &caps.max_uniform_buffer_bindings);
zmoba1fe9d22015-04-15 21:42:512944 DoGetIntegerv(GL_MAX_VARYING_COMPONENTS, &caps.max_varying_components);
2945 DoGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS,
2946 &caps.max_vertex_output_components);
2947 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS,
2948 &caps.max_vertex_uniform_blocks);
2949 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS,
2950 &caps.max_vertex_uniform_components);
2951 DoGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps.min_program_texel_offset);
2952 DoGetIntegerv(GL_NUM_EXTENSIONS, &caps.num_extensions);
2953 DoGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS,
2954 &caps.num_program_binary_formats);
heejin.r.chung8f143292015-02-05 02:44:002955 DoGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
2956 &caps.uniform_buffer_offset_alignment);
zmoba1fe9d22015-04-15 21:42:512957 // TODO(zmo): once we switch to MANGLE, we should query version numbers.
2958 caps.major_version = 3;
2959 caps.minor_version = 0;
heejin.r.chung8f143292015-02-05 02:44:002960 }
[email protected]6d668892013-12-04 21:37:122961
[email protected]6d668892013-12-04 21:37:122962 caps.egl_image_external =
2963 feature_info_->feature_flags().oes_egl_image_external;
christiank07b6d8b2015-02-25 09:41:252964 caps.texture_format_atc =
2965 feature_info_->feature_flags().ext_texture_format_atc;
[email protected]6d668892013-12-04 21:37:122966 caps.texture_format_bgra8888 =
2967 feature_info_->feature_flags().ext_texture_format_bgra8888;
christiank07b6d8b2015-02-25 09:41:252968 caps.texture_format_dxt1 =
2969 feature_info_->feature_flags().ext_texture_format_dxt1;
2970 caps.texture_format_dxt5 =
2971 feature_info_->feature_flags().ext_texture_format_dxt5;
[email protected]6d668892013-12-04 21:37:122972 caps.texture_format_etc1 =
2973 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:202974 caps.texture_format_etc1_npot =
2975 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:122976 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2977 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2978 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2979 caps.discard_framebuffer =
2980 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352981 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122982
2983#if defined(OS_MACOSX)
2984 // This is unconditionally true on mac, no need to test for it at runtime.
2985 caps.iosurface = true;
2986#endif
2987
[email protected]b381ee32014-03-22 02:43:432988 caps.post_sub_buffer = supports_post_sub_buffer_;
reveman340109182014-09-30 15:36:452989 caps.image = true;
[email protected]6d668892013-12-04 21:37:122990
ed9198b422014-10-23 15:01:372991 caps.blend_equation_advanced =
2992 feature_info_->feature_flags().blend_equation_advanced;
2993 caps.blend_equation_advanced_coherent =
2994 feature_info_->feature_flags().blend_equation_advanced_coherent;
hendrikwfc25ca6192014-12-02 06:05:132995 caps.texture_rg = feature_info_->feature_flags().ext_texture_rg;
[email protected]6d668892013-12-04 21:37:122996 return caps;
2997}
2998
[email protected]302ce6d2011-07-07 23:28:112999void GLES2DecoderImpl::UpdateCapabilities() {
3000 util_.set_num_compressed_texture_formats(
3001 validators_->compressed_texture_format.GetValues().size());
3002 util_.set_num_shader_binary_formats(
3003 validators_->shader_binary_format.GetValues().size());
3004}
3005
[email protected]c2f8c8402010-12-06 18:07:243006bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:443007 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
3008
[email protected]c2f8c8402010-12-06 18:07:243009 if (!use_shader_translator_) {
3010 return true;
3011 }
3012 ShBuiltInResources resources;
3013 ShInitBuiltInResources(&resources);
3014 resources.MaxVertexAttribs = group_->max_vertex_attribs();
3015 resources.MaxVertexUniformVectors =
3016 group_->max_vertex_uniform_vectors();
3017 resources.MaxVaryingVectors = group_->max_varying_vectors();
3018 resources.MaxVertexTextureImageUnits =
3019 group_->max_vertex_texture_image_units();
3020 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
3021 resources.MaxTextureImageUnits = group_->max_texture_image_units();
3022 resources.MaxFragmentUniformVectors =
3023 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:493024 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:243025 resources.MaxExpressionComplexity = 256;
3026 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:043027
[email protected]46c86752013-05-21 05:08:393028 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:213029 GLint precision = 0;
3030 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
3031 range, &precision);
[email protected]448e459e2013-06-12 17:00:413032 resources.FragmentPrecisionHigh =
3033 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:143034
[email protected]f0d74742011-10-03 16:31:043035 if (force_webgl_glsl_validation_) {
3036 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:493037 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:133038 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:443039 if (!draw_buffers_explicitly_enabled_)
3040 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:063041 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
oetuaho0decd442014-10-13 08:40:463042 resources.NV_draw_buffers =
3043 draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
[email protected]f0d74742011-10-03 16:31:043044 } else {
3045 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:153046 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:463047 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:153048 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:063049 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:153050 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:493051 resources.EXT_draw_buffers =
3052 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:493053 resources.EXT_frag_depth =
3054 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:063055 resources.EXT_shader_texture_lod =
3056 features().ext_shader_texture_lod ? 1 : 0;
oetuaho0decd442014-10-13 08:40:463057 resources.NV_draw_buffers =
3058 features().nv_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:043059 }
3060
zmo0ee15862015-03-04 03:50:183061 ShShaderSpec shader_spec;
3062 if (force_webgl_glsl_validation_) {
3063 shader_spec = unsafe_es3_apis_enabled() ? SH_WEBGL2_SPEC : SH_WEBGL_SPEC;
3064 } else {
3065 shader_spec = unsafe_es3_apis_enabled() ? SH_GLES3_SPEC : SH_GLES2_SPEC;
3066 }
3067
3068 if ((shader_spec == SH_WEBGL_SPEC || shader_spec == SH_WEBGL2_SPEC) &&
3069 features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:023070 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:053071 else
3072 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:123073 ShaderTranslatorInterface::GlslImplementationType implementation_type =
marcheu1856f5d52015-04-04 01:42:533074 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
3075 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:213076 int driver_bug_workarounds = 0;
3077 if (workarounds().needs_glsl_built_in_function_emulation)
3078 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:543079 if (workarounds().init_gl_position_in_vertex_shader)
3080 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:113081 if (workarounds().unfold_short_circuit_as_ternary_operation)
3082 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:053083 if (workarounds().init_varyings_without_static_use)
3084 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:063085 if (workarounds().unroll_for_loop_with_sampler_array_index)
3086 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:253087 if (workarounds().scalarize_vec_and_mat_constructor_args)
3088 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:273089 if (workarounds().regenerate_struct_names)
3090 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
[email protected]87fb6ab2012-06-13 22:28:043091
avi9ab037202014-12-22 23:49:533092 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
3093 switches::kEmulateShaderPrecision))
oetuahoaffd85abe2014-12-11 09:47:093094 resources.WEBGL_debug_shader_precision = true;
3095
[email protected]03cef9b2014-04-03 15:58:143096 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:263097 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:143098 shader_spec,
3099 &resources,
[email protected]a6739bc2013-09-07 04:45:213100 implementation_type,
3101 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:043102 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:243103 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:383104 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:243105 return false;
3106 }
[email protected]87fb6ab2012-06-13 22:28:043107
[email protected]03cef9b2014-04-03 15:58:143108 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:263109 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:143110 shader_spec,
3111 &resources,
[email protected]a6739bc2013-09-07 04:45:213112 implementation_type,
3113 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:043114 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:243115 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:383116 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:243117 return false;
3118 }
3119 return true;
3120}
3121
[email protected]ae51d192010-04-27 00:48:033122bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:473123 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353124 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033125 return false;
3126 }
3127 }
[email protected]40d90a22013-04-09 03:39:553128 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033129 glGenBuffersARB(n, service_ids.get());
3130 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353131 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033132 }
3133 return true;
3134}
3135
3136bool GLES2DecoderImpl::GenFramebuffersHelper(
3137 GLsizei n, const GLuint* client_ids) {
3138 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353139 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033140 return false;
3141 }
3142 }
[email protected]40d90a22013-04-09 03:39:553143 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033144 glGenFramebuffersEXT(n, service_ids.get());
3145 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353146 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033147 }
3148 return true;
3149}
3150
3151bool GLES2DecoderImpl::GenRenderbuffersHelper(
3152 GLsizei n, const GLuint* client_ids) {
3153 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353154 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033155 return false;
3156 }
3157 }
[email protected]40d90a22013-04-09 03:39:553158 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033159 glGenRenderbuffersEXT(n, service_ids.get());
3160 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353161 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033162 }
3163 return true;
3164}
3165
orglofchcad5a6742014-11-07 19:51:123166bool GLES2DecoderImpl::GenValuebuffersCHROMIUMHelper(GLsizei n,
3167 const GLuint* client_ids) {
3168 for (GLsizei ii = 0; ii < n; ++ii) {
3169 if (GetValuebuffer(client_ids[ii])) {
3170 return false;
3171 }
3172 }
3173 for (GLsizei ii = 0; ii < n; ++ii) {
3174 CreateValuebuffer(client_ids[ii]);
3175 }
3176 return true;
3177}
3178
[email protected]ae51d192010-04-27 00:48:033179bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
3180 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353181 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033182 return false;
3183 }
3184 }
[email protected]40d90a22013-04-09 03:39:553185 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033186 glGenTextures(n, service_ids.get());
3187 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353188 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033189 }
3190 return true;
3191}
3192
3193void GLES2DecoderImpl::DeleteBuffersHelper(
3194 GLsizei n, const GLuint* client_ids) {
3195 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:213196 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103197 if (buffer && !buffer->IsDeleted()) {
zmo2a09dc052015-03-12 00:48:253198 buffer->RemoveMappedRange();
[email protected]e259eb412012-10-13 05:47:243199 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:113200 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:243201 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103202 }
[email protected]ed9f9cd2013-02-27 21:12:353203 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033204 }
[email protected]a93bb842010-02-16 23:03:473205 }
[email protected]07f54fcc2009-12-22 02:46:303206}
3207
[email protected]ae51d192010-04-27 00:48:033208void GLES2DecoderImpl::DeleteFramebuffersHelper(
3209 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453210 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153211 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:113212
[email protected]a25fa872010-03-25 02:57:583213 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353214 Framebuffer* framebuffer =
3215 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103216 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:343217 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]ebfb73c2012-08-15 02:37:453218 GLenum target = supports_separate_framebuffer_binds ?
3219 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
vmiura7d08fee52015-02-18 18:39:343220
3221 // Unbind attachments on FBO before deletion.
3222 if (workarounds().unbind_attachments_on_bound_render_fbo_delete)
3223 framebuffer->DoUnbindGLAttachmentsForWorkaround(target);
3224
[email protected]b177ae22011-11-01 03:29:113225 glBindFramebufferEXT(target, GetBackbufferServiceId());
vmiura7d08fee52015-02-18 18:39:343226 framebuffer_state_.bound_draw_framebuffer = NULL;
3227 framebuffer_state_.clear_state_dirty = true;
[email protected]b177ae22011-11-01 03:29:113228 }
[email protected]9d3b2e12013-10-02 01:04:343229 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
3230 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:453231 GLenum target = supports_separate_framebuffer_binds ?
3232 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113233 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:463234 }
[email protected]70d34263c2013-01-09 00:27:453235 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:353236 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033237 }
[email protected]a25fa872010-03-25 02:57:583238 }
[email protected]07f54fcc2009-12-22 02:46:303239}
3240
[email protected]ae51d192010-04-27 00:48:033241void GLES2DecoderImpl::DeleteRenderbuffersHelper(
3242 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453243 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153244 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:583245 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353246 Renderbuffer* renderbuffer =
3247 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103248 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:113249 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:243250 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103251 }
3252 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453253 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343254 if (framebuffer_state_.bound_read_framebuffer.get()) {
3255 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113256 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103257 }
[email protected]9d3b2e12013-10-02 01:04:343258 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3259 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113260 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103261 }
3262 } else {
[email protected]9d3b2e12013-10-02 01:04:343263 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3264 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113265 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103266 }
3267 }
[email protected]c986af502013-08-14 01:04:443268 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:353269 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033270 }
[email protected]a25fa872010-03-25 02:57:583271 }
[email protected]07f54fcc2009-12-22 02:46:303272}
3273
orglofchcad5a6742014-11-07 19:51:123274void GLES2DecoderImpl::DeleteValuebuffersCHROMIUMHelper(
3275 GLsizei n,
3276 const GLuint* client_ids) {
3277 for (GLsizei ii = 0; ii < n; ++ii) {
3278 Valuebuffer* valuebuffer = GetValuebuffer(client_ids[ii]);
3279 if (valuebuffer) {
3280 if (state_.bound_valuebuffer.get() == valuebuffer) {
3281 state_.bound_valuebuffer = NULL;
3282 }
3283 RemoveValuebuffer(client_ids[ii]);
3284 }
3285 }
3286}
3287
[email protected]ae51d192010-04-27 00:48:033288void GLES2DecoderImpl::DeleteTexturesHelper(
3289 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453290 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153291 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:473292 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:493293 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3294 if (texture_ref) {
3295 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103296 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443297 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463298 }
[email protected]370eaf12013-05-18 09:19:493299 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023300 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493301 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103302 }
3303 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453304 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343305 if (framebuffer_state_.bound_read_framebuffer.get()) {
3306 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113307 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103308 }
[email protected]9d3b2e12013-10-02 01:04:343309 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3310 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113311 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103312 }
3313 } else {
[email protected]9d3b2e12013-10-02 01:04:343314 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3315 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113316 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103317 }
3318 }
[email protected]e51bdf32011-11-23 22:21:463319#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073320 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463321 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3322 ReleaseIOSurfaceForTexture(service_id);
3323 }
3324#endif
[email protected]ed9f9cd2013-02-27 21:12:353325 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033326 }
[email protected]a93bb842010-02-16 23:03:473327 }
[email protected]07f54fcc2009-12-22 02:46:303328}
3329
[email protected]43f28f832010-02-03 02:28:483330// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323331
[email protected]eb54a562010-01-20 21:55:183332bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343333 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383334 return false;
3335
sieversfbaa5dc2015-04-28 00:45:313336 if (WasContextLost()) {
3337 LOG(ERROR) << " GLES2DecoderImpl: Trying to make lost context current.";
3338 return false;
3339 }
3340
3341 if (!context_->MakeCurrent(surface_.get())) {
[email protected]38d139d2011-07-14 00:38:433342 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
sieversfbaa5dc2015-04-28 00:45:313343 MarkContextLost(error::kMakeCurrentFailed);
3344 group_->LoseContexts(error::kUnknown);
3345 return false;
3346 }
[email protected]e9f0ca82013-04-01 23:52:293347
sieversfbaa5dc2015-04-28 00:45:313348 if (CheckResetStatus()) {
3349 LOG(ERROR)
3350 << " GLES2DecoderImpl: Context reset detected after MakeCurrent.";
3351 group_->LoseContexts(error::kUnknown);
[email protected]63c9b052012-05-17 18:27:383352 return false;
[email protected]38d139d2011-07-14 00:38:433353 }
3354
[email protected]69a8701e2013-03-07 21:31:093355 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093356
[email protected]9b753992013-04-27 02:04:413357 // Rebind the FBO if it was unbound by the context.
3358 if (workarounds().unbind_fbo_on_context_switch)
3359 RestoreFramebufferBindings();
3360
[email protected]c986af502013-08-14 01:04:443361 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493362
[email protected]69a8701e2013-03-07 21:31:093363 return true;
3364}
3365
3366void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553367 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323368 if (engine() && query_manager_.get())
3369 query_manager_->ProcessPendingTransferQueries();
3370
[email protected]5b3a8e02013-03-13 05:36:443371 // TODO(epenner): Is there a better place to do this?
3372 // This needs to occur before we execute any batch of commands
3373 // from the client, as the client may have recieved an async
3374 // completion while issuing those commands.
3375 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483376 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183377}
3378
[email protected]8e3e0662010-08-23 18:46:303379static void RebindCurrentFramebuffer(
3380 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063381 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243382 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063383 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463384
[email protected]a3783712012-01-20 22:18:243385 if (framebuffer_id == 0) {
3386 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303387 }
[email protected]297ca1c2011-06-20 23:08:463388
[email protected]8e3e0662010-08-23 18:46:303389 glBindFramebufferEXT(target, framebuffer_id);
3390}
3391
3392void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443393 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463394
[email protected]62e155e2012-10-23 22:43:153395 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303396 RebindCurrentFramebuffer(
3397 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343398 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243399 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303400 } else {
3401 RebindCurrentFramebuffer(
3402 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343403 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243404 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303405 RebindCurrentFramebuffer(
3406 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343407 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243408 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303409 }
[email protected]70d34263c2013-01-09 00:27:453410 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303411}
3412
[email protected]0d6bfdc2011-11-02 01:32:203413bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353414 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203415 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103416 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423417 if (surfaceless_)
3418 return false;
[email protected]60f22d32012-12-12 00:31:583419 if (backbuffer_needs_clear_bits_) {
3420 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323421 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453422 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583423 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473424 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3425 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583426 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453427 state_.SetDeviceDepthMask(GL_TRUE);
3428 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423429 bool reset_draw_buffer = false;
brucedawson18249152014-10-31 23:02:323430 if ((backbuffer_needs_clear_bits_ & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]ee757922014-06-06 05:21:423431 group_->draw_buffer() == GL_NONE) {
3432 reset_draw_buffer = true;
3433 GLenum buf = GL_BACK;
3434 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3435 buf = GL_COLOR_ATTACHMENT0;
3436 glDrawBuffersARB(1, &buf);
3437 }
[email protected]60f22d32012-12-12 00:31:583438 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423439 if (reset_draw_buffer) {
3440 GLenum buf = GL_NONE;
3441 glDrawBuffersARB(1, &buf);
3442 }
[email protected]60f22d32012-12-12 00:31:583443 backbuffer_needs_clear_bits_ = 0;
3444 RestoreClearState();
3445 }
[email protected]0d6bfdc2011-11-02 01:32:203446 return true;
3447 }
3448
[email protected]968351b2011-12-20 08:26:513449 if (framebuffer_manager()->IsComplete(framebuffer)) {
3450 return true;
3451 }
3452
[email protected]0d6bfdc2011-11-02 01:32:203453 GLenum completeness = framebuffer->IsPossiblyComplete();
3454 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513455 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433456 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273457 return false;
3458 }
[email protected]0d6bfdc2011-11-02 01:32:203459
3460 // Are all the attachments cleared?
3461 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3462 texture_manager()->HaveUnclearedMips()) {
3463 if (!framebuffer->IsCleared()) {
3464 // Can we clear them?
[email protected]73276522012-11-09 05:50:203465 if (framebuffer->GetStatus(texture_manager(), target) !=
3466 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513467 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433468 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3469 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203470 return false;
3471 }
3472 ClearUnclearedAttachments(target, framebuffer);
3473 }
3474 }
3475
[email protected]968351b2011-12-20 08:26:513476 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203477 if (framebuffer->GetStatus(texture_manager(), target) !=
3478 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513479 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433480 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3481 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513482 return false;
3483 }
3484 framebuffer_manager()->MarkAsComplete(framebuffer);
3485 }
3486
[email protected]0d6bfdc2011-11-02 01:32:203487 // NOTE: At this point we don't know if the framebuffer is complete but
3488 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273489 return true;
3490}
3491
[email protected]0d6bfdc2011-11-02 01:32:203492bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153493 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513494 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343495 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3496 func_name);
[email protected]28718a92013-04-04 12:12:513497
3498 if (valid)
3499 OnUseFramebuffer();
3500
3501 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203502 }
[email protected]9d3b2e12013-10-02 01:04:343503 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113504 GL_DRAW_FRAMEBUFFER_EXT,
3505 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343506 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113507 GL_READ_FRAMEBUFFER_EXT,
3508 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203509}
3510
[email protected]2ea5950d2014-07-09 18:20:343511bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3512 const char* func_name) {
3513 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3514 framebuffer_state_.bound_read_framebuffer.get() :
3515 framebuffer_state_.bound_draw_framebuffer.get();
3516 if (!framebuffer)
3517 return true;
3518 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3519 LOCAL_SET_GL_ERROR(
3520 GL_INVALID_OPERATION, func_name, "no color image attached");
3521 return false;
3522 }
3523 return true;
3524}
3525
zmo383512cf2014-10-14 00:11:003526bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
3527 TextureRef* texture, GLint level) {
3528 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3529 framebuffer_state_.bound_read_framebuffer.get() :
3530 framebuffer_state_.bound_draw_framebuffer.get();
3531 if (!framebuffer)
3532 return false;
3533 const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
3534 GL_COLOR_ATTACHMENT0);
3535 if (!attachment)
3536 return false;
3537 return attachment->FormsFeedbackLoop(texture, level);
3538}
3539
[email protected]8e3e0662010-08-23 18:46:303540gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353541 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453542 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203543 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353544 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203545 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263546 if (attachment) {
3547 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503548 }
[email protected]9edc6b22010-12-23 02:00:263549 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023550 } else if (offscreen_target_frame_buffer_.get()) {
3551 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353552 } else {
[email protected]f62a5ab2011-05-23 20:34:153553 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023554 }
[email protected]246a70452010-03-05 21:53:503555}
3556
[email protected]68586372013-12-11 01:27:593557GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3558 Framebuffer* framebuffer =
3559 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3560 if (framebuffer != NULL) {
3561 return framebuffer->GetColorAttachmentTextureType();
3562 } else {
3563 return GL_UNSIGNED_BYTE;
3564 }
3565}
3566
[email protected]9edc6b22010-12-23 02:00:263567GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353568 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453569 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203570 if (framebuffer != NULL) {
3571 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463572 } else if (offscreen_target_frame_buffer_.get()) {
3573 return offscreen_target_color_format_;
3574 } else {
3575 return back_buffer_color_format_;
3576 }
3577}
3578
3579GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353580 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453581 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203582 if (framebuffer != NULL) {
3583 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263584 } else if (offscreen_target_frame_buffer_.get()) {
3585 return offscreen_target_color_format_;
3586 } else {
[email protected]32fe9aa2011-01-21 23:47:133587 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263588 }
3589}
3590
[email protected]9a5afa432011-07-22 18:16:393591void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513592 if (!offscreen_saved_color_texture_info_.get())
3593 return;
3594 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3595 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3596 texture_manager()->SetLevelInfo(
3597 offscreen_saved_color_texture_info_.get(),
3598 GL_TEXTURE_2D,
3599 0, // level
3600 GL_RGBA,
3601 offscreen_size_.width(),
3602 offscreen_size_.height(),
3603 1, // depth
3604 0, // border
3605 GL_RGBA,
3606 GL_UNSIGNED_BYTE,
3607 true);
[email protected]737191ee72014-03-09 08:02:423608 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513609 "UpdateParentTextureInfo",
3610 GetErrorState(),
3611 offscreen_saved_color_texture_info_.get(),
3612 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263613 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423614 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513615 "UpdateParentTextureInfo",
3616 GetErrorState(),
3617 offscreen_saved_color_texture_info_.get(),
3618 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263619 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423620 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513621 "UpdateParentTextureInfo",
3622 GetErrorState(),
3623 offscreen_saved_color_texture_info_.get(),
3624 GL_TEXTURE_WRAP_S,
3625 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423626 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513627 "UpdateParentTextureInfo",
3628 GetErrorState(),
3629 offscreen_saved_color_texture_info_.get(),
3630 GL_TEXTURE_WRAP_T,
3631 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443632 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3633 &state_, target);
[email protected]2ad674132013-06-05 07:48:513634 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353635}
3636
[email protected]799b4b22011-08-22 17:09:593637void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073638 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523639 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003640}
3641
[email protected]1d82e822013-04-10 21:32:323642Logger* GLES2DecoderImpl::GetLogger() {
3643 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523644}
3645
[email protected]cac16542014-01-15 17:53:513646void GLES2DecoderImpl::BeginDecoding() {
3647 gpu_tracer_->BeginDecoding();
dyencb86f2f2014-12-09 18:35:413648 gpu_trace_commands_ = gpu_tracer_->IsTracing() && *gpu_decoder_category_;
vmiura1c2b1de2014-09-19 19:03:243649 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3650 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513651}
3652
3653void GLES2DecoderImpl::EndDecoding() {
3654 gpu_tracer_->EndDecoding();
3655}
3656
[email protected]d3eba342013-04-18 21:11:503657ErrorState* GLES2DecoderImpl::GetErrorState() {
3658 return state_.GetErrorState();
3659}
3660
[email protected]e3932abb2013-03-13 00:01:373661void GLES2DecoderImpl::SetShaderCacheCallback(
3662 const ShaderCacheCallback& callback) {
3663 shader_cache_callback_ = callback;
3664}
3665
[email protected]840a7e462013-02-27 01:29:513666void GLES2DecoderImpl::SetWaitSyncPointCallback(
3667 const WaitSyncPointCallback& callback) {
3668 wait_sync_point_callback_ = callback;
3669}
3670
[email protected]85a4ac22013-05-31 01:58:473671AsyncPixelTransferManager*
3672 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3673 return async_pixel_transfer_manager_.get();
3674}
3675
3676void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3677 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593678}
3679
[email protected]498b5c072013-06-04 19:30:073680void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3681 AsyncPixelTransferManager* manager) {
3682 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3683}
3684
[email protected]1318e922010-09-17 22:03:163685bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3686 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493687 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3688 if (texture_ref) {
3689 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163690 return true;
3691 }
3692 return false;
3693}
3694
[email protected]63b465922012-09-06 02:04:523695uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443696 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483697 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523698}
3699
3700base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443701 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483702 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523703}
3704
3705base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3706 return total_processing_commands_time_;
3707}
3708
[email protected]dc25dda2012-09-27 21:36:303709void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3710 total_processing_commands_time_ += time;
3711}
3712
[email protected]63c9b052012-05-17 18:27:383713void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063714 if (!initialized())
3715 return;
3716
[email protected]63c9b052012-05-17 18:27:383717 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053718
[email protected]80eb6b52012-01-19 00:14:413719 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243720 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523721 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023722 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243723 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133724 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343725 framebuffer_state_.bound_read_framebuffer = NULL;
3726 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243727 state_.bound_renderbuffer = NULL;
orglofchcad5a6742014-11-07 19:51:123728 state_.bound_valuebuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413729
[email protected]cadac622013-06-11 16:46:363730 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513731 DCHECK(offscreen_target_color_texture_);
3732 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3733 offscreen_saved_color_texture_->id());
3734 offscreen_saved_color_texture_->Invalidate();
3735 offscreen_saved_color_texture_info_ = NULL;
3736 }
[email protected]eadc96792010-10-27 19:39:393737 if (have_context) {
[email protected]c322e882012-05-23 18:06:183738 if (copy_texture_CHROMIUM_.get()) {
3739 copy_texture_CHROMIUM_->Destroy();
3740 copy_texture_CHROMIUM_.reset();
3741 }
[email protected]43410e92012-04-20 17:06:283742
sievers2384f2b2014-11-18 02:10:353743 clear_framebuffer_blit_.reset();
3744
[email protected]7cd76fd2013-06-02 21:11:113745 if (state_.current_program.get()) {
3746 program_manager()->UnuseProgram(shader_manager(),
3747 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143748 }
3749
[email protected]b1122982010-05-17 23:04:243750 if (attrib_0_buffer_id_) {
3751 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3752 }
[email protected]8fbedc02010-11-18 18:43:403753 if (fixed_attrib_buffer_id_) {
3754 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3755 }
[email protected]b1122982010-05-17 23:04:243756
[email protected]4a4c18b2013-09-13 22:50:103757 if (validation_texture_) {
3758 glDeleteTextures(1, &validation_texture_);
3759 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3760 glDeleteFramebuffersEXT(1, &validation_fbo_);
3761 }
3762
[email protected]97872062010-11-03 19:07:053763 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543764 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053765 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543766 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053767 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023768 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053769 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153770 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053771 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153772 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053773 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023774 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053775 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543776 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273777 if (offscreen_resolved_frame_buffer_.get())
3778 offscreen_resolved_frame_buffer_->Destroy();
3779 if (offscreen_resolved_color_texture_.get())
3780 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053781 } else {
3782 if (offscreen_target_frame_buffer_.get())
3783 offscreen_target_frame_buffer_->Invalidate();
3784 if (offscreen_target_color_texture_.get())
3785 offscreen_target_color_texture_->Invalidate();
3786 if (offscreen_target_color_render_buffer_.get())
3787 offscreen_target_color_render_buffer_->Invalidate();
3788 if (offscreen_target_depth_render_buffer_.get())
3789 offscreen_target_depth_render_buffer_->Invalidate();
3790 if (offscreen_target_stencil_render_buffer_.get())
3791 offscreen_target_stencil_render_buffer_->Invalidate();
3792 if (offscreen_saved_frame_buffer_.get())
3793 offscreen_saved_frame_buffer_->Invalidate();
3794 if (offscreen_saved_color_texture_.get())
3795 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273796 if (offscreen_resolved_frame_buffer_.get())
3797 offscreen_resolved_frame_buffer_->Invalidate();
3798 if (offscreen_resolved_color_texture_.get())
3799 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023800 }
[email protected]83a52d032013-07-24 10:30:373801
3802 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3803 // Otherwise, we can leak objects. http://crbug.com/258772.
3804 // state_.current_program must be reset before group_ is reset because
3805 // the later deletes the ProgramManager object that referred by
3806 // state_.current_program object.
3807 state_.current_program = NULL;
3808
[email protected]43410e92012-04-20 17:06:283809 copy_texture_CHROMIUM_.reset();
sievers2384f2b2014-11-18 02:10:353810 clear_framebuffer_blit_.reset();
[email protected]97872062010-11-03 19:07:053811
[email protected]882ba1e22012-03-08 19:02:533812 if (query_manager_.get()) {
3813 query_manager_->Destroy(have_context);
3814 query_manager_.reset();
3815 }
3816
[email protected]944b62f32012-09-27 02:20:463817 if (vertex_array_manager_ .get()) {
3818 vertex_array_manager_->Destroy(have_context);
3819 vertex_array_manager_.reset();
3820 }
3821
[email protected]d2eaf52f2014-07-31 15:01:243822 if (image_manager_.get()) {
3823 image_manager_->Destroy(have_context);
3824 image_manager_.reset();
3825 }
3826
[email protected]97872062010-11-03 19:07:053827 offscreen_target_frame_buffer_.reset();
3828 offscreen_target_color_texture_.reset();
3829 offscreen_target_color_render_buffer_.reset();
3830 offscreen_target_depth_render_buffer_.reset();
3831 offscreen_target_stencil_render_buffer_.reset();
3832 offscreen_saved_frame_buffer_.reset();
3833 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273834 offscreen_resolved_frame_buffer_.reset();
3835 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463836
[email protected]03cef9b2014-04-03 15:58:143837 // Need to release these before releasing |group_| which may own the
3838 // ShaderTranslatorCache.
3839 fragment_translator_ = NULL;
3840 vertex_translator_ = NULL;
3841
[email protected]85a4ac22013-05-31 01:58:473842 // Should destroy the transfer manager before the texture manager held
3843 // by the context group.
3844 async_pixel_transfer_manager_.reset();
3845
dyendbfb90d2015-03-26 02:41:463846 // Destroy the GPU Tracer which may own some in process GPU Timings.
dyen8ef659882015-03-26 23:32:513847 if (gpu_tracer_) {
3848 gpu_tracer_->Destroy(have_context);
3849 gpu_tracer_.reset();
3850 }
dyendbfb90d2015-03-26 02:41:463851
[email protected]7cd76fd2013-06-02 21:11:113852 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393853 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233854 group_->Destroy(this, have_context);
3855 group_ = NULL;
3856 }
3857
3858 if (context_.get()) {
3859 context_->ReleaseCurrent(NULL);
3860 context_ = NULL;
3861 }
3862
[email protected]e51bdf32011-11-23 22:21:463863#if defined(OS_MACOSX)
3864 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3865 it != texture_to_io_surface_map_.end(); ++it) {
3866 CFRelease(it->second);
3867 }
3868 texture_to_io_surface_map_.clear();
3869#endif
[email protected]96449d2c2009-11-25 00:01:323870}
3871
[email protected]63c9b052012-05-17 18:27:383872void GLES2DecoderImpl::SetSurface(
3873 const scoped_refptr<gfx::GLSurface>& surface) {
3874 DCHECK(context_->IsCurrent(NULL));
3875 DCHECK(surface_.get());
3876 surface_ = surface;
3877 RestoreCurrentFramebufferBindings();
3878}
3879
[email protected]aba551b2014-02-08 03:38:323880void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3881 if (!offscreen_saved_color_texture_.get()) {
3882 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3883 return;
3884 }
[email protected]2ad674132013-06-05 07:48:513885 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243886 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073887 offscreen_saved_color_texture_info_ = TextureRef::Create(
3888 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513889 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3890 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393891 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243892 }
[email protected]aba551b2014-02-08 03:38:323893 mailbox_manager()->ProduceTexture(
sievers8b373ec52014-10-24 23:04:063894 mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243895}
3896
[email protected]799b4b22011-08-22 17:09:593897bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3898 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3899 if (!is_offscreen) {
3900 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3901 << " with an onscreen framebuffer.";
3902 return false;
3903 }
3904
3905 if (offscreen_size_ == size)
3906 return true;
3907
3908 offscreen_size_ = size;
3909 int w = offscreen_size_.width();
3910 int h = offscreen_size_.height();
3911 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3912 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3913 << "to allocate storage due to excessive dimensions.";
3914 return false;
3915 }
3916
3917 // Reallocate the offscreen target buffers.
3918 DCHECK(offscreen_target_color_format_);
3919 if (IsOffscreenBufferMultisampled()) {
3920 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253921 feature_info_.get(),
3922 offscreen_size_,
3923 offscreen_target_color_format_,
3924 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593925 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3926 << "to allocate storage for offscreen target color buffer.";
3927 return false;
3928 }
3929 } else {
3930 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093931 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593932 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3933 << "to allocate storage for offscreen target color texture.";
3934 return false;
3935 }
3936 }
3937 if (offscreen_target_depth_format_ &&
3938 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253939 feature_info_.get(),
3940 offscreen_size_,
3941 offscreen_target_depth_format_,
3942 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593943 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3944 << "to allocate storage for offscreen target depth buffer.";
3945 return false;
3946 }
3947 if (offscreen_target_stencil_format_ &&
3948 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253949 feature_info_.get(),
3950 offscreen_size_,
3951 offscreen_target_stencil_format_,
3952 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593953 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3954 << "to allocate storage for offscreen target stencil buffer.";
3955 return false;
3956 }
3957
3958 // Attach the offscreen target buffers to the target frame buffer.
3959 if (IsOffscreenBufferMultisampled()) {
3960 offscreen_target_frame_buffer_->AttachRenderBuffer(
3961 GL_COLOR_ATTACHMENT0,
3962 offscreen_target_color_render_buffer_.get());
3963 } else {
3964 offscreen_target_frame_buffer_->AttachRenderTexture(
3965 offscreen_target_color_texture_.get());
3966 }
3967 if (offscreen_target_depth_format_) {
3968 offscreen_target_frame_buffer_->AttachRenderBuffer(
3969 GL_DEPTH_ATTACHMENT,
3970 offscreen_target_depth_render_buffer_.get());
3971 }
3972 const bool packed_depth_stencil =
3973 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3974 if (packed_depth_stencil) {
3975 offscreen_target_frame_buffer_->AttachRenderBuffer(
3976 GL_STENCIL_ATTACHMENT,
3977 offscreen_target_depth_render_buffer_.get());
3978 } else if (offscreen_target_stencil_format_) {
3979 offscreen_target_frame_buffer_->AttachRenderBuffer(
3980 GL_STENCIL_ATTACHMENT,
3981 offscreen_target_stencil_render_buffer_.get());
3982 }
3983
3984 if (offscreen_target_frame_buffer_->CheckStatus() !=
3985 GL_FRAMEBUFFER_COMPLETE) {
3986 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3987 << "because offscreen FBO was incomplete.";
3988 return false;
3989 }
3990
3991 // Clear the target frame buffer.
3992 {
3993 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3994 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323995 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453996 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593997 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473998 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3999 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:594000 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:454001 state_.SetDeviceDepthMask(GL_TRUE);
4002 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:594003 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4004 RestoreClearState();
4005 }
[email protected]d85ef76d2011-09-08 22:21:434006
4007 // Destroy the offscreen resolved framebuffers.
4008 if (offscreen_resolved_frame_buffer_.get())
4009 offscreen_resolved_frame_buffer_->Destroy();
4010 if (offscreen_resolved_color_texture_.get())
4011 offscreen_resolved_color_texture_->Destroy();
4012 offscreen_resolved_color_texture_.reset();
4013 offscreen_resolved_frame_buffer_.reset();
4014
[email protected]799b4b22011-08-22 17:09:594015 return true;
[email protected]6217d392010-03-25 22:08:354016}
4017
vmiuracd108592014-09-08 14:36:344018error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
4019 const void* cmd_data) {
4020 const gles2::cmds::ResizeCHROMIUM& c =
4021 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:444022 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:024023 return error::kDeferCommandUntilLater;
4024
[email protected]799b4b22011-08-22 17:09:594025 GLuint width = static_cast<GLuint>(c.width);
4026 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:074027 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:594028 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:414029
4030 width = std::max(1U, width);
4031 height = std::max(1U, height);
4032
[email protected]a0d989162011-11-22 13:15:074033#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
4034 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:004035 // Make sure that we are done drawing to the back buffer before resizing.
4036 glFinish();
4037#endif
[email protected]799b4b22011-08-22 17:09:594038 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
4039 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:494040 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
4041 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
4042 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:594043 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:494044 }
[email protected]7ff86b92010-11-25 17:50:004045 }
[email protected]799b4b22011-08-22 17:09:594046
[email protected]9d37f062011-11-22 01:24:524047 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:074048 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:444049 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:494050 if (!context_->IsCurrent(surface_.get())) {
4051 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
4052 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:054053 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:494054 }
[email protected]658f7562011-09-09 05:24:054055 }
[email protected]799b4b22011-08-22 17:09:594056
4057 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:394058}
4059
[email protected]96449d2c2009-11-25 00:01:324060const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
4061 if (command_id > kStartPoint && command_id < kNumCommands) {
4062 return gles2::GetCommandName(static_cast<CommandId>(command_id));
4063 }
4064 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
4065}
4066
vmiura8266ca72014-09-09 21:37:004067// Decode a command, and call the corresponding GL functions.
4068// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
4069// of commands at once, and is now only used for tests that need to track
4070// individual commands.
4071error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
4072 unsigned int arg_count,
4073 const void* cmd_data) {
4074 return DoCommands(1, cmd_data, arg_count + 1, 0);
4075}
4076
4077// Decode multiple commands, and call the corresponding GL functions.
4078// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
4079// changed by a (malicious) client at any time, so if validation has to happen,
4080// it should operate on a copy of them.
4081// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
4082// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:244083template <bool DebugImpl>
4084error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
4085 const void* buffer,
4086 int num_entries,
4087 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:004088 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:144089 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:004090 const CommandBufferEntry* cmd_data =
4091 static_cast<const CommandBufferEntry*>(buffer);
4092 int process_pos = 0;
4093 unsigned int command = 0;
4094
4095 while (process_pos < num_entries && result == error::kNoError &&
4096 commands_to_process_--) {
4097 const unsigned int size = cmd_data->value_header.size;
4098 command = cmd_data->value_header.command;
4099
4100 if (size == 0) {
4101 result = error::kInvalidSize;
4102 break;
4103 }
4104
4105 if (static_cast<int>(size) + process_pos > num_entries) {
4106 result = error::kOutOfBounds;
4107 break;
4108 }
4109
vmiura1c2b1de2014-09-19 19:03:244110 if (DebugImpl) {
4111 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
4112 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:004113
vmiura1c2b1de2014-09-19 19:03:244114 if (log_commands()) {
4115 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
4116 << "cmd: " << GetCommandName(command);
4117 }
vmiura8266ca72014-09-09 21:37:004118 }
4119
4120 const unsigned int arg_count = size - 1;
4121 unsigned int command_index = command - kStartPoint - 1;
4122 if (command_index < arraysize(command_info)) {
4123 const CommandInfo& info = command_info[command_index];
4124 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
4125 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
4126 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
4127 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:244128 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:004129 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
4130 doing_gpu_trace = true;
dyencb86f2f2014-12-09 18:35:414131 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_decoder"),
4132 GetCommandName(command),
4133 kTraceDecoder);
vmiura8266ca72014-09-09 21:37:004134 }
[email protected]cac16542014-01-15 17:53:514135 }
[email protected]cac16542014-01-15 17:53:514136
vmiura8266ca72014-09-09 21:37:004137 uint32 immediate_data_size = (arg_count - info_arg_count) *
4138 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:324139
vmiura8266ca72014-09-09 21:37:004140 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:514141
vmiura1c2b1de2014-09-19 19:03:244142 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:004143 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:514144
vmiura1c2b1de2014-09-19 19:03:244145 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:004146 GLenum error;
4147 while ((error = glGetError()) != GL_NO_ERROR) {
4148 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
4149 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
4150 << " : " << GetCommandName(command);
4151 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
4152 }
[email protected]b9849abf2009-11-25 19:13:194153 }
vmiura8266ca72014-09-09 21:37:004154 } else {
4155 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:324156 }
4157 } else {
vmiura8266ca72014-09-09 21:37:004158 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:324159 }
vmiura1c2b1de2014-09-19 19:03:244160
4161 if (DebugImpl) {
4162 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
4163 GetCommandName(command));
4164 }
4165
vmiura8266ca72014-09-09 21:37:004166 if (result == error::kNoError &&
4167 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:564168 result = current_decoder_error_;
4169 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:004170 }
4171
4172 if (result != error::kDeferCommandUntilLater) {
4173 process_pos += size;
4174 cmd_data += size;
4175 }
[email protected]a3a93e7b2010-08-28 00:48:564176 }
vmiura8266ca72014-09-09 21:37:004177
4178 if (entries_processed)
4179 *entries_processed = process_pos;
4180
4181 if (error::IsError(result)) {
4182 LOG(ERROR) << "Error: " << result << " for Command "
4183 << GetCommandName(command);
4184 }
4185
[email protected]b9849abf2009-11-25 19:13:194186 return result;
[email protected]96449d2c2009-11-25 00:01:324187}
4188
vmiura1c2b1de2014-09-19 19:03:244189error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
4190 const void* buffer,
4191 int num_entries,
4192 int* entries_processed) {
4193 if (gpu_debug_commands_) {
4194 return DoCommandsImpl<true>(
4195 num_commands, buffer, num_entries, entries_processed);
4196 } else {
4197 return DoCommandsImpl<false>(
4198 num_commands, buffer, num_entries, entries_processed);
4199 }
4200}
4201
[email protected]ed9f9cd2013-02-27 21:12:354202void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
4203 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:504204}
4205
[email protected]882ba1e22012-03-08 19:02:534206void GLES2DecoderImpl::DoFinish() {
4207 glFinish();
[email protected]5a36dc132013-07-23 23:17:554208 ProcessPendingReadPixels();
revemancc241eb2014-11-11 03:30:374209 ProcessPendingQueries(true);
[email protected]882ba1e22012-03-08 19:02:534210}
4211
4212void GLES2DecoderImpl::DoFlush() {
4213 glFlush();
revemancc241eb2014-11-11 03:30:374214 ProcessPendingQueries(false);
[email protected]882ba1e22012-03-08 19:02:534215}
4216
[email protected]3916c97e2010-02-25 03:20:504217void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:454218 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:024219 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:514220 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:534221 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:504222 return;
4223 }
[email protected]e259eb412012-10-13 05:47:244224 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:454225 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:504226}
4227
[email protected]051b1372010-04-12 02:42:084228void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:074229 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:084230 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034231 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:074232 buffer = GetBuffer(client_id);
4233 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:354234 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224235 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4236 "glBindBuffer",
4237 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:354238 return;
4239 }
4240
[email protected]b10492f2013-03-08 05:24:074241 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:034242 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354243 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:074244 buffer = GetBuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034245 }
[email protected]051b1372010-04-12 02:42:084246 }
[email protected]b10492f2013-03-08 05:24:074247 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
4248 if (buffer) {
4249 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:514250 LOCAL_SET_GL_ERROR(
4251 GL_INVALID_OPERATION,
4252 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:474253 return;
4254 }
[email protected]b10492f2013-03-08 05:24:074255 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:474256 }
[email protected]96449d2c2009-11-25 00:01:324257 switch (target) {
4258 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074259 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:324260 break;
4261 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074262 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:324263 break;
4264 default:
[email protected]a93bb842010-02-16 23:03:474265 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:324266 break;
4267 }
[email protected]051b1372010-04-12 02:42:084268 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:324269}
4270
[email protected]f3b191b2013-06-19 03:43:544271bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
4272 bool all_draw_buffers) {
4273 Framebuffer* framebuffer =
4274 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4275 if (!all_draw_buffers || !framebuffer) {
4276 return (GLES2Util::GetChannelsForFormat(
4277 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
4278 }
4279 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:464280}
4281
4282bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354283 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454284 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204285 if (framebuffer) {
4286 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:464287 }
4288 if (offscreen_target_frame_buffer_.get()) {
4289 return offscreen_target_depth_format_ != 0;
4290 }
4291 return back_buffer_has_depth_;
4292}
4293
4294bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354295 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454296 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204297 if (framebuffer) {
4298 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464299 }
4300 if (offscreen_target_frame_buffer_.get()) {
4301 return offscreen_target_stencil_format_ != 0 ||
4302 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4303 }
4304 return back_buffer_has_stencil_;
4305}
4306
4307void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444308 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454309 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4310 state_.SetDeviceColorMask(state_.color_mask_red,
4311 state_.color_mask_green,
4312 state_.color_mask_blue,
4313 state_.color_mask_alpha && have_alpha);
4314
[email protected]297ca1c2011-06-20 23:08:464315 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454316 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4317
[email protected]297ca1c2011-06-20 23:08:464318 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454319 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424320 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454321 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424322 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454323
4324 state_.SetDeviceCapabilityState(
4325 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4326 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224327 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444328 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464329 }
4330}
4331
[email protected]1868a342012-11-07 15:56:024332GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114333 return (offscreen_target_frame_buffer_.get())
4334 ? offscreen_target_frame_buffer_->id()
4335 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024336}
4337
[email protected]8875a5f2014-06-27 08:33:474338void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144339 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4340 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064341 // Restore the Framebuffer first because of bugs in Intel drivers.
4342 // Intel drivers incorrectly clip the viewport settings to
4343 // the size of the current framebuffer object.
4344 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164345 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064346}
4347
4348void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344349 GLuint service_id =
4350 framebuffer_state_.bound_draw_framebuffer.get()
4351 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4352 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064353 if (!features().chromium_framebuffer_multisample) {
4354 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4355 } else {
4356 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344357 service_id = framebuffer_state_.bound_read_framebuffer.get()
4358 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114359 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064360 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4361 }
[email protected]70d34263c2013-01-09 00:27:454362 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064363}
4364
[email protected]8875a5f2014-06-27 08:33:474365void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4366 state_.RestoreRenderbufferBindings();
4367}
4368
[email protected]29a4d902013-02-26 20:18:064369void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104370 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4371 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254372 GLenum target = texture->target();
4373 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064374 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254375 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064376 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254377 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064378 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254379 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064380 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254381 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064382 RestoreTextureUnitBindings(state_.active_texture_unit);
4383 }
[email protected]70d34263c2013-01-09 00:27:454384}
4385
[email protected]cd2ef752014-02-12 23:16:034386void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524387 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4388 // other VAOs.
4389 if (feature_info_->feature_flags().native_vertex_array_object)
4390 glBindVertexArrayOES(0);
4391
[email protected]cd2ef752014-02-12 23:16:034392 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
dcastagna504d45c2015-04-06 19:30:394393 if (i != 0) // Never disable attribute 0
[email protected]cd2ef752014-02-12 23:16:034394 glDisableVertexAttribArray(i);
dcastagna504d45c2015-04-06 19:30:394395 if (features().angle_instanced_arrays)
[email protected]cd2ef752014-02-12 23:16:034396 glVertexAttribDivisorANGLE(i, 0);
4397 }
4398}
4399
4400void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524401 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034402}
4403
[email protected]454157e2014-05-03 02:49:454404void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4405 state_.SetIgnoreCachedStateForTest(ignore);
4406}
4407
[email protected]70d34263c2013-01-09 00:27:454408void GLES2DecoderImpl::OnFboChanged() const {
4409 if (workarounds().restore_scissor_on_fbo_change)
zmo8ac3bab2015-04-18 02:30:584410 state_.fbo_binding_for_scissor_workaround_dirty = true;
ccameron4ff12a732014-12-12 21:38:194411
4412 if (workarounds().gl_begin_gl_end_on_fbo_change_to_backbuffer) {
4413 GLint bound_fbo_unsigned = -1;
4414 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_fbo_unsigned);
4415 GLuint bound_fbo = static_cast<GLuint>(bound_fbo_unsigned);
4416 if (surface_ && surface_->GetBackingFrameBufferObject() == bound_fbo)
4417 surface_->NotifyWasBound();
4418 }
[email protected]28718a92013-04-04 12:12:514419}
4420
4421// Called after the FBO is checked for completeness.
4422void GLES2DecoderImpl::OnUseFramebuffer() const {
zmo8ac3bab2015-04-18 02:30:584423 if (state_.fbo_binding_for_scissor_workaround_dirty) {
4424 state_.fbo_binding_for_scissor_workaround_dirty = false;
[email protected]81fc9d02013-03-14 23:53:324425 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514426 glScissor(state_.scissor_x,
4427 state_.scissor_y,
4428 state_.scissor_width,
4429 state_.scissor_height);
4430
4431 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4432 // it's unclear how this bug works.
4433 glFlush();
4434 }
[email protected]b177ae22011-11-01 03:29:114435}
4436
[email protected]051b1372010-04-12 02:42:084437void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064438 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084439 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034440 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064441 framebuffer = GetFramebuffer(client_id);
4442 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354443 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224444 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4445 "glBindFramebuffer",
4446 "id not generated by glGenFramebuffers");
4447 return;
[email protected]bf5a8d132011-08-16 08:39:354448 }
4449
[email protected]4d8f0dd2013-03-09 14:37:064450 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034451 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354452 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064453 framebuffer = GetFramebuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034454 } else {
[email protected]4d8f0dd2013-03-09 14:37:064455 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084456 }
[email protected]4d8f0dd2013-03-09 14:37:064457 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084458 }
[email protected]4d8f0dd2013-03-09 14:37:064459 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304460
4461 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344462 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304463 }
[email protected]cac16542014-01-15 17:53:514464
4465 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304466 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344467 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304468 }
[email protected]6217d392010-03-25 22:08:354469
[email protected]c986af502013-08-14 01:04:444470 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464471
[email protected]b177ae22011-11-01 03:29:114472 // If we are rendering to the backbuffer get the FBO id for any simulated
4473 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064474 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114475 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464476 }
[email protected]6217d392010-03-25 22:08:354477
[email protected]051b1372010-04-12 02:42:084478 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454479 OnFboChanged();
[email protected]86093972010-03-11 00:13:564480}
4481
[email protected]051b1372010-04-12 02:42:084482void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274483 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084484 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034485 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274486 renderbuffer = GetRenderbuffer(client_id);
4487 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354488 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224489 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4490 "glBindRenderbuffer",
4491 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354492 return;
4493 }
4494
[email protected]8875a5f2014-06-27 08:33:474495 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034496 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354497 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274498 renderbuffer = GetRenderbuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034499 } else {
[email protected]ee2a79c32013-03-10 03:50:274500 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084501 }
[email protected]ee2a79c32013-03-10 03:50:274502 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084503 }
[email protected]caa13ed2014-02-17 11:29:204504 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274505 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474506 state_.bound_renderbuffer_valid = true;
4507 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564508}
4509
[email protected]051b1372010-04-12 02:42:084510void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494511 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084512 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034513 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494514 texture_ref = GetTexture(client_id);
4515 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354516 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224517 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4518 "glBindTexture",
4519 "id not generated by glGenTextures");
4520 return;
[email protected]bf5a8d132011-08-16 08:39:354521 }
4522
[email protected]02965c22013-03-09 02:40:074523 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034524 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414525 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354526 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494527 texture_ref = GetTexture(client_id);
[email protected]ae51d192010-04-27 00:48:034528 }
4529 } else {
[email protected]370eaf12013-05-18 09:19:494530 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084531 }
[email protected]ae51d192010-04-27 00:48:034532
[email protected]1958e0e2010-04-22 05:17:154533 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574534 if (texture_ref) {
4535 Texture* texture = texture_ref->texture();
4536 // Check that we are not trying to bind it to a different target.
4537 if (texture->target() != 0 && texture->target() != target) {
4538 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4539 "glBindTexture",
4540 "texture bound to more than 1 target.");
4541 return;
4542 }
4543 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4544 if (texture->target() == 0) {
4545 texture_manager()->SetTarget(texture_ref, target);
4546 }
4547 glBindTexture(target, texture->service_id());
4548 } else {
4549 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154550 }
[email protected]32145a92012-12-17 09:01:594551
[email protected]e259eb412012-10-13 05:47:244552 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504553 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474554 switch (target) {
4555 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494556 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474557 break;
4558 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494559 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474560 break;
[email protected]61eeb33f2011-07-26 15:30:314561 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494562 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314563 break;
[email protected]e51bdf32011-11-23 22:21:464564 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494565 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464566 break;
[email protected]a93bb842010-02-16 23:03:474567 default:
4568 NOTREACHED(); // Validation should prevent us getting here.
4569 break;
4570 }
4571}
4572
[email protected]07f54fcc2009-12-22 02:46:304573void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244574 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124575 if (index != 0 ||
4576 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244577 glDisableVertexAttribArray(index);
4578 }
[email protected]07f54fcc2009-12-22 02:46:304579 } else {
[email protected]ab09b612013-03-11 22:11:514580 LOCAL_SET_GL_ERROR(
4581 GL_INVALID_VALUE,
4582 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304583 }
4584}
4585
[email protected]60f22d32012-12-12 00:31:584586void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4587 GLsizei numAttachments,
4588 const GLenum* attachments) {
aelias8ef99b8a2015-04-07 23:19:354589 if (workarounds().disable_discard_framebuffer)
dyen5f38cadc2015-03-26 16:58:424590 return;
4591
[email protected]ed9f9cd2013-02-27 21:12:354592 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584593 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4594
4595 // Validates the attachments. If one of them fails
4596 // the whole command fails.
4597 for (GLsizei i = 0; i < numAttachments; ++i) {
4598 if ((framebuffer &&
4599 !validators_->attachment.IsValid(attachments[i])) ||
4600 (!framebuffer &&
4601 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514602 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4603 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584604 return;
4605 }
4606 }
4607
4608 // Marks each one of them as not cleared
4609 for (GLsizei i = 0; i < numAttachments; ++i) {
4610 if (framebuffer) {
4611 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4612 texture_manager(),
4613 attachments[i],
4614 false);
4615 } else {
4616 switch (attachments[i]) {
4617 case GL_COLOR_EXT:
4618 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4619 break;
4620 case GL_DEPTH_EXT:
4621 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4622 case GL_STENCIL_EXT:
4623 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4624 break;
4625 default:
4626 NOTREACHED();
4627 break;
4628 }
4629 }
4630 }
4631
[email protected]d49c5402013-09-11 15:39:024632 // If the default framebuffer is bound but we are still rendering to an
4633 // FBO, translate attachment names that refer to default framebuffer
4634 // channels to corresponding framebuffer attachments.
4635 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4636 for (GLsizei i = 0; i < numAttachments; ++i) {
4637 GLenum attachment = attachments[i];
4638 if (!framebuffer && GetBackbufferServiceId()) {
4639 switch (attachment) {
4640 case GL_COLOR_EXT:
4641 attachment = GL_COLOR_ATTACHMENT0;
4642 break;
4643 case GL_DEPTH_EXT:
4644 attachment = GL_DEPTH_ATTACHMENT;
4645 break;
4646 case GL_STENCIL_EXT:
4647 attachment = GL_STENCIL_ATTACHMENT;
4648 break;
4649 default:
4650 NOTREACHED();
4651 return;
4652 }
4653 }
4654 translated_attachments[i] = attachment;
4655 }
4656
boliu2e7d8a7a2014-10-16 20:35:204657 ScopedRenderTo do_render(framebuffer);
marcheu1856f5d52015-04-04 01:42:534658 if (feature_info_->gl_version_info().is_es3) {
zmo68fcdc62014-12-05 21:51:494659 glInvalidateFramebuffer(
4660 target, numAttachments, translated_attachments.get());
4661 } else {
4662 glDiscardFramebufferEXT(
4663 target, numAttachments, translated_attachments.get());
4664 }
[email protected]60f22d32012-12-12 00:31:584665}
4666
[email protected]07f54fcc2009-12-22 02:46:304667void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244668 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304669 glEnableVertexAttribArray(index);
4670 } else {
[email protected]ab09b612013-03-11 22:11:514671 LOCAL_SET_GL_ERROR(
4672 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304673 }
4674}
4675
[email protected]a93bb842010-02-16 23:03:474676void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444677 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4678 &state_, target);
[email protected]370eaf12013-05-18 09:19:494679 if (!texture_ref ||
4680 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514681 LOCAL_SET_GL_ERROR(
4682 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474683 return;
4684 }
[email protected]38c0a972012-05-12 00:48:024685
[email protected]12d95352012-12-14 07:23:544686 if (target == GL_TEXTURE_CUBE_MAP) {
4687 for (int i = 0; i < 6; ++i) {
4688 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494689 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514690 LOCAL_SET_GL_ERROR(
4691 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544692 return;
4693 }
4694 }
4695 } else {
[email protected]370eaf12013-05-18 09:19:494696 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514697 LOCAL_SET_GL_ERROR(
4698 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544699 return;
4700 }
[email protected]7687479c2012-05-14 23:54:044701 }
4702
[email protected]ab09b612013-03-11 22:11:514703 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194704 // Workaround for Mac driver bug. In the large scheme of things setting
4705 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564706 // hit so there's probably no need to make this conditional. The bug appears
4707 // to be that if the filtering mode is set to something that doesn't require
4708 // mipmaps for rendering, or is never set to something other than the default,
4709 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154710 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194711 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4712 }
[email protected]a93bb842010-02-16 23:03:474713 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154714 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494715 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4716 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194717 }
[email protected]ab09b612013-03-11 22:11:514718 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024719 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494720 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024721 }
[email protected]a93bb842010-02-16 23:03:474722}
4723
[email protected]b273e432010-04-12 17:23:584724bool GLES2DecoderImpl::GetHelper(
4725 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584726 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154727 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4728 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434729 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4730 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214731 // Return the GL implementation's preferred format and (see below type)
4732 // if we have the GL extension that exposes this. This allows the GPU
4733 // client to use the implementation's preferred format for glReadPixels
4734 // for optimisation.
4735 //
4736 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4737 // case when requested on integer/floating point buffers but which is
4738 // acceptable on GLES2 and with the GL_OES_read_format extension.
4739 //
4740 // Therefore if an error occurs we swallow the error and use the
4741 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434742 if (params) {
[email protected]c959a09a2014-03-27 11:44:214743 if (context_->HasExtension("GL_OES_read_format")) {
4744 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4745 GetErrorState());
4746 glGetIntegerv(pname, params);
4747 if (glGetError() == GL_NO_ERROR)
4748 return true;
4749 }
[email protected]68586372013-12-11 01:27:594750 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4751 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434752 }
4753 return true;
4754 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4755 *num_written = 1;
4756 if (params) {
[email protected]c959a09a2014-03-27 11:44:214757 if (context_->HasExtension("GL_OES_read_format")) {
4758 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4759 GetErrorState());
4760 glGetIntegerv(pname, params);
4761 if (glGetError() == GL_NO_ERROR)
4762 return true;
4763 }
[email protected]68586372013-12-11 01:27:594764 *params = GLES2Util::GetPreferredGLReadPixelsType(
4765 GetBoundReadFrameBufferInternalFormat(),
4766 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434767 }
4768 return true;
4769 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4770 *num_written = 1;
4771 if (params) {
4772 *params = group_->max_fragment_uniform_vectors();
4773 }
4774 return true;
4775 case GL_MAX_VARYING_VECTORS:
4776 *num_written = 1;
4777 if (params) {
4778 *params = group_->max_varying_vectors();
4779 }
4780 return true;
4781 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4782 *num_written = 1;
4783 if (params) {
4784 *params = group_->max_vertex_uniform_vectors();
4785 }
4786 return true;
[email protected]4e8a5b122010-05-08 22:00:104787 }
[email protected]5cb735d2011-10-13 01:37:234788 }
4789 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244790 case GL_MAX_VIEWPORT_DIMS:
4791 if (offscreen_target_frame_buffer_.get()) {
4792 *num_written = 2;
4793 if (params) {
4794 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4795 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4796 }
4797 return true;
4798 }
[email protected]5cb735d2011-10-13 01:37:234799 return false;
[email protected]84afefa2011-10-19 21:45:534800 case GL_MAX_SAMPLES:
4801 *num_written = 1;
4802 if (params) {
4803 params[0] = renderbuffer_manager()->max_samples();
4804 }
4805 return true;
4806 case GL_MAX_RENDERBUFFER_SIZE:
4807 *num_written = 1;
4808 if (params) {
4809 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4810 }
4811 return true;
[email protected]5cb735d2011-10-13 01:37:234812 case GL_MAX_TEXTURE_SIZE:
4813 *num_written = 1;
4814 if (params) {
4815 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4816 }
4817 return true;
4818 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4819 *num_written = 1;
4820 if (params) {
4821 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4822 }
4823 return true;
[email protected]2f143d482013-03-14 18:04:494824 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4825 *num_written = 1;
4826 if (params) {
4827 params[0] = group_->max_color_attachments();
4828 }
4829 return true;
4830 case GL_MAX_DRAW_BUFFERS_ARB:
4831 *num_written = 1;
4832 if (params) {
4833 params[0] = group_->max_draw_buffers();
4834 }
4835 return true;
[email protected]297ca1c2011-06-20 23:08:464836 case GL_ALPHA_BITS:
4837 *num_written = 1;
4838 if (params) {
4839 GLint v = 0;
marcheu1856f5d52015-04-04 01:42:534840 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:124841 Framebuffer* framebuffer =
4842 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4843 if (framebuffer) {
4844 glGetFramebufferAttachmentParameterivEXT(
4845 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
4846 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &v);
4847 } else {
4848 v = (back_buffer_color_format_ == GL_RGBA ? 8 : 0);
4849 }
4850 } else {
4851 glGetIntegerv(GL_ALPHA_BITS, &v);
4852 }
4853 params[0] =
4854 BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464855 }
4856 return true;
4857 case GL_DEPTH_BITS:
4858 *num_written = 1;
4859 if (params) {
4860 GLint v = 0;
marcheu1856f5d52015-04-04 01:42:534861 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:124862 Framebuffer* framebuffer =
4863 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4864 if (framebuffer) {
4865 glGetFramebufferAttachmentParameterivEXT(
4866 GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
4867 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &v);
4868 } else {
4869 v = (back_buffer_has_depth_ ? 24 : 0);
4870 }
4871 } else {
4872 glGetIntegerv(GL_DEPTH_BITS, &v);
4873 }
[email protected]297ca1c2011-06-20 23:08:464874 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4875 }
4876 return true;
kbrc9f0e10c2015-03-31 19:49:124877 case GL_RED_BITS:
4878 case GL_GREEN_BITS:
4879 case GL_BLUE_BITS:
4880 *num_written = 1;
4881 if (params) {
4882 GLint v = 0;
marcheu1856f5d52015-04-04 01:42:534883 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:124884 Framebuffer* framebuffer =
4885 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4886 if (framebuffer) {
4887 GLenum framebuffer_enum = 0;
4888 switch (pname) {
4889 case GL_RED_BITS:
4890 framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE;
4891 break;
4892 case GL_GREEN_BITS:
4893 framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
4894 break;
4895 case GL_BLUE_BITS:
4896 framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
4897 break;
4898 }
4899 glGetFramebufferAttachmentParameterivEXT(
4900 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, framebuffer_enum, &v);
4901 } else {
4902 v = 8;
4903 }
4904 } else {
4905 glGetIntegerv(pname, &v);
4906 }
4907 params[0] = v;
4908 }
4909 return true;
[email protected]297ca1c2011-06-20 23:08:464910 case GL_STENCIL_BITS:
4911 *num_written = 1;
4912 if (params) {
4913 GLint v = 0;
marcheu1856f5d52015-04-04 01:42:534914 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:124915 Framebuffer* framebuffer =
4916 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4917 if (framebuffer) {
4918 glGetFramebufferAttachmentParameterivEXT(
4919 GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
4920 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &v);
4921 } else {
4922 v = (back_buffer_has_stencil_ ? 8 : 0);
4923 }
4924 } else {
4925 glGetIntegerv(GL_STENCIL_BITS, &v);
4926 }
[email protected]297ca1c2011-06-20 23:08:464927 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4928 }
4929 return true;
[email protected]656dcaad2010-05-07 17:18:374930 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114931 *num_written = validators_->compressed_texture_format.GetValues().size();
4932 if (params) {
4933 for (GLint ii = 0; ii < *num_written; ++ii) {
4934 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4935 }
4936 }
[email protected]656dcaad2010-05-07 17:18:374937 return true;
[email protected]b273e432010-04-12 17:23:584938 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4939 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104940 if (params) {
[email protected]302ce6d2011-07-07 23:28:114941 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104942 }
[email protected]b273e432010-04-12 17:23:584943 return true;
4944 case GL_NUM_SHADER_BINARY_FORMATS:
4945 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104946 if (params) {
[email protected]302ce6d2011-07-07 23:28:114947 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104948 }
[email protected]b273e432010-04-12 17:23:584949 return true;
4950 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114951 *num_written = validators_->shader_binary_format.GetValues().size();
4952 if (params) {
4953 for (GLint ii = 0; ii < *num_written; ++ii) {
4954 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4955 }
4956 }
4957 return true;
[email protected]b273e432010-04-12 17:23:584958 case GL_SHADER_COMPILER:
4959 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104960 if (params) {
4961 *params = GL_TRUE;
4962 }
[email protected]b273e432010-04-12 17:23:584963 return true;
[email protected]6b8cf1a2010-05-06 16:13:584964 case GL_ARRAY_BUFFER_BINDING:
4965 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104966 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114967 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104968 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244969 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104970 &client_id);
4971 *params = client_id;
4972 } else {
4973 *params = 0;
4974 }
[email protected]6b8cf1a2010-05-06 16:13:584975 }
4976 return true;
4977 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4978 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104979 if (params) {
[email protected]e259eb412012-10-13 05:47:244980 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104981 GLuint client_id = 0;
4982 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254983 state_.vertex_attrib_manager->element_array_buffer()->
4984 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104985 *params = client_id;
4986 } else {
4987 *params = 0;
4988 }
[email protected]6b8cf1a2010-05-06 16:13:584989 }
4990 return true;
4991 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304992 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584993 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104994 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354995 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454996 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204997 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104998 GLuint client_id = 0;
4999 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:205000 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:305001 *params = client_id;
5002 } else {
5003 *params = 0;
5004 }
5005 }
5006 return true;
[email protected]ebfb73c2012-08-15 02:37:455007 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:305008 *num_written = 1;
5009 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:355010 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:455011 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:205012 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305013 GLuint client_id = 0;
5014 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:205015 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:105016 *params = client_id;
5017 } else {
5018 *params = 0;
5019 }
[email protected]6b8cf1a2010-05-06 16:13:585020 }
5021 return true;
5022 case GL_RENDERBUFFER_BINDING:
5023 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:105024 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:355025 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205026 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5027 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:105028 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:105029 } else {
5030 *params = 0;
5031 }
[email protected]6b8cf1a2010-05-06 16:13:585032 }
5033 return true;
5034 case GL_CURRENT_PROGRAM:
5035 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:105036 if (params) {
[email protected]7cd76fd2013-06-02 21:11:115037 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:105038 GLuint client_id = 0;
5039 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:245040 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:105041 *params = client_id;
5042 } else {
5043 *params = 0;
5044 }
[email protected]6b8cf1a2010-05-06 16:13:585045 }
5046 return true;
[email protected]bf835842012-11-19 15:21:515047 case GL_VERTEX_ARRAY_BINDING_OES:
5048 *num_written = 1;
5049 if (params) {
[email protected]7cd76fd2013-06-02 21:11:115050 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:525051 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:515052 GLuint client_id = 0;
5053 vertex_array_manager_->GetClientId(
5054 state_.vertex_attrib_manager->service_id(), &client_id);
5055 *params = client_id;
5056 } else {
5057 *params = 0;
5058 }
5059 }
5060 return true;
[email protected]4e8a5b122010-05-08 22:00:105061 case GL_TEXTURE_BINDING_2D:
5062 *num_written = 1;
5063 if (params) {
[email protected]e259eb412012-10-13 05:47:245064 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:115065 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:105066 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:585067 } else {
5068 *params = 0;
5069 }
[email protected]6b8cf1a2010-05-06 16:13:585070 }
[email protected]4e8a5b122010-05-08 22:00:105071 return true;
5072 case GL_TEXTURE_BINDING_CUBE_MAP:
5073 *num_written = 1;
5074 if (params) {
[email protected]e259eb412012-10-13 05:47:245075 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:115076 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:105077 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:585078 } else {
5079 *params = 0;
5080 }
[email protected]6b8cf1a2010-05-06 16:13:585081 }
[email protected]4e8a5b122010-05-08 22:00:105082 return true;
[email protected]61eeb33f2011-07-26 15:30:315083 case GL_TEXTURE_BINDING_EXTERNAL_OES:
5084 *num_written = 1;
5085 if (params) {
[email protected]e259eb412012-10-13 05:47:245086 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:115087 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:105088 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:315089 } else {
5090 *params = 0;
5091 }
5092 }
5093 return true;
[email protected]e51bdf32011-11-23 22:21:465094 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
5095 *num_written = 1;
5096 if (params) {
[email protected]e259eb412012-10-13 05:47:245097 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:115098 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:105099 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:465100 } else {
5101 *params = 0;
5102 }
5103 }
5104 return true;
[email protected]6c75c712012-06-19 15:43:175105 case GL_UNPACK_FLIP_Y_CHROMIUM:
5106 *num_written = 1;
5107 if (params) {
5108 params[0] = unpack_flip_y_;
5109 }
5110 return true;
5111 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
5112 *num_written = 1;
5113 if (params) {
5114 params[0] = unpack_premultiply_alpha_;
5115 }
5116 return true;
5117 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
5118 *num_written = 1;
5119 if (params) {
5120 params[0] = unpack_unpremultiply_alpha_;
5121 }
5122 return true;
[email protected]6eda6822014-04-03 23:00:505123 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
5124 *num_written = 1;
5125 if (params) {
5126 params[0] = group_->bind_generates_resource() ? 1 : 0;
5127 }
5128 return true;
[email protected]b273e432010-04-12 17:23:585129 default:
[email protected]2f143d482013-03-14 18:04:495130 if (pname >= GL_DRAW_BUFFER0_ARB &&
5131 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
5132 *num_written = 1;
5133 if (params) {
5134 Framebuffer* framebuffer =
5135 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
5136 if (framebuffer) {
5137 params[0] = framebuffer->GetDrawBuffer(pname);
5138 } else { // backbuffer
5139 if (pname == GL_DRAW_BUFFER0_ARB)
5140 params[0] = group_->draw_buffer();
5141 else
5142 params[0] = GL_NONE;
5143 }
5144 }
5145 return true;
5146 }
[email protected]4e8a5b122010-05-08 22:00:105147 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:535148 return false;
[email protected]b273e432010-04-12 17:23:585149 }
5150}
5151
[email protected]4e8a5b122010-05-08 22:00:105152bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
5153 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:265154 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:535155 return true;
5156 }
[email protected]4e8a5b122010-05-08 22:00:105157 return GetHelper(pname, NULL, num_values);
5158}
5159
[email protected]7d3c36e2013-07-12 14:13:165160GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
5161 if (GL_MAX_SAMPLES == pname &&
5162 features().use_img_for_multisampled_render_to_texture) {
5163 return GL_MAX_SAMPLES_IMG;
5164 }
5165 return pname;
5166}
5167
[email protected]b273e432010-04-12 17:23:585168void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
5169 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:105170 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:535171 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:555172 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:265173 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:535174 GetHelper(pname, values.get(), &num_written);
5175 }
[email protected]b273e432010-04-12 17:23:585176 for (GLsizei ii = 0; ii < num_written; ++ii) {
5177 params[ii] = static_cast<GLboolean>(values[ii]);
5178 }
5179 } else {
[email protected]7d3c36e2013-07-12 14:13:165180 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:585181 glGetBooleanv(pname, params);
5182 }
5183}
5184
5185void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
5186 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:105187 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:265188 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:535189 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:555190 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:535191 GetHelper(pname, values.get(), &num_written);
5192 for (GLsizei ii = 0; ii < num_written; ++ii) {
5193 params[ii] = static_cast<GLfloat>(values[ii]);
5194 }
5195 } else {
[email protected]7d3c36e2013-07-12 14:13:165196 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:535197 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:585198 }
[email protected]b273e432010-04-12 17:23:585199 }
5200}
5201
zmo8ac3bab2015-04-18 02:30:585202void GLES2DecoderImpl::DoGetInteger64v(GLenum pname, GLint64* params) {
5203 DCHECK(params);
5204 pname = AdjustGetPname(pname);
5205 glGetInteger64v(pname, params);
5206}
5207
[email protected]b273e432010-04-12 17:23:585208void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
5209 DCHECK(params);
5210 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:265211 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:535212 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:165213 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:585214 glGetIntegerv(pname, params);
5215 }
5216}
5217
[email protected]a0c3e972010-04-21 00:49:135218void GLES2DecoderImpl::DoGetProgramiv(
5219 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:425220 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
5221 if (!program) {
[email protected]a0c3e972010-04-21 00:49:135222 return;
5223 }
[email protected]df37b9932013-03-08 05:21:425224 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:135225}
5226
[email protected]17cfbe0e2013-03-07 01:26:085227void GLES2DecoderImpl::DoGetBufferParameteriv(
5228 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:135229 // Just delegate it. Some validation is actually done before this.
5230 buffer_manager()->ValidateAndDoGetBufferParameteriv(
5231 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:085232}
5233
[email protected]258a3313f2011-10-18 20:13:575234void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:425235 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:575236 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515237 LOCAL_SET_GL_ERROR(
5238 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:575239 return;
5240 }
[email protected]68dcb1f2012-04-07 00:14:565241 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515242 LOCAL_SET_GL_ERROR(
5243 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:565244 return;
5245 }
5246 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:515247 LOCAL_SET_GL_ERROR(
5248 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:565249 return;
5250 }
[email protected]df37b9932013-03-08 05:21:425251 Program* program = GetProgramInfoNotShader(
5252 program_id, "glBindAttribLocation");
5253 if (!program) {
[email protected]258a3313f2011-10-18 20:13:575254 return;
[email protected]558847a2010-03-24 07:02:545255 }
zmo460b593e2014-10-13 23:07:455256 // At this point, the program's shaders may not be translated yet,
5257 // therefore, we may not find the hashed attribute name.
5258 // glBindAttribLocation call with original name is useless.
5259 // So instead, we should simply cache the binding, and then call
5260 // Program::ExecuteBindAttribLocationCalls() right before link.
[email protected]df37b9932013-03-08 05:21:425261 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
zmo460b593e2014-10-13 23:07:455262 // TODO(zmo): Get rid of the following glBindAttribLocation call.
[email protected]df37b9932013-03-08 05:21:425263 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:575264}
5265
[email protected]558847a2010-03-24 07:02:545266error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:345267 uint32 immediate_data_size,
5268 const void* cmd_data) {
5269 const gles2::cmds::BindAttribLocationBucket& c =
5270 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:585271 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:545272 GLuint index = static_cast<GLuint>(c.index);
5273 Bucket* bucket = GetBucket(c.name_bucket_id);
5274 if (!bucket || bucket->size() == 0) {
5275 return error::kInvalidArguments;
5276 }
5277 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:185278 if (!bucket->GetAsString(&name_str)) {
5279 return error::kInvalidArguments;
5280 }
[email protected]258a3313f2011-10-18 20:13:575281 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:545282 return error::kNoError;
5283}
5284
[email protected]2be6abf32012-06-26 00:28:335285void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:425286 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:335287 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515288 LOCAL_SET_GL_ERROR(
5289 GL_INVALID_VALUE,
5290 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:335291 return;
5292 }
5293 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515294 LOCAL_SET_GL_ERROR(
5295 GL_INVALID_OPERATION,
5296 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:335297 return;
5298 }
5299 if (location < 0 || static_cast<uint32>(location) >=
5300 (group_->max_fragment_uniform_vectors() +
5301 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:515302 LOCAL_SET_GL_ERROR(
5303 GL_INVALID_VALUE,
5304 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335305 return;
5306 }
[email protected]df37b9932013-03-08 05:21:425307 Program* program = GetProgramInfoNotShader(
5308 program_id, "glBindUniformLocationCHROMIUM");
5309 if (!program) {
[email protected]2be6abf32012-06-26 00:28:335310 return;
5311 }
[email protected]df37b9932013-03-08 05:21:425312 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:515313 LOCAL_SET_GL_ERROR(
5314 GL_INVALID_VALUE,
5315 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335316 }
5317}
5318
[email protected]2be6abf32012-06-26 00:28:335319error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
5320 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:345321 const void* cmd_data) {
5322 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
5323 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
5324 cmd_data);
[email protected]2be6abf32012-06-26 00:28:335325 GLuint program = static_cast<GLuint>(c.program);
5326 GLint location = static_cast<GLint>(c.location);
5327 Bucket* bucket = GetBucket(c.name_bucket_id);
5328 if (!bucket || bucket->size() == 0) {
5329 return error::kInvalidArguments;
5330 }
5331 std::string name_str;
5332 if (!bucket->GetAsString(&name_str)) {
5333 return error::kInvalidArguments;
5334 }
5335 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
5336 return error::kNoError;
5337}
5338
vmiuracd108592014-09-08 14:36:345339error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
5340 const void* cmd_data) {
5341 const gles2::cmds::DeleteShader& c =
5342 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035343 GLuint client_id = c.shader;
5344 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425345 Shader* shader = GetShader(client_id);
5346 if (shader) {
5347 if (!shader->IsDeleted()) {
dyenc6a36cdd2015-02-25 05:24:315348 shader_manager()->Delete(shader);
[email protected]ca488e12010-12-13 20:06:145349 }
[email protected]ae51d192010-04-27 00:48:035350 } else {
[email protected]ab09b612013-03-11 22:11:515351 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:035352 }
[email protected]96449d2c2009-11-25 00:01:325353 }
[email protected]f7a64ee2010-02-01 22:24:145354 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325355}
5356
vmiuracd108592014-09-08 14:36:345357error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
5358 const void* cmd_data) {
5359 const gles2::cmds::DeleteProgram& c =
5360 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035361 GLuint client_id = c.program;
5362 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425363 Program* program = GetProgram(client_id);
5364 if (program) {
5365 if (!program->IsDeleted()) {
5366 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:145367 }
[email protected]ae51d192010-04-27 00:48:035368 } else {
[email protected]ab09b612013-03-11 22:11:515369 LOCAL_SET_GL_ERROR(
5370 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:035371 }
[email protected]96449d2c2009-11-25 00:01:325372 }
[email protected]f7a64ee2010-02-01 22:24:145373 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325374}
5375
[email protected]a7266a92012-06-28 02:11:085376error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:445377 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:205378 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:465379 ApplyDirtyState();
boliu2e7d8a7a2014-10-16 20:35:205380 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
sievers2384f2b2014-11-18 02:10:355381 if (workarounds().gl_clear_broken) {
5382 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround",
5383 GetErrorState());
5384 if (!BoundFramebufferHasDepthAttachment())
5385 mask &= ~GL_DEPTH_BUFFER_BIT;
5386 if (!BoundFramebufferHasStencilAttachment())
5387 mask &= ~GL_STENCIL_BUFFER_BIT;
5388 clear_framebuffer_blit_->ClearFramebuffer(
5389 this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red,
5390 state_.color_clear_green, state_.color_clear_blue,
5391 state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear);
5392 return error::kNoError;
5393 }
[email protected]3a03a8f2011-03-19 00:51:275394 glClear(mask);
5395 }
[email protected]a7266a92012-06-28 02:11:085396 return error::kNoError;
5397}
5398
[email protected]36cef8ce2010-03-16 07:34:455399void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5400 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035401 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065402 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5403 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515404 LOCAL_SET_GL_ERROR(
5405 GL_INVALID_OPERATION,
5406 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455407 return;
5408 }
[email protected]ae51d192010-04-27 00:48:035409 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275410 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035411 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275412 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5413 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515414 LOCAL_SET_GL_ERROR(
5415 GL_INVALID_OPERATION,
5416 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035417 return;
5418 }
[email protected]ee2a79c32013-03-10 03:50:275419 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035420 }
[email protected]ab09b612013-03-11 22:11:515421 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035422 glFramebufferRenderbufferEXT(
5423 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515424 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265425 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275426 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285427 }
[email protected]9d3b2e12013-10-02 01:04:345428 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445429 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465430 }
[email protected]81fc9d02013-03-14 23:53:325431 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285432}
5433
[email protected]3a2e7c7b2010-08-06 01:12:285434void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465435 if (SetCapabilityState(cap, false)) {
5436 glDisable(cap);
5437 }
[email protected]3a2e7c7b2010-08-06 01:12:285438}
5439
5440void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465441 if (SetCapabilityState(cap, true)) {
5442 glEnable(cap);
5443 }
[email protected]3a2e7c7b2010-08-06 01:12:285444}
5445
[email protected]88a61bf2012-10-27 13:00:425446void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5447 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5448 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5449 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285450}
5451
[email protected]b04e24c2013-01-08 18:35:255452void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425453 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5454 state_.sample_coverage_invert = (invert != 0);
5455 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285456}
5457
[email protected]0d6bfdc2011-11-02 01:32:205458// Assumes framebuffer is complete.
5459void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065460 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305461 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205462 // bind this to the DRAW point, clear then bind back to READ
5463 // TODO(gman): I don't think there is any guarantee that an FBO that
5464 // is complete on the READ attachment will be complete as a DRAW
5465 // attachment.
5466 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065467 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305468 }
[email protected]3a2e7c7b2010-08-06 01:12:285469 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425470 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465471 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205472 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465473 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065474 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5475 1.0f);
[email protected]454157e2014-05-03 02:49:455476 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285477 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535478 if (feature_info_->feature_flags().ext_draw_buffers)
5479 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285480 }
5481
[email protected]4d8f0dd2013-03-09 14:37:065482 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5483 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285484 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475485 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5486 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285487 clear_bits |= GL_STENCIL_BUFFER_BIT;
5488 }
5489
[email protected]4d8f0dd2013-03-09 14:37:065490 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5491 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285492 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455493 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285494 clear_bits |= GL_DEPTH_BUFFER_BIT;
5495 }
5496
[email protected]454157e2014-05-03 02:49:455497 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285498 glClear(clear_bits);
5499
brucedawson18249152014-10-31 23:02:325500 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]0e58af82014-08-08 14:02:535501 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425502 framebuffer->RestoreDrawBuffersAfterClear();
5503
[email protected]968351b2011-12-20 08:26:515504 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065505 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285506
[email protected]c007aa02010-09-02 22:22:405507 RestoreClearState();
5508
5509 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065510 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5511 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485512 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065513 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5514 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485515 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405516 }
5517}
5518
5519void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445520 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245521 glClearColor(
5522 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5523 state_.color_clear_alpha);
5524 glClearStencil(state_.stencil_clear);
5525 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225526 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455527 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285528 }
[email protected]36cef8ce2010-03-16 07:34:455529}
5530
5531GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355532 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305533 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205534 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455535 return GL_FRAMEBUFFER_COMPLETE;
5536 }
[email protected]0d6bfdc2011-11-02 01:32:205537 GLenum completeness = framebuffer->IsPossiblyComplete();
5538 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5539 return completeness;
5540 }
[email protected]73276522012-11-09 05:50:205541 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455542}
5543
5544void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035545 GLenum target, GLenum attachment, GLenum textarget,
5546 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165547 DoFramebufferTexture2DCommon(
5548 "glFramebufferTexture2D", target, attachment,
5549 textarget, client_texture_id, level, 0);
5550}
5551
5552void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5553 GLenum target, GLenum attachment, GLenum textarget,
5554 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165555 DoFramebufferTexture2DCommon(
5556 "glFramebufferTexture2DMultisample", target, attachment,
5557 textarget, client_texture_id, level, samples);
5558}
5559
5560void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5561 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5562 GLuint client_texture_id, GLint level, GLsizei samples) {
5563 if (samples > renderbuffer_manager()->max_samples()) {
5564 LOCAL_SET_GL_ERROR(
5565 GL_INVALID_VALUE,
5566 "glFramebufferTexture2DMultisample", "samples too large");
5567 return;
5568 }
[email protected]4d8f0dd2013-03-09 14:37:065569 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5570 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515571 LOCAL_SET_GL_ERROR(
5572 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165573 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455574 return;
5575 }
[email protected]ae51d192010-04-27 00:48:035576 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495577 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035578 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495579 texture_ref = GetTexture(client_texture_id);
5580 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515581 LOCAL_SET_GL_ERROR(
5582 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165583 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035584 return;
5585 }
[email protected]370eaf12013-05-18 09:19:495586 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035587 }
[email protected]0d6bfdc2011-11-02 01:32:205588
[email protected]80eb6b52012-01-19 00:14:415589 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515590 LOCAL_SET_GL_ERROR(
5591 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165592 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205593 return;
5594 }
5595
[email protected]91c94eb2013-10-22 10:32:545596 if (texture_ref)
5597 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5598
[email protected]7d3c36e2013-07-12 14:13:165599 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5600 if (0 == samples) {
5601 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5602 } else {
5603 if (features().use_img_for_multisampled_render_to_texture) {
5604 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5605 service_id, level, samples);
5606 } else {
5607 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5608 service_id, level, samples);
5609 }
5610 }
5611 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265612 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165613 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5614 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285615 }
[email protected]9d3b2e12013-10-02 01:04:345616 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445617 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465618 }
[email protected]91c94eb2013-10-22 10:32:545619
5620 if (texture_ref)
5621 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5622
[email protected]81fc9d02013-03-14 23:53:325623 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455624}
5625
zmo84c08202014-11-23 15:28:405626void GLES2DecoderImpl::DoFramebufferTextureLayer(
5627 GLenum target, GLenum attachment, GLuint client_texture_id,
5628 GLint level, GLint layer) {
5629 // TODO(zmo): Unsafe ES3 API, missing states update.
5630 GLuint service_id = 0;
5631 TextureRef* texture_ref = NULL;
5632 if (client_texture_id) {
5633 texture_ref = GetTexture(client_texture_id);
5634 if (!texture_ref) {
5635 LOCAL_SET_GL_ERROR(
5636 GL_INVALID_OPERATION,
5637 "glFramebufferTextureLayer", "unknown texture_ref");
5638 return;
5639 }
5640 service_id = texture_ref->service_id();
5641 }
5642 glFramebufferTextureLayer(target, attachment, service_id, level, layer);
5643}
5644
[email protected]36cef8ce2010-03-16 07:34:455645void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5646 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065647 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5648 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515649 LOCAL_SET_GL_ERROR(
5650 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205651 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455652 return;
5653 }
[email protected]74c1ec42010-08-12 01:55:575654 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105655 const Framebuffer::Attachment* attachment_object =
5656 framebuffer->GetAttachment(attachment);
5657 *params = attachment_object ? attachment_object->object_name() : 0;
5658 } else {
[email protected]7d3c36e2013-07-12 14:13:165659 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5660 features().use_img_for_multisampled_render_to_texture) {
5661 pname = GL_TEXTURE_SAMPLES_IMG;
5662 }
[email protected]62e65f02013-05-29 22:28:105663 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575664 }
[email protected]36cef8ce2010-03-16 07:34:455665}
5666
5667void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5668 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355669 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205670 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5671 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515672 LOCAL_SET_GL_ERROR(
5673 GL_INVALID_OPERATION,
5674 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455675 return;
5676 }
[email protected]8875a5f2014-06-27 08:33:475677
5678 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275679 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435680 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5681 *params = renderbuffer->internal_format();
5682 break;
5683 case GL_RENDERBUFFER_WIDTH:
5684 *params = renderbuffer->width();
5685 break;
5686 case GL_RENDERBUFFER_HEIGHT:
5687 *params = renderbuffer->height();
5688 break;
[email protected]7d3c36e2013-07-12 14:13:165689 case GL_RENDERBUFFER_SAMPLES_EXT:
5690 if (features().use_img_for_multisampled_render_to_texture) {
5691 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5692 params);
5693 } else {
5694 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5695 params);
5696 }
[email protected]ad84a3a2012-06-08 21:42:435697 default:
5698 glGetRenderbufferParameterivEXT(target, pname, params);
5699 break;
[email protected]b71f52c2010-06-18 22:20:205700 }
[email protected]36cef8ce2010-03-16 07:34:455701}
5702
[email protected]49cabed2013-11-13 18:15:185703void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305704 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5705 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5706 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445707 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165708
[email protected]49cabed2013-11-13 18:15:185709 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165710 return;
5711 }
5712
[email protected]454157e2014-05-03 02:49:455713 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
boliu2e7d8a7a2014-10-16 20:35:205714 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]f42f05b2013-11-15 21:46:185715 BlitFramebufferHelper(
5716 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455717 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5718 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185719}
5720
[email protected]8875a5f2014-06-27 08:33:475721void GLES2DecoderImpl::EnsureRenderbufferBound() {
5722 if (!state_.bound_renderbuffer_valid) {
5723 state_.bound_renderbuffer_valid = true;
5724 glBindRenderbufferEXT(GL_RENDERBUFFER,
5725 state_.bound_renderbuffer.get()
5726 ? state_.bound_renderbuffer->service_id()
5727 : 0);
5728 }
5729}
5730
[email protected]f42f05b2013-11-15 21:46:185731void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5732 const FeatureInfo* feature_info,
5733 GLenum target,
5734 GLsizei samples,
5735 GLenum internal_format,
5736 GLsizei width,
5737 GLsizei height) {
5738 // TODO(sievers): This could be resolved at the GL binding level, but the
5739 // binding process is currently a bit too 'brute force'.
zmo68fcdc62014-12-05 21:51:495740 if (feature_info->gl_version_info().is_angle) {
[email protected]f42f05b2013-11-15 21:46:185741 glRenderbufferStorageMultisampleANGLE(
5742 target, samples, internal_format, width, height);
5743 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5744 glRenderbufferStorageMultisample(
5745 target, samples, internal_format, width, height);
5746 } else {
5747 glRenderbufferStorageMultisampleEXT(
5748 target, samples, internal_format, width, height);
5749 }
5750}
5751
5752void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5753 GLint srcY0,
5754 GLint srcX1,
5755 GLint srcY1,
5756 GLint dstX0,
5757 GLint dstY0,
5758 GLint dstX1,
5759 GLint dstY1,
5760 GLbitfield mask,
5761 GLenum filter) {
5762 // TODO(sievers): This could be resolved at the GL binding level, but the
5763 // binding process is currently a bit too 'brute force'.
marcheu1856f5d52015-04-04 01:42:535764 if (feature_info_->gl_version_info().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245765 glBlitFramebufferANGLE(
5766 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185767 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5768 glBlitFramebuffer(
5769 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245770 } else {
5771 glBlitFramebufferEXT(
5772 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5773 }
[email protected]8e3e0662010-08-23 18:46:305774}
5775
[email protected]49cabed2013-11-13 18:15:185776bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5777 GLsizei samples,
5778 GLenum internalformat,
5779 GLsizei width,
5780 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535781 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515782 LOCAL_SET_GL_ERROR(
5783 GL_INVALID_VALUE,
5784 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185785 return false;
[email protected]84afefa2011-10-19 21:45:535786 }
5787
5788 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5789 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515790 LOCAL_SET_GL_ERROR(
5791 GL_INVALID_VALUE,
5792 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185793 return false;
[email protected]84afefa2011-10-19 21:45:535794 }
5795
[email protected]7989c9e2013-01-23 06:39:265796 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235797 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5798 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515799 LOCAL_SET_GL_ERROR(
5800 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205801 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185802 return false;
[email protected]8e3e0662010-08-23 18:46:305803 }
5804
[email protected]7989c9e2013-01-23 06:39:265805 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515806 LOCAL_SET_GL_ERROR(
5807 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205808 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185809 return false;
5810 }
5811
5812 return true;
5813}
5814
5815void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5816 GLenum target, GLsizei samples, GLenum internalformat,
5817 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185818 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5819 if (!renderbuffer) {
5820 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5821 "glRenderbufferStorageMultisampleCHROMIUM",
5822 "no renderbuffer bound");
5823 return;
5824 }
5825
5826 if (!ValidateRenderbufferStorageMultisample(
5827 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265828 return;
5829 }
5830
[email protected]8875a5f2014-06-27 08:33:475831 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235832 GLenum impl_format =
5833 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5834 internalformat);
[email protected]49cabed2013-11-13 18:15:185835 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5836 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185837 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:255838 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185839 GLenum error =
5840 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265841 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105842 if (workarounds().validate_multisample_buffer_allocation) {
5843 if (!VerifyMultisampleRenderbufferIntegrity(
5844 renderbuffer->service_id(), impl_format)) {
5845 LOCAL_SET_GL_ERROR(
5846 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185847 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105848 return;
5849 }
5850 }
5851
[email protected]968351b2011-12-20 08:26:515852 // TODO(gman): If renderbuffers tracked which framebuffers they were
5853 // attached to we could just mark those framebuffers as not complete.
5854 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205855 renderbuffer_manager()->SetInfo(
5856 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265857 }
[email protected]8e3e0662010-08-23 18:46:305858}
5859
[email protected]49cabed2013-11-13 18:15:185860// This is the handler for multisampled_render_to_texture extensions.
5861void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5862 GLenum target, GLsizei samples, GLenum internalformat,
5863 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185864 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5865 if (!renderbuffer) {
5866 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5867 "glRenderbufferStorageMultisampleEXT",
5868 "no renderbuffer bound");
5869 return;
5870 }
5871
5872 if (!ValidateRenderbufferStorageMultisample(
5873 samples, internalformat, width, height)) {
5874 return;
5875 }
5876
[email protected]8875a5f2014-06-27 08:33:475877 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185878 GLenum impl_format =
5879 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5880 internalformat);
5881 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5882 if (features().use_img_for_multisampled_render_to_texture) {
5883 glRenderbufferStorageMultisampleIMG(
5884 target, samples, impl_format, width, height);
5885 } else {
5886 glRenderbufferStorageMultisampleEXT(
5887 target, samples, impl_format, width, height);
5888 }
5889 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5890 if (error == GL_NO_ERROR) {
5891 // TODO(gman): If renderbuffers tracked which framebuffers they were
5892 // attached to we could just mark those framebuffers as not complete.
5893 framebuffer_manager()->IncFramebufferStateChangeCount();
5894 renderbuffer_manager()->SetInfo(
5895 renderbuffer, samples, internalformat, width, height);
5896 }
5897}
5898
[email protected]4a4c18b2013-09-13 22:50:105899// This function validates the allocation of a multisampled renderbuffer
5900// by clearing it to a key color, blitting the contents to a texture, and
5901// reading back the color to ensure it matches the key.
5902bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5903 GLuint renderbuffer, GLenum format) {
5904
5905 // Only validate color buffers.
5906 // These formats have been selected because they are very common or are known
5907 // to be used by the WebGL backbuffer. If problems are observed with other
5908 // color formats they can be added here.
dcastagna504d45c2015-04-06 19:30:395909 switch (format) {
[email protected]4a4c18b2013-09-13 22:50:105910 case GL_RGB:
5911 case GL_RGB8:
5912 case GL_RGBA:
5913 case GL_RGBA8:
5914 break;
5915 default:
5916 return true;
5917 }
5918
5919 GLint draw_framebuffer, read_framebuffer;
5920
5921 // Cache framebuffer and texture bindings.
5922 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5923 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5924
5925 if (!validation_texture_) {
5926 GLint bound_texture;
5927 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5928
5929 // Create additional resources needed for the verification.
5930 glGenTextures(1, &validation_texture_);
5931 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5932 glGenFramebuffersEXT(1, &validation_fbo_);
5933
5934 // Texture only needs to be 1x1.
5935 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5936 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5937 GL_UNSIGNED_BYTE, NULL);
5938
5939 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5940 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5941 GL_TEXTURE_2D, validation_texture_, 0);
5942
5943 glBindTexture(GL_TEXTURE_2D, bound_texture);
5944 }
5945
5946 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5947 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5948 GL_RENDERBUFFER, renderbuffer);
5949
5950 // Cache current state and reset it to the values we require.
5951 GLboolean scissor_enabled = false;
5952 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5953 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455954 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105955
[email protected]454157e2014-05-03 02:49:455956 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105957 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455958 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105959
5960 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5961 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5962 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5963
5964 // Clear the buffer to the desired key color.
5965 glClear(GL_COLOR_BUFFER_BIT);
5966
5967 // Blit from the multisample buffer to a standard texture.
5968 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5969 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5970
[email protected]f42f05b2013-11-15 21:46:185971 BlitFramebufferHelper(
5972 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105973
5974 // Read a pixel from the buffer.
5975 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5976
5977 unsigned char pixel[3] = {0, 0, 0};
5978 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5979
5980 // Detach the renderbuffer.
5981 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5982 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5983 GL_RENDERBUFFER, 0);
5984
5985 // Restore cached state.
5986 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455987 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105988
[email protected]454157e2014-05-03 02:49:455989 state_.SetDeviceColorMask(
5990 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105991 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5992 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5993 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5994
5995 // Return true if the pixel matched the desired key color.
5996 return (pixel[0] == 0xFF &&
5997 pixel[1] == 0x00 &&
5998 pixel[2] == 0xFF);
5999}
6000
[email protected]36cef8ce2010-03-16 07:34:456001void GLES2DecoderImpl::DoRenderbufferStorage(
6002 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:356003 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:206004 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
6005 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:516006 LOCAL_SET_GL_ERROR(
6007 GL_INVALID_OPERATION,
6008 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:456009 return;
6010 }
[email protected]876f6fee2010-08-02 23:10:326011
[email protected]84afefa2011-10-19 21:45:536012 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
6013 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:516014 LOCAL_SET_GL_ERROR(
6015 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:536016 return;
6017 }
6018
[email protected]7989c9e2013-01-23 06:39:266019 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:236020 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
6021 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:516022 LOCAL_SET_GL_ERROR(
6023 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:266024 return;
6025 }
6026
6027 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:516028 LOCAL_SET_GL_ERROR(
6029 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:266030 return;
[email protected]b71f52c2010-06-18 22:20:206031 }
[email protected]876f6fee2010-08-02 23:10:326032
[email protected]8875a5f2014-06-27 08:33:476033 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:516034 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:266035 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:236036 target,
6037 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
6038 internalformat),
6039 width,
6040 height);
[email protected]ab09b612013-03-11 22:11:516041 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:266042 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:516043 // TODO(gman): If tetxures tracked which framebuffers they were attached to
6044 // we could just mark those framebuffers as not complete.
6045 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:206046 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:266047 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:266048 }
[email protected]36cef8ce2010-03-16 07:34:456049}
6050
[email protected]df37b9932013-03-08 05:21:426051void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:386052 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:426053 Program* program = GetProgramInfoNotShader(
6054 program_id, "glLinkProgram");
6055 if (!program) {
[email protected]a93bb842010-02-16 23:03:476056 return;
6057 }
[email protected]05afda12011-01-20 00:17:346058
[email protected]df37b9932013-03-08 05:21:426059 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]df37b9932013-03-08 05:21:426060 if (program->Link(shader_manager(),
[email protected]008401532014-02-07 00:10:506061 workarounds().count_all_in_varyings_packing ?
6062 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:116063 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:426064 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:186065 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:426066 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:186067 if (workarounds().clear_uniforms_before_first_program_use)
6068 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:546069 }
6070 }
vmiura8266ca72014-09-09 21:37:006071
6072 // LinkProgram can be very slow. Exit command processing to allow for
6073 // context preemption and GPU watchdog checks.
6074 ExitCommandProcessingEarly();
dcastagna504d45c2015-04-06 19:30:396075}
[email protected]07f54fcc2009-12-22 02:46:306076
zmobcb3fdd62014-12-11 00:49:036077void GLES2DecoderImpl::DoSamplerParameterfv(
6078 GLuint sampler, GLenum pname, const GLfloat* params) {
6079 DCHECK(params);
6080 glSamplerParameterf(sampler, pname, params[0]);
6081}
6082
6083void GLES2DecoderImpl::DoSamplerParameteriv(
6084 GLuint sampler, GLenum pname, const GLint* params) {
6085 DCHECK(params);
6086 glSamplerParameteri(sampler, pname, params[0]);
6087}
6088
[email protected]3916c97e2010-02-25 03:20:506089void GLES2DecoderImpl::DoTexParameterf(
6090 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:446091 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
6092 &state_, target);
[email protected]02965c22013-03-09 02:40:076093 if (!texture) {
[email protected]ab09b612013-03-11 22:11:516094 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:246095 return;
[email protected]07f54fcc2009-12-22 02:46:306096 }
[email protected]cbb22e42011-05-12 23:36:246097
[email protected]737191ee72014-03-09 08:02:426098 texture_manager()->SetParameterf(
6099 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:306100}
6101
[email protected]3916c97e2010-02-25 03:20:506102void GLES2DecoderImpl::DoTexParameteri(
6103 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:446104 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
6105 &state_, target);
[email protected]02965c22013-03-09 02:40:076106 if (!texture) {
[email protected]ab09b612013-03-11 22:11:516107 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:246108 return;
[email protected]3916c97e2010-02-25 03:20:506109 }
[email protected]cbb22e42011-05-12 23:36:246110
[email protected]737191ee72014-03-09 08:02:426111 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:506112 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:506113}
6114
6115void GLES2DecoderImpl::DoTexParameterfv(
6116 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:446117 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
6118 &state_, target);
[email protected]02965c22013-03-09 02:40:076119 if (!texture) {
[email protected]ab09b612013-03-11 22:11:516120 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:246121 return;
[email protected]3916c97e2010-02-25 03:20:506122 }
[email protected]cbb22e42011-05-12 23:36:246123
[email protected]737191ee72014-03-09 08:02:426124 texture_manager()->SetParameterf(
6125 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:506126}
6127
6128void GLES2DecoderImpl::DoTexParameteriv(
6129 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:446130 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
6131 &state_, target);
[email protected]02965c22013-03-09 02:40:076132 if (!texture) {
[email protected]ab09b612013-03-11 22:11:516133 LOCAL_SET_GL_ERROR(
6134 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:246135 return;
[email protected]3916c97e2010-02-25 03:20:506136 }
[email protected]cbb22e42011-05-12 23:36:246137
[email protected]737191ee72014-03-09 08:02:426138 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:506139 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:506140}
6141
orglofchcad5a6742014-11-07 19:51:126142bool GLES2DecoderImpl::CheckCurrentValuebuffer(const char* function_name) {
6143 if (!state_.bound_valuebuffer.get()) {
6144 // There is no valuebuffer bound
6145 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6146 "no valuebuffer in use");
6147 return false;
6148 }
6149 return true;
6150}
6151
6152bool GLES2DecoderImpl::CheckCurrentValuebufferForSubscription(
6153 GLenum subscription,
6154 const char* function_name) {
6155 if (!CheckCurrentValuebuffer(function_name)) {
6156 return false;
6157 }
6158 if (!state_.bound_valuebuffer.get()->IsSubscribed(subscription)) {
6159 // The valuebuffer is not subscribed to the target
6160 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6161 "valuebuffer is not subscribed");
6162 return false;
6163 }
6164 return true;
6165}
6166
6167bool GLES2DecoderImpl::CheckSubscriptionTarget(GLint location,
6168 GLenum subscription,
6169 const char* function_name) {
6170 if (!CheckCurrentProgramForUniform(location, function_name)) {
6171 return false;
6172 }
6173 GLint real_location = -1;
6174 GLint array_index = -1;
6175 const Program::UniformInfo* info =
6176 state_.current_program->GetUniformInfoByFakeLocation(
6177 location, &real_location, &array_index);
6178 if (!info) {
6179 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "unknown location");
6180 return false;
6181 }
6182 if ((ValuebufferManager::ApiTypeForSubscriptionTarget(subscription) &
6183 info->accepts_api_type) == 0) {
6184 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6185 "wrong type for subscription");
6186 return false;
6187 }
6188 return true;
6189}
6190
[email protected]939e7362010-05-13 20:49:106191bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:116192 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:436193 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:516194 LOCAL_SET_GL_ERROR(
6195 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:436196 return false;
[email protected]939e7362010-05-13 20:49:106197 }
[email protected]e259eb412012-10-13 05:47:246198 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:516199 LOCAL_SET_GL_ERROR(
6200 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:106201 return false;
6202 }
6203 return true;
6204}
6205
6206bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
6207 GLint location, const char* function_name) {
6208 if (!CheckCurrentProgram(function_name)) {
6209 return false;
6210 }
6211 return location != -1;
6212}
6213
zmof9a81360f2014-10-17 00:06:146214bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
6215 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
6216 if (!framebuffer)
6217 return false;
6218 const Framebuffer::Attachment* attachment =
6219 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
6220 if (!attachment)
6221 return false;
6222
6223 DCHECK(state_.current_program.get());
6224 const Program::SamplerIndices& sampler_indices =
6225 state_.current_program->sampler_indices();
6226 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
6227 const Program::UniformInfo* uniform_info =
6228 state_.current_program->GetUniformInfo(sampler_indices[ii]);
6229 DCHECK(uniform_info);
6230 if (uniform_info->type != GL_SAMPLER_2D)
6231 continue;
6232 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6233 GLuint texture_unit_index = uniform_info->texture_units[jj];
6234 if (texture_unit_index >= state_.texture_units.size())
6235 continue;
6236 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
6237 TextureRef* texture_ref =
6238 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
6239 if (attachment->IsTexture(texture_ref))
6240 return true;
6241 }
6242 }
6243 return false;
6244}
6245
orglofchcad5a6742014-11-07 19:51:126246bool GLES2DecoderImpl::CheckUniformForApiType(
6247 const Program::UniformInfo* info,
6248 const char* function_name,
6249 Program::UniformApiType api_type) {
6250 DCHECK(info);
6251 if ((api_type & info->accepts_api_type) == 0) {
6252 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6253 "wrong uniform function for type");
6254 return false;
6255 }
6256 return true;
6257}
6258
[email protected]43c2f1f2011-03-25 18:35:366259bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:136260 GLint fake_location,
6261 const char* function_name,
6262 Program::UniformApiType api_type,
6263 GLint* real_location,
6264 GLenum* type,
6265 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:366266 DCHECK(type);
6267 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:126268 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:526269
[email protected]1b0a6752012-02-22 03:44:126270 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:106271 return false;
6272 }
[email protected]43c2f1f2011-03-25 18:35:366273 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:356274 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:246275 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:126276 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:366277 if (!info) {
[email protected]ab09b612013-03-11 22:11:516278 LOCAL_SET_GL_ERROR(
6279 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:106280 return false;
6281 }
orglofchcad5a6742014-11-07 19:51:126282 if (!CheckUniformForApiType(info, function_name, api_type)) {
[email protected]476ccb72012-12-06 15:52:526283 return false;
6284 }
[email protected]43c2f1f2011-03-25 18:35:366285 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:516286 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436287 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:366288 return false;
6289 }
6290 *count = std::min(info->size - array_index, *count);
6291 if (*count <= 0) {
6292 return false;
6293 }
6294 *type = info->type;
[email protected]939e7362010-05-13 20:49:106295 return true;
6296}
6297
[email protected]1b0a6752012-02-22 03:44:126298void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
6299 GLenum type = 0;
6300 GLsizei count = 1;
6301 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136302 if (!PrepForSetUniformByLocation(fake_location,
6303 "glUniform1i",
6304 Program::kUniform1i,
6305 &real_location,
6306 &type,
6307 &count)) {
[email protected]3916c97e2010-02-25 03:20:506308 return;
6309 }
[email protected]e259eb412012-10-13 05:47:246310 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026311 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:516312 LOCAL_SET_GL_ERROR(
6313 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466314 return;
6315 }
[email protected]1b0a6752012-02-22 03:44:126316 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:506317}
6318
6319void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:126320 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:366321 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126322 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136323 if (!PrepForSetUniformByLocation(fake_location,
6324 "glUniform1iv",
6325 Program::kUniform1i,
6326 &real_location,
6327 &type,
6328 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366329 return;
6330 }
[email protected]74727112012-06-13 21:18:086331 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
6332 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:246333 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026334 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:516335 LOCAL_SET_GL_ERROR(
6336 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466337 return;
6338 }
[email protected]43c2f1f2011-03-25 18:35:366339 }
[email protected]1b0a6752012-02-22 03:44:126340 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:506341}
6342
[email protected]939e7362010-05-13 20:49:106343void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:126344 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366345 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126346 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136347 if (!PrepForSetUniformByLocation(fake_location,
6348 "glUniform1fv",
6349 Program::kUniform1f,
6350 &real_location,
6351 &type,
6352 &count)) {
[email protected]939e7362010-05-13 20:49:106353 return;
6354 }
6355 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:556356 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:106357 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:536358 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106359 }
[email protected]1b0a6752012-02-22 03:44:126360 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106361 } else {
[email protected]1b0a6752012-02-22 03:44:126362 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106363 }
6364}
6365
6366void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:126367 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366368 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126369 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136370 if (!PrepForSetUniformByLocation(fake_location,
6371 "glUniform2fv",
6372 Program::kUniform2f,
6373 &real_location,
6374 &type,
6375 &count)) {
[email protected]939e7362010-05-13 20:49:106376 return;
6377 }
6378 if (type == GL_BOOL_VEC2) {
6379 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:556380 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106381 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536382 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106383 }
[email protected]1b0a6752012-02-22 03:44:126384 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106385 } else {
[email protected]1b0a6752012-02-22 03:44:126386 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106387 }
6388}
6389
6390void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:126391 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366392 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126393 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136394 if (!PrepForSetUniformByLocation(fake_location,
6395 "glUniform3fv",
6396 Program::kUniform3f,
6397 &real_location,
6398 &type,
6399 &count)) {
[email protected]939e7362010-05-13 20:49:106400 return;
6401 }
6402 if (type == GL_BOOL_VEC3) {
6403 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:556404 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106405 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536406 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106407 }
[email protected]1b0a6752012-02-22 03:44:126408 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106409 } else {
[email protected]1b0a6752012-02-22 03:44:126410 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106411 }
6412}
6413
6414void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:126415 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366416 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126417 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136418 if (!PrepForSetUniformByLocation(fake_location,
6419 "glUniform4fv",
6420 Program::kUniform4f,
6421 &real_location,
6422 &type,
6423 &count)) {
[email protected]939e7362010-05-13 20:49:106424 return;
6425 }
6426 if (type == GL_BOOL_VEC4) {
6427 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:556428 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106429 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536430 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106431 }
[email protected]1b0a6752012-02-22 03:44:126432 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106433 } else {
[email protected]1b0a6752012-02-22 03:44:126434 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106435 }
6436}
6437
[email protected]43c2f1f2011-03-25 18:35:366438void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:126439 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366440 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126441 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136442 if (!PrepForSetUniformByLocation(fake_location,
6443 "glUniform2iv",
6444 Program::kUniform2i,
6445 &real_location,
6446 &type,
6447 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366448 return;
6449 }
[email protected]1b0a6752012-02-22 03:44:126450 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366451}
6452
6453void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:126454 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366455 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126456 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136457 if (!PrepForSetUniformByLocation(fake_location,
6458 "glUniform3iv",
6459 Program::kUniform3i,
6460 &real_location,
6461 &type,
6462 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366463 return;
6464 }
[email protected]1b0a6752012-02-22 03:44:126465 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366466}
6467
6468void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:126469 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366470 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126471 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136472 if (!PrepForSetUniformByLocation(fake_location,
6473 "glUniform4iv",
6474 Program::kUniform4i,
6475 &real_location,
6476 &type,
6477 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366478 return;
6479 }
[email protected]1b0a6752012-02-22 03:44:126480 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366481}
6482
6483void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126484 GLint fake_location, GLsizei count, GLboolean transpose,
6485 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366486 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126487 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136488 if (!PrepForSetUniformByLocation(fake_location,
6489 "glUniformMatrix2fv",
6490 Program::kUniformMatrix2f,
6491 &real_location,
6492 &type,
6493 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366494 return;
6495 }
[email protected]1b0a6752012-02-22 03:44:126496 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366497}
6498
6499void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126500 GLint fake_location, GLsizei count, GLboolean transpose,
6501 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366502 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126503 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136504 if (!PrepForSetUniformByLocation(fake_location,
6505 "glUniformMatrix3fv",
6506 Program::kUniformMatrix3f,
6507 &real_location,
6508 &type,
6509 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366510 return;
6511 }
[email protected]1b0a6752012-02-22 03:44:126512 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366513}
6514
6515void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126516 GLint fake_location, GLsizei count, GLboolean transpose,
6517 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366518 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126519 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136520 if (!PrepForSetUniformByLocation(fake_location,
6521 "glUniformMatrix4fv",
6522 Program::kUniformMatrix4f,
6523 &real_location,
6524 &type,
6525 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366526 return;
6527 }
[email protected]1b0a6752012-02-22 03:44:126528 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366529}
6530
[email protected]df37b9932013-03-08 05:21:426531void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036532 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426533 Program* program = NULL;
6534 if (program_id) {
6535 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6536 if (!program) {
[email protected]ae51d192010-04-27 00:48:036537 return;
6538 }
[email protected]df37b9932013-03-08 05:21:426539 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506540 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516541 LOCAL_SET_GL_ERROR(
6542 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506543 return;
6544 }
[email protected]df37b9932013-03-08 05:21:426545 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506546 }
[email protected]7cd76fd2013-06-02 21:11:116547 if (state_.current_program.get()) {
6548 program_manager()->UnuseProgram(shader_manager(),
6549 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146550 }
[email protected]df37b9932013-03-08 05:21:426551 state_.current_program = program;
6552 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546553 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116554 if (state_.current_program.get()) {
6555 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186556 if (workarounds().clear_uniforms_before_first_program_use)
6557 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146558 }
[email protected]3916c97e2010-02-25 03:20:506559}
6560
[email protected]ab09b612013-03-11 22:11:516561void GLES2DecoderImpl::RenderWarning(
6562 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326563 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016564}
6565
[email protected]ab09b612013-03-11 22:11:516566void GLES2DecoderImpl::PerformanceWarning(
6567 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506568 logger_.LogMessage(filename, line,
6569 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016570}
6571
[email protected]91c94eb2013-10-22 10:32:546572void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6573 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546574 // Image is already in use if texture is attached to a framebuffer.
6575 if (texture && !texture->IsAttachedToFramebuffer()) {
6576 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6577 if (image) {
6578 ScopedGLErrorSuppressor suppressor(
6579 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6580 GetErrorState());
6581 glBindTexture(textarget, texture->service_id());
6582 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026583 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546584 }
6585 }
6586}
6587
6588void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6589 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546590 // Image is still in use if texture is attached to a framebuffer.
6591 if (texture && !texture->IsAttachedToFramebuffer()) {
6592 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6593 if (image) {
6594 ScopedGLErrorSuppressor suppressor(
6595 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6596 GetErrorState());
6597 glBindTexture(textarget, texture->service_id());
6598 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026599 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546600 }
6601 }
6602}
6603
[email protected]e56131d22013-07-28 16:14:116604bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116605 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546606 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556607 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116608 return true;
[email protected]ef526492010-06-02 23:12:256609 }
[email protected]e2367b42013-05-31 03:37:216610
[email protected]ef526492010-06-02 23:12:256611 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356612 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246613 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506614 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356615 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246616 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506617 DCHECK(uniform_info);
6618 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6619 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026620 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246621 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546622 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366623 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546624 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6625 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256626 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506627 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6628 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546629 textarget,
[email protected]00f893d2010-08-24 18:55:496630 texture_manager()->black_texture_id(uniform_info->type));
dongseong.hwang7d87d722015-01-14 20:02:406631 if (!texture_ref) {
6632 LOCAL_RENDER_WARNING(
6633 std::string("there is no texture bound to the unit ") +
6634 base::IntToString(texture_unit_index));
6635 } else {
6636 LOCAL_RENDER_WARNING(
6637 std::string("texture bound to texture unit ") +
6638 base::IntToString(texture_unit_index) +
6639 " is not renderable. It maybe non-power-of-2 and have"
6640 " incompatible texture filtering.");
6641 }
[email protected]91c94eb2013-10-22 10:32:546642 continue;
[email protected]3916c97e2010-02-25 03:20:506643 }
[email protected]91c94eb2013-10-22 10:32:546644
[email protected]4e7b89202014-01-28 01:44:066645 if (textarget != GL_TEXTURE_CUBE_MAP) {
6646 Texture* texture = texture_ref->texture();
6647 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6648 if (image && !texture->IsAttachedToFramebuffer()) {
6649 ScopedGLErrorSuppressor suppressor(
6650 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6651 textures_set = true;
6652 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6653 image->WillUseTexImage();
6654 continue;
6655 }
[email protected]91c94eb2013-10-22 10:32:546656 }
[email protected]3916c97e2010-02-25 03:20:506657 }
6658 // else: should this be an error?
6659 }
6660 }
[email protected]e56131d22013-07-28 16:14:116661 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506662}
6663
[email protected]91c94eb2013-10-22 10:32:546664void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116665 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356666 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116667 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506668 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356669 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246670 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506671 DCHECK(uniform_info);
6672 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6673 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026674 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246675 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116676 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546677 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496678 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506679 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496680 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116681 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6682 ? texture_unit.bound_texture_2d.get()
6683 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506684 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496685 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546686 continue;
6687 }
6688
[email protected]4e7b89202014-01-28 01:44:066689 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6690 Texture* texture = texture_ref->texture();
6691 gfx::GLImage* image =
6692 texture->GetLevelImage(texture_unit.bind_target, 0);
6693 if (image && !texture->IsAttachedToFramebuffer()) {
6694 ScopedGLErrorSuppressor suppressor(
6695 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6696 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6697 image->DidUseTexImage();
6698 continue;
6699 }
[email protected]3916c97e2010-02-25 03:20:506700 }
6701 }
6702 }
6703 }
6704 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246705 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306706}
6707
[email protected]0d6bfdc2011-11-02 01:32:206708bool GLES2DecoderImpl::ClearUnclearedTextures() {
6709 // Only check if there are some uncleared textures.
6710 if (!texture_manager()->HaveUnsafeTextures()) {
6711 return true;
6712 }
6713
6714 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116715 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356716 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116717 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206718 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356719 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246720 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206721 DCHECK(uniform_info);
6722 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6723 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026724 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246725 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496726 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366727 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496728 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6729 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206730 return false;
6731 }
6732 }
6733 }
6734 }
6735 }
6736 }
6737 return true;
6738}
6739
[email protected]c6aef902012-02-14 03:31:426740bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106741 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6742 GLsizei primcount) {
6743 DCHECK(instanced || primcount == 1);
6744
[email protected]689fa1c52010-06-09 18:35:036745 // NOTE: We specifically do not check current_program->IsValid() because
6746 // it could never be invalid since glUseProgram would have failed. While
6747 // glLinkProgram could later mark the program as invalid the previous
6748 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116749 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506750 // The program does not exist.
6751 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516752 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506753 return false;
6754 }
[email protected]c6aef902012-02-14 03:31:426755
zmof9a81360f2014-10-17 00:06:146756 if (CheckDrawingFeedbackLoops()) {
6757 LOCAL_SET_GL_ERROR(
6758 GL_INVALID_OPERATION, function_name,
6759 "Source and destination textures of the draw are the same.");
6760 return false;
6761 }
6762
[email protected]7cd76fd2013-06-02 21:11:116763 return state_.vertex_attrib_manager
6764 ->ValidateBindings(function_name,
6765 this,
6766 feature_info_.get(),
6767 state_.current_program.get(),
6768 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106769 instanced,
[email protected]7cd76fd2013-06-02 21:11:116770 primcount);
[email protected]b1122982010-05-17 23:04:246771}
6772
[email protected]c13e1da62011-09-09 21:48:306773bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436774 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306775 DCHECK(simulated);
6776 *simulated = false;
6777
marcheu1856f5d52015-04-04 01:42:536778 if (feature_info_->gl_version_info().BehavesLikeGLES())
[email protected]c13e1da62011-09-09 21:48:306779 return true;
[email protected]876f6fee2010-08-02 23:10:326780
[email protected]ac77603c72013-03-08 13:52:066781 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356782 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246783 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246784 bool attrib_0_used =
6785 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066786 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306787 return true;
[email protected]b1122982010-05-17 23:04:246788 }
6789
[email protected]b1122982010-05-17 23:04:246790 // Make a buffer with a single repeated vec4 value enough to
6791 // simulate the constant value that is supposed to be here.
6792 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306793 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476794 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306795
6796 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476797 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306798 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516799 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306800 return false;
6801 }
6802
[email protected]ab09b612013-03-11 22:11:516803 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016804 "Attribute 0 is disabled. This has signficant performance penalty");
6805
[email protected]ab09b612013-03-11 22:11:516806 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306807 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6808
[email protected]8f0b86c2f2012-04-10 05:48:286809 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6810 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496811 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306812 GLenum error = glGetError();
6813 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516814 LOCAL_SET_GL_ERROR(
6815 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306816 return false;
6817 }
[email protected]fc753442011-02-04 19:49:496818 }
[email protected]af6380962012-11-29 23:24:136819
6820 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286821 if (new_buffer ||
6822 (attrib_0_used &&
6823 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136824 (value.v[0] != attrib_0_value_.v[0] ||
6825 value.v[1] != attrib_0_value_.v[1] ||
6826 value.v[2] != attrib_0_value_.v[2] ||
6827 value.v[3] != attrib_0_value_.v[3])))) {
6828 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496829 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6830 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136831 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246832 attrib_0_size_ = size_needed;
6833 }
6834
6835 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6836
[email protected]ac77603c72013-03-08 13:52:066837 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426838 glVertexAttribDivisorANGLE(0, 0);
6839
[email protected]c13e1da62011-09-09 21:48:306840 *simulated = true;
[email protected]b1122982010-05-17 23:04:246841 return true;
[email protected]b1122982010-05-17 23:04:246842}
6843
[email protected]3fc38e22014-05-30 00:13:236844void GLES2DecoderImpl::RestoreStateForAttrib(
6845 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066846 const VertexAttrib* attrib =
6847 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236848 if (restore_array_binding) {
6849 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6850 Buffer* buffer = attrib->buffer();
6851 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6852 glVertexAttribPointer(
6853 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6854 attrib->gl_stride(), ptr);
6855 }
[email protected]ac77603c72013-03-08 13:52:066856 if (attrib->divisor())
6857 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246858 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236859 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6860 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286861
[email protected]265f8992012-07-20 01:03:146862 // Never touch vertex attribute 0's state (in particular, never
6863 // disable it) when running on desktop GL because it will never be
6864 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066865 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146866 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066867 if (attrib->enabled()) {
6868 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146869 } else {
[email protected]ac77603c72013-03-08 13:52:066870 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146871 }
[email protected]43410e92012-04-20 17:06:286872 }
[email protected]b1122982010-05-17 23:04:246873}
[email protected]07f54fcc2009-12-22 02:46:306874
[email protected]8fbedc02010-11-18 18:43:406875bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436876 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426877 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406878 DCHECK(simulated);
6879 *simulated = false;
6880 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6881 return true;
6882
[email protected]e259eb412012-10-13 05:47:246883 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406884 return true;
6885 }
6886
[email protected]ab09b612013-03-11 22:11:516887 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016888 "GL_FIXED attributes have a signficant performance penalty");
6889
[email protected]8fbedc02010-11-18 18:43:406890 // NOTE: we could be smart and try to check if a buffer is used
6891 // twice in 2 different attribs, find the overlapping parts and therefore
6892 // duplicate the minimum amount of data but this whole code path is not meant
6893 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6894 // tests so we just add to the buffer attrib used.
6895
[email protected]c13e1da62011-09-09 21:48:306896 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066897 const VertexAttribManager::VertexAttribList& enabled_attribs =
6898 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6899 for (VertexAttribManager::VertexAttribList::const_iterator it =
6900 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6901 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356902 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066903 state_.current_program->GetAttribInfoByLocation(attrib->index());
6904 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6905 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426906 GLuint num_vertices = max_accessed + 1;
6907 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516908 LOCAL_SET_GL_ERROR(
6909 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426910 return false;
6911 }
[email protected]8fbedc02010-11-18 18:43:406912 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066913 attrib->CanAccess(max_accessed) &&
6914 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476915 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066916 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476917 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516918 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436919 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406920 return false;
6921 }
6922 }
6923 }
6924
[email protected]3aad1a32012-09-07 20:54:476925 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6926 uint32 size_needed = 0;
6927 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306928 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516929 LOCAL_SET_GL_ERROR(
6930 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406931 return false;
6932 }
6933
[email protected]ab09b612013-03-11 22:11:516934 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406935
6936 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306937 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406938 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306939 GLenum error = glGetError();
6940 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516941 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436942 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306943 return false;
6944 }
[email protected]8fbedc02010-11-18 18:43:406945 }
6946
6947 // Copy the elements and convert to float
6948 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066949 for (VertexAttribManager::VertexAttribList::const_iterator it =
6950 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6951 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356952 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066953 state_.current_program->GetAttribInfoByLocation(attrib->index());
6954 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426955 max_vertex_accessed);
6956 GLuint num_vertices = max_accessed + 1;
6957 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516958 LOCAL_SET_GL_ERROR(
6959 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426960 return false;
6961 }
[email protected]8fbedc02010-11-18 18:43:406962 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066963 attrib->CanAccess(max_accessed) &&
6964 attrib->type() == GL_FIXED) {
penghuang5a3210b2014-10-29 18:24:366965 int num_elements = attrib->size() * num_vertices;
6966 const int src_size = num_elements * sizeof(int32);
6967 const int dst_size = num_elements * sizeof(float);
6968 scoped_ptr<float[]> data(new float[num_elements]);
[email protected]8fbedc02010-11-18 18:43:406969 const int32* src = reinterpret_cast<const int32 *>(
penghuang5a3210b2014-10-29 18:24:366970 attrib->buffer()->GetRange(attrib->offset(), src_size));
[email protected]8fbedc02010-11-18 18:43:406971 const int32* end = src + num_elements;
6972 float* dst = data.get();
6973 while (src != end) {
6974 *dst++ = static_cast<float>(*src++) / 65536.0f;
6975 }
penghuang5a3210b2014-10-29 18:24:366976 glBufferSubData(GL_ARRAY_BUFFER, offset, dst_size, data.get());
[email protected]8fbedc02010-11-18 18:43:406977 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066978 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406979 reinterpret_cast<GLvoid*>(offset));
penghuang5a3210b2014-10-29 18:24:366980 offset += dst_size;
[email protected]8fbedc02010-11-18 18:43:406981 }
6982 }
6983 *simulated = true;
6984 return true;
6985}
6986
6987void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6988 // There's no need to call glVertexAttribPointer because we shadow all the
6989 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246990 glBindBuffer(
6991 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116992 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6993 : 0);
[email protected]8fbedc02010-11-18 18:43:406994}
6995
[email protected]ad84a3a2012-06-08 21:42:436996error::Error GLES2DecoderImpl::DoDrawArrays(
6997 const char* function_name,
6998 bool instanced,
6999 GLenum mode,
7000 GLint first,
7001 GLsizei count,
7002 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:227003 error::Error error = WillAccessBoundFramebufferForDraw();
7004 if (error != error::kNoError)
7005 return error;
[email protected]38d139d2011-07-14 00:38:437006 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:517007 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:437008 return error::kNoError;
7009 }
7010 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:517011 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:437012 return error::kNoError;
7013 }
[email protected]c6aef902012-02-14 03:31:427014 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:517015 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:427016 return error::kNoError;
7017 }
[email protected]ad84a3a2012-06-08 21:42:437018 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:437019 return error::kNoError;
7020 }
7021 // We have to check this here because the prototype for glDrawArrays
7022 // is GLint not GLsizei.
7023 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:517024 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:437025 return error::kNoError;
7026 }
7027
[email protected]ac6904d62014-07-30 12:00:107028 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:517029 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:437030 return error::kNoError;
7031 }
7032
7033 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:107034 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:207035 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:517036 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:207037 return error::kNoError;
7038 }
[email protected]c13e1da62011-09-09 21:48:307039 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:437040 if (!SimulateAttrib0(
7041 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:307042 return error::kNoError;
7043 }
[email protected]38d139d2011-07-14 00:38:437044 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:437045 if (SimulateFixedAttribs(
7046 function_name, max_vertex_accessed, &simulated_fixed_attribs,
7047 primcount)) {
[email protected]e56131d22013-07-28 16:14:117048 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:437049 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:377050 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:427051 if (!instanced) {
7052 glDrawArrays(mode, first, count);
7053 } else {
7054 glDrawArraysInstancedANGLE(mode, first, count, primcount);
7055 }
[email protected]38d139d2011-07-14 00:38:437056 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:547057 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:437058 }
7059 if (simulated_fixed_attribs) {
7060 RestoreStateForSimulatedFixedAttribs();
7061 }
7062 }
7063 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:237064 // We don't have to restore attrib 0 generic data at the end of this
7065 // function even if it is simulated. This is because we will simulate
7066 // it in each draw call, and attrib 0 generic data queries use cached
7067 // values instead of passing down to the underlying driver.
7068 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:437069 }
[email protected]38d139d2011-07-14 00:38:437070 }
7071 return error::kNoError;
7072}
7073
vmiuracd108592014-09-08 14:36:347074error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
7075 const void* cmd_data) {
7076 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:437077 return DoDrawArrays("glDrawArrays",
7078 false,
[email protected]c6aef902012-02-14 03:31:427079 static_cast<GLenum>(c.mode),
7080 static_cast<GLint>(c.first),
7081 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:107082 1);
[email protected]c6aef902012-02-14 03:31:427083}
7084
7085error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:347086 uint32 immediate_data_size,
7087 const void* cmd_data) {
7088 const gles2::cmds::DrawArraysInstancedANGLE& c =
7089 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157090 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517091 LOCAL_SET_GL_ERROR(
7092 GL_INVALID_OPERATION,
7093 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427094 return error::kNoError;
7095 }
[email protected]ad84a3a2012-06-08 21:42:437096 return DoDrawArrays("glDrawArraysIntancedANGLE",
7097 true,
[email protected]c6aef902012-02-14 03:31:427098 static_cast<GLenum>(c.mode),
7099 static_cast<GLint>(c.first),
7100 static_cast<GLsizei>(c.count),
7101 static_cast<GLsizei>(c.primcount));
7102}
7103
[email protected]ad84a3a2012-06-08 21:42:437104error::Error GLES2DecoderImpl::DoDrawElements(
7105 const char* function_name,
7106 bool instanced,
7107 GLenum mode,
7108 GLsizei count,
7109 GLenum type,
7110 int32 offset,
7111 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:227112 error::Error error = WillAccessBoundFramebufferForDraw();
7113 if (error != error::kNoError)
7114 return error;
[email protected]e259eb412012-10-13 05:47:247115 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:517116 LOCAL_SET_GL_ERROR(
7117 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:297118 return error::kNoError;
7119 }
7120
[email protected]8eee29c2010-04-29 03:38:297121 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:517122 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:297123 return error::kNoError;
7124 }
7125 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517126 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297127 return error::kNoError;
7128 }
[email protected]9438b012010-06-15 22:55:057129 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:517130 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:297131 return error::kNoError;
7132 }
[email protected]9438b012010-06-15 22:55:057133 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517134 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:297135 return error::kNoError;
7136 }
[email protected]c6aef902012-02-14 03:31:427137 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:517138 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:427139 return error::kNoError;
7140 }
[email protected]8eee29c2010-04-29 03:38:297141
[email protected]ad84a3a2012-06-08 21:42:437142 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:277143 return error::kNoError;
7144 }
7145
[email protected]ac6904d62014-07-30 12:00:107146 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:317147 return error::kNoError;
7148 }
7149
[email protected]8eee29c2010-04-29 03:38:297150 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:087151 Buffer* element_array_buffer =
7152 state_.vertex_attrib_manager->element_array_buffer();
7153
7154 if (!element_array_buffer->GetMaxValueForRange(
7155 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:517156 LOCAL_SET_GL_ERROR(
7157 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:297158 return error::kNoError;
7159 }
7160
[email protected]ac6904d62014-07-30 12:00:107161 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:207162 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:517163 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:207164 return error::kNoError;
7165 }
[email protected]c13e1da62011-09-09 21:48:307166 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:437167 if (!SimulateAttrib0(
7168 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:307169 return error::kNoError;
7170 }
[email protected]8fbedc02010-11-18 18:43:407171 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:437172 if (SimulateFixedAttribs(
7173 function_name, max_vertex_accessed, &simulated_fixed_attribs,
7174 primcount)) {
[email protected]e56131d22013-07-28 16:14:117175 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:467176 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:087177 // TODO(gman): Refactor to hide these details in BufferManager or
7178 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:407179 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:087180 bool used_client_side_array = false;
7181 if (element_array_buffer->IsClientSideArray()) {
7182 used_client_side_array = true;
7183 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
7184 indices = element_array_buffer->GetRange(offset, 0);
7185 }
7186
[email protected]00c2cf92014-03-14 00:08:377187 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:427188 if (!instanced) {
7189 glDrawElements(mode, count, type, indices);
7190 } else {
7191 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
7192 }
[email protected]17cfbe0e2013-03-07 01:26:087193
7194 if (used_client_side_array) {
7195 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
7196 element_array_buffer->service_id());
7197 }
7198
[email protected]8fbedc02010-11-18 18:43:407199 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:547200 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:407201 }
7202 if (simulated_fixed_attribs) {
7203 RestoreStateForSimulatedFixedAttribs();
7204 }
[email protected]ba3176a2009-12-16 18:19:467205 }
[email protected]b1122982010-05-17 23:04:247206 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:237207 // We don't have to restore attrib 0 generic data at the end of this
7208 // function even if it is simulated. This is because we will simulate
7209 // it in each draw call, and attrib 0 generic data queries use cached
7210 // values instead of passing down to the underlying driver.
7211 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:247212 }
[email protected]96449d2c2009-11-25 00:01:327213 }
[email protected]f7a64ee2010-02-01 22:24:147214 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327215}
7216
vmiuracd108592014-09-08 14:36:347217error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
7218 const void* cmd_data) {
7219 const gles2::cmds::DrawElements& c =
7220 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:437221 return DoDrawElements("glDrawElements",
7222 false,
[email protected]c6aef902012-02-14 03:31:427223 static_cast<GLenum>(c.mode),
7224 static_cast<GLsizei>(c.count),
7225 static_cast<GLenum>(c.type),
7226 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:107227 1);
[email protected]c6aef902012-02-14 03:31:427228}
7229
7230error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:347231 uint32 immediate_data_size,
7232 const void* cmd_data) {
7233 const gles2::cmds::DrawElementsInstancedANGLE& c =
7234 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157235 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517236 LOCAL_SET_GL_ERROR(
7237 GL_INVALID_OPERATION,
7238 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427239 return error::kNoError;
7240 }
[email protected]ad84a3a2012-06-08 21:42:437241 return DoDrawElements("glDrawElementsInstancedANGLE",
7242 true,
[email protected]c6aef902012-02-14 03:31:427243 static_cast<GLenum>(c.mode),
7244 static_cast<GLsizei>(c.count),
7245 static_cast<GLenum>(c.type),
7246 static_cast<int32>(c.index_offset),
7247 static_cast<GLsizei>(c.primcount));
7248}
7249
[email protected]269200b12010-11-18 22:53:067250GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:237251 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
7252 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:077253 Buffer* buffer = GetBuffer(buffer_id);
7254 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:037255 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517256 LOCAL_SET_GL_ERROR(
7257 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:237258 } else {
[email protected]b10492f2013-03-08 05:24:077259 if (!buffer->GetMaxValueForRange(
7260 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:037261 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517262 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:067263 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437264 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:237265 }
7266 }
7267 return max_vertex_accessed;
7268}
7269
zmo1bb3d1d2015-01-21 20:29:437270void GLES2DecoderImpl::DoShaderSource(
7271 GLuint client_id, GLsizei count, const char** data, const GLint* length) {
7272 std::string str;
7273 for (GLsizei ii = 0; ii < count; ++ii) {
dyen7b0b4ba52015-02-04 21:38:067274 if (length && length[ii] > 0)
7275 str.append(data[ii], length[ii]);
7276 else
7277 str.append(data[ii]);
zmo1bb3d1d2015-01-21 20:29:437278 }
[email protected]df37b9932013-03-08 05:21:427279 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
7280 if (!shader) {
zmo1bb3d1d2015-01-21 20:29:437281 return;
[email protected]96449d2c2009-11-25 00:01:327282 }
[email protected]45bf5152010-02-12 00:11:317283 // Note: We don't actually call glShaderSource here. We wait until
dyen7b0b4ba52015-02-04 21:38:067284 // we actually compile the shader.
zmo576a0492014-09-13 01:12:327285 shader->set_source(str);
[email protected]558847a2010-03-24 07:02:547286}
7287
zmo38923562015-01-29 20:17:397288void GLES2DecoderImpl::DoTransformFeedbackVaryings(
7289 GLuint client_program_id, GLsizei count, const char* const* varyings,
7290 GLenum buffer_mode) {
7291 Program* program = GetProgramInfoNotShader(
7292 client_program_id, "glTransformFeedbackVaryings");
7293 if (!program) {
7294 return;
7295 }
bajones63ead732015-03-14 00:12:467296 program->TransformFeedbackVaryings(count, varyings, buffer_mode);
zmo38923562015-01-29 20:17:397297 glTransformFeedbackVaryings(
7298 program->service_id(), count, varyings, buffer_mode);
7299}
7300
[email protected]ae51d192010-04-27 00:48:037301void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:387302 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:427303 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
7304 if (!shader) {
[email protected]45bf5152010-02-12 00:11:317305 return;
7306 }
dyen0ff9e4402015-02-12 22:27:437307
7308 scoped_refptr<ShaderTranslatorInterface> translator;
[email protected]b1d2dcb2010-05-17 19:24:187309 if (use_shader_translator_) {
dyen0ff9e4402015-02-12 22:27:437310 translator = shader->shader_type() == GL_VERTEX_SHADER ?
7311 vertex_translator_ : fragment_translator_;
[email protected]de17df392010-04-23 21:09:417312 }
[email protected]de17df392010-04-23 21:09:417313
dyen0ff9e4402015-02-12 22:27:437314 const Shader::TranslatedShaderSourceType source_type =
7315 feature_info_->feature_flags().angle_translated_shader_source ?
7316 Shader::kANGLE : Shader::kGL;
7317 shader->RequestCompile(translator, source_type);
vmiura8266ca72014-09-09 21:37:007318}
[email protected]45bf5152010-02-12 00:11:317319
[email protected]ddd968b82010-03-02 00:44:297320void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:427321 GLuint shader_id, GLenum pname, GLint* params) {
7322 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
7323 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:297324 return;
7325 }
dyen0ff9e4402015-02-12 22:27:437326
7327 // Compile now for statuses that require it.
7328 switch (pname) {
7329 case GL_COMPILE_STATUS:
7330 case GL_INFO_LOG_LENGTH:
7331 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
7332 shader->DoCompile();
7333 break;
7334
7335 default:
7336 break;
7337 }
7338
[email protected]8f1ccdac2010-05-19 21:01:487339 switch (pname) {
7340 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:327341 *params = shader->source().size();
7342 if (*params)
7343 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:487344 return;
7345 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:327346 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:417347 return;
[email protected]8f1ccdac2010-05-19 21:01:487348 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:327349 *params = shader->log_info().size();
7350 if (*params)
7351 ++(*params);
[email protected]e5186162010-06-14 18:54:417352 return;
[email protected]d6a53e42011-10-05 00:09:367353 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:327354 *params = shader->translated_source().size();
7355 if (*params)
7356 ++(*params);
[email protected]d6a53e42011-10-05 00:09:367357 return;
[email protected]8f1ccdac2010-05-19 21:01:487358 default:
7359 break;
[email protected]ddd968b82010-03-02 00:44:297360 }
[email protected]df37b9932013-03-08 05:21:427361 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:297362}
7363
vmiuracd108592014-09-08 14:36:347364error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
7365 const void* cmd_data) {
7366 const gles2::cmds::GetShaderSource& c =
7367 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427368 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:037369 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7370 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427371 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:327372 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:297373 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:297374 return error::kNoError;
7375 }
zmo576a0492014-09-13 01:12:327376 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:037377 return error::kNoError;
7378}
7379
[email protected]d6a53e42011-10-05 00:09:367380error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
7381 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347382 const void* cmd_data) {
7383 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
7384 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
7385 cmd_data);
[email protected]df37b9932013-03-08 05:21:427386 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:367387 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7388 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427389 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:207390 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:427391 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:367392 bucket->SetSize(0);
7393 return error::kNoError;
7394 }
7395
dyen0ff9e4402015-02-12 22:27:437396 // Make sure translator has been utilized in compile.
7397 shader->DoCompile();
7398
zmo576a0492014-09-13 01:12:327399 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:367400 return error::kNoError;
7401}
7402
[email protected]ae51d192010-04-27 00:48:037403error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:347404 uint32 immediate_data_size,
7405 const void* cmd_data) {
7406 const gles2::cmds::GetProgramInfoLog& c =
7407 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427408 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:587409 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7410 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427411 Program* program = GetProgramInfoNotShader(
7412 program_id, "glGetProgramInfoLog");
7413 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:467414 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037415 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:317416 }
[email protected]df37b9932013-03-08 05:21:427417 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:037418 return error::kNoError;
7419}
7420
7421error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:347422 uint32 immediate_data_size,
7423 const void* cmd_data) {
7424 const gles2::cmds::GetShaderInfoLog& c =
7425 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427426 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:587427 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7428 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427429 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:327430 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:467431 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037432 return error::kNoError;
7433 }
dyen0ff9e4402015-02-12 22:27:437434
7435 // Shader must be compiled in order to get the info log.
7436 shader->DoCompile();
7437
zmo576a0492014-09-13 01:12:327438 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:037439 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327440}
7441
[email protected]d058bca2012-11-26 10:27:267442bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
7443 return state_.GetEnabled(cap);
7444}
7445
[email protected]1958e0e2010-04-22 05:17:157446bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:217447 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107448 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157449}
7450
7451bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357452 const Framebuffer* framebuffer =
7453 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107454 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157455}
7456
7457bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367458 // IsProgram is true for programs as soon as they are created, until they are
7459 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:357460 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:107461 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157462}
7463
7464bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357465 const Renderbuffer* renderbuffer =
7466 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107467 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157468}
7469
7470bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367471 // IsShader is true for shaders as soon as they are created, until they
7472 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:357473 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:107474 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157475}
7476
7477bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:497478 const TextureRef* texture_ref = GetTexture(client_id);
7479 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:037480}
7481
7482void GLES2DecoderImpl::DoAttachShader(
7483 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427484 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587485 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:427486 if (!program) {
[email protected]ae51d192010-04-27 00:48:037487 return;
[email protected]1958e0e2010-04-22 05:17:157488 }
[email protected]df37b9932013-03-08 05:21:427489 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
7490 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037491 return;
7492 }
[email protected]df37b9932013-03-08 05:21:427493 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517494 LOCAL_SET_GL_ERROR(
7495 GL_INVALID_OPERATION,
7496 "glAttachShader",
7497 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:317498 return;
7499 }
[email protected]df37b9932013-03-08 05:21:427500 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037501}
7502
7503void GLES2DecoderImpl::DoDetachShader(
7504 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427505 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587506 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427507 if (!program) {
[email protected]ae51d192010-04-27 00:48:037508 return;
7509 }
[email protected]df37b9932013-03-08 05:21:427510 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7511 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037512 return;
7513 }
[email protected]df37b9932013-03-08 05:21:427514 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517515 LOCAL_SET_GL_ERROR(
7516 GL_INVALID_OPERATION,
7517 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227518 return;
7519 }
[email protected]df37b9932013-03-08 05:21:427520 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037521}
7522
7523void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427524 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587525 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427526 if (!program) {
[email protected]ae51d192010-04-27 00:48:037527 return;
7528 }
[email protected]df37b9932013-03-08 05:21:427529 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157530}
7531
[email protected]ac77603c72013-03-08 13:52:067532void GLES2DecoderImpl::GetVertexAttribHelper(
7533 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247534 switch (pname) {
7535 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067536 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247537 if (buffer && !buffer->IsDeleted()) {
7538 GLuint client_id;
7539 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7540 *params = client_id;
7541 }
7542 break;
7543 }
7544 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067545 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247546 break;
7547 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067548 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247549 break;
7550 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067551 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247552 break;
7553 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067554 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247555 break;
7556 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067557 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247558 break;
[email protected]c6aef902012-02-14 03:31:427559 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067560 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427561 break;
[email protected]ac77603c72013-03-08 13:52:067562 default:
7563 NOTREACHED();
7564 break;
7565 }
7566}
7567
[email protected]4c6f5462014-03-05 00:26:567568void GLES2DecoderImpl::DoGetTexParameterfv(
7569 GLenum target, GLenum pname, GLfloat* params) {
7570 InitTextureMaxAnisotropyIfNeeded(target, pname);
7571 glGetTexParameterfv(target, pname, params);
7572}
7573
7574void GLES2DecoderImpl::DoGetTexParameteriv(
7575 GLenum target, GLenum pname, GLint* params) {
7576 InitTextureMaxAnisotropyIfNeeded(target, pname);
7577 glGetTexParameteriv(target, pname, params);
7578}
7579
7580void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7581 GLenum target, GLenum pname) {
7582 if (!workarounds().init_texture_max_anisotropy)
7583 return;
7584 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7585 !validators_->texture_parameter.IsValid(pname)) {
7586 return;
7587 }
7588
7589 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7590 &state_, target);
7591 if (!texture_ref) {
7592 LOCAL_SET_GL_ERROR(
7593 GL_INVALID_OPERATION,
7594 "glGetTexParamter{fi}v", "unknown texture for target");
7595 return;
7596 }
7597 Texture* texture = texture_ref->texture();
7598 texture->InitTextureMaxAnisotropyIfNeeded(target);
7599}
7600
[email protected]ac77603c72013-03-08 13:52:067601void GLES2DecoderImpl::DoGetVertexAttribfv(
7602 GLuint index, GLenum pname, GLfloat* params) {
7603 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7604 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517605 LOCAL_SET_GL_ERROR(
7606 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067607 return;
7608 }
7609 switch (pname) {
7610 case GL_CURRENT_VERTEX_ATTRIB: {
7611 const Vec4& value = state_.attrib_values[index];
7612 params[0] = value.v[0];
7613 params[1] = value.v[1];
7614 params[2] = value.v[2];
7615 params[3] = value.v[3];
7616 break;
7617 }
7618 default: {
7619 GLint value = 0;
7620 GetVertexAttribHelper(attrib, pname, &value);
7621 *params = static_cast<GLfloat>(value);
7622 break;
7623 }
7624 }
7625}
7626
7627void GLES2DecoderImpl::DoGetVertexAttribiv(
7628 GLuint index, GLenum pname, GLint* params) {
7629 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7630 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517631 LOCAL_SET_GL_ERROR(
7632 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067633 return;
7634 }
7635 switch (pname) {
[email protected]af6380962012-11-29 23:24:137636 case GL_CURRENT_VERTEX_ATTRIB: {
7637 const Vec4& value = state_.attrib_values[index];
7638 params[0] = static_cast<GLint>(value.v[0]);
7639 params[1] = static_cast<GLint>(value.v[1]);
7640 params[2] = static_cast<GLint>(value.v[2]);
7641 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247642 break;
[email protected]af6380962012-11-29 23:24:137643 }
[email protected]b1122982010-05-17 23:04:247644 default:
[email protected]ac77603c72013-03-08 13:52:067645 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247646 break;
7647 }
7648}
7649
[email protected]af6380962012-11-29 23:24:137650bool GLES2DecoderImpl::SetVertexAttribValue(
7651 const char* function_name, GLuint index, const GLfloat* value) {
7652 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517653 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137654 return false;
[email protected]b1122982010-05-17 23:04:247655 }
[email protected]af6380962012-11-29 23:24:137656 Vec4& v = state_.attrib_values[index];
7657 v.v[0] = value[0];
7658 v.v[1] = value[1];
7659 v.v[2] = value[2];
7660 v.v[3] = value[3];
7661 return true;
7662}
7663
7664void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7665 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7666 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7667 glVertexAttrib1f(index, v0);
7668 }
[email protected]b1122982010-05-17 23:04:247669}
7670
7671void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137672 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7673 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7674 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247675 }
[email protected]b1122982010-05-17 23:04:247676}
7677
7678void GLES2DecoderImpl::DoVertexAttrib3f(
7679 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137680 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7681 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7682 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247683 }
[email protected]b1122982010-05-17 23:04:247684}
7685
7686void GLES2DecoderImpl::DoVertexAttrib4f(
7687 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137688 GLfloat v[4] = { v0, v1, v2, v3, };
7689 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7690 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247691 }
[email protected]b1122982010-05-17 23:04:247692}
7693
7694void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137695 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7696 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7697 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247698 }
[email protected]b1122982010-05-17 23:04:247699}
7700
7701void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137702 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7703 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7704 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247705 }
[email protected]b1122982010-05-17 23:04:247706}
7707
7708void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137709 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7710 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7711 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247712 }
[email protected]b1122982010-05-17 23:04:247713}
7714
7715void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137716 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7717 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247718 }
[email protected]b1122982010-05-17 23:04:247719}
7720
zmo0c4b7cf2014-11-26 00:52:117721error::Error GLES2DecoderImpl::HandleVertexAttribIPointer(
7722 uint32 immediate_data_size,
7723 const void* cmd_data) {
7724 // TODO(zmo): Unsafe ES3 API, missing states update.
7725 if (!unsafe_es3_apis_enabled())
7726 return error::kUnknownCommand;
7727 const gles2::cmds::VertexAttribIPointer& c =
7728 *static_cast<const gles2::cmds::VertexAttribIPointer*>(cmd_data);
7729 GLuint indx = c.indx;
7730 GLint size = c.size;
7731 GLenum type = c.type;
7732 GLsizei stride = c.stride;
7733 GLsizei offset = c.offset;
7734 const void* ptr = reinterpret_cast<const void*>(offset);
7735 glVertexAttribIPointer(indx, size, type, stride, ptr);
7736 return error::kNoError;
7737}
7738
[email protected]f7a64ee2010-02-01 22:24:147739error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347740 uint32 immediate_data_size,
7741 const void* cmd_data) {
7742 const gles2::cmds::VertexAttribPointer& c =
7743 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467744
[email protected]7cd76fd2013-06-02 21:11:117745 if (!state_.bound_array_buffer.get() ||
7746 state_.bound_array_buffer->IsDeleted()) {
7747 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527748 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517749 LOCAL_SET_GL_ERROR(
7750 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467751 return error::kNoError;
7752 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517753 LOCAL_SET_GL_ERROR(
7754 GL_INVALID_VALUE,
7755 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467756 return error::kNoError;
7757 }
[email protected]96449d2c2009-11-25 00:01:327758 }
[email protected]8eee29c2010-04-29 03:38:297759
7760 GLuint indx = c.indx;
7761 GLint size = c.size;
7762 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327763 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:297764 GLsizei stride = c.stride;
7765 GLsizei offset = c.offset;
7766 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057767 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517768 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297769 return error::kNoError;
7770 }
[email protected]9438b012010-06-15 22:55:057771 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517772 LOCAL_SET_GL_ERROR(
7773 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297774 return error::kNoError;
7775 }
7776 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517777 LOCAL_SET_GL_ERROR(
7778 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297779 return error::kNoError;
7780 }
7781 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517782 LOCAL_SET_GL_ERROR(
7783 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297784 return error::kNoError;
7785 }
7786 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517787 LOCAL_SET_GL_ERROR(
7788 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297789 return error::kNoError;
7790 }
7791 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517792 LOCAL_SET_GL_ERROR(
7793 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297794 return error::kNoError;
7795 }
7796 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317797 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127798 // component_size must be a power of two to use & as optimized modulo.
7799 DCHECK(GLES2Util::IsPOT(component_size));
7800 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517801 LOCAL_SET_GL_ERROR(
7802 GL_INVALID_OPERATION,
7803 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317804 return error::kNoError;
7805 }
[email protected]a07a23602014-08-05 11:36:127806 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517807 LOCAL_SET_GL_ERROR(
7808 GL_INVALID_OPERATION,
7809 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297810 return error::kNoError;
7811 }
[email protected]7cd76fd2013-06-02 21:11:117812 state_.vertex_attrib_manager
7813 ->SetAttribInfo(indx,
7814 state_.bound_array_buffer.get(),
7815 size,
7816 type,
7817 normalized,
7818 stride,
7819 stride != 0 ? stride : component_size * size,
7820 offset);
[email protected]8fbedc02010-11-18 18:43:407821 if (type != GL_FIXED) {
7822 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7823 }
[email protected]f7a64ee2010-02-01 22:24:147824 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327825}
7826
[email protected]43410e92012-04-20 17:06:287827void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7828 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247829 state_.viewport_x = x;
7830 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027831 state_.viewport_width = std::min(width, viewport_max_width_);
7832 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287833 glViewport(x, y, width, height);
7834}
7835
[email protected]c6aef902012-02-14 03:31:427836error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347837 uint32 immediate_data_size,
7838 const void* cmd_data) {
7839 const gles2::cmds::VertexAttribDivisorANGLE& c =
7840 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157841 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517842 LOCAL_SET_GL_ERROR(
7843 GL_INVALID_OPERATION,
7844 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537845 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427846 }
7847 GLuint index = c.index;
7848 GLuint divisor = c.divisor;
7849 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517850 LOCAL_SET_GL_ERROR(
7851 GL_INVALID_VALUE,
7852 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427853 return error::kNoError;
7854 }
7855
[email protected]e259eb412012-10-13 05:47:247856 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427857 index,
7858 divisor);
7859 glVertexAttribDivisorANGLE(index, divisor);
7860 return error::kNoError;
7861}
7862
[email protected]68586372013-12-11 01:27:597863template <typename pixel_data_type>
7864static void WriteAlphaData(
dcastagna504d45c2015-04-06 19:30:397865 void* pixels, uint32 row_count, uint32 channel_count,
[email protected]68586372013-12-11 01:27:597866 uint32 alpha_channel_index, uint32 unpadded_row_size,
7867 uint32 padded_row_size, pixel_data_type alpha_value) {
7868 DCHECK_GT(channel_count, 0U);
7869 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7870 uint32 unpadded_row_size_in_elements =
7871 unpadded_row_size / sizeof(pixel_data_type);
7872 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7873 uint32 padded_row_size_in_elements =
7874 padded_row_size / sizeof(pixel_data_type);
7875 pixel_data_type* dst =
7876 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7877 for (uint32 yy = 0; yy < row_count; ++yy) {
7878 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7879 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7880 *d = alpha_value;
7881 }
7882 dst += padded_row_size_in_elements;
7883 }
7884}
7885
[email protected]5a36dc132013-07-23 23:17:557886void GLES2DecoderImpl::FinishReadPixels(
7887 const cmds::ReadPixels& c,
7888 GLuint buffer) {
7889 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7890 GLsizei width = c.width;
7891 GLsizei height = c.height;
7892 GLenum format = c.format;
7893 GLenum type = c.type;
7894 typedef cmds::ReadPixels::Result Result;
7895 uint32 pixels_size;
7896 Result* result = NULL;
7897 if (c.result_shm_id != 0) {
7898 result = GetSharedMemoryAs<Result*>(
7899 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7900 if (!result) {
7901 if (buffer != 0) {
7902 glDeleteBuffersARB(1, &buffer);
7903 }
7904 return;
7905 }
7906 }
7907 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427908 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]5a36dc132013-07-23 23:17:557909 NULL, NULL);
7910 void* pixels = GetSharedMemoryAs<void*>(
7911 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7912 if (!pixels) {
7913 if (buffer != 0) {
7914 glDeleteBuffersARB(1, &buffer);
7915 }
7916 return;
7917 }
7918
7919 if (buffer != 0) {
7920 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337921 void* data;
7922 if (features().map_buffer_range) {
7923 data = glMapBufferRange(
7924 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7925 } else {
7926 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7927 }
miub70d78592014-11-15 03:53:477928 if (!data) {
7929 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer",
7930 "Unable to map memory for readback.");
7931 return;
7932 }
[email protected]5a36dc132013-07-23 23:17:557933 memcpy(pixels, data, pixels_size);
7934 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7935 // have to restore the state.
7936 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7937 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7938 glDeleteBuffersARB(1, &buffer);
7939 }
7940
7941 if (result != NULL) {
7942 *result = true;
7943 }
7944
7945 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7946 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7947 if ((channels_exist & 0x0008) == 0 &&
7948 workarounds().clear_alpha_in_readpixels) {
7949 // Set the alpha to 255 because some drivers are buggy in this regard.
7950 uint32 temp_size;
7951
7952 uint32 unpadded_row_size;
7953 uint32 padded_row_size;
7954 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427955 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]5a36dc132013-07-23 23:17:557956 &unpadded_row_size, &padded_row_size)) {
7957 return;
7958 }
[email protected]68586372013-12-11 01:27:597959
7960 uint32 channel_count = 0;
7961 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557962 switch (format) {
7963 case GL_RGBA:
7964 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597965 channel_count = 4;
7966 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557967 break;
[email protected]68586372013-12-11 01:27:597968 case GL_ALPHA:
7969 channel_count = 1;
7970 alpha_channel = 0;
7971 break;
7972 }
7973
7974 if (channel_count > 0) {
7975 switch (type) {
7976 case GL_UNSIGNED_BYTE:
7977 WriteAlphaData<uint8>(
7978 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7979 padded_row_size, 0xFF);
7980 break;
7981 case GL_FLOAT:
7982 WriteAlphaData<float>(
7983 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7984 padded_row_size, 1.0f);
7985 break;
7986 case GL_HALF_FLOAT:
7987 WriteAlphaData<uint16>(
7988 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7989 padded_row_size, 0x3C00);
7990 break;
[email protected]5a36dc132013-07-23 23:17:557991 }
[email protected]5a36dc132013-07-23 23:17:557992 }
7993 }
7994}
7995
vmiuracd108592014-09-08 14:36:347996error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7997 const void* cmd_data) {
7998 const gles2::cmds::ReadPixels& c =
7999 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:218000 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:228001 error::Error fbo_error = WillAccessBoundFramebufferForRead();
8002 if (fbo_error != error::kNoError)
8003 return fbo_error;
[email protected]612d2f82009-12-08 20:49:318004 GLint x = c.x;
8005 GLint y = c.y;
8006 GLsizei width = c.width;
8007 GLsizei height = c.height;
8008 GLenum format = c.format;
8009 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:328010 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:568011 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:518012 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:568013 return error::kNoError;
8014 }
[email protected]ed9f9cd2013-02-27 21:12:358015 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:188016 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348017 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428018 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:248019 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:188020 return error::kOutOfBounds;
8021 }
[email protected]612d2f82009-12-08 20:49:318022 void* pixels = GetSharedMemoryAs<void*>(
8023 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:108024 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148025 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:468026 }
[email protected]de43f082013-04-02 01:16:108027 Result* result = NULL;
8028 if (c.result_shm_id != 0) {
8029 result = GetSharedMemoryAs<Result*>(
8030 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8031 if (!result) {
8032 return error::kOutOfBounds;
8033 }
8034 }
[email protected]a51788e2010-02-24 21:54:258035
[email protected]9438b012010-06-15 22:55:058036 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518037 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:298038 return error::kNoError;
8039 }
[email protected]68586372013-12-11 01:27:598040 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518041 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:128042 return error::kNoError;
8043 }
[email protected]68586372013-12-11 01:27:598044 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
8045 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
8046 // format and type are acceptable enums but not guaranteed to be supported
8047 // for this framebuffer. Have to ask gl if they are valid.
8048 GLint preferred_format = 0;
8049 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
8050 GLint preferred_type = 0;
8051 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
8052 if (format != static_cast<GLenum>(preferred_format) ||
8053 type != static_cast<GLenum>(preferred_type)) {
8054 LOCAL_SET_GL_ERROR(
8055 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
8056 "with the current read framebuffer");
8057 return error::kNoError;
8058 }
8059 }
[email protected]57f223832010-03-19 01:57:568060 if (width == 0 || height == 0) {
8061 return error::kNoError;
8062 }
8063
[email protected]57f223832010-03-19 01:57:568064 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:308065 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:568066
[email protected]3aad1a32012-09-07 20:54:478067 int32 max_x;
8068 int32 max_y;
8069 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:518070 LOCAL_SET_GL_ERROR(
8071 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:148072 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:318073 }
[email protected]57f223832010-03-19 01:57:568074
[email protected]2ea5950d2014-07-09 18:20:348075 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
8076 return error::kNoError;
8077 }
8078
[email protected]0d6bfdc2011-11-02 01:32:208079 if (!CheckBoundFramebuffersValid("glReadPixels")) {
8080 return error::kNoError;
8081 }
8082
[email protected]caa13ed2014-02-17 11:29:208083 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:108084
8085 ScopedResolvedFrameBufferBinder binder(this, false, true);
8086
[email protected]d37231fa2010-04-09 21:16:028087 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:568088 // The user requested an out of range area. Get the results 1 line
8089 // at a time.
8090 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:348091 uint32 unpadded_row_size;
8092 uint32 padded_row_size;
8093 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428094 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:348095 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:518096 LOCAL_SET_GL_ERROR(
8097 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:568098 return error::kNoError;
8099 }
8100
8101 GLint dest_x_offset = std::max(-x, 0);
8102 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:348103 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428104 dest_x_offset, 1, 1, format, type, state_.pack_alignment,
8105 &dest_row_offset, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518106 LOCAL_SET_GL_ERROR(
8107 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:568108 return error::kNoError;
8109 }
8110
8111 // Copy each row into the larger dest rect.
8112 int8* dst = static_cast<int8*>(pixels);
8113 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:028114 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:568115 GLint read_width = read_end_x - read_x;
8116 for (GLint yy = 0; yy < height; ++yy) {
8117 GLint ry = y + yy;
8118
8119 // Clear the row.
8120 memset(dst, 0, unpadded_row_size);
8121
8122 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:028123 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:568124 glReadPixels(
8125 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
8126 }
8127 dst += padded_row_size;
8128 }
8129 } else {
[email protected]5a36dc132013-07-23 23:17:558130 if (async && features().use_async_readpixels) {
miu50cef602014-11-11 01:35:418131 GLuint buffer = 0;
[email protected]5a36dc132013-07-23 23:17:558132 glGenBuffersARB(1, &buffer);
8133 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
miub70d78592014-11-15 03:53:478134 // For ANGLE client version 2, GL_STREAM_READ is not available.
marcheu1856f5d52015-04-04 01:42:538135 const GLenum usage_hint = feature_info_->gl_version_info().is_angle ?
zmo68fcdc62014-12-05 21:51:498136 GL_STATIC_DRAW : GL_STREAM_READ;
miub70d78592014-11-15 03:53:478137 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint);
[email protected]5a36dc132013-07-23 23:17:558138 GLenum error = glGetError();
8139 if (error == GL_NO_ERROR) {
8140 glReadPixels(x, y, width, height, format, type, 0);
8141 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
8142 new FenceCallback()));
8143 WaitForReadPixels(base::Bind(
8144 &GLES2DecoderImpl::FinishReadPixels,
8145 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
8146 <GLES2DecoderImpl>(this),
8147 c, buffer));
8148 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
8149 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:598150 } else {
8151 // On error, unbind pack buffer and fall through to sync readpixels
8152 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
miu50cef602014-11-11 01:35:418153 glDeleteBuffersARB(1, &buffer);
[email protected]5a36dc132013-07-23 23:17:558154 }
8155 }
[email protected]57f223832010-03-19 01:57:568156 glReadPixels(x, y, width, height, format, type, pixels);
8157 }
[email protected]ab09b612013-03-11 22:11:518158 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:258159 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:108160 if (result != NULL) {
8161 *result = true;
8162 }
[email protected]5a36dc132013-07-23 23:17:558163 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:258164 }
[email protected]4848b9f82011-03-10 18:37:568165
[email protected]f7a64ee2010-02-01 22:24:148166 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328167}
8168
vmiuracd108592014-09-08 14:36:348169error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
8170 const void* cmd_data) {
8171 const gles2::cmds::PixelStorei& c =
8172 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198173 GLenum pname = c.pname;
8174 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:058175 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518176 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:128177 return error::kNoError;
8178 }
[email protected]222471d2011-11-30 18:06:398179 switch (pname) {
8180 case GL_PACK_ALIGNMENT:
8181 case GL_UNPACK_ALIGNMENT:
8182 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:518183 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:208184 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:398185 return error::kNoError;
8186 }
[email protected]164d6d52012-05-05 00:55:038187 break;
[email protected]0a1e9ad2012-05-04 21:13:038188 case GL_UNPACK_FLIP_Y_CHROMIUM:
8189 unpack_flip_y_ = (param != 0);
8190 return error::kNoError;
8191 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
8192 unpack_premultiply_alpha_ = (param != 0);
8193 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:178194 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
8195 unpack_unpremultiply_alpha_ = (param != 0);
8196 return error::kNoError;
[email protected]222471d2011-11-30 18:06:398197 default:
8198 break;
[email protected]b9849abf2009-11-25 19:13:198199 }
8200 glPixelStorei(pname, param);
8201 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:438202 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:248203 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:438204 break;
8205 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:428206 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:438207 break;
8208 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:248209 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:438210 break;
8211 default:
8212 // Validation should have prevented us from getting here.
8213 NOTREACHED();
8214 break;
[email protected]b9849abf2009-11-25 19:13:198215 }
[email protected]f7a64ee2010-02-01 22:24:148216 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198217}
8218
[email protected]1c75a3702011-11-11 14:15:288219error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:348220 uint32 immediate_data_size,
8221 const void* cmd_data) {
8222 const gles2::cmds::PostSubBufferCHROMIUM& c =
8223 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:388224 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:278225 {
8226 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
8227 }
[email protected]b381ee32014-03-22 02:43:438228 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:518229 LOCAL_SET_GL_ERROR(
8230 GL_INVALID_OPERATION,
8231 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:288232 return error::kNoError;
8233 }
[email protected]8f9b8dd2013-09-12 18:05:138234 bool is_tracing;
8235 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
8236 &is_tracing);
8237 if (is_tracing) {
8238 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
8239 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
8240 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
8241 is_offscreen ? offscreen_size_ : surface_->GetSize());
8242 }
[email protected]7794d512012-04-17 20:36:498243 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:288244 return error::kNoError;
[email protected]7794d512012-04-17 20:36:498245 } else {
8246 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:288247 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:498248 }
[email protected]1c75a3702011-11-11 14:15:288249}
8250
[email protected]957f0642014-04-09 16:50:018251error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
8252 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348253 const void* cmd_data) {
8254 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
8255 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:108256 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
8257 if (!ref) {
8258 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8259 "glScheduleOverlayPlaneCHROMIUM",
8260 "unknown texture");
8261 return error::kNoError;
8262 }
8263 gfx::GLImage* image =
8264 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
8265 if (!image) {
8266 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8267 "glScheduleOverlayPlaneCHROMIUM",
8268 "unsupported texture format");
8269 return error::kNoError;
8270 }
8271 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
8272 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
8273 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
8274 "glScheduleOverlayPlaneCHROMIUM",
8275 "invalid transform enum");
8276 return error::kNoError;
8277 }
8278 if (!surface_->ScheduleOverlayPlane(
8279 c.plane_z_order,
8280 transform,
8281 image,
8282 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
8283 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
8284 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8285 "glScheduleOverlayPlaneCHROMIUM",
8286 "failed to schedule overlay");
8287 }
[email protected]957f0642014-04-09 16:50:018288 return error::kNoError;
8289}
8290
[email protected]558847a2010-03-24 07:02:548291error::Error GLES2DecoderImpl::GetAttribLocationHelper(
8292 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8293 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578294 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518295 LOCAL_SET_GL_ERROR(
8296 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578297 return error::kNoError;
8298 }
[email protected]df37b9932013-03-08 05:21:428299 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:588300 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:428301 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148302 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198303 }
[email protected]df37b9932013-03-08 05:21:428304 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518305 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438306 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258307 return error::kNoError;
8308 }
[email protected]b9849abf2009-11-25 19:13:198309 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548310 location_shm_id, location_shm_offset, sizeof(GLint));
8311 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148312 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198313 }
[email protected]558847a2010-03-24 07:02:548314 // Require the client to init this incase the context is lost and we are no
8315 // longer executing commands.
8316 if (*location != -1) {
8317 return error::kGenericError;
8318 }
[email protected]df37b9932013-03-08 05:21:428319 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148320 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198321}
8322
[email protected]558847a2010-03-24 07:02:548323error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:348324 uint32 immediate_data_size,
8325 const void* cmd_data) {
8326 const gles2::cmds::GetAttribLocation& c =
8327 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548328 Bucket* bucket = GetBucket(c.name_bucket_id);
8329 if (!bucket) {
8330 return error::kInvalidArguments;
8331 }
8332 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188333 if (!bucket->GetAsString(&name_str)) {
8334 return error::kInvalidArguments;
8335 }
[email protected]558847a2010-03-24 07:02:548336 return GetAttribLocationHelper(
8337 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8338}
8339
8340error::Error GLES2DecoderImpl::GetUniformLocationHelper(
8341 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8342 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578343 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518344 LOCAL_SET_GL_ERROR(
8345 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578346 return error::kNoError;
8347 }
[email protected]df37b9932013-03-08 05:21:428348 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:208349 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:428350 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148351 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198352 }
[email protected]df37b9932013-03-08 05:21:428353 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518354 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438355 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258356 return error::kNoError;
8357 }
[email protected]b9849abf2009-11-25 19:13:198358 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548359 location_shm_id, location_shm_offset, sizeof(GLint));
8360 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148361 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198362 }
[email protected]558847a2010-03-24 07:02:548363 // Require the client to init this incase the context is lost an we are no
8364 // longer executing commands.
8365 if (*location != -1) {
8366 return error::kGenericError;
8367 }
[email protected]df37b9932013-03-08 05:21:428368 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148369 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198370}
8371
[email protected]f7a64ee2010-02-01 22:24:148372error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:348373 uint32 immediate_data_size,
8374 const void* cmd_data) {
8375 const gles2::cmds::GetUniformLocation& c =
8376 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548377 Bucket* bucket = GetBucket(c.name_bucket_id);
8378 if (!bucket) {
8379 return error::kInvalidArguments;
8380 }
8381 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188382 if (!bucket->GetAsString(&name_str)) {
8383 return error::kInvalidArguments;
8384 }
[email protected]558847a2010-03-24 07:02:548385 return GetUniformLocationHelper(
8386 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:198387}
8388
zmo155435a42015-02-13 05:06:538389error::Error GLES2DecoderImpl::HandleGetUniformIndices(
8390 uint32 immediate_data_size,
8391 const void* cmd_data) {
8392 if (!unsafe_es3_apis_enabled())
8393 return error::kUnknownCommand;
8394 const gles2::cmds::GetUniformIndices& c =
8395 *static_cast<const gles2::cmds::GetUniformIndices*>(cmd_data);
8396 Bucket* bucket = GetBucket(c.names_bucket_id);
8397 if (!bucket) {
8398 return error::kInvalidArguments;
8399 }
8400 GLsizei count = 0;
8401 std::vector<char*> names;
8402 std::vector<GLint> len;
8403 if (!bucket->GetAsStrings(&count, &names, &len) || count <= 0) {
8404 return error::kInvalidArguments;
8405 }
8406 typedef cmds::GetUniformIndices::Result Result;
8407 Result* result = GetSharedMemoryAs<Result*>(
8408 c.indices_shm_id, c.indices_shm_offset,
8409 Result::ComputeSize(static_cast<size_t>(count)));
8410 GLuint* indices = result ? result->GetData() : NULL;
8411 if (indices == NULL) {
8412 return error::kOutOfBounds;
8413 }
8414 // Check that the client initialized the result.
8415 if (result->size != 0) {
8416 return error::kInvalidArguments;
8417 }
8418 Program* program = GetProgramInfoNotShader(c.program, "glGetUniformIndices");
8419 if (!program) {
8420 return error::kNoError;
8421 }
8422 GLuint service_id = program->service_id();
8423 GLint link_status = GL_FALSE;
8424 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
8425 if (link_status != GL_TRUE) {
8426 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8427 "glGetUniformIndices", "program not linked");
8428 return error::kNoError;
8429 }
8430 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetUniformIndices");
8431 glGetUniformIndices(service_id, count, &names[0], indices);
8432 GLenum error = glGetError();
8433 if (error == GL_NO_ERROR) {
8434 result->SetNumResults(count);
8435 } else {
8436 LOCAL_SET_GL_ERROR(error, "GetUniformIndices", "");
8437 }
8438 return error::kNoError;
8439}
8440
zmo5393fb52015-01-27 01:50:488441error::Error GLES2DecoderImpl::GetFragDataLocationHelper(
8442 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8443 const std::string& name_str) {
8444 GLint* location = GetSharedMemoryAs<GLint*>(
8445 location_shm_id, location_shm_offset, sizeof(GLint));
8446 if (!location) {
8447 return error::kOutOfBounds;
8448 }
8449 // Require the client to init this incase the context is lost and we are no
8450 // longer executing commands.
8451 if (*location != -1) {
8452 return error::kGenericError;
8453 }
8454 Program* program = GetProgramInfoNotShader(
8455 client_id, "glGetFragDataLocation");
8456 if (!program) {
8457 return error::kNoError;
8458 }
8459 *location = glGetFragDataLocation(program->service_id(), name_str.c_str());
8460 return error::kNoError;
8461}
8462
8463error::Error GLES2DecoderImpl::HandleGetFragDataLocation(
8464 uint32 immediate_data_size,
8465 const void* cmd_data) {
8466 if (!unsafe_es3_apis_enabled())
8467 return error::kUnknownCommand;
8468 const gles2::cmds::GetFragDataLocation& c =
8469 *static_cast<const gles2::cmds::GetFragDataLocation*>(cmd_data);
8470 Bucket* bucket = GetBucket(c.name_bucket_id);
8471 if (!bucket) {
8472 return error::kInvalidArguments;
8473 }
8474 std::string name_str;
8475 if (!bucket->GetAsString(&name_str)) {
8476 return error::kInvalidArguments;
8477 }
8478 return GetFragDataLocationHelper(
8479 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8480}
8481
zmo4a16ff992015-02-05 22:18:418482error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex(
8483 uint32 immediate_data_size, const void* cmd_data) {
8484 if (!unsafe_es3_apis_enabled())
8485 return error::kUnknownCommand;
8486 const gles2::cmds::GetUniformBlockIndex& c =
8487 *static_cast<const gles2::cmds::GetUniformBlockIndex*>(cmd_data);
8488 Bucket* bucket = GetBucket(c.name_bucket_id);
8489 if (!bucket) {
8490 return error::kInvalidArguments;
8491 }
8492 std::string name_str;
8493 if (!bucket->GetAsString(&name_str)) {
8494 return error::kInvalidArguments;
8495 }
8496 GLuint* index = GetSharedMemoryAs<GLuint*>(
8497 c.index_shm_id, c.index_shm_offset, sizeof(GLuint));
8498 if (!index) {
8499 return error::kOutOfBounds;
8500 }
8501 // Require the client to init this in case the context is lost and we are no
8502 // longer executing commands.
8503 if (*index != GL_INVALID_INDEX) {
8504 return error::kGenericError;
8505 }
8506 Program* program = GetProgramInfoNotShader(
8507 c.program, "glGetUniformBlockIndex");
8508 if (!program) {
8509 return error::kNoError;
8510 }
8511 *index = glGetUniformBlockIndex(program->service_id(), name_str.c_str());
8512 return error::kNoError;
8513}
8514
vmiuracd108592014-09-08 14:36:348515error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
8516 const void* cmd_data) {
8517 const gles2::cmds::GetString& c =
8518 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:298519 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:058520 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:518521 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:298522 return error::kNoError;
8523 }
kbrc9f0e10c2015-03-31 19:49:128524
8525 const char* str = nullptr;
[email protected]f0d74742011-10-03 16:31:048526 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:158527 switch (name) {
8528 case GL_VERSION:
8529 str = "OpenGL ES 2.0 Chromium";
8530 break;
8531 case GL_SHADING_LANGUAGE_VERSION:
8532 str = "OpenGL ES GLSL ES 1.0 Chromium";
8533 break;
[email protected]32939602012-05-09 06:25:168534 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:168535 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:388536 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
8537 // They are used by WEBGL_debug_renderer_info.
8538 if (!force_webgl_glsl_validation_)
8539 str = "Chromium";
kbrc9f0e10c2015-03-31 19:49:128540 else
8541 str = reinterpret_cast<const char*>(glGetString(name));
[email protected]32939602012-05-09 06:25:168542 break;
[email protected]1958e0e2010-04-22 05:17:158543 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:048544 {
[email protected]70dc60932013-06-04 03:33:498545 // For WebGL contexts, strip out the OES derivatives and
8546 // EXT frag depth extensions if they have not been enabled.
8547 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:048548 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:498549 if (!derivatives_explicitly_enabled_) {
8550 size_t offset = extensions.find(kOESDerivativeExtension);
8551 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098552 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:498553 std::string());
8554 }
8555 }
8556 if (!frag_depth_explicitly_enabled_) {
8557 size_t offset = extensions.find(kEXTFragDepthExtension);
8558 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098559 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:498560 std::string());
8561 }
[email protected]f0d74742011-10-03 16:31:048562 }
[email protected]aff39ac82013-06-08 04:53:138563 if (!draw_buffers_explicitly_enabled_) {
8564 size_t offset = extensions.find(kEXTDrawBuffersExtension);
8565 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098566 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:138567 std::string());
8568 }
8569 }
[email protected]93c2fd82014-04-16 02:46:068570 if (!shader_texture_lod_explicitly_enabled_) {
8571 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
8572 if (std::string::npos != offset) {
8573 extensions.replace(offset,
8574 arraysize(kEXTShaderTextureLodExtension),
8575 std::string());
8576 }
8577 }
[email protected]f0d74742011-10-03 16:31:048578 } else {
[email protected]6f5fac9d12012-06-26 21:02:458579 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:048580 }
[email protected]b381ee32014-03-22 02:43:438581 if (supports_post_sub_buffer_)
8582 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:458583 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:048584 }
[email protected]1958e0e2010-04-22 05:17:158585 break;
8586 default:
kbrc9f0e10c2015-03-31 19:49:128587 str = reinterpret_cast<const char*>(glGetString(name));
[email protected]1958e0e2010-04-22 05:17:158588 break;
8589 }
[email protected]ddd968b82010-03-02 00:44:298590 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:158591 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:298592 return error::kNoError;
8593}
8594
vmiuracd108592014-09-08 14:36:348595error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
8596 const void* cmd_data) {
8597 const gles2::cmds::BufferData& c =
8598 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:118599 GLenum target = static_cast<GLenum>(c.target);
8600 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
8601 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8602 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8603 GLenum usage = static_cast<GLenum>(c.usage);
8604 const void* data = NULL;
8605 if (data_shm_id != 0 || data_shm_offset != 0) {
8606 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
8607 if (!data) {
8608 return error::kOutOfBounds;
8609 }
8610 }
[email protected]0fbba3732013-07-17 15:40:138611 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:148612 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198613}
8614
[email protected]0c86dbf2010-03-05 08:14:118615void GLES2DecoderImpl::DoBufferSubData(
8616 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:138617 // Just delegate it. Some validation is actually done before this.
8618 buffer_manager()->ValidateAndDoBufferSubData(
8619 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:198620}
8621
[email protected]0d6bfdc2011-11-02 01:32:208622bool GLES2DecoderImpl::ClearLevel(
boliu45dc77a2015-02-25 23:26:318623 Texture* texture,
[email protected]0d6bfdc2011-11-02 01:32:208624 unsigned target,
8625 int level,
[email protected]d8e6c9242014-02-20 16:56:258626 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:208627 unsigned format,
8628 unsigned type,
8629 int width,
[email protected]4502e6492011-12-14 19:39:158630 int height,
8631 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:008632 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:008633 if (feature_info_->feature_flags().angle_depth_texture &&
8634 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:008635 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
8636 // on depth formats.
8637 GLuint fb = 0;
8638 glGenFramebuffersEXT(1, &fb);
8639 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
8640
8641 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
8642 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
8643 GL_DEPTH_ATTACHMENT;
8644
boliu45dc77a2015-02-25 23:26:318645 glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, attachment, target,
8646 texture->service_id(), level);
[email protected]81375742012-06-08 00:04:008647 // ANGLE promises a depth only attachment ok.
8648 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8649 GL_FRAMEBUFFER_COMPLETE) {
8650 return false;
8651 }
8652 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:478653 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8654 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008655 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458656 state_.SetDeviceDepthMask(GL_TRUE);
8657 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:008658 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8659
8660 RestoreClearState();
8661
8662 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358663 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008664 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8665 GLuint fb_service_id =
8666 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8667 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8668 return true;
8669 }
8670
[email protected]45d15a62012-04-18 14:33:178671 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8672
8673 uint32 size;
8674 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348675 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428676 width, height, 1, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178677 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208678 return false;
8679 }
[email protected]45d15a62012-04-18 14:33:178680
[email protected]a5d3dad2012-05-26 04:34:448681 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8682
[email protected]45d15a62012-04-18 14:33:178683 int tile_height;
8684
8685 if (size > kMaxZeroSize) {
8686 if (kMaxZeroSize < padded_row_size) {
8687 // That'd be an awfully large texture.
8688 return false;
8689 }
8690 // We should never have a large total size with a zero row size.
8691 DCHECK_GT(padded_row_size, 0U);
8692 tile_height = kMaxZeroSize / padded_row_size;
8693 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428694 width, tile_height, 1, format, type, state_.unpack_alignment, &size,
[email protected]e259eb412012-10-13 05:47:248695 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178696 return false;
8697 }
[email protected]4502e6492011-12-14 19:39:158698 } else {
[email protected]45d15a62012-04-18 14:33:178699 tile_height = height;
8700 }
8701
8702 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558703 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178704 memset(zero.get(), 0, size);
boliu45dc77a2015-02-25 23:26:318705 glBindTexture(texture->target(), texture->service_id());
[email protected]45d15a62012-04-18 14:33:178706
boliu45dc77a2015-02-25 23:26:318707 bool has_images = texture->HasImages();
[email protected]45d15a62012-04-18 14:33:178708 GLint y = 0;
8709 while (y < height) {
8710 GLint h = y + tile_height > height ? height - y : tile_height;
boliu45dc77a2015-02-25 23:26:318711 if (is_texture_immutable || h != height || has_images) {
[email protected]45d15a62012-04-18 14:33:178712 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8713 } else {
[email protected]8f1d2aa2013-05-10 23:45:388714 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258715 target, level, internal_format, width, h, 0, format, type,
8716 zero.get());
[email protected]45d15a62012-04-18 14:33:178717 }
8718 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158719 }
boliu45dc77a2015-02-25 23:26:318720 TextureRef* bound_texture =
8721 texture_manager()->GetTextureInfoForTarget(&state_, texture->target());
8722 glBindTexture(texture->target(),
8723 bound_texture ? bound_texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208724 return true;
8725}
8726
[email protected]ad84a3a2012-06-08 21:42:438727namespace {
8728
8729const int kS3TCBlockWidth = 4;
8730const int kS3TCBlockHeight = 4;
8731const int kS3TCDXT1BlockSize = 8;
8732const int kS3TCDXT3AndDXT5BlockSize = 16;
8733
8734bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518735 return (size == 1) ||
8736 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438737}
8738
[email protected]8aec81ec2014-04-29 01:04:518739bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128740 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518741}
8742
[email protected]ad84a3a2012-06-08 21:42:438743} // anonymous namespace.
8744
8745bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8746 const char* function_name,
8747 GLsizei width, GLsizei height, GLenum format, size_t size) {
8748 unsigned int bytes_required = 0;
8749
8750 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518751 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438752 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518753 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8754 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438755 int num_blocks_across =
8756 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8757 int num_blocks_down =
8758 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8759 int num_blocks = num_blocks_across * num_blocks_down;
8760 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8761 break;
8762 }
[email protected]8aec81ec2014-04-29 01:04:518763 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8764 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438765 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8766 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8767 int num_blocks_across =
8768 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8769 int num_blocks_down =
8770 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8771 int num_blocks = num_blocks_across * num_blocks_down;
8772 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8773 break;
8774 }
[email protected]8aec81ec2014-04-29 01:04:518775 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8776 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8777 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8778 break;
8779 }
8780 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8781 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8782 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078783 break;
8784 }
[email protected]ad84a3a2012-06-08 21:42:438785 default:
[email protected]ab09b612013-03-11 22:11:518786 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438787 return false;
8788 }
8789
8790 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518791 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438792 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8793 return false;
8794 }
8795
8796 return true;
8797}
8798
8799bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8800 const char* function_name,
8801 GLint level, GLsizei width, GLsizei height, GLenum format) {
8802 switch (format) {
8803 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8804 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8805 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8806 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8807 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518808 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438809 GL_INVALID_OPERATION, function_name,
8810 "width or height invalid for level");
8811 return false;
8812 }
8813 return true;
8814 }
[email protected]8aec81ec2014-04-29 01:04:518815 case GL_ATC_RGB_AMD:
8816 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8817 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8818 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078819 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518820 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078821 GL_INVALID_OPERATION, function_name,
8822 "width or height invalid for level");
8823 return false;
8824 }
8825 return true;
[email protected]8aec81ec2014-04-29 01:04:518826 }
8827 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8828 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8829 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8830 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8831 if (!IsValidPVRTCSize(level, width) ||
8832 !IsValidPVRTCSize(level, height)) {
8833 LOCAL_SET_GL_ERROR(
8834 GL_INVALID_OPERATION, function_name,
8835 "width or height invalid for level");
8836 return false;
8837 }
8838 return true;
8839 }
[email protected]ad84a3a2012-06-08 21:42:438840 default:
8841 return false;
8842 }
8843}
8844
8845bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8846 const char* function_name,
8847 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8848 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358849 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438850 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518851 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438852 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8853 return false;
8854 }
8855
8856 switch (format) {
8857 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8858 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8859 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8860 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8861 const int kBlockWidth = 4;
8862 const int kBlockHeight = 4;
8863 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518864 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438865 GL_INVALID_OPERATION, function_name,
8866 "xoffset or yoffset not multiple of 4");
8867 return false;
8868 }
8869 GLsizei tex_width = 0;
8870 GLsizei tex_height = 0;
8871 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8872 width - xoffset > tex_width ||
8873 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518874 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438875 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8876 return false;
8877 }
8878 return ValidateCompressedTexDimensions(
8879 function_name, level, width, height, format);
8880 }
[email protected]8aec81ec2014-04-29 01:04:518881 case GL_ATC_RGB_AMD:
8882 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8883 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8884 LOCAL_SET_GL_ERROR(
8885 GL_INVALID_OPERATION, function_name,
8886 "not supported for ATC textures");
8887 return false;
8888 }
[email protected]2d3765b2012-10-03 00:31:078889 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518890 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078891 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208892 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078893 return false;
8894 }
[email protected]8aec81ec2014-04-29 01:04:518895 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8896 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8897 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8898 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8899 if ((xoffset != 0) || (yoffset != 0)) {
8900 LOCAL_SET_GL_ERROR(
8901 GL_INVALID_OPERATION, function_name,
8902 "xoffset and yoffset must be zero");
8903 return false;
8904 }
8905 GLsizei tex_width = 0;
8906 GLsizei tex_height = 0;
8907 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8908 width != tex_width ||
8909 height != tex_height) {
8910 LOCAL_SET_GL_ERROR(
8911 GL_INVALID_OPERATION, function_name,
8912 "dimensions must match existing texture level dimensions");
8913 return false;
8914 }
8915 return ValidateCompressedTexDimensions(
8916 function_name, level, width, height, format);
8917 }
[email protected]ad84a3a2012-06-08 21:42:438918 default:
8919 return false;
8920 }
8921}
8922
[email protected]a93bb842010-02-16 23:03:478923error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8924 GLenum target,
8925 GLint level,
8926 GLenum internal_format,
8927 GLsizei width,
8928 GLsizei height,
8929 GLint border,
8930 GLsizei image_size,
8931 const void* data) {
[email protected]a93bb842010-02-16 23:03:478932 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058933 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518934 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8935 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298936 return error::kNoError;
8937 }
[email protected]9438b012010-06-15 22:55:058938 if (!validators_->compressed_texture_format.IsValid(
8939 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518940 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538941 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478942 return error::kNoError;
8943 }
[email protected]80eb6b52012-01-19 00:14:418944 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478945 border != 0) {
[email protected]ab09b612013-03-11 22:11:518946 LOCAL_SET_GL_ERROR(
8947 GL_INVALID_VALUE,
8948 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478949 return error::kNoError;
8950 }
[email protected]c986af502013-08-14 01:04:448951 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8952 &state_, target);
[email protected]370eaf12013-05-18 09:19:498953 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518954 LOCAL_SET_GL_ERROR(
8955 GL_INVALID_VALUE,
8956 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478957 return error::kNoError;
8958 }
[email protected]370eaf12013-05-18 09:19:498959 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078960 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518961 LOCAL_SET_GL_ERROR(
8962 GL_INVALID_OPERATION,
8963 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438964 return error::kNoError;
8965 }
8966
8967 if (!ValidateCompressedTexDimensions(
8968 "glCompressedTexImage2D", level, width, height, internal_format) ||
8969 !ValidateCompressedTexFuncData(
8970 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178971 return error::kNoError;
8972 }
[email protected]968351b2011-12-20 08:26:518973
[email protected]7989c9e2013-01-23 06:39:268974 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518975 LOCAL_SET_GL_ERROR(
8976 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268977 return error::kNoError;
8978 }
8979
[email protected]02965c22013-03-09 02:40:078980 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448981 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518982 }
8983
[email protected]40d90a22013-04-09 03:39:558984 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478985 if (!data) {
8986 zero.reset(new int8[image_size]);
8987 memset(zero.get(), 0, image_size);
8988 data = zero.get();
8989 }
[email protected]ab09b612013-03-11 22:11:518990 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478991 glCompressedTexImage2D(
8992 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518993 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438994 if (error == GL_NO_ERROR) {
8995 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498996 texture_ref, target, level, internal_format,
8997 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438998 }
vmiura8266ca72014-09-09 21:37:008999
9000 // This may be a slow command. Exit command processing to allow for
9001 // context preemption and GPU watchdog checks.
9002 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:479003 return error::kNoError;
9004}
9005
[email protected]f7a64ee2010-02-01 22:24:149006error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:349007 uint32 immediate_data_size,
9008 const void* cmd_data) {
9009 const gles2::cmds::CompressedTexImage2D& c =
9010 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:199011 GLenum target = static_cast<GLenum>(c.target);
9012 GLint level = static_cast<GLint>(c.level);
9013 GLenum internal_format = static_cast<GLenum>(c.internalformat);
9014 GLsizei width = static_cast<GLsizei>(c.width);
9015 GLsizei height = static_cast<GLsizei>(c.height);
9016 GLint border = static_cast<GLint>(c.border);
9017 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
9018 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
9019 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
9020 const void* data = NULL;
9021 if (data_shm_id != 0 || data_shm_offset != 0) {
9022 data = GetSharedMemoryAs<const void*>(
9023 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:469024 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:149025 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:199026 }
9027 }
[email protected]a93bb842010-02-16 23:03:479028 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:199029 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:199030}
9031
[email protected]b6140d02010-05-17 14:47:169032error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:349033 uint32 immediate_data_size,
9034 const void* cmd_data) {
9035 const gles2::cmds::CompressedTexImage2DBucket& c =
9036 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:169037 GLenum target = static_cast<GLenum>(c.target);
9038 GLint level = static_cast<GLint>(c.level);
9039 GLenum internal_format = static_cast<GLenum>(c.internalformat);
9040 GLsizei width = static_cast<GLsizei>(c.width);
9041 GLsizei height = static_cast<GLsizei>(c.height);
9042 GLint border = static_cast<GLint>(c.border);
9043 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289044 if (!bucket) {
9045 return error::kInvalidArguments;
9046 }
9047 uint32 data_size = bucket->size();
9048 GLsizei imageSize = data_size;
9049 const void* data = bucket->GetData(0, data_size);
9050 if (!data) {
9051 return error::kInvalidArguments;
9052 }
[email protected]b6140d02010-05-17 14:47:169053 return DoCompressedTexImage2D(
9054 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:289055 imageSize, data);
[email protected]b6140d02010-05-17 14:47:169056}
9057
9058error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
9059 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:349060 const void* cmd_data) {
9061 const gles2::cmds::CompressedTexSubImage2DBucket& c =
9062 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:169063 GLenum target = static_cast<GLenum>(c.target);
9064 GLint level = static_cast<GLint>(c.level);
9065 GLint xoffset = static_cast<GLint>(c.xoffset);
9066 GLint yoffset = static_cast<GLint>(c.yoffset);
9067 GLsizei width = static_cast<GLsizei>(c.width);
9068 GLsizei height = static_cast<GLsizei>(c.height);
9069 GLenum format = static_cast<GLenum>(c.format);
9070 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289071 if (!bucket) {
9072 return error::kInvalidArguments;
9073 }
[email protected]b6140d02010-05-17 14:47:169074 uint32 data_size = bucket->size();
9075 GLsizei imageSize = data_size;
9076 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:289077 if (!data) {
9078 return error::kInvalidArguments;
9079 }
[email protected]9438b012010-06-15 22:55:059080 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:519081 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:539082 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:169083 return error::kNoError;
9084 }
[email protected]9438b012010-06-15 22:55:059085 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:519086 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9087 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:059088 return error::kNoError;
9089 }
[email protected]b6140d02010-05-17 14:47:169090 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:519091 LOCAL_SET_GL_ERROR(
9092 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:169093 return error::kNoError;
9094 }
9095 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:519096 LOCAL_SET_GL_ERROR(
9097 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:169098 return error::kNoError;
9099 }
9100 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:519101 LOCAL_SET_GL_ERROR(
9102 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:169103 return error::kNoError;
9104 }
[email protected]cadde4a2010-07-31 17:10:439105 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:169106 target, level, xoffset, yoffset, width, height, format, imageSize, data);
9107 return error::kNoError;
9108}
9109
vmiuracd108592014-09-08 14:36:349110error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
9111 const void* cmd_data) {
9112 const gles2::cmds::TexImage2D& c =
9113 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139114 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
9115 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:449116 // Set as failed for now, but if it successed, this will be set to not failed.
9117 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:199118 GLenum target = static_cast<GLenum>(c.target);
9119 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:449120 // TODO(kloveless): Change TexImage2D command to use unsigned integer
9121 // for internalformat.
9122 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:199123 GLsizei width = static_cast<GLsizei>(c.width);
9124 GLsizei height = static_cast<GLsizei>(c.height);
9125 GLint border = static_cast<GLint>(c.border);
9126 GLenum format = static_cast<GLenum>(c.format);
9127 GLenum type = static_cast<GLenum>(c.type);
9128 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
9129 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:189130 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:349131 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429132 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
9133 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:189134 return error::kOutOfBounds;
9135 }
[email protected]b9849abf2009-11-25 19:13:199136 const void* pixels = NULL;
9137 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
9138 pixels = GetSharedMemoryAs<const void*>(
9139 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:469140 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:149141 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:199142 }
9143 }
[email protected]f598f422012-12-07 08:30:039144
bajones6b0124f42015-04-07 23:14:429145 // For testing only. Allows us to stress the ability to respond to OOM errors.
9146 if (workarounds().simulate_out_of_memory_on_large_textures &&
9147 (width * height >= 4096 * 4096)) {
9148 LOCAL_SET_GL_ERROR(
9149 GL_OUT_OF_MEMORY,
9150 "glTexImage2D", "synthetic out of memory");
9151 return error::kNoError;
9152 }
9153
[email protected]c986af502013-08-14 01:04:449154 TextureManager::DoTextImage2DArguments args = {
9155 target, level, internal_format, width, height, border, format, type,
9156 pixels, pixels_size};
9157 texture_manager()->ValidateAndDoTexImage2D(
9158 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:009159
9160 // This may be a slow command. Exit command processing to allow for
9161 // context preemption and GPU watchdog checks.
9162 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039163 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:199164}
9165
zmobcadd6592015-01-08 20:13:429166error::Error GLES2DecoderImpl::HandleTexImage3D(uint32 immediate_data_size,
9167 const void* cmd_data) {
9168 // TODO(zmo): Unsafe ES3 API.
9169 if (!unsafe_es3_apis_enabled())
9170 return error::kUnknownCommand;
9171
9172 const gles2::cmds::TexImage3D& c =
9173 *static_cast<const gles2::cmds::TexImage3D*>(cmd_data);
9174 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage3D",
9175 "widthXheight", c.width * c.height, "depth", c.depth);
9176 GLenum target = static_cast<GLenum>(c.target);
9177 GLint level = static_cast<GLint>(c.level);
9178 GLenum internal_format = static_cast<GLenum>(c.internalformat);
9179 GLsizei width = static_cast<GLsizei>(c.width);
9180 GLsizei height = static_cast<GLsizei>(c.height);
9181 GLsizei depth = static_cast<GLsizei>(c.depth);
9182 GLint border = static_cast<GLint>(c.border);
9183 GLenum format = static_cast<GLenum>(c.format);
9184 GLenum type = static_cast<GLenum>(c.type);
9185 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
9186 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
9187 uint32 pixels_size;
9188 if (!GLES2Util::ComputeImageDataSizes(
9189 width, height, depth, format, type, state_.unpack_alignment, &pixels_size,
9190 NULL, NULL)) {
9191 return error::kOutOfBounds;
9192 }
9193 const void* pixels = NULL;
9194 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
9195 pixels = GetSharedMemoryAs<const void*>(
9196 pixels_shm_id, pixels_shm_offset, pixels_size);
9197 if (!pixels) {
9198 return error::kOutOfBounds;
9199 }
9200 }
9201
9202 glTexImage3D(target, level, internal_format, width, height, depth, border,
9203 format, type, pixels);
9204
9205 // This may be a slow command. Exit command processing to allow for
9206 // context preemption and GPU watchdog checks.
9207 ExitCommandProcessingEarly();
9208 return error::kNoError;
9209}
9210
[email protected]cadde4a2010-07-31 17:10:439211void GLES2DecoderImpl::DoCompressedTexSubImage2D(
9212 GLenum target,
9213 GLint level,
9214 GLint xoffset,
9215 GLint yoffset,
9216 GLsizei width,
9217 GLsizei height,
9218 GLenum format,
9219 GLsizei image_size,
9220 const void * data) {
[email protected]c986af502013-08-14 01:04:449221 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9222 &state_, target);
[email protected]370eaf12013-05-18 09:19:499223 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519224 LOCAL_SET_GL_ERROR(
9225 GL_INVALID_OPERATION,
9226 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439227 return;
9228 }
[email protected]370eaf12013-05-18 09:19:499229 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:439230 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:529231 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079232 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519233 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:529234 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439235 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:529236 return;
9237 }
9238 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:519239 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:529240 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439241 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:529242 return;
9243 }
[email protected]02965c22013-03-09 02:40:079244 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529245 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519246 LOCAL_SET_GL_ERROR(
9247 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:439248 return;
9249 }
[email protected]ad84a3a2012-06-08 21:42:439250
9251 if (!ValidateCompressedTexFuncData(
9252 "glCompressedTexSubImage2D", width, height, format, image_size) ||
9253 !ValidateCompressedTexSubDimensions(
9254 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:079255 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:439256 return;
9257 }
9258
9259
[email protected]0d6bfdc2011-11-02 01:32:209260 // Note: There is no need to deal with texture cleared tracking here
9261 // because the validation above means you can only get here if the level
9262 // is already a matching compressed format and in that case
9263 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:439264 glCompressedTexSubImage2D(
9265 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:009266
9267 // This may be a slow command. Exit command processing to allow for
9268 // context preemption and GPU watchdog checks.
9269 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439270}
9271
[email protected]6e288612010-12-21 20:45:039272static void Clip(
9273 GLint start, GLint range, GLint sourceRange,
9274 GLint* out_start, GLint* out_range) {
9275 DCHECK(out_start);
9276 DCHECK(out_range);
9277 if (start < 0) {
9278 range += start;
9279 start = 0;
9280 }
9281 GLint end = start + range;
9282 if (end > sourceRange) {
9283 range -= end - sourceRange;
9284 }
9285 *out_start = start;
9286 *out_range = range;
9287}
9288
[email protected]cadde4a2010-07-31 17:10:439289void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:449290 GLenum target,
9291 GLint level,
9292 GLenum internal_format,
9293 GLint x,
9294 GLint y,
9295 GLsizei width,
9296 GLsizei height,
9297 GLint border) {
[email protected]09e17272012-11-30 10:30:449298 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449299 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9300 &state_, target);
[email protected]370eaf12013-05-18 09:19:499301 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519302 LOCAL_SET_GL_ERROR(
9303 GL_INVALID_OPERATION,
9304 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439305 return;
9306 }
[email protected]370eaf12013-05-18 09:19:499307 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079308 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519309 LOCAL_SET_GL_ERROR(
9310 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:539311 return;
[email protected]97dc7cbe2011-12-06 17:26:179312 }
[email protected]80eb6b52012-01-19 00:14:419313 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:189314 border != 0) {
[email protected]ab09b612013-03-11 22:11:519315 LOCAL_SET_GL_ERROR(
9316 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:189317 return;
9318 }
[email protected]17a961192014-02-14 15:20:529319 if (!texture_manager()->ValidateFormatAndTypeCombination(
9320 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
9321 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:009322 return;
9323 }
[email protected]f5719fb2010-08-04 18:27:189324
[email protected]9edc6b22010-12-23 02:00:269325 // Check we have compatible formats.
9326 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9327 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9328 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
9329
9330 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519331 LOCAL_SET_GL_ERROR(
9332 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269333 return;
9334 }
9335
[email protected]81375742012-06-08 00:04:009336 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519337 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009338 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:269339 "glCopyTexImage2D", "can not be used with depth or stencil textures");
9340 return;
9341 }
9342
9343 uint32 estimated_size = 0;
9344 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429345 width, height, 1, internal_format, GL_UNSIGNED_BYTE,
9346 state_.unpack_alignment, &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519347 LOCAL_SET_GL_ERROR(
9348 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269349 return;
9350 }
9351
9352 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519353 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:009354 return;
9355 }
9356
[email protected]2ea5950d2014-07-09 18:20:349357 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
9358 return;
9359 }
9360
zmo383512cf2014-10-14 00:11:009361 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9362 LOCAL_SET_GL_ERROR(
9363 GL_INVALID_OPERATION,
9364 "glCopyTexImage2D", "source and destination textures are the same");
9365 return;
9366 }
9367
[email protected]a0b78dc2011-11-11 10:43:109368 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
9369 return;
9370 }
9371
[email protected]ab09b612013-03-11 22:11:519372 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:279373 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039374 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:269375
[email protected]02965c22013-03-09 02:40:079376 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:449377 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:469378 }
9379
[email protected]9edc6b22010-12-23 02:00:269380 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:039381 GLint copyX = 0;
9382 GLint copyY = 0;
9383 GLint copyWidth = 0;
9384 GLint copyHeight = 0;
9385 Clip(x, width, size.width(), &copyX, &copyWidth);
9386 Clip(y, height, size.height(), &copyY, &copyHeight);
9387
9388 if (copyX != x ||
9389 copyY != y ||
9390 copyWidth != width ||
9391 copyHeight != height) {
9392 // some part was clipped so clear the texture.
boliu45dc77a2015-02-25 23:26:319393 if (!ClearLevel(texture, target, level, internal_format, internal_format,
9394 GL_UNSIGNED_BYTE, width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:519395 LOCAL_SET_GL_ERROR(
9396 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:039397 return;
9398 }
[email protected]6e288612010-12-21 20:45:039399 if (copyHeight > 0 && copyWidth > 0) {
9400 GLint dx = copyX - x;
9401 GLint dy = copyY - y;
9402 GLint destX = dx;
9403 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:379404 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039405 glCopyTexSubImage2D(target, level,
9406 destX, destY, copyX, copyY,
9407 copyWidth, copyHeight);
9408 }
9409 } else {
[email protected]00c2cf92014-03-14 00:08:379410 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039411 glCopyTexImage2D(target, level, internal_format,
9412 copyX, copyY, copyWidth, copyHeight, border);
9413 }
[email protected]ab09b612013-03-11 22:11:519414 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:439415 if (error == GL_NO_ERROR) {
9416 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499417 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:209418 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:439419 }
vmiura8266ca72014-09-09 21:37:009420
9421 // This may be a slow command. Exit command processing to allow for
9422 // context preemption and GPU watchdog checks.
9423 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439424}
9425
9426void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:449427 GLenum target,
9428 GLint level,
9429 GLint xoffset,
9430 GLint yoffset,
9431 GLint x,
9432 GLint y,
9433 GLsizei width,
9434 GLsizei height) {
[email protected]09e17272012-11-30 10:30:449435 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449436 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9437 &state_, target);
[email protected]370eaf12013-05-18 09:19:499438 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519439 LOCAL_SET_GL_ERROR(
9440 GL_INVALID_OPERATION,
9441 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439442 return;
9443 }
[email protected]370eaf12013-05-18 09:19:499444 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:439445 GLenum type = 0;
9446 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:079447 if (!texture->GetLevelType(target, level, &type, &format) ||
9448 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529449 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519450 LOCAL_SET_GL_ERROR(
9451 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:439452 return;
9453 }
[email protected]85a4ac22013-05-31 01:58:479454 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519455 LOCAL_SET_GL_ERROR(
9456 GL_INVALID_OPERATION,
9457 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599458 return;
9459 }
[email protected]9edc6b22010-12-23 02:00:269460
9461 // Check we have compatible formats.
9462 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9463 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9464 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
9465
[email protected]2d3765b2012-10-03 00:31:079466 if (!channels_needed ||
9467 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519468 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439469 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269470 return;
9471 }
9472
[email protected]81375742012-06-08 00:04:009473 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519474 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009475 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439476 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:009477 return;
9478 }
9479
[email protected]2ea5950d2014-07-09 18:20:349480 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
9481 return;
9482 }
9483
zmo383512cf2014-10-14 00:11:009484 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9485 LOCAL_SET_GL_ERROR(
9486 GL_INVALID_OPERATION,
9487 "glCopyTexSubImage2D", "source and destination textures are the same");
9488 return;
9489 }
9490
[email protected]a0b78dc2011-11-11 10:43:109491 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
9492 return;
9493 }
9494
[email protected]de26b3c2011-08-03 21:54:279495 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039496 gfx::Size size = GetBoundReadFrameBufferSize();
9497 GLint copyX = 0;
9498 GLint copyY = 0;
9499 GLint copyWidth = 0;
9500 GLint copyHeight = 0;
9501 Clip(x, width, size.width(), &copyX, &copyWidth);
9502 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:209503
dongseong.hwang351519f2015-01-21 14:33:599504 if (xoffset != 0 || yoffset != 0 || width != size.width() ||
9505 height != size.height()) {
9506 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
9507 level)) {
9508 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D",
9509 "dimensions too big");
9510 return;
9511 }
9512 } else {
9513 // Write all pixels in below.
9514 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]0d6bfdc2011-11-02 01:32:209515 }
9516
[email protected]6e288612010-12-21 20:45:039517 if (copyX != x ||
9518 copyY != y ||
9519 copyWidth != width ||
9520 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:209521 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:039522 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:349523 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429524 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:249525 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519526 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439527 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:039528 return;
9529 }
[email protected]40d90a22013-04-09 03:39:559530 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:039531 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:379532 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039533 glTexSubImage2D(
9534 target, level, xoffset, yoffset, width, height,
9535 format, type, zero.get());
9536 }
[email protected]0d6bfdc2011-11-02 01:32:209537
[email protected]6e288612010-12-21 20:45:039538 if (copyHeight > 0 && copyWidth > 0) {
9539 GLint dx = copyX - x;
9540 GLint dy = copyY - y;
9541 GLint destX = xoffset + dx;
9542 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:379543 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039544 glCopyTexSubImage2D(target, level,
9545 destX, destY, copyX, copyY,
9546 copyWidth, copyHeight);
9547 }
vmiura8266ca72014-09-09 21:37:009548
9549 // This may be a slow command. Exit command processing to allow for
9550 // context preemption and GPU watchdog checks.
9551 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439552}
9553
[email protected]f598f422012-12-07 08:30:039554bool GLES2DecoderImpl::ValidateTexSubImage2D(
9555 error::Error* error,
9556 const char* function_name,
9557 GLenum target,
9558 GLint level,
9559 GLint xoffset,
9560 GLint yoffset,
9561 GLsizei width,
9562 GLsizei height,
9563 GLenum format,
9564 GLenum type,
9565 const void * data) {
9566 (*error) = error::kNoError;
9567 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:519568 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:039569 return false;
9570 }
9571 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:519572 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:039573 return false;
9574 }
9575 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:519576 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:039577 return false;
9578 }
[email protected]c986af502013-08-14 01:04:449579 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9580 &state_, target);
[email protected]370eaf12013-05-18 09:19:499581 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519582 LOCAL_SET_GL_ERROR(
9583 GL_INVALID_OPERATION,
9584 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:039585 return false;
[email protected]cadde4a2010-07-31 17:10:439586 }
[email protected]370eaf12013-05-18 09:19:499587 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:529588 GLenum current_type = 0;
9589 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079590 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519591 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:039592 GL_INVALID_OPERATION, function_name, "level does not exist.");
9593 return false;
[email protected]df6cf1ad2011-01-29 01:20:529594 }
[email protected]17a961192014-02-14 15:20:529595 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
9596 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:039597 return false;
[email protected]df6cf1ad2011-01-29 01:20:529598 }
9599 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:519600 LOCAL_SET_GL_ERROR(
9601 GL_INVALID_OPERATION,
9602 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:039603 return false;
[email protected]df6cf1ad2011-01-29 01:20:529604 }
[email protected]85a4ac22013-05-31 01:58:479605 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519606 LOCAL_SET_GL_ERROR(
9607 GL_INVALID_OPERATION,
9608 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599609 return false;
9610 }
[email protected]02965c22013-03-09 02:40:079611 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529612 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519613 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:039614 return false;
[email protected]cadde4a2010-07-31 17:10:439615 }
[email protected]81375742012-06-08 00:04:009616 if ((GLES2Util::GetChannelsForFormat(format) &
9617 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519618 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009619 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:039620 function_name, "can not supply data for depth or stencil textures");
9621 return false;
[email protected]81375742012-06-08 00:04:009622 }
[email protected]f598f422012-12-07 08:30:039623 if (data == NULL) {
9624 (*error) = error::kOutOfBounds;
9625 return false;
9626 }
9627 return true;
9628}
[email protected]81375742012-06-08 00:04:009629
[email protected]f598f422012-12-07 08:30:039630error::Error GLES2DecoderImpl::DoTexSubImage2D(
9631 GLenum target,
9632 GLint level,
9633 GLint xoffset,
9634 GLint yoffset,
9635 GLsizei width,
9636 GLsizei height,
9637 GLenum format,
9638 GLenum type,
9639 const void * data) {
9640 error::Error error = error::kNoError;
9641 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
9642 xoffset, yoffset, width, height, format, type, data)) {
9643 return error;
9644 }
[email protected]c986af502013-08-14 01:04:449645 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9646 &state_, target);
[email protected]370eaf12013-05-18 09:19:499647 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:159648 GLsizei tex_width = 0;
9649 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:079650 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:159651 DCHECK(ok);
9652 if (xoffset != 0 || yoffset != 0 ||
9653 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:499654 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
9655 target, level)) {
[email protected]ab09b612013-03-11 22:11:519656 LOCAL_SET_GL_ERROR(
9657 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:039658 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:309659 }
[email protected]c986af502013-08-14 01:04:449660 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159661 glTexSubImage2D(
9662 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:039663 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:209664 }
[email protected]4502e6492011-12-14 19:39:159665
[email protected]345ba902013-11-14 21:39:009666 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
boliu45dc77a2015-02-25 23:26:319667 !texture->IsImmutable() &&
9668 !texture->HasImages()) {
[email protected]c986af502013-08-14 01:04:449669 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:259670 GLenum internal_format;
9671 GLenum tex_type;
9672 texture->GetLevelType(target, level, &tex_type, &internal_format);
9673 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
9674 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:389675 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:259676 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:159677 } else {
[email protected]c986af502013-08-14 01:04:449678 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159679 glTexSubImage2D(
9680 target, level, xoffset, yoffset, width, height, format, type, data);
9681 }
[email protected]370eaf12013-05-18 09:19:499682 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:009683
9684 // This may be a slow command. Exit command processing to allow for
9685 // context preemption and GPU watchdog checks.
9686 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039687 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:439688}
9689
vmiuracd108592014-09-08 14:36:349690error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
9691 const void* cmd_data) {
9692 const gles2::cmds::TexSubImage2D& c =
9693 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139694 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
9695 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:009696 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:449697 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:009698 return error::kNoError;
9699
9700 GLenum target = static_cast<GLenum>(c.target);
9701 GLint level = static_cast<GLint>(c.level);
9702 GLint xoffset = static_cast<GLint>(c.xoffset);
9703 GLint yoffset = static_cast<GLint>(c.yoffset);
9704 GLsizei width = static_cast<GLsizei>(c.width);
9705 GLsizei height = static_cast<GLsizei>(c.height);
9706 GLenum format = static_cast<GLenum>(c.format);
9707 GLenum type = static_cast<GLenum>(c.type);
9708 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:349709 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429710 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]e259eb412012-10-13 05:47:249711 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:009712 return error::kOutOfBounds;
9713 }
9714 const void* pixels = GetSharedMemoryAs<const void*>(
9715 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:039716 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:009717 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:009718}
9719
zmobcadd6592015-01-08 20:13:429720// TODO(zmo): Remove the below stub once we add the real function binding.
9721// Currently it's missing due to a gmock limitation.
9722static void glTexSubImage3D(
9723 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
9724 GLsizei height, GLsizei width, GLsizei depth, GLenum format, GLenum type,
9725 const void* pixels) {
9726 NOTIMPLEMENTED();
9727}
9728
9729error::Error GLES2DecoderImpl::HandleTexSubImage3D(uint32 immediate_data_size,
9730 const void* cmd_data) {
9731 // TODO(zmo): Unsafe ES3 API.
9732 if (!unsafe_es3_apis_enabled())
9733 return error::kUnknownCommand;
9734
9735 const gles2::cmds::TexSubImage3D& c =
9736 *static_cast<const gles2::cmds::TexSubImage3D*>(cmd_data);
9737 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage3D",
9738 "widthXheight", c.width * c.height, "depth", c.depth);
9739 GLenum target = static_cast<GLenum>(c.target);
9740 GLint level = static_cast<GLint>(c.level);
9741 GLint xoffset = static_cast<GLint>(c.xoffset);
9742 GLint yoffset = static_cast<GLint>(c.yoffset);
9743 GLint zoffset = static_cast<GLint>(c.zoffset);
9744 GLsizei width = static_cast<GLsizei>(c.width);
9745 GLsizei height = static_cast<GLsizei>(c.height);
9746 GLsizei depth = static_cast<GLsizei>(c.depth);
9747 GLenum format = static_cast<GLenum>(c.format);
9748 GLenum type = static_cast<GLenum>(c.type);
9749 uint32 data_size;
9750 if (!GLES2Util::ComputeImageDataSizes(
9751 width, height, depth, format, type, state_.unpack_alignment, &data_size,
9752 NULL, NULL)) {
9753 return error::kOutOfBounds;
9754 }
9755 const void* pixels = GetSharedMemoryAs<const void*>(
9756 c.pixels_shm_id, c.pixels_shm_offset, data_size);
9757 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
9758 depth, format, type, pixels);
9759 return error::kNoError;
9760}
9761
[email protected]f7a64ee2010-02-01 22:24:149762error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349763 uint32 immediate_data_size,
9764 const void* cmd_data) {
9765 const gles2::cmds::GetVertexAttribPointerv& c =
9766 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369767 GLuint index = static_cast<GLuint>(c.index);
9768 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359769 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259770 Result* result = GetSharedMemoryAs<Result*>(
9771 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369772 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149773 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369774 }
[email protected]07d0cc82010-02-17 04:51:409775 // Check that the client initialized the result.
9776 if (result->size != 0) {
9777 return error::kInvalidArguments;
9778 }
[email protected]9438b012010-06-15 22:55:059779 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519780 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9781 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149782 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369783 }
[email protected]3916c97e2010-02-25 03:20:509784 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519785 LOCAL_SET_GL_ERROR(
9786 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149787 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369788 }
[email protected]0bfd9882010-02-05 23:02:259789 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089790 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359791 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149792 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329793}
9794
vmiura181c74002015-03-20 01:32:519795bool GLES2DecoderImpl::GetUniformSetup(GLuint program_id,
9796 GLint fake_location,
9797 uint32 shm_id,
9798 uint32 shm_offset,
9799 error::Error* error,
9800 GLint* real_location,
9801 GLuint* service_id,
9802 void** result_pointer,
9803 GLenum* result_type,
9804 GLsizei* result_size) {
[email protected]939e7362010-05-13 20:49:109805 DCHECK(error);
9806 DCHECK(service_id);
9807 DCHECK(result_pointer);
9808 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129809 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379810 *error = error::kNoError;
9811 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259812 SizedResult<GLint>* result;
9813 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9814 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9815 if (!result) {
[email protected]f7b85372010-02-03 01:11:379816 *error = error::kOutOfBounds;
9817 return false;
9818 }
[email protected]0bfd9882010-02-05 23:02:259819 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379820 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259821 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429822 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9823 if (!program) {
[email protected]ae51d192010-04-27 00:48:039824 return false;
9825 }
[email protected]df37b9932013-03-08 05:21:429826 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379827 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519828 LOCAL_SET_GL_ERROR(
9829 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379830 return false;
9831 }
[email protected]df37b9932013-03-08 05:21:429832 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369833 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359834 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429835 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129836 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369837 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379838 // No such location.
[email protected]ab09b612013-03-11 22:11:519839 LOCAL_SET_GL_ERROR(
9840 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379841 return false;
9842 }
[email protected]43c2f1f2011-03-25 18:35:369843 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509844 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379845 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519846 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379847 return false;
9848 }
[email protected]0bfd9882010-02-05 23:02:259849 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9850 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9851 if (!result) {
[email protected]f7b85372010-02-03 01:11:379852 *error = error::kOutOfBounds;
9853 return false;
9854 }
[email protected]0bfd9882010-02-05 23:02:259855 result->size = size;
vmiura181c74002015-03-20 01:32:519856 *result_size = size;
[email protected]939e7362010-05-13 20:49:109857 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379858 return true;
9859}
9860
vmiuracd108592014-09-08 14:36:349861error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9862 const void* cmd_data) {
9863 const gles2::cmds::GetUniformiv& c =
9864 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379865 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339866 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379867 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109868 GLenum result_type;
vmiura181c74002015-03-20 01:32:519869 GLsizei result_size;
[email protected]1b0a6752012-02-22 03:44:129870 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379871 Error error;
[email protected]0bfd9882010-02-05 23:02:259872 void* result;
vmiura181c74002015-03-20 01:32:519873 if (GetUniformSetup(program, fake_location, c.params_shm_id,
9874 c.params_shm_offset, &error, &real_location, &service_id,
9875 &result, &result_type, &result_size)) {
[email protected]0bfd9882010-02-05 23:02:259876 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129877 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359878 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379879 }
9880 return error;
[email protected]96449d2c2009-11-25 00:01:329881}
9882
vmiuracd108592014-09-08 14:36:349883error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9884 const void* cmd_data) {
9885 const gles2::cmds::GetUniformfv& c =
9886 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379887 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339888 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379889 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129890 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379891 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359892 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109893 Result* result;
9894 GLenum result_type;
vmiura181c74002015-03-20 01:32:519895 GLsizei result_size;
9896 if (GetUniformSetup(program, fake_location, c.params_shm_id,
9897 c.params_shm_offset, &error, &real_location, &service_id,
9898 reinterpret_cast<void**>(&result), &result_type,
9899 &result_size)) {
[email protected]939e7362010-05-13 20:49:109900 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9901 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
vmiura181c74002015-03-20 01:32:519902 GLsizei num_values = result_size / sizeof(Result::Type);
[email protected]40d90a22013-04-09 03:39:559903 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129904 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109905 GLfloat* dst = result->GetData();
9906 for (GLsizei ii = 0; ii < num_values; ++ii) {
9907 dst[ii] = (temp[ii] != 0);
9908 }
9909 } else {
[email protected]1b0a6752012-02-22 03:44:129910 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109911 }
[email protected]f7b85372010-02-03 01:11:379912 }
9913 return error;
[email protected]96449d2c2009-11-25 00:01:329914}
9915
[email protected]f7a64ee2010-02-01 22:24:149916error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349917 uint32 immediate_data_size,
9918 const void* cmd_data) {
9919 const gles2::cmds::GetShaderPrecisionFormat& c =
9920 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259921 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9922 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359923 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259924 Result* result = GetSharedMemoryAs<Result*>(
9925 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9926 if (!result) {
9927 return error::kOutOfBounds;
9928 }
[email protected]07d0cc82010-02-17 04:51:409929 // Check that the client initialized the result.
9930 if (result->success != 0) {
9931 return error::kInvalidArguments;
9932 }
[email protected]9438b012010-06-15 22:55:059933 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519934 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539935 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299936 return error::kNoError;
9937 }
[email protected]9438b012010-06-15 22:55:059938 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519939 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539940 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299941 return error::kNoError;
9942 }
9943
9944 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409945
[email protected]46c86752013-05-21 05:08:399946 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409947 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219948 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409949
9950 result->min_range = range[0];
9951 result->max_range = range[1];
9952 result->precision = precision;
9953
[email protected]f7a64ee2010-02-01 22:24:149954 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329955}
9956
[email protected]f7a64ee2010-02-01 22:24:149957error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349958 uint32 immediate_data_size,
9959 const void* cmd_data) {
9960 const gles2::cmds::GetAttachedShaders& c =
9961 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259962 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429963 GLuint program_id = static_cast<GLuint>(c.program);
9964 Program* program = GetProgramInfoNotShader(
9965 program_id, "glGetAttachedShaders");
9966 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259967 return error::kNoError;
9968 }
[email protected]ed9f9cd2013-02-27 21:12:359969 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259970 uint32 max_count = Result::ComputeMaxResults(result_size);
9971 Result* result = GetSharedMemoryAs<Result*>(
9972 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9973 if (!result) {
9974 return error::kOutOfBounds;
9975 }
[email protected]07d0cc82010-02-17 04:51:409976 // Check that the client initialized the result.
9977 if (result->size != 0) {
9978 return error::kInvalidArguments;
9979 }
[email protected]0bfd9882010-02-05 23:02:259980 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039981 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429982 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259983 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039984 if (!shader_manager()->GetClientId(result->GetData()[ii],
9985 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259986 NOTREACHED();
9987 return error::kGenericError;
9988 }
9989 }
9990 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149991 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329992}
9993
[email protected]f7a64ee2010-02-01 22:24:149994error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349995 uint32 immediate_data_size,
9996 const void* cmd_data) {
9997 const gles2::cmds::GetActiveUniform& c =
9998 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429999 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:2510000 GLuint index = c.index;
10001 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:3510002 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:2510003 Result* result = GetSharedMemoryAs<Result*>(
10004 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10005 if (!result) {
10006 return error::kOutOfBounds;
10007 }
[email protected]07d0cc82010-02-17 04:51:4010008 // Check that the client initialized the result.
10009 if (result->success != 0) {
10010 return error::kInvalidArguments;
10011 }
[email protected]df37b9932013-03-08 05:21:4210012 Program* program = GetProgramInfoNotShader(
10013 program_id, "glGetActiveUniform");
10014 if (!program) {
[email protected]0bfd9882010-02-05 23:02:2510015 return error::kNoError;
10016 }
[email protected]ed9f9cd2013-02-27 21:12:3510017 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:4210018 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:2510019 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:5110020 LOCAL_SET_GL_ERROR(
10021 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:2510022 return error::kNoError;
10023 }
10024 result->success = 1; // true.
10025 result->size = uniform_info->size;
10026 result->type = uniform_info->type;
10027 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:2910028 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:1410029 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:3210030}
10031
zmoa2b555d2015-02-06 23:50:3910032error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockiv(
10033 uint32 immediate_data_size, const void* cmd_data) {
10034 if (!unsafe_es3_apis_enabled())
10035 return error::kUnknownCommand;
10036 const gles2::cmds::GetActiveUniformBlockiv& c =
10037 *static_cast<const gles2::cmds::GetActiveUniformBlockiv*>(cmd_data);
10038 GLuint program_id = c.program;
10039 GLuint index = static_cast<GLuint>(c.index);
10040 GLenum pname = static_cast<GLenum>(c.pname);
10041 Program* program = GetProgramInfoNotShader(
zmo8fab00c2015-02-07 02:45:0510042 program_id, "glGetActiveUniformBlockiv");
zmoa2b555d2015-02-06 23:50:3910043 if (!program) {
10044 return error::kNoError;
10045 }
10046 GLuint service_id = program->service_id();
10047 GLint link_status = GL_FALSE;
10048 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10049 if (link_status != GL_TRUE) {
10050 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10051 "glGetActiveActiveUniformBlockiv", "program not linked");
10052 return error::kNoError;
10053 }
10054 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformBlockiv");
10055 GLsizei num_values = 1;
10056 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
10057 GLint num = 0;
10058 glGetActiveUniformBlockiv(
10059 service_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &num);
10060 GLenum error = glGetError();
10061 if (error != GL_NO_ERROR) {
10062 // Assume this will the same error if calling with pname.
10063 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
10064 return error::kNoError;
10065 }
10066 num_values = static_cast<GLsizei>(num);
10067 }
10068 typedef cmds::GetActiveUniformBlockiv::Result Result;
10069 Result* result = GetSharedMemoryAs<Result*>(
10070 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
10071 GLint* params = result ? result->GetData() : NULL;
10072 if (params == NULL) {
10073 return error::kOutOfBounds;
10074 }
10075 // Check that the client initialized the result.
10076 if (result->size != 0) {
10077 return error::kInvalidArguments;
10078 }
10079 glGetActiveUniformBlockiv(service_id, index, pname, params);
10080 GLenum error = glGetError();
10081 if (error == GL_NO_ERROR) {
10082 result->SetNumResults(num_values);
10083 } else {
10084 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
10085 }
10086 return error::kNoError;
10087}
10088
zmo4a16ff992015-02-05 22:18:4110089error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockName(
10090 uint32 immediate_data_size, const void* cmd_data) {
10091 if (!unsafe_es3_apis_enabled())
10092 return error::kUnknownCommand;
10093 const gles2::cmds::GetActiveUniformBlockName& c =
10094 *static_cast<const gles2::cmds::GetActiveUniformBlockName*>(cmd_data);
10095 GLuint program_id = c.program;
10096 GLuint index = c.index;
10097 uint32 name_bucket_id = c.name_bucket_id;
10098 typedef cmds::GetActiveUniformBlockName::Result Result;
10099 Result* result = GetSharedMemoryAs<Result*>(
10100 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10101 if (!result) {
10102 return error::kOutOfBounds;
10103 }
10104 // Check that the client initialized the result.
10105 if (*result != 0) {
10106 return error::kInvalidArguments;
10107 }
10108 Program* program = GetProgramInfoNotShader(
10109 program_id, "glGetActiveUniformBlockName");
10110 if (!program) {
10111 return error::kNoError;
10112 }
10113 GLuint service_id = program->service_id();
10114 GLint link_status = GL_FALSE;
10115 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10116 if (link_status != GL_TRUE) {
10117 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10118 "glGetActiveActiveUniformBlockName", "program not linked");
10119 return error::kNoError;
10120 }
10121 GLint max_length = 0;
10122 glGetProgramiv(
10123 service_id, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_length);
10124 // Increase one so &buffer[0] is always valid.
10125 GLsizei buf_size = static_cast<GLsizei>(max_length) + 1;
10126 std::vector<char> buffer(buf_size);
10127 GLsizei length = 0;
10128 glGetActiveUniformBlockName(
10129 service_id, index, buf_size, &length, &buffer[0]);
10130 if (length == 0) {
10131 *result = 0;
10132 return error::kNoError;
10133 }
10134 *result = 1;
10135 Bucket* bucket = CreateBucket(name_bucket_id);
10136 DCHECK_GT(buf_size, length);
10137 DCHECK_EQ(0, buffer[length]);
10138 bucket->SetFromString(&buffer[0]);
10139 return error::kNoError;
10140}
10141
zmoc7e7e13f2015-02-17 22:07:0710142error::Error GLES2DecoderImpl::HandleGetActiveUniformsiv(
10143 uint32 immediate_data_size, const void* cmd_data) {
10144 if (!unsafe_es3_apis_enabled())
10145 return error::kUnknownCommand;
10146 const gles2::cmds::GetActiveUniformsiv& c =
10147 *static_cast<const gles2::cmds::GetActiveUniformsiv*>(cmd_data);
10148 GLuint program_id = c.program;
10149 GLenum pname = static_cast<GLenum>(c.pname);
10150 Bucket* bucket = GetBucket(c.indices_bucket_id);
10151 if (!bucket) {
10152 return error::kInvalidArguments;
10153 }
10154 GLsizei count = static_cast<GLsizei>(bucket->size() / sizeof(GLuint));
10155 const GLuint* indices = bucket->GetDataAs<const GLuint*>(0, bucket->size());
10156 typedef cmds::GetActiveUniformsiv::Result Result;
10157 Result* result = GetSharedMemoryAs<Result*>(
10158 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(count));
10159 GLint* params = result ? result->GetData() : NULL;
10160 if (params == NULL) {
10161 return error::kOutOfBounds;
10162 }
10163 // Check that the client initialized the result.
10164 if (result->size != 0) {
10165 return error::kInvalidArguments;
10166 }
10167 Program* program = GetProgramInfoNotShader(
10168 program_id, "glGetActiveUniformsiv");
10169 if (!program) {
10170 return error::kNoError;
10171 }
10172 GLuint service_id = program->service_id();
10173 GLint link_status = GL_FALSE;
10174 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10175 if (link_status != GL_TRUE) {
10176 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10177 "glGetActiveUniformsiv", "program not linked");
10178 return error::kNoError;
10179 }
10180 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformsiv");
10181 glGetActiveUniformsiv(service_id, count, indices, pname, params);
10182 GLenum error = glGetError();
10183 if (error == GL_NO_ERROR) {
10184 result->SetNumResults(count);
10185 } else {
10186 LOCAL_SET_GL_ERROR(error, "GetActiveUniformsiv", "");
10187 }
10188 return error::kNoError;
10189}
10190
vmiuracd108592014-09-08 14:36:3410191error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
10192 const void* cmd_data) {
10193 const gles2::cmds::GetActiveAttrib& c =
10194 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:4210195 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:2510196 GLuint index = c.index;
10197 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:3510198 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:2510199 Result* result = GetSharedMemoryAs<Result*>(
10200 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10201 if (!result) {
10202 return error::kOutOfBounds;
10203 }
[email protected]07d0cc82010-02-17 04:51:4010204 // Check that the client initialized the result.
10205 if (result->success != 0) {
10206 return error::kInvalidArguments;
10207 }
[email protected]df37b9932013-03-08 05:21:4210208 Program* program = GetProgramInfoNotShader(
10209 program_id, "glGetActiveAttrib");
10210 if (!program) {
[email protected]0bfd9882010-02-05 23:02:2510211 return error::kNoError;
10212 }
[email protected]ed9f9cd2013-02-27 21:12:3510213 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:4210214 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:2510215 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:5110216 LOCAL_SET_GL_ERROR(
10217 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:2510218 return error::kNoError;
10219 }
10220 result->success = 1; // true.
10221 result->size = attrib_info->size;
10222 result->type = attrib_info->type;
10223 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:2910224 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:1410225 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:3210226}
10227
vmiuracd108592014-09-08 14:36:3410228error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
10229 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:5810230#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:5110231 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:5810232 return error::kNoError;
10233#else
10234 GLsizei n = static_cast<GLsizei>(c.n);
10235 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:5110236 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:5810237 return error::kNoError;
10238 }
10239 GLsizei length = static_cast<GLsizei>(c.length);
10240 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:5110241 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:5810242 return error::kNoError;
10243 }
10244 uint32 data_size;
10245 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
10246 return error::kOutOfBounds;
10247 }
10248 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
10249 c.shaders_shm_id, c.shaders_shm_offset, data_size);
10250 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
10251 const void* binary = GetSharedMemoryAs<const void*>(
10252 c.binary_shm_id, c.binary_shm_offset, length);
10253 if (shaders == NULL || binary == NULL) {
10254 return error::kOutOfBounds;
10255 }
[email protected]0782b14b2014-05-24 13:04:1610256 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:5810257 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:4210258 Shader* shader = GetShader(shaders[ii]);
10259 if (!shader) {
[email protected]ab09b612013-03-11 22:11:5110260 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:5810261 return error::kNoError;
10262 }
[email protected]df37b9932013-03-08 05:21:4210263 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:5810264 }
10265 // TODO(gman): call glShaderBinary
10266 return error::kNoError;
10267#endif
10268}
10269
[email protected]6d792ee12013-05-15 00:40:5610270void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:4910271 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:0810272
[email protected]64ace852011-05-19 21:49:4910273 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:4210274 // TRACE_EVENT for gpu tests:
10275 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:4210276 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:4210277 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
10278 "width", (is_offscreen ? offscreen_size_.width() :
10279 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:5610280 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:4910281 "offscreen", is_offscreen,
10282 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:1510283 {
[email protected]a36ed4832014-04-24 16:40:2710284 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:1510285 }
10286
dyenb547eff62015-01-17 00:14:5610287 ScopedGPUTrace scoped_gpu_trace(gpu_tracer_.get(), kTraceDecoder,
10288 "gpu_toplevel", "SwapBuffer");
10289
[email protected]8f9b8dd2013-09-12 18:05:1310290 bool is_tracing;
10291 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
10292 &is_tracing);
10293 if (is_tracing) {
10294 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
10295 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
10296 is_offscreen ? offscreen_size_ : surface_->GetSize());
10297 }
10298
[email protected]6217d392010-03-25 22:08:3510299 // If offscreen then don't actually SwapBuffers to the display. Just copy
10300 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:4910301 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:3110302 TRACE_EVENT2("gpu", "Offscreen",
10303 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:5310304 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
10305 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
10306 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
10307 // fix this.
[email protected]62e155e2012-10-23 22:43:1510308 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:5310309 offscreen_saved_frame_buffer_->Create();
10310 glFinish();
10311 }
10312
10313 // Allocate the offscreen saved color texture.
10314 DCHECK(offscreen_saved_color_format_);
10315 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:0910316 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:5310317
10318 offscreen_saved_frame_buffer_->AttachRenderTexture(
10319 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:0510320 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
10321 if (offscreen_saved_frame_buffer_->CheckStatus() !=
10322 GL_FRAMEBUFFER_COMPLETE) {
10323 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
10324 << "because offscreen saved FBO was incomplete.";
sieversfbaa5dc2015-04-28 00:45:3110325 MarkContextLost(error::kUnknown);
10326 group_->LoseContexts(error::kUnknown);
[email protected]6d792ee12013-05-15 00:40:5610327 return;
[email protected]f0cfe752013-01-14 01:09:0510328 }
[email protected]1fb8c482011-08-31 01:01:5310329
[email protected]f0cfe752013-01-14 01:09:0510330 // Clear the offscreen color texture.
10331 // TODO(piman): Is this still necessary?
10332 {
10333 ScopedFrameBufferBinder binder(this,
10334 offscreen_saved_frame_buffer_->id());
10335 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:4510336 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
10337 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:0510338 glClear(GL_COLOR_BUFFER_BIT);
10339 RestoreClearState();
10340 }
[email protected]1fb8c482011-08-31 01:01:5310341 }
10342
10343 UpdateParentTextureInfo();
10344 }
10345
[email protected]f0cfe752013-01-14 01:09:0510346 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:5610347 return;
[email protected]ab09b612013-03-11 22:11:5110348 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010349 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:3510350
[email protected]34ff8b0c2010-10-01 20:06:0210351 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:1310352 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:2710353 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:4810354 } else {
[email protected]069944672012-04-25 20:52:2310355 ScopedFrameBufferBinder binder(this,
10356 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:1310357
[email protected]069944672012-04-25 20:52:2310358 if (offscreen_target_buffer_preserved_) {
10359 // Copy the target frame buffer to the saved offscreen texture.
10360 offscreen_saved_color_texture_->Copy(
10361 offscreen_saved_color_texture_->size(),
10362 offscreen_saved_color_format_);
10363 } else {
10364 // Flip the textures in the parent context via the texture manager.
10365 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:4910366 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:2310367 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:5610368
[email protected]069944672012-04-25 20:52:2310369 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
10370 offscreen_target_frame_buffer_->AttachRenderTexture(
10371 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:4810372 }
[email protected]069944672012-04-25 20:52:2310373
10374 // Ensure the side effects of the copy are visible to the parent
10375 // context. There is no need to do this for ANGLE because it uses a
10376 // single D3D device for all contexts.
marcheu1856f5d52015-04-04 01:42:5310377 if (!feature_info_->gl_version_info().is_angle)
[email protected]069944672012-04-25 20:52:2310378 glFlush();
[email protected]0c8c9d22010-06-25 17:36:3910379 }
[email protected]6217d392010-03-25 22:08:3510380 } else {
[email protected]f62a5ab2011-05-23 20:34:1510381 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:0110382 LOG(ERROR) << "Context lost because SwapBuffers failed.";
sieversfbaa5dc2015-04-28 00:45:3110383 if (!CheckResetStatus()) {
10384 MarkContextLost(error::kUnknown);
10385 group_->LoseContexts(error::kUnknown);
10386 }
[email protected]d0498742010-09-20 20:27:0110387 }
[email protected]6217d392010-03-25 22:08:3510388 }
vmiura8266ca72014-09-09 21:37:0010389
10390 // This may be a slow command. Exit command processing to allow for
10391 // context preemption and GPU watchdog checks.
10392 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:3510393}
10394
dcastagna504d45c2015-04-06 19:30:3910395void GLES2DecoderImpl::DoSwapInterval(int interval) {
bajones2345c1f2014-12-09 04:45:5110396 context_->SetSwapInterval(interval);
10397}
10398
[email protected]d4239852011-08-12 04:51:2210399error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:3410400 uint32 immediate_data_size,
10401 const void* cmd_data) {
10402 const gles2::cmds::EnableFeatureCHROMIUM& c =
10403 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:1810404 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2810405 if (!bucket || bucket->size() == 0) {
10406 return error::kInvalidArguments;
10407 }
[email protected]ed9f9cd2013-02-27 21:12:3510408 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:1810409 Result* result = GetSharedMemoryAs<Result*>(
10410 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10411 if (!result) {
10412 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:1010413 }
[email protected]b1d2dcb2010-05-17 19:24:1810414 // Check that the client initialized the result.
10415 if (*result != 0) {
10416 return error::kInvalidArguments;
10417 }
10418 std::string feature_str;
10419 if (!bucket->GetAsString(&feature_str)) {
10420 return error::kInvalidArguments;
10421 }
10422
10423 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:2210424 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:1810425 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:2210426 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
penghuang0140c182015-01-12 23:20:1210427 buffer_manager()->set_allow_fixed_attribs(true);
[email protected]8fbedc02010-11-18 18:43:4010428 // TODO(gman): decide how to remove the need for this const_cast.
10429 // I could make validators_ non const but that seems bad as this is the only
10430 // place it is needed. I could make some special friend class of validators
10431 // just to allow this to set them. That seems silly. I could refactor this
10432 // code to use the extension mechanism or the initialization attributes to
10433 // turn this feature on. Given that the only real point of this is to make
10434 // the conformance tests pass and given that there is lots of real work that
10435 // needs to be done it seems like refactoring for one to one of those
10436 // methods is a very low priority.
10437 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:0410438 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
10439 force_webgl_glsl_validation_ = true;
10440 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:1810441 } else {
10442 return error::kNoError;
10443 }
10444
10445 *result = 1; // true.
10446 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:1010447}
10448
[email protected]c2f8c8402010-12-06 18:07:2410449error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
10450 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:3410451 const void* cmd_data) {
10452 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
10453 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
10454 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2410455 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:3510456 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:1910457 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:2410458 bucket->SetFromString(info->extensions().c_str());
10459 return error::kNoError;
10460}
10461
10462error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:3410463 uint32 immediate_data_size,
10464 const void* cmd_data) {
10465 const gles2::cmds::RequestExtensionCHROMIUM& c =
10466 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2410467 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2810468 if (!bucket || bucket->size() == 0) {
10469 return error::kInvalidArguments;
10470 }
[email protected]c2f8c8402010-12-06 18:07:2410471 std::string feature_str;
10472 if (!bucket->GetAsString(&feature_str)) {
10473 return error::kInvalidArguments;
10474 }
10475
[email protected]4b7eba92013-01-08 02:23:5610476 bool desire_webgl_glsl_validation =
10477 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
10478 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:4910479 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:1310480 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:0610481 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:5610482 if (force_webgl_glsl_validation_) {
10483 desire_standard_derivatives =
10484 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:4910485 desire_frag_depth =
10486 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:1310487 desire_draw_buffers =
10488 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:0610489 desire_shader_texture_lod =
10490 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:0410491 }
10492
[email protected]4b7eba92013-01-08 02:23:5610493 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:4910494 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:1310495 desire_frag_depth != frag_depth_explicitly_enabled_ ||
10496 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:4910497 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
10498 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
10499 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:1310500 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:0610501 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:2410502 InitializeShaderTranslator();
10503 }
10504
[email protected]302ce6d2011-07-07 23:28:1110505 UpdateCapabilities();
10506
[email protected]c2f8c8402010-12-06 18:07:2410507 return error::kNoError;
10508}
10509
[email protected]2318d342011-07-11 22:27:4210510error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:3410511 uint32 immediate_data_size,
10512 const void* cmd_data) {
10513 const gles2::cmds::GetProgramInfoCHROMIUM& c =
10514 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:4210515 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:4210516 uint32 bucket_id = c.bucket_id;
10517 Bucket* bucket = CreateBucket(bucket_id);
10518 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:4210519 Program* program = NULL;
10520 program = GetProgram(program_id);
10521 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:4610522 return error::kNoError;
[email protected]2318d342011-07-11 22:27:4210523 }
[email protected]df37b9932013-03-08 05:21:4210524 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:4210525 return error::kNoError;
10526}
10527
zmo4a16ff992015-02-05 22:18:4110528error::Error GLES2DecoderImpl::HandleGetUniformBlocksCHROMIUM(
10529 uint32 immediate_data_size, const void* cmd_data) {
10530 if (!unsafe_es3_apis_enabled())
10531 return error::kUnknownCommand;
10532 const gles2::cmds::GetUniformBlocksCHROMIUM& c =
10533 *static_cast<const gles2::cmds::GetUniformBlocksCHROMIUM*>(cmd_data);
10534 GLuint program_id = static_cast<GLuint>(c.program);
10535 uint32 bucket_id = c.bucket_id;
10536 Bucket* bucket = CreateBucket(bucket_id);
10537 bucket->SetSize(sizeof(UniformBlocksHeader)); // in case we fail.
10538 Program* program = NULL;
10539 program = GetProgram(program_id);
10540 if (!program || !program->IsValid()) {
10541 return error::kNoError;
10542 }
10543 program->GetUniformBlocks(bucket);
10544 return error::kNoError;
10545}
10546
zmoc7e7e13f2015-02-17 22:07:0710547error::Error GLES2DecoderImpl::HandleGetUniformsES3CHROMIUM(
10548 uint32 immediate_data_size, const void* cmd_data) {
10549 if (!unsafe_es3_apis_enabled())
10550 return error::kUnknownCommand;
10551 const gles2::cmds::GetUniformsES3CHROMIUM& c =
10552 *static_cast<const gles2::cmds::GetUniformsES3CHROMIUM*>(cmd_data);
10553 GLuint program_id = static_cast<GLuint>(c.program);
10554 uint32 bucket_id = c.bucket_id;
10555 Bucket* bucket = CreateBucket(bucket_id);
10556 bucket->SetSize(sizeof(UniformsES3Header)); // in case we fail.
10557 Program* program = NULL;
10558 program = GetProgram(program_id);
10559 if (!program || !program->IsValid()) {
10560 return error::kNoError;
10561 }
10562 program->GetUniformsES3(bucket);
10563 return error::kNoError;
10564}
10565
zmo10842492015-02-12 00:44:1610566error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVarying(
10567 uint32 immediate_data_size,
10568 const void* cmd_data) {
10569 if (!unsafe_es3_apis_enabled())
10570 return error::kUnknownCommand;
10571 const gles2::cmds::GetTransformFeedbackVarying& c =
10572 *static_cast<const gles2::cmds::GetTransformFeedbackVarying*>(cmd_data);
10573 GLuint program_id = c.program;
10574 GLuint index = c.index;
10575 uint32 name_bucket_id = c.name_bucket_id;
10576 typedef cmds::GetTransformFeedbackVarying::Result Result;
10577 Result* result = GetSharedMemoryAs<Result*>(
10578 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10579 if (!result) {
10580 return error::kOutOfBounds;
10581 }
10582 // Check that the client initialized the result.
10583 if (result->success != 0) {
10584 return error::kInvalidArguments;
10585 }
10586 Program* program = GetProgramInfoNotShader(
10587 program_id, "glGetTransformFeedbackVarying");
10588 if (!program) {
10589 return error::kNoError;
10590 }
10591 GLuint service_id = program->service_id();
10592 GLint link_status = GL_FALSE;
10593 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10594 if (link_status != GL_TRUE) {
10595 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10596 "glGetTransformFeedbackVarying", "program not linked");
10597 return error::kNoError;
10598 }
10599 GLint max_length = 0;
10600 glGetProgramiv(
10601 service_id, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_length);
10602 max_length = std::max(1, max_length);
10603 std::vector<char> buffer(max_length);
10604 GLsizei length = 0;
10605 GLsizei size = 0;
10606 GLenum type = 0;
10607 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetTransformFeedbackVarying");
10608 glGetTransformFeedbackVarying(
10609 service_id, index, max_length, &length, &size, &type, &buffer[0]);
10610 GLenum error = glGetError();
10611 if (error != GL_NO_ERROR) {
10612 LOCAL_SET_GL_ERROR(error, "glGetTransformFeedbackVarying", "");
10613 return error::kNoError;
10614 }
10615 result->success = 1; // true.
10616 result->size = static_cast<int32_t>(size);
10617 result->type = static_cast<uint32_t>(type);
10618 Bucket* bucket = CreateBucket(name_bucket_id);
10619 DCHECK(length >= 0 && length < max_length);
10620 buffer[length] = '\0'; // Just to be safe.
10621 bucket->SetFromString(&buffer[0]);
10622 return error::kNoError;
10623}
10624
10625error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVaryingsCHROMIUM(
10626 uint32 immediate_data_size, const void* cmd_data) {
10627 if (!unsafe_es3_apis_enabled())
10628 return error::kUnknownCommand;
10629 const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM& c =
10630 *static_cast<const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM*>(
10631 cmd_data);
10632 GLuint program_id = static_cast<GLuint>(c.program);
10633 uint32 bucket_id = c.bucket_id;
10634 Bucket* bucket = CreateBucket(bucket_id);
10635 bucket->SetSize(sizeof(TransformFeedbackVaryingsHeader)); // in case we fail.
10636 Program* program = NULL;
10637 program = GetProgram(program_id);
10638 if (!program || !program->IsValid()) {
10639 return error::kNoError;
10640 }
10641 program->GetTransformFeedbackVaryings(bucket);
10642 return error::kNoError;
10643}
10644
[email protected]38d139d2011-07-14 00:38:4310645error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
sieversfbaa5dc2015-04-28 00:45:3110646 return context_lost_reason_;
10647}
10648
10649error::ContextLostReason GLES2DecoderImpl::GetContextLostReasonFromResetStatus(
10650 GLenum reset_status) const {
10651 switch (reset_status) {
[email protected]ad84a3a2012-06-08 21:42:4310652 case GL_NO_ERROR:
10653 // TODO(kbr): improve the precision of the error code in this case.
10654 // Consider delegating to context for error code if MakeCurrent fails.
10655 return error::kUnknown;
10656 case GL_GUILTY_CONTEXT_RESET_ARB:
10657 return error::kGuilty;
10658 case GL_INNOCENT_CONTEXT_RESET_ARB:
10659 return error::kInnocent;
10660 case GL_UNKNOWN_CONTEXT_RESET_ARB:
10661 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:4310662 }
10663
10664 NOTREACHED();
10665 return error::kUnknown;
10666}
10667
sieversfbaa5dc2015-04-28 00:45:3110668bool GLES2DecoderImpl::WasContextLost() const {
10669 return context_was_lost_;
10670}
10671
10672bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() const {
10673 return WasContextLost() && reset_by_robustness_extension_;
10674}
10675
10676void GLES2DecoderImpl::MarkContextLost(error::ContextLostReason reason) {
10677 // Only lose the context once.
10678 if (WasContextLost())
10679 return;
10680
10681 // Don't make GL calls in here, the context might not be current.
10682 context_lost_reason_ = reason;
10683 current_decoder_error_ = error::kLostContext;
10684 context_was_lost_ = true;
10685
jbauman7a059312014-10-16 19:30:5410686 // Some D3D drivers cannot recover from device lost in the GPU process
10687 // sandbox. Allow a new GPU process to launch.
10688 if (workarounds().exit_on_context_lost) {
10689 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
10690 << " a D3D device in the Chrome GPU process sandbox.";
10691#if defined(OS_WIN)
10692 base::win::SetShouldCrashOnProcessDetach(false);
10693#endif
10694 exit(0);
10695 }
10696}
10697
sieversfbaa5dc2015-04-28 00:45:3110698bool GLES2DecoderImpl::CheckResetStatus() {
10699 DCHECK(!WasContextLost());
10700 DCHECK(context_->IsCurrent(NULL));
10701
dongseong.hwange1cb2aa2015-02-11 09:33:3310702 if (IsRobustnessSupported()) {
oetuaho37cc50e2014-10-31 11:19:2010703 // If the reason for the call was a GL error, we can try to determine the
10704 // reset status more accurately.
10705 GLenum driver_status = glGetGraphicsResetStatusARB();
sieversfbaa5dc2015-04-28 00:45:3110706 if (driver_status == GL_NO_ERROR)
10707 return false;
oetuaho37cc50e2014-10-31 11:19:2010708
sieversfbaa5dc2015-04-28 00:45:3110709 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
10710 << " context lost via ARB/EXT_robustness. Reset status = "
10711 << GLES2Util::GetStringEnum(driver_status);
10712
10713 // Don't pretend we know which client was responsible.
10714 if (workarounds().use_virtualized_gl_contexts)
10715 driver_status = GL_UNKNOWN_CONTEXT_RESET_ARB;
10716
10717 switch (driver_status) {
10718 case GL_GUILTY_CONTEXT_RESET_ARB:
10719 MarkContextLost(error::kGuilty);
10720 break;
10721 case GL_INNOCENT_CONTEXT_RESET_ARB:
10722 MarkContextLost(error::kInnocent);
10723 break;
10724 case GL_UNKNOWN_CONTEXT_RESET_ARB:
10725 MarkContextLost(error::kUnknown);
10726 break;
10727 default:
10728 NOTREACHED();
10729 return false;
10730 }
10731 reset_by_robustness_extension_ = true;
10732 return true;
10733 }
10734 return false;
[email protected]c4485aad62012-12-17 10:19:0910735}
10736
[email protected]b096d032013-03-08 03:08:0110737error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410738 uint32 immediate_data_size,
10739 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:0110740 return error::kUnknownCommand;
10741}
10742
[email protected]840a7e462013-02-27 01:29:5110743error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410744 uint32 immediate_data_size,
10745 const void* cmd_data) {
10746 const gles2::cmds::WaitSyncPointCHROMIUM& c =
10747 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
sievers173a20d2014-10-22 18:19:3210748 uint32 sync_point = c.sync_point;
[email protected]840a7e462013-02-27 01:29:5110749 if (wait_sync_point_callback_.is_null())
10750 return error::kNoError;
10751
sievers173a20d2014-10-22 18:19:3210752 return wait_sync_point_callback_.Run(sync_point) ?
[email protected]840a7e462013-02-27 01:29:5110753 error::kNoError : error::kDeferCommandUntilLater;
10754}
10755
[email protected]5dfc457b2013-12-13 11:13:0710756error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:3410757 uint32 immediate_data_size,
10758 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:0710759 if (surface_->DeferDraws())
10760 return error::kDeferCommandUntilLater;
10761 if (!surface_->SetBackbufferAllocation(false))
10762 return error::kLostContext;
10763 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
10764 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
10765 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
10766 return error::kNoError;
10767}
10768
[email protected]882ba1e22012-03-08 19:02:5310769bool GLES2DecoderImpl::GenQueriesEXTHelper(
10770 GLsizei n, const GLuint* client_ids) {
10771 for (GLsizei ii = 0; ii < n; ++ii) {
10772 if (query_manager_->GetQuery(client_ids[ii])) {
10773 return false;
10774 }
10775 }
[email protected]4eea7e62014-04-22 21:14:4310776 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:5310777 return true;
10778}
10779
10780void GLES2DecoderImpl::DeleteQueriesEXTHelper(
10781 GLsizei n, const GLuint* client_ids) {
10782 for (GLsizei ii = 0; ii < n; ++ii) {
10783 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
10784 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:1310785 ContextState::QueryMap::iterator it =
10786 state_.current_queries.find(query->target());
10787 if (it != state_.current_queries.end())
10788 state_.current_queries.erase(it);
10789
[email protected]c45f1972012-03-14 07:27:3610790 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:5310791 }
[email protected]4eea7e62014-04-22 21:14:4310792 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:5310793 }
10794}
10795
revemancc241eb2014-11-11 03:30:3710796bool GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
[email protected]22e3f552012-03-13 01:54:1910797 if (query_manager_.get() == NULL) {
10798 return false;
10799 }
revemancc241eb2014-11-11 03:30:3710800 if (!query_manager_->ProcessPendingQueries(did_finish)) {
[email protected]22e3f552012-03-13 01:54:1910801 current_decoder_error_ = error::kOutOfBounds;
10802 }
10803 return query_manager_->HavePendingQueries();
10804}
10805
[email protected]5a36dc132013-07-23 23:17:5510806// Note that if there are no pending readpixels right now,
10807// this function will call the callback immediately.
10808void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
10809 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
10810 pending_readpixel_fences_.back()->callbacks.push_back(callback);
10811 } else {
10812 callback.Run();
10813 }
10814}
10815
10816void GLES2DecoderImpl::ProcessPendingReadPixels() {
10817 while (!pending_readpixel_fences_.empty() &&
10818 pending_readpixel_fences_.front()->fence->HasCompleted()) {
10819 std::vector<base::Closure> callbacks =
10820 pending_readpixel_fences_.front()->callbacks;
10821 pending_readpixel_fences_.pop();
10822 for (size_t i = 0; i < callbacks.size(); i++) {
10823 callbacks[i].Run();
10824 }
10825 }
10826}
10827
[email protected]2b1767cf2013-03-16 09:25:0510828bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510829 return !pending_readpixel_fences_.empty() ||
10830 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510831}
10832
10833void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510834 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:4810835 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:0510836 return;
[email protected]b68b100752013-06-05 08:34:4810837 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510838 ProcessFinishedAsyncTransfers();
10839}
10840
vmiuracd108592014-09-08 14:36:3410841error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
10842 const void* cmd_data) {
10843 const gles2::cmds::BeginQueryEXT& c =
10844 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310845 GLenum target = static_cast<GLenum>(c.target);
10846 GLuint client_id = static_cast<GLuint>(c.id);
10847 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
10848 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10849
[email protected]c45f1972012-03-14 07:27:3610850 switch (target) {
10851 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:5510852 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:3110853 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
10854 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:0010855 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:3610856 break;
[email protected]6a25ae422014-04-17 23:48:2710857 case GL_COMMANDS_COMPLETED_CHROMIUM:
10858 if (!features().chromium_sync_query) {
10859 LOCAL_SET_GL_ERROR(
10860 GL_INVALID_OPERATION, "glBeginQueryEXT",
10861 "not enabled for commands completed queries");
10862 return error::kNoError;
10863 }
10864 break;
[email protected]c45f1972012-03-14 07:27:3610865 default:
[email protected]62e155e2012-10-23 22:43:1510866 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:5110867 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:0010868 GL_INVALID_OPERATION, "glBeginQueryEXT",
10869 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:3610870 return error::kNoError;
10871 }
10872 break;
[email protected]882ba1e22012-03-08 19:02:5310873 }
10874
[email protected]8ebd46c2014-01-08 12:06:1310875 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110876 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310877 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:5310878 return error::kNoError;
10879 }
10880
10881 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:5110882 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:5310883 return error::kNoError;
10884 }
10885
10886 QueryManager::Query* query = query_manager_->GetQuery(client_id);
10887 if (!query) {
[email protected]4eea7e62014-04-22 21:14:4310888 if (!query_manager_->IsValidQuery(client_id)) {
10889 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10890 "glBeginQueryEXT",
10891 "id not made by glGenQueriesEXT");
10892 return error::kNoError;
10893 }
[email protected]c45f1972012-03-14 07:27:3610894 query = query_manager_->CreateQuery(
10895 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:5310896 }
10897
[email protected]c45f1972012-03-14 07:27:3610898 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110899 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310900 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:5310901 return error::kNoError;
10902 } else if (query->shm_id() != sync_shm_id ||
10903 query->shm_offset() != sync_shm_offset) {
10904 DLOG(ERROR) << "Shared memory used by query not the same as before";
10905 return error::kInvalidArguments;
10906 }
10907
[email protected]c45f1972012-03-14 07:27:3610908 if (!query_manager_->BeginQuery(query)) {
10909 return error::kOutOfBounds;
10910 }
[email protected]882ba1e22012-03-08 19:02:5310911
[email protected]8ebd46c2014-01-08 12:06:1310912 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:5310913 return error::kNoError;
10914}
10915
vmiuracd108592014-09-08 14:36:3410916error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
10917 const void* cmd_data) {
10918 const gles2::cmds::EndQueryEXT& c =
10919 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310920 GLenum target = static_cast<GLenum>(c.target);
10921 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:1310922 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:5310923
[email protected]8ebd46c2014-01-08 12:06:1310924 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110925 LOCAL_SET_GL_ERROR(
10926 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:5310927 return error::kNoError;
10928 }
[email protected]882ba1e22012-03-08 19:02:5310929
[email protected]8ebd46c2014-01-08 12:06:1310930 QueryManager::Query* query = it->second.get();
10931 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:3610932 return error::kOutOfBounds;
10933 }
10934
[email protected]fe8d73c2013-02-16 22:37:3210935 query_manager_->ProcessPendingTransferQueries();
10936
[email protected]8ebd46c2014-01-08 12:06:1310937 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:5310938 return error::kNoError;
10939}
10940
[email protected]944b62f32012-09-27 02:20:4610941bool GLES2DecoderImpl::GenVertexArraysOESHelper(
10942 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610943 for (GLsizei ii = 0; ii < n; ++ii) {
10944 if (GetVertexAttribManager(client_ids[ii])) {
10945 return false;
10946 }
10947 }
[email protected]ab4fd7282012-10-12 16:25:5710948
[email protected]62e155e2012-10-23 22:43:1510949 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710950 // Emulated VAO
10951 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810952 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:5710953 }
10954 } else {
[email protected]40d90a22013-04-09 03:39:5510955 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:5710956
10957 glGenVertexArraysOES(n, service_ids.get());
10958 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810959 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:5710960 }
[email protected]944b62f32012-09-27 02:20:4610961 }
[email protected]ab4fd7282012-10-12 16:25:5710962
[email protected]944b62f32012-09-27 02:20:4610963 return true;
10964}
10965
10966void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
10967 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610968 for (GLsizei ii = 0; ii < n; ++ii) {
10969 VertexAttribManager* vao =
10970 GetVertexAttribManager(client_ids[ii]);
10971 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:1110972 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:1110973 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:4610974 }
10975 RemoveVertexAttribManager(client_ids[ii]);
10976 }
10977 }
10978}
10979
10980void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610981 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:4610982 if (client_id != 0) {
10983 vao = GetVertexAttribManager(client_id);
10984 if (!vao) {
10985 // Unlike most Bind* methods, the spec explicitly states that VertexArray
10986 // only allows names that have been previously generated. As such, we do
10987 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:5110988 LOCAL_SET_GL_ERROR(
10989 GL_INVALID_OPERATION,
10990 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:4610991 current_decoder_error_ = error::kNoError;
10992 return;
[email protected]944b62f32012-09-27 02:20:4610993 }
[email protected]944b62f32012-09-27 02:20:4610994 } else {
[email protected]81f20a622014-04-18 01:54:5210995 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4610996 }
10997
[email protected]ab4fd7282012-10-12 16:25:5710998 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110999 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2411000 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1511001 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5711002 EmulateVertexArrayState();
11003 } else {
[email protected]da364812014-05-09 21:39:4811004 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5711005 glBindVertexArrayOES(service_id);
11006 }
11007 }
11008}
11009
11010// Used when OES_vertex_array_object isn't natively supported
11011void GLES2DecoderImpl::EmulateVertexArrayState() {
11012 // Setup the Vertex attribute state
11013 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2311014 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5711015 }
11016
11017 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2111018 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2411019 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5711020 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
11021 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4611022}
11023
11024bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4611025 const VertexAttribManager* vao =
11026 GetVertexAttribManager(client_id);
11027 return vao && vao->IsValid() && !vao->IsDeleted();
11028}
11029
[email protected]e51bdf32011-11-23 22:21:4611030#if defined(OS_MACOSX)
11031void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
11032 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
11033 texture_id);
11034 if (it != texture_to_io_surface_map_.end()) {
11035 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5311036 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4611037 CFRelease(surface);
11038 texture_to_io_surface_map_.erase(it);
11039 }
11040}
11041#endif
11042
11043void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
11044 GLenum target, GLsizei width, GLsizei height,
11045 GLuint io_surface_id, GLuint plane) {
11046#if defined(OS_MACOSX)
11047 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5111048 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311049 GL_INVALID_OPERATION,
11050 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4611051 return;
11052 }
11053
[email protected]e51bdf32011-11-23 22:21:4611054 if (target != GL_TEXTURE_RECTANGLE_ARB) {
11055 // This might be supported in the future, and if we could require
11056 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
11057 // could delete a lot of code. For now, perform strict validation so we
11058 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5111059 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4611060 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4311061 "glTexImageIOSurface2DCHROMIUM",
11062 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4611063 return;
11064 }
11065
[email protected]09d50362012-10-18 20:54:3711066 // Default target might be conceptually valid, but disallow it to avoid
11067 // accidents.
[email protected]c986af502013-08-14 01:04:4411068 TextureRef* texture_ref =
11069 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911070 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111071 LOCAL_SET_GL_ERROR(
11072 GL_INVALID_OPERATION,
11073 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4611074 return;
11075 }
[email protected]e51bdf32011-11-23 22:21:4611076
11077 // Look up the new IOSurface. Note that because of asynchrony
11078 // between processes this might fail; during live resizing the
11079 // plugin process might allocate and release an IOSurface before
11080 // this process gets a chance to look it up. Hold on to any old
11081 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5311082 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4611083 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5111084 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311085 GL_INVALID_OPERATION,
11086 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4611087 return;
11088 }
11089
11090 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4911091 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4611092
11093 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
11094 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4911095 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4611096
11097 CGLContextObj context =
11098 static_cast<CGLContextObj>(context_->GetHandle());
11099
[email protected]c3a6b4a2014-06-04 09:25:5311100 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4611101 context,
11102 target,
11103 GL_RGBA,
11104 width,
11105 height,
11106 GL_BGRA,
11107 GL_UNSIGNED_INT_8_8_8_8_REV,
11108 surface,
11109 plane);
11110
11111 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5111112 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4611113 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4311114 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4611115 return;
11116 }
11117
11118 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911119 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4611120 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
11121
11122#else
[email protected]ab09b612013-03-11 22:11:5111123 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4311124 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4611125#endif
11126}
11127
[email protected]97dc7cbe2011-12-06 17:26:1711128static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
11129 switch (internalformat) {
11130 case GL_RGB565:
11131 return GL_RGB;
11132 case GL_RGBA4:
11133 return GL_RGBA;
11134 case GL_RGB5_A1:
11135 return GL_RGBA;
11136 case GL_RGB8_OES:
11137 return GL_RGB;
11138 case GL_RGBA8_OES:
11139 return GL_RGBA;
11140 case GL_LUMINANCE8_ALPHA8_EXT:
11141 return GL_LUMINANCE_ALPHA;
11142 case GL_LUMINANCE8_EXT:
11143 return GL_LUMINANCE;
11144 case GL_ALPHA8_EXT:
11145 return GL_ALPHA;
11146 case GL_RGBA32F_EXT:
11147 return GL_RGBA;
11148 case GL_RGB32F_EXT:
11149 return GL_RGB;
11150 case GL_ALPHA32F_EXT:
11151 return GL_ALPHA;
11152 case GL_LUMINANCE32F_EXT:
11153 return GL_LUMINANCE;
11154 case GL_LUMINANCE_ALPHA32F_EXT:
11155 return GL_LUMINANCE_ALPHA;
11156 case GL_RGBA16F_EXT:
11157 return GL_RGBA;
11158 case GL_RGB16F_EXT:
11159 return GL_RGB;
11160 case GL_ALPHA16F_EXT:
11161 return GL_ALPHA;
11162 case GL_LUMINANCE16F_EXT:
11163 return GL_LUMINANCE;
11164 case GL_LUMINANCE_ALPHA16F_EXT:
11165 return GL_LUMINANCE_ALPHA;
11166 case GL_BGRA8_EXT:
11167 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5911168 case GL_SRGB8_ALPHA8_EXT:
11169 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1711170 default:
11171 return GL_NONE;
11172 }
11173}
11174
dongseong.hwang46305b12015-03-05 18:28:0411175bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUM(
11176 const char* function_name,
11177 GLenum target,
11178 TextureRef* source_texture_ref,
11179 TextureRef* dest_texture_ref,
11180 GLenum dest_internal_format) {
[email protected]370eaf12013-05-18 09:19:4911181 if (!source_texture_ref || !dest_texture_ref) {
dongseong.hwang46305b12015-03-05 18:28:0411182 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown texture id");
11183 return false;
[email protected]43410e92012-04-20 17:06:2811184 }
11185
11186 if (GL_TEXTURE_2D != target) {
dongseong.hwang46305b12015-03-05 18:28:0411187 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
11188 "invalid texture target");
11189 return false;
[email protected]43410e92012-04-20 17:06:2811190 }
11191
[email protected]370eaf12013-05-18 09:19:4911192 Texture* source_texture = source_texture_ref->texture();
11193 Texture* dest_texture = dest_texture_ref->texture();
dongseong.hwang46305b12015-03-05 18:28:0411194 if (source_texture == dest_texture) {
11195 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11196 "source and destination textures are the same");
11197 return false;
11198 }
11199
[email protected]02965c22013-03-09 02:40:0711200 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2511201 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3411202 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
11203 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
dongseong.hwang46305b12015-03-05 18:28:0411204 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
[email protected]3ecc1052013-09-26 08:59:0011205 "invalid texture target binding");
dongseong.hwang46305b12015-03-05 18:28:0411206 return false;
[email protected]0a1e9ad2012-05-04 21:13:0311207 }
11208
dongseong.hwang46305b12015-03-05 18:28:0411209 GLenum source_type = 0;
11210 GLenum source_internal_format = 0;
11211 source_texture->GetLevelType(source_texture->target(), 0, &source_type,
11212 &source_internal_format);
[email protected]43410e92012-04-20 17:06:2811213
dongseong.hwang46305b12015-03-05 18:28:0411214 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
11215 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
11216 // renderable on some platforms.
11217 bool valid_dest_format = dest_internal_format == GL_RGB ||
11218 dest_internal_format == GL_RGBA ||
11219 dest_internal_format == GL_BGRA_EXT;
11220 bool valid_source_format = source_internal_format == GL_ALPHA ||
11221 source_internal_format == GL_RGB ||
11222 source_internal_format == GL_RGBA ||
11223 source_internal_format == GL_LUMINANCE ||
11224 source_internal_format == GL_LUMINANCE_ALPHA ||
11225 source_internal_format == GL_BGRA_EXT;
11226 if (!valid_source_format || !valid_dest_format) {
11227 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11228 "invalid internal format");
11229 return false;
11230 }
11231 return true;
11232}
11233
11234void GLES2DecoderImpl::DoCopyTextureCHROMIUM(GLenum target,
11235 GLuint source_id,
11236 GLuint dest_id,
11237 GLenum internal_format,
11238 GLenum dest_type) {
11239 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
11240
11241 TextureRef* source_texture_ref = GetTexture(source_id);
11242 TextureRef* dest_texture_ref = GetTexture(dest_id);
11243 Texture* source_texture = source_texture_ref->texture();
11244 Texture* dest_texture = dest_texture_ref->texture();
11245 int source_width = 0;
11246 int source_height = 0;
[email protected]3e0dfd72014-02-21 06:28:4111247 gfx::GLImage* image =
11248 source_texture->GetLevelImage(source_texture->target(), 0);
11249 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5511250 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5611251 source_width = size.width();
11252 source_height = size.height();
11253 if (source_width <= 0 || source_height <= 0) {
11254 LOCAL_SET_GL_ERROR(
11255 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5511256 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5611257 return;
11258 }
[email protected]3ecc1052013-09-26 08:59:0011259 } else {
11260 if (!source_texture->GetLevelSize(
11261 source_texture->target(), 0, &source_width, &source_height)) {
11262 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
11263 "glCopyTextureChromium",
11264 "source texture has no level 0");
11265 return;
11266 }
11267
11268 // Check that this type of texture is allowed.
dongseong.hwang46305b12015-03-05 18:28:0411269 if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
11270 source_width, source_height, 1)) {
[email protected]3ecc1052013-09-26 08:59:0011271 LOCAL_SET_GL_ERROR(
11272 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
11273 return;
11274 }
[email protected]377976552013-05-14 23:32:5611275 }
11276
[email protected]a6e3d282014-08-22 22:20:4411277 GLenum source_type = 0;
11278 GLenum source_internal_format = 0;
11279 source_texture->GetLevelType(
11280 source_texture->target(), 0, &source_type, &source_internal_format);
11281
dongseong.hwang46305b12015-03-05 18:28:0411282 if (dest_texture->IsImmutable()) {
11283 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyTextureCHROMIUM",
11284 "texture is immutable");
11285 return;
11286 }
11287
11288 if (!ValidateCopyTextureCHROMIUM("glCopyTextureCHROMIUM", target,
11289 source_texture_ref, dest_texture_ref,
11290 internal_format)) {
11291 return;
11292 }
11293
11294 // Clear the source texture if necessary.
11295 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
11296 source_texture->target(), 0)) {
11297 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM",
11298 "dimensions too big");
[email protected]a6e3d282014-08-22 22:20:4411299 return;
11300 }
11301
[email protected]cf6b8f62012-05-25 21:43:3711302 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
11303 // needed because it takes 10s of milliseconds to initialize.
11304 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5111305 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3711306 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2711307 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3711308 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5111309 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3711310 return;
11311 }
11312
[email protected]efc87712014-07-09 00:22:4711313 GLenum dest_type_previous = dest_type;
11314 GLenum dest_internal_format = internal_format;
dongseong.hwang46305b12015-03-05 18:28:0411315 int dest_width = 0;
11316 int dest_height = 0;
11317 bool dest_level_defined =
11318 dest_texture->GetLevelSize(GL_TEXTURE_2D, 0, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2811319
[email protected]0a1e9ad2012-05-04 21:13:0311320 if (dest_level_defined) {
dongseong.hwang46305b12015-03-05 18:28:0411321 dest_texture->GetLevelType(GL_TEXTURE_2D, 0, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0711322 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0311323 }
11324
11325 // Resize the destination texture to the dimensions of the source texture.
11326 if (!dest_level_defined || dest_width != source_width ||
11327 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5411328 dest_internal_format != internal_format ||
11329 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2811330 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5111331 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0711332 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
dongseong.hwang46305b12015-03-05 18:28:0411333 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, source_width, source_height,
11334 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5111335 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0311336 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0211337 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2811338 return;
[email protected]0a1e9ad2012-05-04 21:13:0311339 }
[email protected]43410e92012-04-20 17:06:2811340
11341 texture_manager()->SetLevelInfo(
dongseong.hwang46305b12015-03-05 18:28:0411342 dest_texture_ref, GL_TEXTURE_2D, 0, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0311343 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2511344 } else {
dongseong.hwang46305b12015-03-05 18:28:0411345 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0,
11346 true);
[email protected]43410e92012-04-20 17:06:2811347 }
11348
[email protected]00c2cf92014-03-14 00:08:3711349 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5411350
revemance8fbe82014-09-05 02:19:5211351 // Try using GLImage::CopyTexImage when possible.
11352 bool unpack_premultiply_alpha_change =
11353 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
dongseong.hwang46305b12015-03-05 18:28:0411354 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change) {
revemance8fbe82014-09-05 02:19:5211355 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
11356 if (image->CopyTexImage(GL_TEXTURE_2D))
11357 return;
11358 }
11359
11360 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
11361
[email protected]5394a4102013-04-18 05:41:3711362 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
11363 // before presenting.
11364 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
11365 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
dongseong.hwang46305b12015-03-05 18:28:0411366 // instead of using kIdentityMatrix crbug.com/226218.
[email protected]5394a4102013-04-18 05:41:3711367 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
dongseong.hwang46305b12015-03-05 18:28:0411368 this, source_texture->target(), source_texture->service_id(),
11369 dest_texture->service_id(), source_width, source_height, unpack_flip_y_,
11370 unpack_premultiply_alpha_, unpack_unpremultiply_alpha_,
11371 kIdentityMatrix);
[email protected]5394a4102013-04-18 05:41:3711372 } else {
dongseong.hwang46305b12015-03-05 18:28:0411373 copy_texture_CHROMIUM_->DoCopyTexture(
11374 this, source_texture->target(), source_texture->service_id(),
11375 source_internal_format, dest_texture->service_id(), internal_format,
11376 source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
11377 unpack_unpremultiply_alpha_);
11378 }
11379
11380 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
11381}
11382
11383void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(GLenum target,
11384 GLuint source_id,
11385 GLuint dest_id,
11386 GLint xoffset,
11387 GLint yoffset) {
11388 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopySubTextureCHROMIUM");
11389
11390 TextureRef* source_texture_ref = GetTexture(source_id);
11391 TextureRef* dest_texture_ref = GetTexture(dest_id);
11392 Texture* source_texture = source_texture_ref->texture();
11393 Texture* dest_texture = dest_texture_ref->texture();
11394 int source_width = 0;
11395 int source_height = 0;
11396 gfx::GLImage* image =
11397 source_texture->GetLevelImage(source_texture->target(), 0);
11398 if (image) {
11399 gfx::Size size = image->GetSize();
11400 source_width = size.width();
11401 source_height = size.height();
11402 if (source_width <= 0 || source_height <= 0) {
11403 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
11404 "invalid image size");
11405 return;
11406 }
11407 } else {
11408 if (!source_texture->GetLevelSize(source_texture->target(), 0,
11409 &source_width, &source_height)) {
11410 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
11411 "source texture has no level 0");
11412 return;
11413 }
11414
11415 // Check that this type of texture is allowed.
11416 if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
11417 source_width, source_height, 1)) {
11418 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
11419 "source texture bad dimensions");
11420 return;
11421 }
11422 }
11423
11424 GLenum source_type = 0;
11425 GLenum source_internal_format = 0;
11426 source_texture->GetLevelType(source_texture->target(), 0, &source_type,
11427 &source_internal_format);
11428 GLenum dest_type = 0;
11429 GLenum dest_internal_format = 0;
11430 bool dest_level_defined = dest_texture->GetLevelType(
11431 dest_texture->target(), 0, &dest_type, &dest_internal_format);
11432 if (!dest_level_defined) {
11433 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopySubTextureCHROMIUM",
11434 "destination texture is not defined");
11435 return;
11436 }
11437 if (!dest_texture->ValidForTexture(dest_texture->target(), 0, xoffset,
11438 yoffset, source_width, source_height,
11439 dest_type)) {
11440 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
11441 "destination texture bad dimensions.");
11442 return;
11443 }
11444
11445 if (!ValidateCopyTextureCHROMIUM("glCopySubTextureCHROMIUM", target,
11446 source_texture_ref, dest_texture_ref,
11447 dest_internal_format)) {
11448 return;
11449 }
11450
11451 // Clear the source texture if necessary.
11452 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
11453 source_texture->target(), 0)) {
11454 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM",
11455 "source texture dimensions too big");
11456 return;
11457 }
11458
11459 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
11460 // needed because it takes 10s of milliseconds to initialize.
11461 if (!copy_texture_CHROMIUM_.get()) {
11462 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopySubTextureCHROMIUM");
11463 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
11464 copy_texture_CHROMIUM_->Initialize(this);
11465 RestoreCurrentFramebufferBindings();
11466 if (LOCAL_PEEK_GL_ERROR("glCopySubTextureCHROMIUM") != GL_NO_ERROR)
11467 return;
11468 }
11469
11470 int dest_width = 0;
11471 int dest_height = 0;
11472 bool ok =
11473 dest_texture->GetLevelSize(GL_TEXTURE_2D, 0, &dest_width, &dest_height);
11474 DCHECK(ok);
11475 if (xoffset != 0 || yoffset != 0 || source_width != dest_width ||
11476 source_height != dest_height) {
11477 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target,
11478 0)) {
11479 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM",
11480 "destination texture dimensions too big");
11481 return;
11482 }
11483 } else {
11484 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0,
11485 true);
11486 }
11487
11488 ScopedModifyPixels modify(dest_texture_ref);
11489
11490 // Try using GLImage::CopyTexSubImage when possible.
11491 bool unpack_premultiply_alpha_change =
11492 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
11493 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change &&
11494 !xoffset && !yoffset) {
11495 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
11496 if (image->CopyTexImage(GL_TEXTURE_2D))
11497 return;
11498 }
11499
11500 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
11501
11502 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
11503 // before presenting.
11504 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
11505 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
11506 // instead of using kIdentityMatrix crbug.com/226218.
11507 copy_texture_CHROMIUM_->DoCopySubTextureWithTransform(
11508 this, source_texture->target(), source_texture->service_id(),
11509 dest_texture->service_id(), xoffset, yoffset, dest_width, dest_height,
11510 source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
11511 unpack_unpremultiply_alpha_, kIdentityMatrix);
11512 } else {
11513 copy_texture_CHROMIUM_->DoCopySubTexture(
11514 this, source_texture->target(), source_texture->service_id(),
11515 source_internal_format, dest_texture->service_id(),
11516 dest_internal_format, xoffset, yoffset, dest_width, dest_height,
11517 source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
11518 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3711519 }
[email protected]91c94eb2013-10-22 10:32:5411520
11521 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2811522}
11523
[email protected]97dc7cbe2011-12-06 17:26:1711524static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
11525 switch (internalformat) {
11526 case GL_RGB565:
11527 return GL_UNSIGNED_SHORT_5_6_5;
11528 case GL_RGBA4:
11529 return GL_UNSIGNED_SHORT_4_4_4_4;
11530 case GL_RGB5_A1:
11531 return GL_UNSIGNED_SHORT_5_5_5_1;
11532 case GL_RGB8_OES:
11533 return GL_UNSIGNED_BYTE;
11534 case GL_RGBA8_OES:
11535 return GL_UNSIGNED_BYTE;
11536 case GL_LUMINANCE8_ALPHA8_EXT:
11537 return GL_UNSIGNED_BYTE;
11538 case GL_LUMINANCE8_EXT:
11539 return GL_UNSIGNED_BYTE;
11540 case GL_ALPHA8_EXT:
11541 return GL_UNSIGNED_BYTE;
11542 case GL_RGBA32F_EXT:
11543 return GL_FLOAT;
11544 case GL_RGB32F_EXT:
11545 return GL_FLOAT;
11546 case GL_ALPHA32F_EXT:
11547 return GL_FLOAT;
11548 case GL_LUMINANCE32F_EXT:
11549 return GL_FLOAT;
11550 case GL_LUMINANCE_ALPHA32F_EXT:
11551 return GL_FLOAT;
11552 case GL_RGBA16F_EXT:
11553 return GL_HALF_FLOAT_OES;
11554 case GL_RGB16F_EXT:
11555 return GL_HALF_FLOAT_OES;
11556 case GL_ALPHA16F_EXT:
11557 return GL_HALF_FLOAT_OES;
11558 case GL_LUMINANCE16F_EXT:
11559 return GL_HALF_FLOAT_OES;
11560 case GL_LUMINANCE_ALPHA16F_EXT:
11561 return GL_HALF_FLOAT_OES;
11562 case GL_BGRA8_EXT:
11563 return GL_UNSIGNED_BYTE;
11564 default:
11565 return GL_NONE;
11566 }
11567}
11568
11569void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4411570 GLenum target,
11571 GLint levels,
11572 GLenum internal_format,
11573 GLsizei width,
11574 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1311575 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
11576 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4111577 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0011578 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5111579 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311580 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1711581 return;
11582 }
[email protected]c986af502013-08-14 01:04:4411583 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11584 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911585 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111586 LOCAL_SET_GL_ERROR(
11587 GL_INVALID_OPERATION,
11588 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1711589 return;
11590 }
[email protected]370eaf12013-05-18 09:19:4911591 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0711592 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4411593 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1711594 }
[email protected]02965c22013-03-09 02:40:0711595 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5111596 LOCAL_SET_GL_ERROR(
11597 GL_INVALID_OPERATION,
11598 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1711599 return;
11600 }
[email protected]7989c9e2013-01-23 06:39:2611601
11602 GLenum format = ExtractFormatFromStorageFormat(internal_format);
11603 GLenum type = ExtractTypeFromStorageFormat(internal_format);
11604
11605 {
11606 GLsizei level_width = width;
11607 GLsizei level_height = height;
11608 uint32 estimated_size = 0;
11609 for (int ii = 0; ii < levels; ++ii) {
11610 uint32 level_size = 0;
11611 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211612 level_width, level_height, 1, format, type, state_.unpack_alignment,
[email protected]7989c9e2013-01-23 06:39:2611613 &estimated_size, NULL, NULL) ||
11614 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5111615 LOCAL_SET_GL_ERROR(
11616 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2611617 return;
11618 }
11619 level_width = std::max(1, level_width >> 1);
11620 level_height = std::max(1, level_height >> 1);
11621 }
11622 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5111623 LOCAL_SET_GL_ERROR(
11624 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611625 return;
11626 }
11627 }
11628
[email protected]ab09b612013-03-11 22:11:5111629 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3811630 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5111631 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1711632 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1511633 GLsizei level_width = width;
11634 GLsizei level_height = height;
11635 for (int ii = 0; ii < levels; ++ii) {
11636 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911637 texture_ref, target, ii, format,
11638 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1511639 level_width = std::max(1, level_width >> 1);
11640 level_height = std::max(1, level_height >> 1);
11641 }
[email protected]02965c22013-03-09 02:40:0711642 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1711643 }
[email protected]97dc7cbe2011-12-06 17:26:1711644}
[email protected]e51bdf32011-11-23 22:21:4611645
[email protected]78b514b2012-05-01 21:50:5911646error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3411647 uint32 immediate_data_size,
11648 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3511649 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5911650}
11651
11652void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3711653 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0211654 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3211655 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3711656 "mailbox[0]", static_cast<unsigned char>(data[0]));
11657
[email protected]43f253da2014-06-10 17:51:2211658 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11659 &state_, target);
11660 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
11661}
11662
11663void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
11664 GLenum target, const GLbyte* data) {
11665 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
11666 "context", logger_.GetLogPrefix(),
11667 "mailbox[0]", static_cast<unsigned char>(data[0]));
11668
11669 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
11670 target, data);
11671}
11672
11673void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
11674 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3711675 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2211676 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3711677 "mailbox that was not generated by "
11678 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0211679
[email protected]370eaf12013-05-18 09:19:4911680 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111681 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2211682 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5911683 return;
11684 }
11685
[email protected]62e65f02013-05-29 22:28:1011686 Texture* produced = texture_manager()->Produce(texture_ref);
11687 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5111688 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2211689 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
11690 return;
11691 }
11692
11693 if (produced->target() != target) {
11694 LOCAL_SET_GL_ERROR(
11695 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5911696 return;
11697 }
11698
sievers8b373ec52014-10-24 23:04:0611699 group_->mailbox_manager()->ProduceTexture(mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5911700}
11701
11702void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3711703 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0211704 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3211705 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3711706 "mailbox[0]", static_cast<unsigned char>(data[0]));
11707 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
11708 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
11709 "mailbox that was not generated by "
11710 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0211711
[email protected]62e65f02013-05-29 22:28:1011712 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4411713 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1111714 if (!texture_ref.get()) {
11715 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11716 "glConsumeTextureCHROMIUM",
11717 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5911718 return;
11719 }
[email protected]62e65f02013-05-29 22:28:1011720 GLuint client_id = texture_ref->client_id();
11721 if (!client_id) {
11722 LOCAL_SET_GL_ERROR(
11723 GL_INVALID_OPERATION,
11724 "glConsumeTextureCHROMIUM", "unknown texture for target");
11725 return;
11726 }
sievers8b373ec52014-10-24 23:04:0611727 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]62e65f02013-05-29 22:28:1011728 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5111729 LOCAL_SET_GL_ERROR(
11730 GL_INVALID_OPERATION,
11731 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5911732 return;
11733 }
[email protected]62e65f02013-05-29 22:28:1011734 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5111735 LOCAL_SET_GL_ERROR(
11736 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1011737 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5911738 return;
11739 }
[email protected]62e65f02013-05-29 22:28:1011740
11741 DeleteTexturesHelper(1, &client_id);
11742 texture_ref = texture_manager()->Consume(client_id, texture);
11743 glBindTexture(target, texture_ref->service_id());
11744
11745 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
11746 unit.bind_target = target;
11747 switch (target) {
11748 case GL_TEXTURE_2D:
11749 unit.bound_texture_2d = texture_ref;
11750 break;
11751 case GL_TEXTURE_CUBE_MAP:
11752 unit.bound_texture_cube_map = texture_ref;
11753 break;
11754 case GL_TEXTURE_EXTERNAL_OES:
11755 unit.bound_texture_external_oes = texture_ref;
11756 break;
11757 case GL_TEXTURE_RECTANGLE_ARB:
11758 unit.bound_texture_rectangle_arb = texture_ref;
11759 break;
11760 default:
11761 NOTREACHED(); // Validation should prevent us getting here.
11762 break;
11763 }
[email protected]78b514b2012-05-01 21:50:5911764}
11765
bajonesd8388be02015-04-04 00:15:4311766void GLES2DecoderImpl::EnsureTextureForClientId(
11767 GLenum target,
11768 GLuint client_id) {
11769 TextureRef* texture_ref = GetTexture(client_id);
11770 if (!texture_ref) {
11771 GLuint service_id;
11772 glGenTextures(1, &service_id);
11773 DCHECK_NE(0u, service_id);
11774 texture_ref = CreateTexture(client_id, service_id);
11775 texture_manager()->SetTarget(texture_ref, target);
11776 glBindTexture(target, service_id);
11777 RestoreCurrentTextureBindings(&state_, target);
11778 }
11779}
11780
11781// If CreateAndConsumeTexture fails we still need to ensure that the client_id
11782// provided is associated with a service_id/TextureRef for consistency, even if
11783// the resulting texture is incomplete.
[email protected]43f253da2014-06-10 17:51:2211784error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
11785 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3411786 const void* cmd_data) {
11787 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
11788 *static_cast<
11789 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
11790 cmd_data);
[email protected]43f253da2014-06-10 17:51:2211791 GLenum target = static_cast<GLenum>(c.target);
11792 uint32_t data_size;
11793 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
11794 return error::kOutOfBounds;
11795 }
11796 if (data_size > immediate_data_size) {
11797 return error::kOutOfBounds;
11798 }
11799 const GLbyte* mailbox =
11800 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
11801 if (!validators_->texture_bind_target.IsValid(target)) {
11802 LOCAL_SET_GL_ERROR_INVALID_ENUM(
11803 "glCreateAndConsumeTextureCHROMIUM", target, "target");
11804 return error::kNoError;
11805 }
11806 if (mailbox == NULL) {
11807 return error::kOutOfBounds;
11808 }
11809 uint32_t client_id = c.client_id;
11810 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
11811 return error::kNoError;
11812}
11813
11814void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
11815 const GLbyte* data, GLuint client_id) {
11816 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
11817 "context", logger_.GetLogPrefix(),
11818 "mailbox[0]", static_cast<unsigned char>(data[0]));
11819 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
11820 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
11821 "passed a mailbox that was not "
11822 "generated by GenMailboxCHROMIUM.";
11823
11824 TextureRef* texture_ref = GetTexture(client_id);
11825 if (texture_ref) {
bajonesd8388be02015-04-04 00:15:4311826 // No need to call EnsureTextureForClientId here, the client_id already has
11827 // an associated texture.
[email protected]43f253da2014-06-10 17:51:2211828 LOCAL_SET_GL_ERROR(
11829 GL_INVALID_OPERATION,
11830 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
11831 return;
11832 }
sievers8b373ec52014-10-24 23:04:0611833 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]43f253da2014-06-10 17:51:2211834 if (!texture) {
bajonesd8388be02015-04-04 00:15:4311835 EnsureTextureForClientId(target, client_id);
[email protected]43f253da2014-06-10 17:51:2211836 LOCAL_SET_GL_ERROR(
11837 GL_INVALID_OPERATION,
11838 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
11839 return;
11840 }
bajonesd8388be02015-04-04 00:15:4311841
[email protected]43f253da2014-06-10 17:51:2211842 if (texture->target() != target) {
bajonesd8388be02015-04-04 00:15:4311843 EnsureTextureForClientId(target, client_id);
[email protected]43f253da2014-06-10 17:51:2211844 LOCAL_SET_GL_ERROR(
11845 GL_INVALID_OPERATION,
11846 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
11847 return;
11848 }
11849
[email protected]43f253da2014-06-10 17:51:2211850 texture_ref = texture_manager()->Consume(client_id, texture);
11851}
11852
orglofchcad5a6742014-11-07 19:51:1211853bool GLES2DecoderImpl::DoIsValuebufferCHROMIUM(GLuint client_id) {
11854 const Valuebuffer* valuebuffer = GetValuebuffer(client_id);
11855 return valuebuffer && valuebuffer->IsValid();
11856}
11857
11858void GLES2DecoderImpl::DoBindValueBufferCHROMIUM(GLenum target,
11859 GLuint client_id) {
11860 Valuebuffer* valuebuffer = NULL;
11861 if (client_id != 0) {
11862 valuebuffer = GetValuebuffer(client_id);
11863 if (!valuebuffer) {
11864 if (!group_->bind_generates_resource()) {
11865 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindValuebufferCHROMIUM",
11866 "id not generated by glBindValuebufferCHROMIUM");
11867 return;
11868 }
11869
11870 // It's a new id so make a valuebuffer for it.
11871 CreateValuebuffer(client_id);
11872 valuebuffer = GetValuebuffer(client_id);
11873 }
11874 valuebuffer->MarkAsValid();
11875 }
11876 state_.bound_valuebuffer = valuebuffer;
11877}
11878
11879void GLES2DecoderImpl::DoSubscribeValueCHROMIUM(GLenum target,
11880 GLenum subscription) {
11881 if (!CheckCurrentValuebuffer("glSubscribeValueCHROMIUM")) {
11882 return;
11883 }
11884 state_.bound_valuebuffer.get()->AddSubscription(subscription);
11885}
11886
11887void GLES2DecoderImpl::DoPopulateSubscribedValuesCHROMIUM(GLenum target) {
11888 if (!CheckCurrentValuebuffer("glPopulateSubscribedValuesCHROMIUM")) {
11889 return;
11890 }
11891 valuebuffer_manager()->UpdateValuebufferState(state_.bound_valuebuffer.get());
11892}
11893
11894void GLES2DecoderImpl::DoUniformValueBufferCHROMIUM(GLint location,
11895 GLenum target,
11896 GLenum subscription) {
11897 if (!CheckCurrentValuebufferForSubscription(
11898 subscription, "glPopulateSubscribedValuesCHROMIUM")) {
11899 return;
11900 }
11901 if (!CheckSubscriptionTarget(location, subscription,
11902 "glPopulateSubscribedValuesCHROMIUM")) {
11903 return;
11904 }
11905 const ValueState* state =
11906 state_.bound_valuebuffer.get()->GetState(subscription);
11907 if (state) {
11908 switch (subscription) {
11909 case GL_MOUSE_POSITION_CHROMIUM:
11910 DoUniform2iv(location, 1, state->int_value);
11911 break;
11912 default:
11913 NOTREACHED() << "Unhandled uniform subscription target "
11914 << subscription;
11915 break;
11916 }
11917 }
11918}
11919
[email protected]d2a0e1a2012-08-12 02:25:0111920void GLES2DecoderImpl::DoInsertEventMarkerEXT(
11921 GLsizei length, const GLchar* marker) {
11922 if (!marker) {
11923 marker = "";
11924 }
11925 debug_marker_manager_.SetMarker(
11926 length ? std::string(marker, length) : std::string(marker));
11927}
11928
11929void GLES2DecoderImpl::DoPushGroupMarkerEXT(
11930 GLsizei length, const GLchar* marker) {
11931 if (!marker) {
11932 marker = "";
11933 }
[email protected]cac16542014-01-15 17:53:5111934 std::string name = length ? std::string(marker, length) : std::string(marker);
11935 debug_marker_manager_.PushGroup(name);
dyen4bb43282015-01-08 01:09:5611936 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_group_marker"), name,
11937 kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111938}
11939
11940void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
11941 debug_marker_manager_.PopGroup();
dyen4bb43282015-01-08 01:09:5611942 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111943}
11944
[email protected]09d50362012-10-18 20:54:3711945void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
11946 GLenum target, GLint image_id) {
11947 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711948
[email protected]bc26e8d2014-01-29 00:40:3011949 if (target == GL_TEXTURE_CUBE_MAP) {
11950 LOCAL_SET_GL_ERROR(
11951 GL_INVALID_ENUM,
11952 "glBindTexImage2DCHROMIUM", "invalid target");
11953 return;
11954 }
11955
[email protected]09d50362012-10-18 20:54:3711956 // Default target might be conceptually valid, but disallow it to avoid
11957 // accidents.
[email protected]c986af502013-08-14 01:04:4411958 TextureRef* texture_ref =
11959 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911960 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111961 LOCAL_SET_GL_ERROR(
11962 GL_INVALID_OPERATION,
11963 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711964 return;
11965 }
11966
11967 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11968 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111969 LOCAL_SET_GL_ERROR(
11970 GL_INVALID_OPERATION,
11971 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711972 return;
11973 }
11974
[email protected]b8160812013-04-09 00:41:0411975 {
11976 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011977 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611978 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0411979 LOCAL_SET_GL_ERROR(
11980 GL_INVALID_OPERATION,
11981 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
11982 return;
11983 }
[email protected]09d50362012-10-18 20:54:3711984 }
11985
11986 gfx::Size size = gl_image->GetSize();
11987 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911988 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3711989 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4911990 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3711991}
11992
11993void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
11994 GLenum target, GLint image_id) {
11995 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711996
11997 // Default target might be conceptually valid, but disallow it to avoid
11998 // accidents.
[email protected]c986af502013-08-14 01:04:4411999 TextureRef* texture_ref =
12000 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4912001 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5112002 LOCAL_SET_GL_ERROR(
12003 GL_INVALID_OPERATION,
12004 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3712005 return;
12006 }
12007
12008 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
12009 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5112010 LOCAL_SET_GL_ERROR(
12011 GL_INVALID_OPERATION,
12012 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3712013 return;
12014 }
12015
12016 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4912017 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3712018 return;
12019
[email protected]b8160812013-04-09 00:41:0412020 {
12021 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3012022 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2612023 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0412024 }
[email protected]09d50362012-10-18 20:54:3712025
12026 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4912027 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3712028 GL_RGBA, GL_UNSIGNED_BYTE, false);
12029}
[email protected]d2a0e1a2012-08-12 02:25:0112030
[email protected]94307712012-11-16 23:26:1112031error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3412032 uint32 immediate_data_size,
12033 const void* cmd_data) {
12034 const gles2::cmds::TraceBeginCHROMIUM& c =
12035 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
dyencb86f2f2014-12-09 18:35:4112036 Bucket* category_bucket = GetBucket(c.category_bucket_id);
12037 Bucket* name_bucket = GetBucket(c.name_bucket_id);
12038 if (!category_bucket || category_bucket->size() == 0 ||
12039 !name_bucket || name_bucket->size() == 0) {
[email protected]94307712012-11-16 23:26:1112040 return error::kInvalidArguments;
12041 }
dyencb86f2f2014-12-09 18:35:4112042
12043 std::string category_name;
12044 std::string trace_name;
12045 if (!category_bucket->GetAsString(&category_name) ||
12046 !name_bucket->GetAsString(&trace_name)) {
[email protected]94307712012-11-16 23:26:1112047 return error::kInvalidArguments;
12048 }
dyencb86f2f2014-12-09 18:35:4112049
dyencb86f2f2014-12-09 18:35:4112050 if (!gpu_tracer_->Begin(category_name, trace_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5112051 LOCAL_SET_GL_ERROR(
12052 GL_INVALID_OPERATION,
12053 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1412054 return error::kNoError;
12055 }
[email protected]94307712012-11-16 23:26:1112056 return error::kNoError;
12057}
12058
12059void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
dyen4bb43282015-01-08 01:09:5612060 if (!gpu_tracer_->End(kTraceCHROMIUM)) {
12061 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
12062 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1112063 return;
12064 }
[email protected]94307712012-11-16 23:26:1112065}
12066
[email protected]2f143d482013-03-14 18:04:4912067void GLES2DecoderImpl::DoDrawBuffersEXT(
12068 GLsizei count, const GLenum* bufs) {
12069 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
12070 LOCAL_SET_GL_ERROR(
12071 GL_INVALID_VALUE,
12072 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
12073 return;
12074 }
12075
12076 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
12077 if (framebuffer) {
12078 for (GLsizei i = 0; i < count; ++i) {
12079 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
12080 bufs[i] != GL_NONE) {
12081 LOCAL_SET_GL_ERROR(
12082 GL_INVALID_OPERATION,
12083 "glDrawBuffersEXT",
12084 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
12085 return;
12086 }
12087 }
12088 glDrawBuffersARB(count, bufs);
12089 framebuffer->SetDrawBuffers(count, bufs);
12090 } else { // backbuffer
12091 if (count > 1 ||
12092 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
12093 LOCAL_SET_GL_ERROR(
12094 GL_INVALID_OPERATION,
12095 "glDrawBuffersEXT",
12096 "more than one buffer or bufs not GL_NONE or GL_BACK");
12097 return;
12098 }
12099 GLenum mapped_buf = bufs[0];
12100 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
12101 bufs[0] == GL_BACK) {
12102 mapped_buf = GL_COLOR_ATTACHMENT0;
12103 }
12104 glDrawBuffersARB(count, &mapped_buf);
12105 group_->set_draw_buffer(bufs[0]);
12106 }
12107}
12108
[email protected]a6a09f852014-05-23 13:05:0312109void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
sieversfbaa5dc2015-04-28 00:45:3112110 MarkContextLost(GetContextLostReasonFromResetStatus(current));
12111 group_->LoseContexts(GetContextLostReasonFromResetStatus(other));
12112 reset_by_robustness_extension_ = true;
[email protected]a6a09f852014-05-23 13:05:0312113}
12114
kkinnunen337d59632014-08-26 10:19:5712115void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
12116 const GLfloat* matrix) {
12117 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
12118 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
12119 if (!features().chromium_path_rendering) {
12120 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
12121 "glMatrixLoadfCHROMIUM",
12122 "function not available");
12123 return;
12124 }
12125
12126 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
12127 ? state_.projection_matrix
12128 : state_.modelview_matrix;
12129 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
12130 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
12131 // since the values of the _NV and _CHROMIUM tokens match.
12132 glMatrixLoadfEXT(matrix_mode, matrix);
12133}
12134
12135void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
12136 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
12137 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
12138
12139 if (!features().chromium_path_rendering) {
12140 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
12141 "glMatrixLoadIdentityCHROMIUM",
12142 "function not available");
12143 return;
12144 }
12145
kkinnunen337d59632014-08-26 10:19:5712146 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
12147 ? state_.projection_matrix
12148 : state_.modelview_matrix;
12149 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
12150 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
12151 // since the values of the _NV and _CHROMIUM tokens match.
12152 glMatrixLoadIdentityEXT(matrix_mode);
12153}
12154
[email protected]32145a92012-12-17 09:01:5912155bool GLES2DecoderImpl::ValidateAsyncTransfer(
12156 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4712157 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5912158 GLenum target,
12159 GLint level,
12160 const void * data) {
12161 // We only support async uploads to 2D textures for now.
12162 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5112163 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5912164 return false;
12165 }
12166 // We only support uploads to level zero for now.
12167 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5112168 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5912169 return false;
12170 }
12171 // A transfer buffer must be bound, even for asyncTexImage2D.
12172 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5112173 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5912174 return false;
12175 }
12176 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4712177 if (!texture_ref ||
12178 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5112179 LOCAL_SET_GL_ERROR(
12180 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5912181 function_name, "transfer already in progress");
12182 return false;
12183 }
12184 return true;
12185}
12186
[email protected]e3c4a9ab2014-03-31 09:07:0212187base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
12188 uint32 async_upload_token,
12189 uint32 sync_data_shm_id,
12190 uint32 sync_data_shm_offset) {
12191 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2512192 if (!buffer.get() ||
12193 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0212194 return base::Closure();
12195
12196 AsyncMemoryParams mem_params(buffer,
12197 sync_data_shm_offset,
12198 sizeof(AsyncUploadSync));
12199
12200 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
12201 new AsyncUploadTokenCompletionObserver(async_upload_token));
12202
12203 return base::Bind(
12204 &AsyncPixelTransferManager::AsyncNotifyCompletion,
12205 base::Unretained(GetAsyncPixelTransferManager()),
12206 mem_params,
12207 observer);
12208}
12209
[email protected]69023942012-11-30 19:57:1612210error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412211 uint32 immediate_data_size,
12212 const void* cmd_data) {
12213 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
12214 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1612215 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1612216 GLenum target = static_cast<GLenum>(c.target);
12217 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4412218 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1612219 GLsizei width = static_cast<GLsizei>(c.width);
12220 GLsizei height = static_cast<GLsizei>(c.height);
12221 GLint border = static_cast<GLint>(c.border);
12222 GLenum format = static_cast<GLenum>(c.format);
12223 GLenum type = static_cast<GLenum>(c.type);
12224 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
12225 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
12226 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0212227 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
12228 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
12229 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
12230
12231 base::ScopedClosureRunner scoped_completion_callback;
12232 if (async_upload_token) {
12233 base::Closure completion_closure =
12234 AsyncUploadTokenCompletionClosure(async_upload_token,
12235 sync_data_shm_id,
12236 sync_data_shm_offset);
12237 if (completion_closure.is_null())
12238 return error::kInvalidArguments;
12239
12240 scoped_completion_callback.Reset(completion_closure);
12241 }
[email protected]32145a92012-12-17 09:01:5912242
12243 // TODO(epenner): Move this and copies of this memory validation
12244 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1612245 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4212246 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
12247 NULL, NULL)) {
[email protected]69023942012-11-30 19:57:1612248 return error::kOutOfBounds;
12249 }
12250 const void* pixels = NULL;
12251 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
12252 pixels = GetSharedMemoryAs<const void*>(
12253 pixels_shm_id, pixels_shm_offset, pixels_size);
12254 if (!pixels) {
12255 return error::kOutOfBounds;
12256 }
12257 }
12258
[email protected]c986af502013-08-14 01:04:4412259 TextureManager::DoTextImage2DArguments args = {
12260 target, level, internal_format, width, height, border, format, type,
12261 pixels, pixels_size};
12262 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5912263 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4412264 if (!texture_manager()->ValidateTexImage2D(
12265 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5912266 return error::kNoError;
12267 }
12268
12269 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4912270 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5912271 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4712272 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5912273 return error::kNoError;
12274
12275 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0712276 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5112277 LOCAL_SET_GL_ERROR(
12278 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5912279 "glAsyncTexImage2DCHROMIUM", "already defined");
12280 return error::kNoError;
12281 }
12282
[email protected]7989c9e2013-01-23 06:39:2612283 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5112284 LOCAL_SET_GL_ERROR(
12285 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2612286 return error::kNoError;
12287 }
12288
[email protected]5b3a8e02013-03-13 05:36:4412289 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3812290 AsyncTexImage2DParams tex_params = {
12291 target, level, static_cast<GLenum>(internal_format),
12292 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1212293 AsyncMemoryParams mem_params(
12294 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5912295
[email protected]5b3a8e02013-03-13 05:36:4412296 // Set up the async state if needed, and make the texture
12297 // immutable so the async state stays valid. The level info
12298 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1812299 AsyncPixelTransferDelegate* delegate =
12300 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
12301 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4412302 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5912303
[email protected]896425e2013-06-12 17:27:1812304 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4412305 tex_params,
12306 mem_params,
12307 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4912308 // The callback is only invoked if the transfer delegate still
12309 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4412310 // ownership that both of these pointers are valid.
12311 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4912312 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4412313 tex_params));
[email protected]f598f422012-12-07 08:30:0312314 return error::kNoError;
[email protected]69023942012-11-30 19:57:1612315}
12316
12317error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412318 uint32 immediate_data_size,
12319 const void* cmd_data) {
12320 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
12321 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1612322 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1612323 GLenum target = static_cast<GLenum>(c.target);
12324 GLint level = static_cast<GLint>(c.level);
12325 GLint xoffset = static_cast<GLint>(c.xoffset);
12326 GLint yoffset = static_cast<GLint>(c.yoffset);
12327 GLsizei width = static_cast<GLsizei>(c.width);
12328 GLsizei height = static_cast<GLsizei>(c.height);
12329 GLenum format = static_cast<GLenum>(c.format);
12330 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0212331 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
12332 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
12333 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
12334
12335 base::ScopedClosureRunner scoped_completion_callback;
12336 if (async_upload_token) {
12337 base::Closure completion_closure =
12338 AsyncUploadTokenCompletionClosure(async_upload_token,
12339 sync_data_shm_id,
12340 sync_data_shm_offset);
12341 if (completion_closure.is_null())
12342 return error::kInvalidArguments;
12343
12344 scoped_completion_callback.Reset(completion_closure);
12345 }
[email protected]32145a92012-12-17 09:01:5912346
12347 // TODO(epenner): Move this and copies of this memory validation
12348 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1612349 uint32 data_size;
12350 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4212351 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]69023942012-11-30 19:57:1612352 NULL, NULL)) {
12353 return error::kOutOfBounds;
12354 }
12355 const void* pixels = GetSharedMemoryAs<const void*>(
12356 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5912357
12358 // All the normal glTexSubImage2D validation.
12359 error::Error error = error::kNoError;
12360 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
12361 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
12362 return error;
[email protected]69023942012-11-30 19:57:1612363 }
12364
[email protected]32145a92012-12-17 09:01:5912365 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4412366 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
12367 &state_, target);
[email protected]370eaf12013-05-18 09:19:4912368 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5912369 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4712370 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5912371 return error::kNoError;
12372
12373 // Guarantee async textures are always 'cleared' as follows:
12374 // - AsyncTexImage2D can not redefine an existing texture
12375 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
12376 // - AsyncTexSubImage2D clears synchronously if not already cleared.
12377 // - Textures become immutable after an async call.
12378 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0712379 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4912380 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
12381 target, level)) {
[email protected]ab09b612013-03-11 22:11:5112382 LOCAL_SET_GL_ERROR(
12383 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2512384 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5912385 return error::kNoError;
12386 }
12387 }
12388
[email protected]5b3a8e02013-03-13 05:36:4412389 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0312390 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5912391 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1212392 AsyncMemoryParams mem_params(
12393 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1812394 AsyncPixelTransferDelegate* delegate =
12395 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
12396 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4412397 // TODO(epenner): We may want to enforce exclusive use
12398 // of async APIs in which case this should become an error,
12399 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0312400 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4412401 0, 0, 0, 0, 0, 0};
12402 texture->GetLevelSize(target, level, &define_params.width,
12403 &define_params.height);
12404 texture->GetLevelType(target, level, &define_params.type,
12405 &define_params.internal_format);
12406 // Set up the async state if needed, and make the texture
12407 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1812408 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4712409 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4412410 texture->SetImmutable(true);
12411 }
12412
[email protected]896425e2013-06-12 17:27:1812413 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5912414 return error::kNoError;
[email protected]69023942012-11-30 19:57:1612415}
12416
[email protected]a00c1f742013-03-05 17:02:1612417error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412418 uint32 immediate_data_size,
12419 const void* cmd_data) {
12420 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
12421 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1612422 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
12423 GLenum target = static_cast<GLenum>(c.target);
12424
12425 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5112426 LOCAL_SET_GL_ERROR(
12427 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1612428 return error::kNoError;
12429 }
[email protected]c986af502013-08-14 01:04:4412430 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
12431 &state_, target);
[email protected]370eaf12013-05-18 09:19:4912432 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5112433 LOCAL_SET_GL_ERROR(
12434 GL_INVALID_OPERATION,
12435 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1612436 return error::kNoError;
12437 }
[email protected]896425e2013-06-12 17:27:1812438 AsyncPixelTransferDelegate* delegate =
12439 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
12440 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4912441 LOCAL_SET_GL_ERROR(
12442 GL_INVALID_OPERATION,
12443 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
12444 return error::kNoError;
12445 }
[email protected]896425e2013-06-12 17:27:1812446 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0912447 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1612448 return error::kNoError;
12449}
12450
[email protected]e3c4a9ab2014-03-31 09:07:0212451error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412452 uint32 immediate_data_size,
12453 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0212454 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
12455
12456 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
12457 ProcessFinishedAsyncTransfers();
12458 return error::kNoError;
12459}
12460
zmo8fab00c2015-02-07 02:45:0512461error::Error GLES2DecoderImpl::HandleUniformBlockBinding(
12462 uint32_t immediate_data_size, const void* cmd_data) {
12463 if (!unsafe_es3_apis_enabled())
12464 return error::kUnknownCommand;
12465 const gles2::cmds::UniformBlockBinding& c =
12466 *static_cast<const gles2::cmds::UniformBlockBinding*>(cmd_data);
12467 GLuint client_id = c.program;
12468 GLuint index = static_cast<GLuint>(c.index);
12469 GLuint binding = static_cast<GLuint>(c.binding);
12470 Program* program = GetProgramInfoNotShader(
12471 client_id, "glUniformBlockBinding");
12472 if (!program) {
12473 return error::kNoError;
12474 }
12475 GLuint service_id = program->service_id();
12476 glUniformBlockBinding(service_id, index, binding);
12477 return error::kNoError;
12478}
12479
zmo3366957e2015-02-18 23:40:0712480error::Error GLES2DecoderImpl::HandleClientWaitSync(
12481 uint32_t immediate_data_size, const void* cmd_data) {
12482 if (!unsafe_es3_apis_enabled())
12483 return error::kUnknownCommand;
12484 const gles2::cmds::ClientWaitSync& c =
12485 *static_cast<const gles2::cmds::ClientWaitSync*>(cmd_data);
12486 GLuint sync = static_cast<GLuint>(c.sync);
12487 GLbitfield flags = static_cast<GLbitfield>(c.flags);
12488 GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1);
12489 typedef cmds::ClientWaitSync::Result Result;
12490 Result* result_dst = GetSharedMemoryAs<Result*>(
12491 c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
12492 if (!result_dst) {
12493 return error::kOutOfBounds;
12494 }
12495 if (*result_dst != GL_WAIT_FAILED) {
12496 return error::kInvalidArguments;
12497 }
12498 GLsync service_sync = 0;
12499 if (!group_->GetSyncServiceId(sync, &service_sync)) {
12500 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "ClientWaitSync", "invalid sync");
12501 return error::kNoError;
12502 }
12503 *result_dst = glClientWaitSync(service_sync, flags, timeout);
12504 return error::kNoError;
12505}
12506
zmo41e40582015-02-19 02:13:3012507error::Error GLES2DecoderImpl::HandleWaitSync(
12508 uint32_t immediate_data_size, const void* cmd_data) {
12509 if (!unsafe_es3_apis_enabled())
12510 return error::kUnknownCommand;
12511 const gles2::cmds::WaitSync& c =
12512 *static_cast<const gles2::cmds::WaitSync*>(cmd_data);
12513 GLuint sync = static_cast<GLuint>(c.sync);
12514 GLbitfield flags = static_cast<GLbitfield>(c.flags);
12515 GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1);
12516 GLsync service_sync = 0;
12517 if (!group_->GetSyncServiceId(sync, &service_sync)) {
12518 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "WaitSync", "invalid sync");
12519 return error::kNoError;
12520 }
12521 glWaitSync(service_sync, flags, timeout);
12522 return error::kNoError;
12523}
12524
zmoa06b9882015-03-10 20:50:3412525error::Error GLES2DecoderImpl::HandleMapBufferRange(
12526 uint32_t immediate_data_size, const void* cmd_data) {
12527 if (!unsafe_es3_apis_enabled()) {
12528 return error::kUnknownCommand;
12529 }
12530 const gles2::cmds::MapBufferRange& c =
12531 *static_cast<const gles2::cmds::MapBufferRange*>(cmd_data);
12532 GLenum target = static_cast<GLenum>(c.target);
12533 GLbitfield access = static_cast<GLbitfield>(c.access);
12534 GLintptr offset = static_cast<GLintptr>(c.offset);
12535 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
12536
12537 typedef cmds::MapBufferRange::Result Result;
12538 Result* result = GetSharedMemoryAs<Result*>(
12539 c.result_shm_id, c.result_shm_offset, sizeof(*result));
12540 if (!result) {
12541 return error::kOutOfBounds;
12542 }
12543 if (*result != 0) {
12544 *result = 0;
12545 return error::kInvalidArguments;
12546 }
12547 int8_t* mem =
12548 GetSharedMemoryAs<int8_t*>(c.data_shm_id, c.data_shm_offset, size);
12549 if (!mem) {
12550 return error::kOutOfBounds;
12551 }
12552
12553 GLbitfield mask = GL_MAP_INVALIDATE_BUFFER_BIT;
12554 if ((access & mask) == mask) {
12555 // TODO(zmo): To be on the safe side, always map
12556 // GL_MAP_INVALIDATE_BUFFER_BIT to GL_MAP_INVALIDATE_RANGE_BIT.
12557 access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT);
12558 access = (access | GL_MAP_INVALIDATE_RANGE_BIT);
12559 }
12560 // TODO(zmo): Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of
12561 // undefined behaviors.
12562 mask = GL_MAP_READ_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
12563 if ((access & mask) == mask) {
12564 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "MapBufferRange",
12565 "incompatible access bits");
12566 return error::kNoError;
12567 }
12568 access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT);
12569 if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT &&
12570 (access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) {
12571 access = (access | GL_MAP_READ_BIT);
12572 }
12573 void* ptr = glMapBufferRange(target, offset, size, access);
12574 if (ptr == nullptr) {
12575 return error::kNoError;
12576 }
12577 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
12578 DCHECK(buffer);
zmo2a09dc052015-03-12 00:48:2512579 buffer->SetMappedRange(offset, size, access, ptr,
12580 GetSharedMemoryBuffer(c.data_shm_id));
zmoa06b9882015-03-10 20:50:3412581 if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) {
12582 memcpy(mem, ptr, size);
12583 }
12584 *result = 1;
12585 return error::kNoError;
12586}
12587
zmo2a09dc052015-03-12 00:48:2512588error::Error GLES2DecoderImpl::HandleUnmapBuffer(
12589 uint32_t immediate_data_size, const void* cmd_data) {
12590 if (!unsafe_es3_apis_enabled()) {
12591 return error::kUnknownCommand;
12592 }
12593 const gles2::cmds::UnmapBuffer& c =
12594 *static_cast<const gles2::cmds::UnmapBuffer*>(cmd_data);
12595 GLenum target = static_cast<GLenum>(c.target);
12596
12597 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
12598 if (!buffer) {
12599 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", "no buffer bound");
12600 return error::kNoError;
12601 }
12602 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange();
12603 if (!mapped_range) {
12604 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer",
12605 "buffer is unmapped");
12606 return error::kNoError;
12607 }
12608 if ((mapped_range->access & GL_MAP_WRITE_BIT) == 0 ||
12609 (mapped_range->access & GL_MAP_FLUSH_EXPLICIT_BIT) ==
12610 GL_MAP_FLUSH_EXPLICIT_BIT) {
12611 // If we don't need to write back, or explict flush is required, no copying
12612 // back is needed.
12613 } else {
12614 void* mem = mapped_range->GetShmPointer();
12615 if (!mem) {
12616 return error::kOutOfBounds;
12617 }
12618 DCHECK(mapped_range->pointer);
12619 memcpy(mapped_range->pointer, mem, mapped_range->size);
12620 }
12621 buffer->RemoveMappedRange();
12622 GLboolean rt = glUnmapBuffer(target);
12623 if (rt == GL_FALSE) {
12624 // At this point, we have already done the necessary validation, so
12625 // GL_FALSE indicates data corruption.
12626 // TODO(zmo): We could redo the map / copy data / unmap to recover, but
12627 // the second unmap could still return GL_FALSE. For now, we simply lose
12628 // the contexts in the share group.
12629 LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE";
sieversfbaa5dc2015-04-28 00:45:3112630 // Need to lose current context before broadcasting!
12631 MarkContextLost(error::kGuilty);
12632 group_->LoseContexts(error::kInnocent);
zmo2a09dc052015-03-12 00:48:2512633 return error::kLostContext;
12634 }
12635 return error::kNoError;
12636}
12637
[email protected]91c94eb2013-10-22 10:32:5412638void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
12639 TextureRef* texture_ref) {
12640 Texture* texture = texture_ref->texture();
12641 DoDidUseTexImageIfNeeded(texture, texture->target());
12642}
12643
sieversfbaa5dc2015-04-28 00:45:3112644// Note that GL_LOST_CONTEXT is specific to GLES.
12645// For desktop GL we have to query the reset status proactively.
oetuaho37cc50e2014-10-31 11:19:2012646void GLES2DecoderImpl::OnContextLostError() {
sieversfbaa5dc2015-04-28 00:45:3112647 if (!WasContextLost()) {
12648 // Need to lose current context before broadcasting!
12649 CheckResetStatus();
12650 group_->LoseContexts(error::kUnknown);
12651 reset_by_robustness_extension_ = true;
12652 }
oetuaho37cc50e2014-10-31 11:19:2012653}
12654
[email protected]828a3932014-04-02 14:43:1312655void GLES2DecoderImpl::OnOutOfMemoryError() {
sieversfbaa5dc2015-04-28 00:45:3112656 if (lose_context_when_out_of_memory_ && !WasContextLost()) {
12657 error::ContextLostReason other = error::kOutOfMemory;
12658 if (CheckResetStatus()) {
12659 other = error::kUnknown;
12660 } else {
12661 // Need to lose current context before broadcasting!
12662 MarkContextLost(error::kOutOfMemory);
12663 }
12664 group_->LoseContexts(other);
[email protected]828a3932014-04-02 14:43:1312665 }
12666}
12667
[email protected]96449d2c2009-11-25 00:01:3212668// Include the auto-generated part of this file. We split this because it means
12669// we can easily edit the non-auto generated parts right here in this file
12670// instead of having to edit some template or the code generator.
12671#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
12672
12673} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2512674} // namespace gpu