blob: 14c74dc56b345112606e3327773aae32a64c58b0 [file] [log] [blame]
[email protected]529c6672012-01-04 02:18:261// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]96449d2c2009-11-25 00:01:322// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]8a837bb2010-01-05 00:21:245#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
[email protected]74470702010-01-06 18:51:166
7#include <stdio.h>
8
[email protected]1aef98132010-02-23 18:00:079#include <algorithm>
[email protected]f39f4b3f2010-05-12 17:04:0810#include <list>
[email protected]96449d2c2009-11-25 00:01:3211#include <map>
[email protected]94307712012-11-16 23:26:1112#include <stack>
[email protected]f39f4b3f2010-05-12 17:04:0813#include <string>
14#include <vector>
[email protected]5a6db6c2010-04-22 18:32:0615
[email protected]00eb49a2010-08-12 20:46:5716#include "base/at_exit.h"
[email protected]9d37f062011-11-22 01:24:5217#include "base/bind.h"
[email protected]e3c4a9ab2014-03-31 09:07:0218#include "base/callback_helpers.h"
[email protected]e844ae22012-01-14 03:36:2619#include "base/command_line.h"
[email protected]1078f912011-12-23 13:12:1420#include "base/debug/trace_event.h"
[email protected]b2e92592014-01-10 15:47:1521#include "base/debug/trace_event_synthetic_delay.h"
[email protected]5aa95ac2014-08-14 15:20:5622#include "base/float_util.h"
[email protected]3b63f8f42011-03-28 01:54:1523#include "base/memory/scoped_ptr.h"
[email protected]e3c4a9ab2014-03-31 09:07:0224#include "base/numerics/safe_math.h"
[email protected]f4390962013-06-11 07:29:2225#include "base/strings/string_number_conversions.h"
[email protected]6d668892013-12-04 21:37:1226#include "base/strings/string_split.h"
[email protected]d37231fa2010-04-09 21:16:0227#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3228#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2229#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3230#include "gpu/command_buffer/common/gles2_cmd_format.h"
31#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1032#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5133#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2234#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
35#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5036#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3237#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5038#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2439#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5040#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1141#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5842#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3243#include "gpu/command_buffer/service/gl_utils.h"
[email protected]43410e92012-04-20 17:06:2844#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4645#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1346#include "gpu/command_buffer/service/gpu_state_tracer.h"
[email protected]e844ae22012-01-14 03:36:2647#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1448#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3749#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5950#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2551#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4752#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5353#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5854#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4755#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4556#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0457#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]a93bb842010-02-16 23:03:4758#include "gpu/command_buffer/service/texture_manager.h"
orglofchcad5a6742014-11-07 19:51:1259#include "gpu/command_buffer/service/valuebuffer_manager.h"
[email protected]944b62f32012-09-27 02:20:4660#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2261#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]6896d7f2014-04-28 20:24:1562#include "third_party/smhasher/src/City.h"
[email protected]5a36dc132013-07-23 23:17:5563#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3764#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2765#include "ui/gl/gl_implementation.h"
66#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2767
[email protected]e51bdf32011-11-23 22:21:4668#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:5369#include <IOSurface/IOSurfaceAPI.h>
70// Note that this must be included after gl_bindings.h to avoid conflicts.
71#include <OpenGL/CGLIOSurface.h>
[email protected]e51bdf32011-11-23 22:21:4672#endif
[email protected]de17df392010-04-23 21:09:4173
[email protected]6eb775352013-08-27 05:57:1674#if defined(OS_WIN)
75#include "base/win/win_util.h"
76#endif
77
[email protected]a7a27ace2009-12-12 00:11:2578namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3279namespace gles2 {
80
[email protected]f0d74742011-10-03 16:31:0481namespace {
[email protected]693ca512012-11-13 18:09:1382
[email protected]f0d74742011-10-03 16:31:0483static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4984static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1385static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]93c2fd82014-04-16 02:46:0686static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
[email protected]693ca512012-11-13 18:09:1387
[email protected]448e459e2013-06-12 17:00:4188static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
89 GLint rangeMax,
90 GLint precision) {
91 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
92}
93
[email protected]8dc1bf92013-03-12 03:58:2194static void GetShaderPrecisionFormatImpl(GLenum shader_type,
95 GLenum precision_type,
96 GLint *range, GLint *precision) {
97 switch (precision_type) {
98 case GL_LOW_INT:
99 case GL_MEDIUM_INT:
100 case GL_HIGH_INT:
101 // These values are for a 32-bit twos-complement integer format.
102 range[0] = 31;
103 range[1] = 30;
104 *precision = 0;
105 break;
106 case GL_LOW_FLOAT:
107 case GL_MEDIUM_FLOAT:
108 case GL_HIGH_FLOAT:
109 // These values are for an IEEE single-precision floating-point format.
110 range[0] = 127;
111 range[1] = 127;
112 *precision = 23;
113 break;
114 default:
115 NOTREACHED();
116 break;
117 }
118
[email protected]8af4d5e2013-03-15 23:55:33119 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
120 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21121 // This function is sometimes defined even though it's really just
122 // a stub, so we need to set range and precision as if it weren't
123 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44124 // On Mac OS with some GPUs, calling this generates a
125 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
126 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21127 glGetShaderPrecisionFormat(shader_type, precision_type,
128 range, precision);
[email protected]448e459e2013-06-12 17:00:41129
130 // TODO(brianderson): Make the following official workarounds.
131
132 // Some drivers have bugs where they report the ranges as a negative number.
133 // Taking the absolute value here shouldn't hurt because negative numbers
134 // aren't expected anyway.
135 range[0] = abs(range[0]);
136 range[1] = abs(range[1]);
137
138 // If the driver reports a precision for highp float that isn't actually
139 // highp, don't pretend like it's supported because shader compilation will
140 // fail anyway.
141 if (precision_type == GL_HIGH_FLOAT &&
142 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
143 range[0] = 0;
144 range[1] = 0;
145 *precision = 0;
146 }
[email protected]8dc1bf92013-03-12 03:58:21147 }
148}
149
[email protected]d286ebbc2014-07-03 17:19:10150static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
151 switch (plane_transform) {
152 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
153 return gfx::OVERLAY_TRANSFORM_NONE;
154 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
155 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
156 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
157 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
158 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
159 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
160 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
161 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
162 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
163 return gfx::OVERLAY_TRANSFORM_ROTATE_270;
164 default:
165 return gfx::OVERLAY_TRANSFORM_INVALID;
166 }
167}
168
[email protected]b04e24c2013-01-08 18:35:25169} // namespace
[email protected]f0d74742011-10-03 16:31:04170
[email protected]6217d392010-03-25 22:08:35171class GLES2DecoderImpl;
172
[email protected]ab09b612013-03-11 22:11:51173// Local versions of the SET_GL_ERROR macros
174#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50175 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51176#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50177 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
178 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51179#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50180 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
181 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51182#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50183 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
184 function_name)
[email protected]ab09b612013-03-11 22:11:51185#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50186 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51187#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50188 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51189#define LOCAL_PERFORMANCE_WARNING(msg) \
190 PerformanceWarning(__FILE__, __LINE__, msg)
191#define LOCAL_RENDER_WARNING(msg) \
192 RenderWarning(__FILE__, __LINE__, msg)
193
[email protected]07f54fcc2009-12-22 02:46:30194// Check that certain assumptions the code makes are true. There are places in
195// the code where shared memory is passed direclty to GL. Example, glUniformiv,
196// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
197// a few others) are 32bits. If they are not 32bits the code will have to change
198// to call those GL functions with service side memory and then copy the results
199// to shared memory, converting the sizes.
200COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
201 GLint_not_same_size_as_uint32);
202COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
203 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37204COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
205 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30206
[email protected]43f28f832010-02-03 02:28:48207// TODO(kbr): the use of this anonymous namespace core dumps the
208// linker on Mac OS X 10.6 when the symbol ordering file is used
209// namespace {
[email protected]96449d2c2009-11-25 00:01:32210
211// Returns the address of the first byte after a struct.
212template <typename T>
213const void* AddressAfterStruct(const T& pod) {
214 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
215}
216
[email protected]07f54fcc2009-12-22 02:46:30217// Returns the address of the frst byte after the struct or NULL if size >
218// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32219template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30220RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
221 uint32 size,
222 uint32 immediate_data_size) {
223 return (size <= immediate_data_size) ?
224 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
225 NULL;
[email protected]96449d2c2009-11-25 00:01:32226}
227
[email protected]07f54fcc2009-12-22 02:46:30228// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18229bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32230 GLuint count,
231 size_t size,
[email protected]a76b0052010-03-05 00:33:18232 unsigned int elements_per_unit,
233 uint32* dst) {
234 uint32 value;
235 if (!SafeMultiplyUint32(count, size, &value)) {
236 return false;
237 }
238 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
239 return false;
240 }
241 *dst = value;
242 return true;
[email protected]96449d2c2009-11-25 00:01:32243}
244
[email protected]258a3313f2011-10-18 20:13:57245// Return true if a character belongs to the ASCII subset as defined in
246// GLSL ES 1.0 spec section 3.1.
247static bool CharacterIsValidForGLES(unsigned char c) {
248 // Printing characters are valid except " $ ` @ \ ' DEL.
249 if (c >= 32 && c <= 126 &&
250 c != '"' &&
251 c != '$' &&
252 c != '`' &&
253 c != '@' &&
254 c != '\\' &&
255 c != '\'') {
256 return true;
257 }
258 // Horizontal tab, line feed, vertical tab, form feed, carriage return
259 // are also valid.
260 if (c >= 9 && c <= 13) {
261 return true;
262 }
263
264 return false;
265}
266
267static bool StringIsValidForGLES(const char* str) {
268 for (; *str; ++str) {
269 if (!CharacterIsValidForGLES(*str)) {
270 return false;
271 }
272 }
273 return true;
274}
275
[email protected]6217d392010-03-25 22:08:35276// This class prevents any GL errors that occur when it is in scope from
277// being reported to the client.
278class ScopedGLErrorSuppressor {
279 public:
[email protected]ab09b612013-03-11 22:11:51280 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30281 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35282 ~ScopedGLErrorSuppressor();
283 private:
[email protected]ab09b612013-03-11 22:11:51284 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30285 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35286 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
287};
288
[email protected]2b10c02d2014-01-29 16:43:02289// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35290// object goes out of scope. Also temporarily switches to using active texture
291// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02292class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35293 public:
[email protected]00c2cf92014-03-14 00:08:37294 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02295 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35296
297 private:
[email protected]ce296892013-10-24 22:04:36298 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02299 GLenum target_;
300 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35301};
302
303// Temporarily changes a decoder's bound render buffer and restore it when this
304// object goes out of scope.
305class ScopedRenderBufferBinder {
306 public:
[email protected]00c2cf92014-03-14 00:08:37307 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35308 ~ScopedRenderBufferBinder();
309
310 private:
[email protected]18e785a2013-10-09 03:29:41311 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35312 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
313};
314
315// Temporarily changes a decoder's bound frame buffer and restore it when this
316// object goes out of scope.
317class ScopedFrameBufferBinder {
318 public:
[email protected]00c2cf92014-03-14 00:08:37319 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35320 ~ScopedFrameBufferBinder();
321
322 private:
323 GLES2DecoderImpl* decoder_;
324 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
325};
326
[email protected]34ff8b0c2010-10-01 20:06:02327// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52328// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27329// if it is bound or enforce_internal_framebuffer is true. If internal is
330// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02331class ScopedResolvedFrameBufferBinder {
332 public:
[email protected]00c2cf92014-03-14 00:08:37333 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
334 bool enforce_internal_framebuffer,
335 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02336 ~ScopedResolvedFrameBufferBinder();
337
338 private:
339 GLES2DecoderImpl* decoder_;
340 bool resolve_and_bind_;
341 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
342};
343
[email protected]00c2cf92014-03-14 00:08:37344class ScopedModifyPixels {
345 public:
346 explicit ScopedModifyPixels(TextureRef* ref);
347 ~ScopedModifyPixels();
348
349 private:
350 TextureRef* ref_;
351};
352
353ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
354 if (ref_)
355 ref_->texture()->OnWillModifyPixels();
356}
357
358ScopedModifyPixels::~ScopedModifyPixels() {
359 if (ref_)
360 ref_->texture()->OnDidModifyPixels();
361}
362
363class ScopedRenderTo {
364 public:
365 explicit ScopedRenderTo(Framebuffer* framebuffer);
366 ~ScopedRenderTo();
367
368 private:
369 const Framebuffer* framebuffer_;
370};
371
372ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
373 : framebuffer_(framebuffer) {
374 if (framebuffer)
375 framebuffer_->OnWillRenderTo();
376}
377
378ScopedRenderTo::~ScopedRenderTo() {
379 if (framebuffer_)
380 framebuffer_->OnDidRenderTo();
381}
382
[email protected]6217d392010-03-25 22:08:35383// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35384class BackTexture {
[email protected]6217d392010-03-25 22:08:35385 public:
[email protected]ce296892013-10-24 22:04:36386 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35387 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35388
389 // Create a new render texture.
390 void Create();
391
392 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09393 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35394
395 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58396 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35397
398 // Destroy the render texture. This must be explicitly called before
399 // destroying this object.
400 void Destroy();
401
[email protected]97872062010-11-03 19:07:05402 // Invalidate the texture. This can be used when a context is lost and it is
403 // not possible to make it current in order to free the resource.
404 void Invalidate();
405
[email protected]6217d392010-03-25 22:08:35406 GLuint id() const {
407 return id_;
408 }
409
[email protected]d37231fa2010-04-09 21:16:02410 gfx::Size size() const {
411 return size_;
412 }
413
[email protected]6217d392010-03-25 22:08:35414 private:
[email protected]ff6493f2012-07-31 19:52:25415 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36416 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48417 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35418 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02419 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35420 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35421};
422
423// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35424class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35425 public:
[email protected]d5a28e452013-10-10 01:01:40426 explicit BackRenderbuffer(
427 RenderbufferManager* renderbuffer_manager,
428 MemoryTracker* memory_tracker,
429 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35430 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35431
432 // Create a new render buffer.
433 void Create();
434
435 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18436 bool AllocateStorage(const FeatureInfo* feature_info,
437 const gfx::Size& size,
438 GLenum format,
439 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35440
441 // Destroy the render buffer. This must be explicitly called before destroying
442 // this object.
443 void Destroy();
444
[email protected]97872062010-11-03 19:07:05445 // Invalidate the render buffer. This can be used when a context is lost and
446 // it is not possible to make it current in order to free the resource.
447 void Invalidate();
448
[email protected]6217d392010-03-25 22:08:35449 GLuint id() const {
450 return id_;
451 }
452
453 private:
[email protected]d5a28e452013-10-10 01:01:40454 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25455 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40456 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48457 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35458 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35459 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35460};
461
462// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35463class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35464 public:
[email protected]ed9f9cd2013-02-27 21:12:35465 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
466 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35467
468 // Create a new frame buffer.
469 void Create();
470
471 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35472 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35473
[email protected]b9363b22010-06-09 22:06:15474 // Attach a render buffer to a frame buffer. Note that this unbinds any
475 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35476 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35477
[email protected]6217d392010-03-25 22:08:35478 // Destroy the frame buffer. This must be explicitly called before destroying
479 // this object.
480 void Destroy();
481
[email protected]97872062010-11-03 19:07:05482 // Invalidate the frame buffer. This can be used when a context is lost and it
483 // is not possible to make it current in order to free the resource.
484 void Invalidate();
485
[email protected]6217d392010-03-25 22:08:35486 // See glCheckFramebufferStatusEXT.
487 GLenum CheckStatus();
488
489 GLuint id() const {
490 return id_;
491 }
492
493 private:
494 GLES2DecoderImpl* decoder_;
495 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35496 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35497};
[email protected]34ff8b0c2010-10-01 20:06:02498
[email protected]5a36dc132013-07-23 23:17:55499struct FenceCallback {
500 explicit FenceCallback()
501 : fence(gfx::GLFence::Create()) {
502 DCHECK(fence);
503 }
[email protected]5a36dc132013-07-23 23:17:55504 std::vector<base::Closure> callbacks;
505 scoped_ptr<gfx::GLFence> fence;
506};
507
[email protected]e3c4a9ab2014-03-31 09:07:02508class AsyncUploadTokenCompletionObserver
509 : public AsyncPixelTransferCompletionObserver {
510 public:
511 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
512 : async_upload_token_(async_upload_token) {
513 }
514
dcheng1f4d1d72014-10-21 16:21:58515 void DidComplete(const AsyncMemoryParams& mem_params) override {
dcheng6ef3c5552014-08-30 05:34:19516 DCHECK(mem_params.buffer().get());
[email protected]e3c4a9ab2014-03-31 09:07:02517 void* data = mem_params.GetDataAddress();
518 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
519 sync->SetAsyncUploadToken(async_upload_token_);
520 }
521
522 private:
dcheng1f4d1d72014-10-21 16:21:58523 ~AsyncUploadTokenCompletionObserver() override {}
[email protected]e3c4a9ab2014-03-31 09:07:02524
525 uint32 async_upload_token_;
526
527 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
528};
529
[email protected]43f28f832010-02-03 02:28:48530// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32531
[email protected]efc87712014-07-09 00:22:47532// static
533const unsigned int GLES2Decoder::kDefaultStencilMask =
534 static_cast<unsigned int>(-1);
535
[email protected]ddb1e5a2010-12-13 20:10:45536bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
537 uint32* service_texture_id) {
538 return false;
539}
540
[email protected]a3ded6d2010-10-19 06:44:39541GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06542 : initialized_(false),
543 debug_(false),
[email protected]1d82e822013-04-10 21:32:32544 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32545}
546
[email protected]3916c97e2010-02-25 03:20:50547GLES2Decoder::~GLES2Decoder() {
548}
549
[email protected]cac16542014-01-15 17:53:51550void GLES2Decoder::BeginDecoding() {}
551
552void GLES2Decoder::EndDecoding() {}
553
[email protected]f39f4b3f2010-05-12 17:04:08554// This class implements GLES2Decoder so we don't have to expose all the GLES2
555// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54556class GLES2DecoderImpl : public GLES2Decoder,
[email protected]828a3932014-04-02 14:43:13557 public FramebufferManager::TextureDetachObserver,
558 public ErrorStateClient {
[email protected]f39f4b3f2010-05-12 17:04:08559 public:
[email protected]aa7666122011-09-02 19:45:52560 explicit GLES2DecoderImpl(ContextGroup* group);
dcheng1f4d1d72014-10-21 16:21:58561 ~GLES2DecoderImpl() override;
[email protected]f39f4b3f2010-05-12 17:04:08562
[email protected]96449d2c2009-11-25 00:01:32563 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58564 Error DoCommand(unsigned int command,
565 unsigned int arg_count,
566 const void* args) override;
[email protected]96449d2c2009-11-25 00:01:32567
dcheng1f4d1d72014-10-21 16:21:58568 error::Error DoCommands(unsigned int num_commands,
569 const void* buffer,
570 int num_entries,
571 int* entries_processed) override;
vmiura8266ca72014-09-09 21:37:00572
vmiura1c2b1de2014-09-19 19:03:24573 template <bool DebugImpl>
574 error::Error DoCommandsImpl(unsigned int num_commands,
575 const void* buffer,
576 int num_entries,
577 int* entries_processed);
578
[email protected]96449d2c2009-11-25 00:01:32579 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58580 const char* GetCommandName(unsigned int command_id) const override;
[email protected]96449d2c2009-11-25 00:01:32581
582 // Overridden from GLES2Decoder.
dcheng1f4d1d72014-10-21 16:21:58583 bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
584 const scoped_refptr<gfx::GLContext>& context,
585 bool offscreen,
586 const gfx::Size& size,
587 const DisallowedFeatures& disallowed_features,
588 const std::vector<int32>& attribs) override;
589 void Destroy(bool have_context) override;
590 void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
591 void ProduceFrontBuffer(const Mailbox& mailbox) override;
592 bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
[email protected]9a5afa432011-07-22 18:16:39593 void UpdateParentTextureInfo();
dcheng1f4d1d72014-10-21 16:21:58594 bool MakeCurrent() override;
595 GLES2Util* GetGLES2Util() override { return &util_; }
596 gfx::GLContext* GetGLContext() override { return context_.get(); }
597 ContextGroup* GetContextGroup() override { return group_.get(); }
598 Capabilities GetCapabilities() override;
599 void RestoreState(const ContextState* prev_state) override;
[email protected]29a4d902013-02-26 20:18:06600
dcheng1f4d1d72014-10-21 16:21:58601 void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); }
602 void RestoreAllTextureUnitBindings(
mohan.reddy5e1b8952014-10-08 01:38:17603 const ContextState* prev_state) const override {
[email protected]5baa86bc2014-01-16 04:33:16604 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55605 }
dcheng1f4d1d72014-10-21 16:21:58606 void RestoreActiveTextureUnitBinding(unsigned int target) const override {
[email protected]4b2d2b262014-03-21 22:05:27607 state_.RestoreActiveTextureUnitBinding(target);
608 }
dcheng1f4d1d72014-10-21 16:21:58609 void RestoreBufferBindings() const override {
[email protected]29a4d902013-02-26 20:18:06610 state_.RestoreBufferBindings();
611 }
dcheng1f4d1d72014-10-21 16:21:58612 void RestoreGlobalState() const override { state_.RestoreGlobalState(NULL); }
613 void RestoreProgramBindings() const override {
[email protected]29a4d902013-02-26 20:18:06614 state_.RestoreProgramBindings();
615 }
dcheng1f4d1d72014-10-21 16:21:58616 void RestoreTextureUnitBindings(unsigned unit) const override {
[email protected]5baa86bc2014-01-16 04:33:16617 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06618 }
dcheng1f4d1d72014-10-21 16:21:58619 void RestoreFramebufferBindings() const override;
620 void RestoreRenderbufferBindings() override;
621 void RestoreTextureState(unsigned service_id) const override;
[email protected]29a4d902013-02-26 20:18:06622
dcheng1f4d1d72014-10-21 16:21:58623 void ClearAllAttributes() const override;
624 void RestoreAllAttributes() const override;
[email protected]cd2ef752014-02-12 23:16:03625
dcheng1f4d1d72014-10-21 16:21:58626 QueryManager* GetQueryManager() override { return query_manager_.get(); }
627 VertexArrayManager* GetVertexArrayManager() override {
[email protected]944b62f32012-09-27 02:20:46628 return vertex_array_manager_.get();
629 }
dcheng1f4d1d72014-10-21 16:21:58630 ImageManager* GetImageManager() override { return image_manager_.get(); }
revemancc241eb2014-11-11 03:30:37631 bool ProcessPendingQueries(bool did_finish) override;
dcheng1f4d1d72014-10-21 16:21:58632 bool HasMoreIdleWork() override;
633 void PerformIdleWork() override;
[email protected]43f28f832010-02-03 02:28:48634
dcheng1f4d1d72014-10-21 16:21:58635 void WaitForReadPixels(base::Closure callback) override;
[email protected]5a36dc132013-07-23 23:17:55636
dcheng1f4d1d72014-10-21 16:21:58637 void SetResizeCallback(
mohan.reddy5e1b8952014-10-08 01:38:17638 const base::Callback<void(gfx::Size, float)>& callback) override;
[email protected]22f320a2011-08-30 01:17:00639
dcheng1f4d1d72014-10-21 16:21:58640 Logger* GetLogger() override;
[email protected]cac16542014-01-15 17:53:51641
dcheng1f4d1d72014-10-21 16:21:58642 void BeginDecoding() override;
643 void EndDecoding() override;
[email protected]cac16542014-01-15 17:53:51644
dcheng1f4d1d72014-10-21 16:21:58645 ErrorState* GetErrorState() override;
646 const ContextState* GetContextState() override { return &state_; }
[email protected]1d82e822013-04-10 21:32:32647
dcheng1f4d1d72014-10-21 16:21:58648 void SetShaderCacheCallback(const ShaderCacheCallback& callback) override;
649 void SetWaitSyncPointCallback(const WaitSyncPointCallback& callback) override;
[email protected]22f320a2011-08-30 01:17:00650
dcheng1f4d1d72014-10-21 16:21:58651 AsyncPixelTransferManager* GetAsyncPixelTransferManager() override;
652 void ResetAsyncPixelTransferManagerForTest() override;
653 void SetAsyncPixelTransferManagerForTest(
mohan.reddy5e1b8952014-10-08 01:38:17654 AsyncPixelTransferManager* manager) override;
dcheng1f4d1d72014-10-21 16:21:58655 void SetIgnoreCachedStateForTest(bool ignore) override;
[email protected]69a8701e2013-03-07 21:31:09656 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59657
dcheng1f4d1d72014-10-21 16:21:58658 bool GetServiceTextureId(uint32 client_texture_id,
659 uint32* service_texture_id) override;
[email protected]43f28f832010-02-03 02:28:48660
dcheng1f4d1d72014-10-21 16:21:58661 uint32 GetTextureUploadCount() override;
662 base::TimeDelta GetTotalTextureUploadTime() override;
663 base::TimeDelta GetTotalProcessingCommandsTime() override;
664 void AddProcessingCommandsTime(base::TimeDelta) override;
[email protected]63b465922012-09-06 02:04:52665
[email protected]8e3e0662010-08-23 18:46:30666 // Restores the current state to the user's settings.
667 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30668
[email protected]297ca1c2011-06-20 23:08:46669 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
670 void ApplyDirtyState();
671
672 // These check the state of the currently bound framebuffer or the
673 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54674 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
675 // check with all attached and enabled color attachments.
676 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46677 bool BoundFramebufferHasDepthAttachment();
678 bool BoundFramebufferHasStencilAttachment();
679
dcheng1f4d1d72014-10-21 16:21:58680 error::ContextLostReason GetContextLostReason() override;
[email protected]38d139d2011-07-14 00:38:43681
[email protected]91c94eb2013-10-22 10:32:54682 // Overridden from FramebufferManager::TextureDetachObserver:
dcheng1f4d1d72014-10-21 16:21:58683 void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) override;
[email protected]91c94eb2013-10-22 10:32:54684
[email protected]828a3932014-04-02 14:43:13685 // Overriden from ErrorStateClient.
oetuaho37cc50e2014-10-31 11:19:20686 void OnContextLostError() override;
dcheng1f4d1d72014-10-21 16:21:58687 void OnOutOfMemoryError() override;
[email protected]828a3932014-04-02 14:43:13688
[email protected]8875a5f2014-06-27 08:33:47689 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
690 void EnsureRenderbufferBound();
691
[email protected]f42f05b2013-11-15 21:46:18692 // Helpers to facilitate calling into compatible extensions.
693 static void RenderbufferStorageMultisampleHelper(
694 const FeatureInfo* feature_info,
695 GLenum target,
696 GLsizei samples,
697 GLenum internal_format,
698 GLsizei width,
699 GLsizei height);
700
701 void BlitFramebufferHelper(GLint srcX0,
702 GLint srcY0,
703 GLint srcX1,
704 GLint srcY1,
705 GLint dstX0,
706 GLint dstY0,
707 GLint dstX1,
708 GLint dstY1,
709 GLbitfield mask,
710 GLenum filter);
[email protected]345ba902013-11-14 21:39:00711
[email protected]96449d2c2009-11-25 00:01:32712 private:
[email protected]70d34263c2013-01-09 00:27:45713 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02714 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35715 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35716
[email protected]c2f8c8402010-12-06 18:07:24717 // Initialize or re-initialize the shader translator.
718 bool InitializeShaderTranslator();
719
[email protected]302ce6d2011-07-07 23:28:11720 void UpdateCapabilities();
721
[email protected]ae51d192010-04-27 00:48:03722 // Helpers for the glGen and glDelete functions.
723 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
724 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
725 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
726 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
727 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
728 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
729 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
730 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
orglofchcad5a6742014-11-07 19:51:12731 bool GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
732 void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53733 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
734 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46735 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
736 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47737
[email protected]e3c4a9ab2014-03-31 09:07:02738 // Helper for async upload token completion notification callback.
739 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
740 uint32 sync_data_shm_id,
741 uint32 sync_data_shm_offset);
742
743
744
[email protected]70d34263c2013-01-09 00:27:45745 // Workarounds
746 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51747 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45748
[email protected]3916c97e2010-02-25 03:20:50749 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50750 BufferManager* buffer_manager() {
751 return group_->buffer_manager();
752 }
753
[email protected]a25fa872010-03-25 02:57:58754 RenderbufferManager* renderbuffer_manager() {
755 return group_->renderbuffer_manager();
756 }
757
758 FramebufferManager* framebuffer_manager() {
759 return group_->framebuffer_manager();
760 }
761
orglofchcad5a6742014-11-07 19:51:12762 ValuebufferManager* valuebuffer_manager() {
763 return group_->valuebuffer_manager();
764 }
765
[email protected]3916c97e2010-02-25 03:20:50766 ProgramManager* program_manager() {
767 return group_->program_manager();
768 }
769
770 ShaderManager* shader_manager() {
771 return group_->shader_manager();
772 }
773
[email protected]03cef9b2014-04-03 15:58:14774 ShaderTranslatorCache* shader_translator_cache() {
775 return group_->shader_translator_cache();
776 }
777
[email protected]29a4d902013-02-26 20:18:06778 const TextureManager* texture_manager() const {
779 return group_->texture_manager();
780 }
781
[email protected]3916c97e2010-02-25 03:20:50782 TextureManager* texture_manager() {
783 return group_->texture_manager();
784 }
785
[email protected]78b514b2012-05-01 21:50:59786 MailboxManager* mailbox_manager() {
787 return group_->mailbox_manager();
788 }
789
[email protected]b63f1d62014-07-18 15:40:59790 ImageManager* image_manager() { return image_manager_.get(); }
[email protected]09d50362012-10-18 20:54:37791
[email protected]944b62f32012-09-27 02:20:46792 VertexArrayManager* vertex_array_manager() {
793 return vertex_array_manager_.get();
794 }
795
[email protected]7989c9e2013-01-23 06:39:26796 MemoryTracker* memory_tracker() {
797 return group_->memory_tracker();
798 }
799
800 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
801 MemoryTracker* tracker = memory_tracker();
802 if (tracker) {
803 return tracker->EnsureGPUMemoryAvailable(estimated_size);
804 }
805 return true;
806 }
807
[email protected]34ff8b0c2010-10-01 20:06:02808 bool IsOffscreenBufferMultisampled() const {
809 return offscreen_target_samples_ > 1;
810 }
811
[email protected]ed9f9cd2013-02-27 21:12:35812 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49813 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03814 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35815 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47816 }
817
818 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49819 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07820 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47821 }
822
823 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35824 void RemoveTexture(GLuint client_id) {
825 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50826 }
[email protected]a93bb842010-02-16 23:03:47827
[email protected]d37231fa2010-04-09 21:16:02828 // Get the size (in pixels) of the currently bound frame buffer (either FBO
829 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30830 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02831
[email protected]9edc6b22010-12-23 02:00:26832 // Get the format of the currently bound frame buffer (either FBO or regular
833 // back buffer)
[email protected]68586372013-12-11 01:27:59834 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26835 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46836 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26837
[email protected]a93bb842010-02-16 23:03:47838 // Wrapper for CompressedTexImage2D commands.
839 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37840 GLenum target,
841 GLint level,
842 GLenum internal_format,
843 GLsizei width,
844 GLsizei height,
845 GLint border,
846 GLsizei image_size,
847 const void* data);
[email protected]a93bb842010-02-16 23:03:47848
[email protected]cadde4a2010-07-31 17:10:43849 // Wrapper for CompressedTexSubImage2D.
850 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37851 GLenum target,
852 GLint level,
853 GLint xoffset,
854 GLint yoffset,
855 GLsizei width,
856 GLsizei height,
857 GLenum format,
858 GLsizei imageSize,
859 const void * data);
[email protected]cadde4a2010-07-31 17:10:43860
861 // Wrapper for CopyTexImage2D.
862 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37863 GLenum target,
864 GLint level,
865 GLenum internal_format,
866 GLint x,
867 GLint y,
868 GLsizei width,
869 GLsizei height,
870 GLint border);
[email protected]cadde4a2010-07-31 17:10:43871
[email protected]6d792ee12013-05-15 00:40:56872 // Wrapper for SwapBuffers.
873 void DoSwapBuffers();
874
[email protected]cadde4a2010-07-31 17:10:43875 // Wrapper for CopyTexSubImage2D.
876 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37877 GLenum target,
878 GLint level,
879 GLint xoffset,
880 GLint yoffset,
881 GLint x,
882 GLint y,
883 GLsizei width,
884 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43885
[email protected]f598f422012-12-07 08:30:03886 // Validation for TexSubImage2D.
887 bool ValidateTexSubImage2D(
888 error::Error* error,
889 const char* function_name,
890 GLenum target,
891 GLint level,
892 GLint xoffset,
893 GLint yoffset,
894 GLsizei width,
895 GLsizei height,
896 GLenum format,
897 GLenum type,
898 const void * data);
899
[email protected]cadde4a2010-07-31 17:10:43900 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03901 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37902 GLenum target,
903 GLint level,
904 GLint xoffset,
905 GLint yoffset,
906 GLsizei width,
907 GLsizei height,
908 GLenum format,
909 GLenum type,
910 const void * data);
[email protected]cadde4a2010-07-31 17:10:43911
[email protected]32145a92012-12-17 09:01:59912 // Extra validation for async tex(Sub)Image2D.
913 bool ValidateAsyncTransfer(
914 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47915 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59916 GLenum target,
917 GLint level,
918 const void * data);
919
[email protected]e51bdf32011-11-23 22:21:46920 // Wrapper for TexImageIOSurface2DCHROMIUM.
921 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37922 GLenum target,
923 GLsizei width,
924 GLsizei height,
925 GLuint io_surface_id,
926 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46927
[email protected]43410e92012-04-20 17:06:28928 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37929 GLenum target,
930 GLuint source_id,
931 GLuint target_id,
932 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54933 GLenum internal_format,
934 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28935
[email protected]97dc7cbe2011-12-06 17:26:17936 // Wrapper for TexStorage2DEXT.
937 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37938 GLenum target,
939 GLint levels,
940 GLenum internal_format,
941 GLsizei width,
942 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17943
[email protected]78b514b2012-05-01 21:50:59944 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22945 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
946 const GLbyte* key);
947 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
948 GLenum target, const GLbyte* data);
949
[email protected]78b514b2012-05-01 21:50:59950 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22951 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
952 GLuint client_id);
[email protected]78b514b2012-05-01 21:50:59953
orglofchcad5a6742014-11-07 19:51:12954 bool DoIsValuebufferCHROMIUM(GLuint client_id);
955 void DoBindValueBufferCHROMIUM(GLenum target, GLuint valuebuffer);
956 void DoSubscribeValueCHROMIUM(GLenum target, GLenum subscription);
957 void DoPopulateSubscribedValuesCHROMIUM(GLenum target);
958 void DoUniformValueBufferCHROMIUM(GLint location,
959 GLenum target,
960 GLenum subscription);
961
[email protected]09d50362012-10-18 20:54:37962 void DoBindTexImage2DCHROMIUM(
963 GLenum target,
964 GLint image_id);
965 void DoReleaseTexImage2DCHROMIUM(
966 GLenum target,
967 GLint image_id);
968
[email protected]94307712012-11-16 23:26:11969 void DoTraceEndCHROMIUM(void);
970
[email protected]2f143d482013-03-14 18:04:49971 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
972
[email protected]a6a09f852014-05-23 13:05:03973 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
974
kkinnunen337d59632014-08-26 10:19:57975 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
976 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
977
[email protected]ed9f9cd2013-02-27 21:12:35978 // Creates a Program for the given program.
979 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57980 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35981 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47982 }
983
[email protected]07f54fcc2009-12-22 02:46:30984 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35985 Program* GetProgram(GLuint client_id) {
986 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46987 }
[email protected]07f54fcc2009-12-22 02:46:30988
[email protected]cae20172012-12-07 00:06:19989#if defined(NDEBUG)
990 void LogClientServiceMapping(
991 const char* /* function_name */,
992 GLuint /* client_id */,
993 GLuint /* service_id */) {
994 }
995 template<typename T>
996 void LogClientServiceForInfo(
997 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
998 }
999#else
1000 void LogClientServiceMapping(
1001 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:261002 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:471003 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
1004 << ": client_id = " << client_id
1005 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:261006 }
[email protected]cae20172012-12-07 00:06:191007 }
1008 template<typename T>
1009 void LogClientServiceForInfo(
1010 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:261011 if (info) {
[email protected]cae20172012-12-07 00:06:191012 LogClientServiceMapping(function_name, client_id, info->service_id());
1013 }
1014 }
1015#endif
1016
[email protected]6b8cf1a2010-05-06 16:13:581017 // Gets the program info for the given program. If it's not a program
1018 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:351019 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:581020 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421021 Program* program = GetProgram(client_id);
1022 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351023 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511024 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431025 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581026 } else {
[email protected]ab09b612013-03-11 22:11:511027 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581028 }
1029 }
[email protected]df37b9932013-03-08 05:21:421030 LogClientServiceForInfo(program, client_id, function_name);
1031 return program;
[email protected]6b8cf1a2010-05-06 16:13:581032 }
1033
1034
[email protected]ed9f9cd2013-02-27 21:12:351035 // Creates a Shader for the given shader.
1036 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571037 GLuint client_id,
1038 GLuint service_id,
1039 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351040 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571041 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311042 }
1043
1044 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351045 Shader* GetShader(GLuint client_id) {
1046 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311047 }
1048
[email protected]6b8cf1a2010-05-06 16:13:581049 // Gets the shader info for the given shader. If it's not a shader generates a
1050 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351051 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581052 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421053 Shader* shader = GetShader(client_id);
1054 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351055 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511056 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431057 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581058 } else {
[email protected]ab09b612013-03-11 22:11:511059 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431060 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581061 }
1062 }
[email protected]df37b9932013-03-08 05:21:421063 LogClientServiceForInfo(shader, client_id, function_name);
1064 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581065 }
1066
[email protected]a93bb842010-02-16 23:03:471067 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351068 void CreateBuffer(GLuint client_id, GLuint service_id) {
1069 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471070 }
1071
[email protected]07f54fcc2009-12-22 02:46:301072 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211073 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071074 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1075 return buffer;
[email protected]1d32bc82010-01-13 22:06:461076 }
[email protected]07f54fcc2009-12-22 02:46:301077
[email protected]a93bb842010-02-16 23:03:471078 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1079 // on glDeleteBuffers so we can make sure the user does not try to render
1080 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351081 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471082
[email protected]a25fa872010-03-25 02:57:581083 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351084 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1085 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581086 }
1087
1088 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061089 Framebuffer* GetFramebuffer(GLuint client_id) {
1090 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581091 }
1092
1093 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351094 void RemoveFramebuffer(GLuint client_id) {
1095 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581096 }
1097
1098 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351099 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1100 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031101 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581102 }
1103
1104 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271105 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1106 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581107 }
1108
1109 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351110 void RemoveRenderbuffer(GLuint client_id) {
1111 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581112 }
1113
orglofchcad5a6742014-11-07 19:51:121114 // Creates a valuebuffer info for the given valuebuffer.
1115 void CreateValuebuffer(GLuint client_id) {
1116 return valuebuffer_manager()->CreateValuebuffer(client_id);
1117 }
1118
1119 // Gets the valuebuffer info for a given valuebuffer.
1120 Valuebuffer* GetValuebuffer(GLuint client_id) {
1121 return valuebuffer_manager()->GetValuebuffer(client_id);
1122 }
1123
1124 // Removes the valuebuffer info for the given valuebuffer.
1125 void RemoveValuebuffer(GLuint client_id) {
1126 valuebuffer_manager()->RemoveValuebuffer(client_id);
1127 }
1128
[email protected]944b62f32012-09-27 02:20:461129 // Gets the vertex attrib manager for the given vertex array.
1130 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1131 VertexAttribManager* info =
1132 vertex_array_manager()->GetVertexAttribManager(client_id);
1133 return info;
1134 }
1135
1136 // Removes the vertex attrib manager for the given vertex array.
1137 void RemoveVertexAttribManager(GLuint client_id) {
1138 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1139 }
1140
1141 // Creates a vertex attrib manager for the given vertex array.
[email protected]da364812014-05-09 21:39:481142 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1143 GLuint client_id,
1144 GLuint service_id,
1145 bool client_visible) {
1146 return vertex_array_manager()->CreateVertexAttribManager(
1147 client_id, service_id, group_->max_vertex_attribs(), client_visible);
[email protected]944b62f32012-09-27 02:20:461148 }
1149
[email protected]258a3313f2011-10-18 20:13:571150 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331151 void DoBindUniformLocationCHROMIUM(
1152 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571153
[email protected]558847a2010-03-24 07:02:541154 error::Error GetAttribLocationHelper(
1155 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1156 const std::string& name_str);
1157
1158 error::Error GetUniformLocationHelper(
1159 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1160 const std::string& name_str);
1161
[email protected]3916c97e2010-02-25 03:20:501162 // Helper for glShaderSource.
1163 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031164 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301165
[email protected]0d6bfdc2011-11-02 01:32:201166 // Clear any textures used by the current program.
1167 bool ClearUnclearedTextures();
1168
[email protected]0d6bfdc2011-11-02 01:32:201169 // Clears any uncleared attachments attached to the given frame buffer.
1170 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061171 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281172
[email protected]0d6bfdc2011-11-02 01:32:201173 // overridden from GLES2Decoder
dcheng1f4d1d72014-10-21 16:21:581174 bool ClearLevel(unsigned service_id,
1175 unsigned bind_target,
1176 unsigned target,
1177 int level,
1178 unsigned internal_format,
1179 unsigned format,
1180 unsigned type,
1181 int width,
1182 int height,
1183 bool is_texture_immutable) override;
[email protected]0d6bfdc2011-11-02 01:32:201184
[email protected]c007aa02010-09-02 22:22:401185 // Restore all GL state that affects clearing.
1186 void RestoreClearState();
1187
[email protected]3a2e7c7b2010-08-06 01:12:281188 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461189 // Returns: true if glEnable/glDisable should actually be called.
1190 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281191
[email protected]0d6bfdc2011-11-02 01:32:201192 // Check that the currently bound framebuffers are valid.
1193 // Generates GL error if not.
1194 bool CheckBoundFramebuffersValid(const char* func_name);
1195
[email protected]2ea5950d2014-07-09 18:20:341196 // Check that the currently bound read framebuffer has a color image
1197 // attached. Generates GL error if not.
1198 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1199
zmo383512cf2014-10-14 00:11:001200 // Check that the currently bound read framebuffer's color image
1201 // isn't the target texture of the glCopyTex{Sub}Image2D.
1202 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
1203
[email protected]0d6bfdc2011-11-02 01:32:201204 // Check if a framebuffer meets our requirements.
1205 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351206 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201207 GLenum target,
1208 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271209
orglofchcad5a6742014-11-07 19:51:121210 // Check if the current valuebuffer exists and is valid. If not generates
1211 // the appropriate GL error. Returns true if the current valuebuffer is in
1212 // a usable state.
1213 bool CheckCurrentValuebuffer(const char* function_name);
1214
1215 // Check if the current valuebuffer exists and is valiud and that the
1216 // value buffer is actually subscribed to the given subscription
1217 bool CheckCurrentValuebufferForSubscription(GLenum subscription,
1218 const char* function_name);
1219
1220 // Check if the location can be used for the given subscription target. If not
1221 // generates the appropriate GL error. Returns true if the location is usable
1222 bool CheckSubscriptionTarget(GLint location,
1223 GLenum subscription,
1224 const char* function_name);
1225
[email protected]939e7362010-05-13 20:49:101226 // Checks if the current program exists and is valid. If not generates the
1227 // appropriate GL error. Returns true if the current program is in a usable
1228 // state.
1229 bool CheckCurrentProgram(const char* function_name);
1230
1231 // Checks if the current program exists and is valid and that location is not
1232 // -1. If the current program is not valid generates the appropriate GL
1233 // error. Returns true if the current program is in a usable state and
1234 // location is not -1.
1235 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1236
zmof9a81360f2014-10-17 00:06:141237 // Checks if the current program samples a texture that is also the color
1238 // image of the current bound framebuffer, i.e., the source and destination
1239 // of the draw operation are the same.
1240 bool CheckDrawingFeedbackLoops();
1241
orglofchcad5a6742014-11-07 19:51:121242 // Checks if |api_type| is valid for the given uniform
1243 // If the api type is not valid generates the appropriate GL
1244 // error. Returns true if |api_type| is valid for the uniform
1245 bool CheckUniformForApiType(const Program::UniformInfo* info,
1246 const char* function_name,
1247 Program::UniformApiType api_type);
1248
[email protected]939e7362010-05-13 20:49:101249 // Gets the type of a uniform for a location in the current program. Sets GL
1250 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361251 // program is valid and the location exists. Adjusts count so it
1252 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131253 bool PrepForSetUniformByLocation(GLint fake_location,
1254 const char* function_name,
1255 Program::UniformApiType api_type,
1256 GLint* real_location,
1257 GLenum* type,
1258 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101259
[email protected]b177ae22011-11-01 03:29:111260 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021261 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111262
[email protected]b273e432010-04-12 17:23:581263 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1264 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1265
[email protected]ac77603c72013-03-08 13:52:061266 // Helper for glGetVertexAttrib
1267 void GetVertexAttribHelper(
1268 const VertexAttrib* attrib, GLenum pname, GLint* param);
1269
[email protected]96449d2c2009-11-25 00:01:321270 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031271 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321272
1273 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031274 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321275
[email protected]3916c97e2010-02-25 03:20:501276 // Wrapper for glActiveTexture
1277 void DoActiveTexture(GLenum texture_unit);
1278
[email protected]ae51d192010-04-27 00:48:031279 // Wrapper for glAttachShader
1280 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1281
[email protected]96449d2c2009-11-25 00:01:321282 // Wrapper for glBindBuffer since we need to track the current targets.
1283 void DoBindBuffer(GLenum target, GLuint buffer);
1284
[email protected]86093972010-03-11 00:13:561285 // Wrapper for glBindFramebuffer since we need to track the current targets.
1286 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1287
1288 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1289 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1290
[email protected]a93bb842010-02-16 23:03:471291 // Wrapper for glBindTexture since we need to track the current targets.
1292 void DoBindTexture(GLenum target, GLuint texture);
1293
[email protected]944b62f32012-09-27 02:20:461294 // Wrapper for glBindVertexArrayOES
1295 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571296 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461297
[email protected]49cabed2013-11-13 18:15:181298 // Wrapper for glBlitFramebufferCHROMIUM.
1299 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301300 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1301 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1302 GLbitfield mask, GLenum filter);
1303
[email protected]36cef8ce2010-03-16 07:34:451304 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111305 void DoBufferSubData(
1306 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1307
[email protected]36cef8ce2010-03-16 07:34:451308 // Wrapper for glCheckFramebufferStatus
1309 GLenum DoCheckFramebufferStatus(GLenum target);
1310
[email protected]3a03a8f2011-03-19 00:51:271311 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081312 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271313
[email protected]88a61bf2012-10-27 13:00:421314 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421315 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251316 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281317
[email protected]45bf5152010-02-12 00:11:311318 // Wrapper for glCompileShader.
1319 void DoCompileShader(GLuint shader);
1320
[email protected]ae51d192010-04-27 00:48:031321 // Wrapper for glDetachShader
1322 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1323
[email protected]3a2e7c7b2010-08-06 01:12:281324 // Wrapper for glDisable
1325 void DoDisable(GLenum cap);
1326
[email protected]07f54fcc2009-12-22 02:46:301327 // Wrapper for glDisableVertexAttribArray.
1328 void DoDisableVertexAttribArray(GLuint index);
1329
[email protected]60f22d32012-12-12 00:31:581330 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1331 // attachments.
1332 void DoDiscardFramebufferEXT(GLenum target,
1333 GLsizei numAttachments,
1334 const GLenum* attachments);
1335
[email protected]3a2e7c7b2010-08-06 01:12:281336 // Wrapper for glEnable
1337 void DoEnable(GLenum cap);
1338
[email protected]07f54fcc2009-12-22 02:46:301339 // Wrapper for glEnableVertexAttribArray.
1340 void DoEnableVertexAttribArray(GLuint index);
1341
[email protected]882ba1e22012-03-08 19:02:531342 // Wrapper for glFinish.
1343 void DoFinish();
1344
1345 // Wrapper for glFlush.
1346 void DoFlush();
1347
[email protected]36cef8ce2010-03-16 07:34:451348 // Wrapper for glFramebufferRenderbufffer.
1349 void DoFramebufferRenderbuffer(
1350 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1351 GLuint renderbuffer);
1352
1353 // Wrapper for glFramebufferTexture2D.
1354 void DoFramebufferTexture2D(
1355 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1356 GLint level);
1357
[email protected]7d3c36e2013-07-12 14:13:161358 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1359 void DoFramebufferTexture2DMultisample(
1360 GLenum target, GLenum attachment, GLenum textarget,
1361 GLuint texture, GLint level, GLsizei samples);
1362
1363 // Common implementation for both DoFramebufferTexture2D wrappers.
1364 void DoFramebufferTexture2DCommon(const char* name,
1365 GLenum target, GLenum attachment, GLenum textarget,
1366 GLuint texture, GLint level, GLsizei samples);
1367
[email protected]a93bb842010-02-16 23:03:471368 // Wrapper for glGenerateMipmap
1369 void DoGenerateMipmap(GLenum target);
1370
[email protected]7d3c36e2013-07-12 14:13:161371 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1372 // to account for different pname values defined in different extension
1373 // variants.
1374 GLenum AdjustGetPname(GLenum pname);
1375
[email protected]b273e432010-04-12 17:23:581376 // Wrapper for DoGetBooleanv.
1377 void DoGetBooleanv(GLenum pname, GLboolean* params);
1378
1379 // Wrapper for DoGetFloatv.
1380 void DoGetFloatv(GLenum pname, GLfloat* params);
1381
[email protected]36cef8ce2010-03-16 07:34:451382 // Wrapper for glGetFramebufferAttachmentParameteriv.
1383 void DoGetFramebufferAttachmentParameteriv(
1384 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1385
[email protected]a0c3e972010-04-21 00:49:131386 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581387 void DoGetIntegerv(GLenum pname, GLint* params);
1388
[email protected]29a9eb52010-04-13 09:04:231389 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061390 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231391 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1392
[email protected]17cfbe0e2013-03-07 01:26:081393 // Wrapper for glGetBufferParameteriv.
1394 void DoGetBufferParameteriv(
1395 GLenum target, GLenum pname, GLint* params);
1396
[email protected]a0c3e972010-04-21 00:49:131397 // Wrapper for glGetProgramiv.
1398 void DoGetProgramiv(
1399 GLuint program_id, GLenum pname, GLint* params);
1400
[email protected]36cef8ce2010-03-16 07:34:451401 // Wrapper for glRenderbufferParameteriv.
1402 void DoGetRenderbufferParameteriv(
1403 GLenum target, GLenum pname, GLint* params);
1404
[email protected]ddd968b82010-03-02 00:44:291405 // Wrapper for glGetShaderiv
1406 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1407
[email protected]4c6f5462014-03-05 00:26:561408 // Wrappers for glGetTexParameter.
1409 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1410 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1411 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1412
[email protected]b1122982010-05-17 23:04:241413 // Wrappers for glGetVertexAttrib.
1414 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1415 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1416
[email protected]1958e0e2010-04-22 05:17:151417 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241418 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151419 bool DoIsBuffer(GLuint client_id);
1420 bool DoIsFramebuffer(GLuint client_id);
1421 bool DoIsProgram(GLuint client_id);
1422 bool DoIsRenderbuffer(GLuint client_id);
1423 bool DoIsShader(GLuint client_id);
1424 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461425 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151426
[email protected]07f54fcc2009-12-22 02:46:301427 // Wrapper for glLinkProgram
1428 void DoLinkProgram(GLuint program);
1429
[email protected]36cef8ce2010-03-16 07:34:451430 // Wrapper for glRenderbufferStorage.
1431 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031432 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451433
[email protected]49cabed2013-11-13 18:15:181434 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1435 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301436 GLenum target, GLsizei samples, GLenum internalformat,
1437 GLsizei width, GLsizei height);
1438
[email protected]49cabed2013-11-13 18:15:181439 // Handler for glRenderbufferStorageMultisampleEXT
1440 // (multisampled_render_to_texture).
1441 void DoRenderbufferStorageMultisampleEXT(
1442 GLenum target, GLsizei samples, GLenum internalformat,
1443 GLsizei width, GLsizei height);
1444
1445 // Common validation for multisample extensions.
1446 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1447 GLenum internalformat,
1448 GLsizei width,
1449 GLsizei height);
1450
[email protected]4a4c18b2013-09-13 22:50:101451 // Verifies that the currently bound multisample renderbuffer is valid
1452 // Very slow! Only done on platforms with driver bugs that return invalid
1453 // buffers under memory pressure
1454 bool VerifyMultisampleRenderbufferIntegrity(
1455 GLuint renderbuffer, GLenum format);
1456
[email protected]b273e432010-04-12 17:23:581457 // Wrapper for glReleaseShaderCompiler.
1458 void DoReleaseShaderCompiler() { }
1459
[email protected]3916c97e2010-02-25 03:20:501460 // Wrappers for glTexParameter functions.
1461 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1462 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1463 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1464 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1465
1466 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1467 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121468 void DoUniform1i(GLint fake_location, GLint v0);
1469 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1470 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1471 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1472 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101473
1474 // Wrappers for glUniformfv because some drivers don't correctly accept
1475 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121476 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1477 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1478 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1479 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501480
[email protected]43c2f1f2011-03-25 18:35:361481 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121482 GLint fake_location, GLsizei count, GLboolean transpose,
1483 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361484 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121485 GLint fake_location, GLsizei count, GLboolean transpose,
1486 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361487 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121488 GLint fake_location, GLsizei count, GLboolean transpose,
1489 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361490
[email protected]af6380962012-11-29 23:24:131491 bool SetVertexAttribValue(
1492 const char* function_name, GLuint index, const GLfloat* value);
1493
[email protected]b1122982010-05-17 23:04:241494 // Wrappers for glVertexAttrib??
1495 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1496 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1497 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1498 void DoVertexAttrib4f(
1499 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1500 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1501 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1502 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1503 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1504
[email protected]43410e92012-04-20 17:06:281505 // Wrapper for glViewport
1506 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1507
[email protected]07f54fcc2009-12-22 02:46:301508 // Wrapper for glUseProgram
1509 void DoUseProgram(GLuint program);
1510
[email protected]ae51d192010-04-27 00:48:031511 // Wrapper for glValidateProgram.
1512 void DoValidateProgram(GLuint program_client_id);
1513
[email protected]d2a0e1a2012-08-12 02:25:011514 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1515 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1516 void DoPopGroupMarkerEXT(void);
1517
[email protected]4e8a5b122010-05-08 22:00:101518 // Gets the number of values that will be returned by glGetXXX. Returns
1519 // false if pname is unknown.
1520 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1521
[email protected]07f54fcc2009-12-22 02:46:301522 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431523 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101524 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1525 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301526
[email protected]c13e1da62011-09-09 21:48:301527 // Returns true if successful, simulated will be true if attrib0 was
1528 // simulated.
[email protected]c6aef902012-02-14 03:31:421529 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431530 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231531 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241532
[email protected]91c94eb2013-10-22 10:32:541533 // If an image is bound to texture, this will call Will/DidUseTexImage
1534 // if needed.
1535 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1536 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1537
1538 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111539 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541540 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501541
[email protected]8fbedc02010-11-18 18:43:401542 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421543 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431544 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421545 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401546 void RestoreStateForSimulatedFixedAttribs();
1547
[email protected]c6aef902012-02-14 03:31:421548 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101549 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421550 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431551 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421552 bool instanced, GLenum mode, GLint first, GLsizei count,
1553 GLsizei primcount);
1554 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431555 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421556 bool instanced, GLenum mode, GLsizei count, GLenum type,
1557 int32 offset, GLsizei primcount);
1558
[email protected]61eeb33f2011-07-26 15:30:311559 GLenum GetBindTargetForSamplerType(GLenum type) {
1560 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461561 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1562 switch (type) {
1563 case GL_SAMPLER_2D:
1564 return GL_TEXTURE_2D;
1565 case GL_SAMPLER_CUBE:
1566 return GL_TEXTURE_CUBE_MAP;
1567 case GL_SAMPLER_EXTERNAL_OES:
1568 return GL_TEXTURE_EXTERNAL_OES;
1569 case GL_SAMPLER_2D_RECT_ARB:
1570 return GL_TEXTURE_RECTANGLE_ARB;
1571 }
1572
1573 NOTREACHED();
1574 return 0;
[email protected]61eeb33f2011-07-26 15:30:311575 }
1576
[email protected]8e3e0662010-08-23 18:46:301577 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061578 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1579 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301580 switch (target) {
1581 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451582 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341583 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301584 break;
[email protected]ebfb73c2012-08-15 02:37:451585 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341586 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301587 break;
1588 default:
1589 NOTREACHED();
1590 break;
1591 }
[email protected]4d8f0dd2013-03-09 14:37:061592 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301593 }
1594
[email protected]ed9f9cd2013-02-27 21:12:351595 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201596 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271597 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201598 switch (target) {
1599 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111600 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201601 break;
1602 default:
1603 NOTREACHED();
1604 break;
1605 }
[email protected]ee2a79c32013-03-10 03:50:271606 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201607 }
1608
[email protected]f7b85372010-02-03 01:11:371609 // Validates the program and location for a glGetUniform call and returns
1610 // a SizeResult setup to receive the result. Returns true if glGetUniform
1611 // should be called.
1612 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121613 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371614 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121615 error::Error* error, GLint* real_location, GLuint* service_id,
1616 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371617
jbauman7a059312014-10-16 19:30:541618 void MaybeExitOnContextLost();
dcheng1f4d1d72014-10-21 16:21:581619 bool WasContextLost() override;
1620 bool WasContextLostByRobustnessExtension() override;
1621 void LoseContext(uint32 reset_status) override;
[email protected]38d139d2011-07-14 00:38:431622
[email protected]e51bdf32011-11-23 22:21:461623#if defined(OS_MACOSX)
1624 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1625#endif
1626
[email protected]ad84a3a2012-06-08 21:42:431627 bool ValidateCompressedTexDimensions(
1628 const char* function_name,
1629 GLint level, GLsizei width, GLsizei height, GLenum format);
1630 bool ValidateCompressedTexFuncData(
1631 const char* function_name,
1632 GLsizei width, GLsizei height, GLenum format, size_t size);
1633 bool ValidateCompressedTexSubDimensions(
1634 const char* function_name,
1635 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1636 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351637 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431638
[email protected]ab09b612013-03-11 22:11:511639 void RenderWarning(const char* filename, int line, const std::string& msg);
1640 void PerformanceWarning(
1641 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011642
[email protected]62e155e2012-10-23 22:43:151643 const FeatureInfo::FeatureFlags& features() const {
1644 return feature_info_->feature_flags();
1645 }
1646
1647 const FeatureInfo::Workarounds& workarounds() const {
1648 return feature_info_->workarounds();
1649 }
1650
[email protected]a7266a92012-06-28 02:11:081651 bool ShouldDeferDraws() {
1652 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341653 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081654 surface_->DeferDraws();
1655 }
1656
[email protected]09e17272012-11-30 10:30:441657 bool ShouldDeferReads() {
1658 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341659 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441660 surface_->DeferDraws();
1661 }
1662
[email protected]c76fe672013-12-13 23:30:221663 error::Error WillAccessBoundFramebufferForDraw() {
1664 if (ShouldDeferDraws())
1665 return error::kDeferCommandUntilLater;
1666 if (!offscreen_target_frame_buffer_.get() &&
1667 !framebuffer_state_.bound_draw_framebuffer.get() &&
1668 !surface_->SetBackbufferAllocation(true))
1669 return error::kLostContext;
1670 return error::kNoError;
1671 }
1672
1673 error::Error WillAccessBoundFramebufferForRead() {
1674 if (ShouldDeferReads())
1675 return error::kDeferCommandUntilLater;
1676 if (!offscreen_target_frame_buffer_.get() &&
1677 !framebuffer_state_.bound_read_framebuffer.get() &&
1678 !surface_->SetBackbufferAllocation(true))
1679 return error::kLostContext;
1680 return error::kNoError;
1681 }
1682
vmiura8266ca72014-09-09 21:37:001683 // Set remaining commands to process to 0 to force DoCommands to return
1684 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1685 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1686
[email protected]5a36dc132013-07-23 23:17:551687 void ProcessPendingReadPixels();
1688 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1689
[email protected]96449d2c2009-11-25 00:01:321690 // Generate a member function prototype for each command in an automated and
1691 // typesafe way.
vmiuracd108592014-09-08 14:36:341692#define GLES2_CMD_OP(name) \
1693 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321694
1695 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1696
1697 #undef GLES2_CMD_OP
1698
[email protected]2f2d7042010-04-14 21:45:581699 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381700 scoped_refptr<gfx::GLSurface> surface_;
1701 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021702
[email protected]a3ded6d2010-10-19 06:44:391703 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351704 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391705
[email protected]1d82e822013-04-10 21:32:321706 DebugMarkerManager debug_marker_manager_;
1707 Logger logger_;
1708
[email protected]e259eb412012-10-13 05:47:241709 // All the state for this context.
1710 ContextState state_;
1711
[email protected]34ff8b0c2010-10-01 20:06:021712 // Current width and height of the offscreen frame buffer.
1713 gfx::Size offscreen_size_;
1714
[email protected]96449d2c2009-11-25 00:01:321715 // Util to help with GL.
1716 GLES2Util util_;
1717
[email protected]43410e92012-04-20 17:06:281718 // unpack flip y as last set by glPixelStorei
1719 bool unpack_flip_y_;
1720
[email protected]6c75c712012-06-19 15:43:171721 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281722 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171723 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281724
[email protected]b1122982010-05-17 23:04:241725 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1726 GLuint attrib_0_buffer_id_;
1727
1728 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131729 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241730
[email protected]fc753442011-02-04 19:49:491731 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1732 bool attrib_0_buffer_matches_value_;
1733
[email protected]b1122982010-05-17 23:04:241734 // The size of attrib 0.
1735 GLsizei attrib_0_size_;
1736
[email protected]8fbedc02010-11-18 18:43:401737 // The buffer used to simulate GL_FIXED attribs.
1738 GLuint fixed_attrib_buffer_id_;
1739
1740 // The size of fiixed attrib buffer.
1741 GLsizei fixed_attrib_buffer_size_;
1742
[email protected]b9363b22010-06-09 22:06:151743 // The offscreen frame buffer that the client renders to. With EGL, the
1744 // depth and stencil buffers are separate. With regular GL there is a single
1745 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1746 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351747 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1748 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1749 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1750 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1751 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021752 GLenum offscreen_target_color_format_;
1753 GLenum offscreen_target_depth_format_;
1754 GLenum offscreen_target_stencil_format_;
1755 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561756 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351757
[email protected]de26b3c2011-08-03 21:54:271758 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351759 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1760 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491761 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351762 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271763
1764 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351765 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1766 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051767 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351768
[email protected]882ba1e22012-03-08 19:02:531769 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531770
[email protected]944b62f32012-09-27 02:20:461771 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1772
[email protected]b63f1d62014-07-18 15:40:591773 scoped_ptr<ImageManager> image_manager_;
1774
[email protected]729c0b42013-05-26 02:05:071775 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001776
[email protected]840a7e462013-02-27 01:29:511777 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481778
[email protected]e3932abb2013-03-13 00:01:371779 ShaderCacheCallback shader_cache_callback_;
1780
[email protected]85a4ac22013-05-31 01:58:471781 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421782
[email protected]32fe9aa2011-01-21 23:47:131783 // The format of the back buffer_
1784 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461785 bool back_buffer_has_depth_;
1786 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131787
achaulkcf5316f2014-09-26 19:28:421788 bool surfaceless_;
1789
[email protected]60f22d32012-12-12 00:31:581790 // Backbuffer attachments that are currently undefined.
1791 uint32 backbuffer_needs_clear_bits_;
1792
[email protected]a6a09f852014-05-23 13:05:031793 // The current decoder error communicates the decoder error through command
1794 // processing functions that do not return the error value. Should be set only
1795 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561796 error::Error current_decoder_error_;
1797
[email protected]b1d2dcb2010-05-17 19:24:181798 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041799 scoped_refptr<ShaderTranslator> vertex_translator_;
1800 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181801
[email protected]e82fb792011-09-22 00:33:291802 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411803
[email protected]915a59a12010-09-30 21:29:111804 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051805 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351806 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051807
[email protected]65225772011-05-12 21:10:241808 int frame_number_;
1809
vmiura8266ca72014-09-09 21:37:001810 // Number of commands remaining to be processed in DoCommands().
1811 int commands_to_process_;
1812
[email protected]706b69f2012-07-27 04:59:301813 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431814 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221815 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431816 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431817
[email protected]f0d74742011-10-03 16:31:041818 // These flags are used to override the state of the shared feature_info_
1819 // member. Because the same FeatureInfo instance may be shared among many
1820 // contexts, the assumptions on the availablity of extensions in WebGL
1821 // contexts may be broken. These flags override the shared state to preserve
1822 // WebGL semantics.
1823 bool force_webgl_glsl_validation_;
1824 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491825 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131826 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061827 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041828
[email protected]062c38b2012-01-18 03:25:101829 bool compile_shader_always_succeeds_;
1830
[email protected]828a3932014-04-02 14:43:131831 // An optional behaviour to lose the context and group when OOM.
1832 bool lose_context_when_out_of_memory_;
1833
[email protected]cae20172012-12-07 00:06:191834 // Log extra info.
1835 bool service_logging_;
1836
[email protected]e51bdf32011-11-23 22:21:461837#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531838 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461839 TextureToIOSurfaceMap texture_to_io_surface_map_;
1840#endif
1841
[email protected]43410e92012-04-20 17:06:281842 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1843
[email protected]1868a342012-11-07 15:56:021844 // Cached values of the currently assigned viewport dimensions.
1845 GLsizei viewport_max_width_;
1846 GLsizei viewport_max_height_;
1847
[email protected]63b465922012-09-06 02:04:521848 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521849 base::TimeDelta total_processing_commands_time_;
1850
[email protected]c986af502013-08-14 01:04:441851 // States related to each manager.
1852 DecoderTextureState texture_state_;
1853 DecoderFramebufferState framebuffer_state_;
1854
[email protected]fb97b662013-02-20 23:02:141855 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131856 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:241857 const unsigned char* cb_command_trace_category_;
[email protected]cac16542014-01-15 17:53:511858 int gpu_trace_level_;
1859 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:241860 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:111861
[email protected]5a36dc132013-07-23 23:17:551862 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1863
[email protected]4a4c18b2013-09-13 22:50:101864 // Used to validate multisample renderbuffers if needed
1865 GLuint validation_texture_;
1866 GLuint validation_fbo_multisample_;
1867 GLuint validation_fbo_;
1868
vmiuracd108592014-09-08 14:36:341869 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1870 uint32 immediate_data_size,
1871 const void* data);
1872
1873 // A struct to hold info about each command.
1874 struct CommandInfo {
1875 CmdHandler cmd_handler;
1876 uint8 arg_flags; // How to handle the arguments for this command
1877 uint8 cmd_flags; // How to handle this command
1878 uint16 arg_count; // How many arguments are expected for this command.
1879 };
1880
1881 // A table of CommandInfo for all the commands.
1882 static const CommandInfo command_info[kNumCommands - kStartPoint];
1883
[email protected]96449d2c2009-11-25 00:01:321884 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1885};
1886
vmiuracd108592014-09-08 14:36:341887const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1888#define GLES2_CMD_OP(name) \
1889 { \
1890 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
1891 cmds::name::cmd_flags, \
1892 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1893 } \
1894 , /* NOLINT */
1895 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1896#undef GLES2_CMD_OP
1897};
1898
[email protected]ab09b612013-03-11 22:11:511899ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301900 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511901 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301902 error_state_(error_state) {
1903 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351904}
1905
1906ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301907 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351908}
1909
[email protected]2b10c02d2014-01-29 16:43:021910static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361911 TextureUnit& info = state->texture_units[0];
1912 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021913 scoped_refptr<TextureRef> texture_ref;
1914 switch (target) {
1915 case GL_TEXTURE_2D:
1916 texture_ref = info.bound_texture_2d;
1917 break;
1918 case GL_TEXTURE_CUBE_MAP:
1919 texture_ref = info.bound_texture_cube_map;
1920 break;
1921 case GL_TEXTURE_EXTERNAL_OES:
1922 texture_ref = info.bound_texture_external_oes;
1923 break;
1924 case GL_TEXTURE_RECTANGLE_ARB:
1925 texture_ref = info.bound_texture_rectangle_arb;
1926 break;
1927 default:
1928 NOTREACHED();
1929 break;
1930 }
1931 if (texture_ref.get()) {
1932 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361933 } else {
1934 last_id = 0;
1935 }
1936
[email protected]2b10c02d2014-01-29 16:43:021937 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361938 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1939}
1940
[email protected]2b10c02d2014-01-29 16:43:021941ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1942 GLuint id,
1943 GLenum target)
1944 : state_(state),
1945 target_(target) {
[email protected]ab09b612013-03-11 22:11:511946 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021947 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351948
1949 // TODO(apatrick): Check if there are any other states that need to be reset
1950 // before binding a new texture.
1951 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021952 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351953}
1954
[email protected]2b10c02d2014-01-29 16:43:021955ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511956 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021957 "ScopedTextureBinder::dtor", state_->GetErrorState());
1958 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351959}
1960
[email protected]18e785a2013-10-09 03:29:411961ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351962 GLuint id)
[email protected]18e785a2013-10-09 03:29:411963 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511964 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411965 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351966 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1967}
1968
1969ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511970 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411971 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1972 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351973}
1974
1975ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1976 GLuint id)
1977 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511978 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301979 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351980 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451981 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351982}
1983
1984ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511985 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301986 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:301987 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351988}
1989
[email protected]34ff8b0c2010-10-01 20:06:021990ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271991 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521992 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:341993 resolve_and_bind_ = (
1994 decoder_->offscreen_target_frame_buffer_.get() &&
1995 decoder_->IsOffscreenBufferMultisampled() &&
1996 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1997 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021998 if (!resolve_and_bind_)
1999 return;
2000
[email protected]ab09b612013-03-11 22:11:512001 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302002 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022003 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
2004 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:272005 GLuint targetid;
2006 if (internal) {
2007 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
2008 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:352009 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:272010 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352011 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:362012 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:272013 decoder_->offscreen_resolved_color_texture_->Create();
2014
2015 DCHECK(decoder_->offscreen_saved_color_format_);
2016 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:092017 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
2018 false);
[email protected]de26b3c2011-08-03 21:54:272019 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
2020 decoder_->offscreen_resolved_color_texture_.get());
2021 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
2022 GL_FRAMEBUFFER_COMPLETE) {
2023 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
2024 << "because offscreen resolved FBO was incomplete.";
2025 return;
2026 }
2027 }
2028 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
2029 } else {
2030 targetid = decoder_->offscreen_saved_frame_buffer_->id();
2031 }
2032 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022033 const int width = decoder_->offscreen_size_.width();
2034 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:452035 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:182036 decoder->BlitFramebufferHelper(0,
2037 0,
2038 width,
2039 height,
2040 0,
2041 0,
2042 width,
2043 height,
2044 GL_COLOR_BUFFER_BIT,
2045 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:272046 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022047}
2048
2049ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
2050 if (!resolve_and_bind_)
2051 return;
2052
[email protected]ab09b612013-03-11 22:11:512053 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302054 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022055 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222056 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452057 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182058 }
[email protected]34ff8b0c2010-10-01 20:06:022059}
2060
[email protected]ce296892013-10-24 22:04:362061BackTexture::BackTexture(
2062 MemoryTracker* memory_tracker,
2063 ContextState* state)
2064 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2065 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482066 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252067 id_(0) {
[email protected]6217d392010-03-25 22:08:352068}
2069
[email protected]ed9f9cd2013-02-27 21:12:352070BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352071 // This does not destroy the render texture because that would require that
2072 // the associated GL context was current. Just check that it was explicitly
2073 // destroyed.
2074 DCHECK_EQ(id_, 0u);
2075}
2076
[email protected]ed9f9cd2013-02-27 21:12:352077void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302078 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362079 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352080 Destroy();
2081 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022082 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262083 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2084 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582085 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2086 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162087
2088 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2089 // never called on an offscreen context, no data will ever be uploaded to the
2090 // saved offscreen color texture (it is deferred until to when SwapBuffers
2091 // is called). My idea is that some nvidia drivers might have a bug where
2092 // deleting a texture that has never been populated might cause a
2093 // crash.
2094 glTexImage2D(
2095 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482096
2097 bytes_allocated_ = 16u * 16u * 4u;
2098 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352099}
2100
[email protected]ed9f9cd2013-02-27 21:12:352101bool BackTexture::AllocateStorage(
2102 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352103 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302104 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362105 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022106 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092107 uint32 image_size = 0;
2108 GLES2Util::ComputeImageDataSizes(
2109 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
2110 NULL, NULL);
2111
[email protected]7989c9e2013-01-23 06:39:262112 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2113 return false;
2114 }
2115
[email protected]40d90a22013-04-09 03:39:552116 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092117 if (zero) {
2118 zero_data.reset(new char[image_size]);
2119 memset(zero_data.get(), 0, image_size);
2120 }
[email protected]6217d392010-03-25 22:08:352121
[email protected]8f1d2aa2013-05-10 23:45:382122 glTexImage2D(GL_TEXTURE_2D,
2123 0, // mip level
2124 format,
2125 size.width(),
2126 size.height(),
2127 0, // border
2128 format,
2129 GL_UNSIGNED_BYTE,
2130 zero_data.get());
[email protected]6217d392010-03-25 22:08:352131
[email protected]d37231fa2010-04-09 21:16:022132 size_ = size;
2133
[email protected]1078f912011-12-23 13:12:142134 bool success = glGetError() == GL_NO_ERROR;
2135 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482136 memory_tracker_.TrackMemFree(bytes_allocated_);
2137 bytes_allocated_ = image_size;
2138 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142139 }
2140 return success;
[email protected]6217d392010-03-25 22:08:352141}
2142
[email protected]ed9f9cd2013-02-27 21:12:352143void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352144 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302145 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362146 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022147 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352148 glCopyTexImage2D(GL_TEXTURE_2D,
2149 0, // level
[email protected]3a4d0c52011-06-29 23:11:582150 format,
[email protected]6217d392010-03-25 22:08:352151 0, 0,
2152 size.width(),
2153 size.height(),
2154 0); // border
2155}
2156
[email protected]ed9f9cd2013-02-27 21:12:352157void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352158 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302159 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362160 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352161 glDeleteTextures(1, &id_);
2162 id_ = 0;
2163 }
[email protected]68e81a4a62012-12-13 01:16:482164 memory_tracker_.TrackMemFree(bytes_allocated_);
2165 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352166}
2167
[email protected]ed9f9cd2013-02-27 21:12:352168void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052169 id_ = 0;
2170}
2171
[email protected]d5a28e452013-10-10 01:01:402172BackRenderbuffer::BackRenderbuffer(
2173 RenderbufferManager* renderbuffer_manager,
2174 MemoryTracker* memory_tracker,
2175 ContextState* state)
2176 : renderbuffer_manager_(renderbuffer_manager),
2177 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2178 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482179 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252180 id_(0) {
[email protected]6217d392010-03-25 22:08:352181}
2182
[email protected]ed9f9cd2013-02-27 21:12:352183BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352184 // This does not destroy the render buffer because that would require that
2185 // the associated GL context was current. Just check that it was explicitly
2186 // destroyed.
2187 DCHECK_EQ(id_, 0u);
2188}
2189
[email protected]ed9f9cd2013-02-27 21:12:352190void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302191 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402192 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352193 Destroy();
2194 glGenRenderbuffersEXT(1, &id_);
2195}
2196
[email protected]f42f05b2013-11-15 21:46:182197bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2198 const gfx::Size& size,
2199 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352200 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512201 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402202 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2203 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262204
2205 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402206 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232207 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262208 return false;
2209 }
2210
2211 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2212 return false;
2213 }
2214
[email protected]34ff8b0c2010-10-01 20:06:022215 if (samples <= 1) {
2216 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2217 format,
2218 size.width(),
2219 size.height());
2220 } else {
[email protected]f42f05b2013-11-15 21:46:182221 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2222 GL_RENDERBUFFER,
2223 samples,
2224 format,
2225 size.width(),
2226 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022227 }
[email protected]1078f912011-12-23 13:12:142228 bool success = glGetError() == GL_NO_ERROR;
2229 if (success) {
[email protected]d5a28e452013-10-10 01:01:402230 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482231 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262232 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402233 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482234 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142235 }
2236 return success;
[email protected]6217d392010-03-25 22:08:352237}
2238
[email protected]ed9f9cd2013-02-27 21:12:352239void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352240 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302241 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402242 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352243 glDeleteRenderbuffersEXT(1, &id_);
2244 id_ = 0;
2245 }
[email protected]68e81a4a62012-12-13 01:16:482246 memory_tracker_.TrackMemFree(bytes_allocated_);
2247 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352248}
2249
[email protected]ed9f9cd2013-02-27 21:12:352250void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052251 id_ = 0;
2252}
2253
[email protected]ed9f9cd2013-02-27 21:12:352254BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352255 : decoder_(decoder),
2256 id_(0) {
2257}
2258
[email protected]ed9f9cd2013-02-27 21:12:352259BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352260 // This does not destroy the frame buffer because that would require that
2261 // the associated GL context was current. Just check that it was explicitly
2262 // destroyed.
2263 DCHECK_EQ(id_, 0u);
2264}
2265
[email protected]ed9f9cd2013-02-27 21:12:352266void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302267 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2268 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352269 Destroy();
2270 glGenFramebuffersEXT(1, &id_);
2271}
2272
[email protected]ed9f9cd2013-02-27 21:12:352273void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352274 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512275 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302276 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352277 ScopedFrameBufferBinder binder(decoder_, id_);
2278 GLuint attach_id = texture ? texture->id() : 0;
2279 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2280 GL_COLOR_ATTACHMENT0,
2281 GL_TEXTURE_2D,
2282 attach_id,
2283 0);
2284}
2285
[email protected]ed9f9cd2013-02-27 21:12:352286void BackFramebuffer::AttachRenderBuffer(GLenum target,
2287 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352288 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512289 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302290 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352291 ScopedFrameBufferBinder binder(decoder_, id_);
2292 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2293 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152294 target,
[email protected]6217d392010-03-25 22:08:352295 GL_RENDERBUFFER,
2296 attach_id);
2297}
2298
[email protected]ed9f9cd2013-02-27 21:12:352299void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352300 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302301 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2302 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352303 glDeleteFramebuffersEXT(1, &id_);
2304 id_ = 0;
2305 }
2306}
2307
[email protected]ed9f9cd2013-02-27 21:12:352308void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052309 id_ = 0;
2310}
2311
[email protected]ed9f9cd2013-02-27 21:12:352312GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352313 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302314 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2315 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352316 ScopedFrameBufferBinder binder(decoder_, id_);
2317 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2318}
2319
[email protected]aa7666122011-09-02 19:45:522320GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2321 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322322}
2323
[email protected]aa7666122011-09-02 19:45:522324GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392325 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572326 group_(group),
[email protected]1d82e822013-04-10 21:32:322327 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132328 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282329 unpack_flip_y_(false),
2330 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172331 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242332 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492333 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242334 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402335 fixed_attrib_buffer_id_(0),
2336 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022337 offscreen_target_color_format_(0),
2338 offscreen_target_depth_format_(0),
2339 offscreen_target_stencil_format_(0),
2340 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562341 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052342 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132343 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462344 back_buffer_has_depth_(false),
2345 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422346 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582347 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562348 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052349 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112350 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002351 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432352 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302353 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512354 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222355 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432356 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042357 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102358 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492359 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132360 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062361 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282362 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132363 lose_context_when_out_of_memory_(false),
[email protected]cae20172012-12-07 00:06:192364 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2365 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022366 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102367 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002368 texture_state_(group_->feature_info()
2369 ->workarounds()
2370 .texsubimage2d_faster_than_teximage2d),
vmiura1c2b1de2014-09-19 19:03:242371 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2372 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
2373 gpu_trace_level_(2),
2374 gpu_trace_commands_(false),
2375 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102376 validation_texture_(0),
2377 validation_fbo_multisample_(0),
2378 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572379 DCHECK(group);
2380
[email protected]b1122982010-05-17 23:04:242381 attrib_0_value_.v[0] = 0.0f;
2382 attrib_0_value_.v[1] = 0.0f;
2383 attrib_0_value_.v[2] = 0.0f;
2384 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152385
[email protected]c2f8c8402010-12-06 18:07:242386 // The shader translator is used for WebGL even when running on EGL
2387 // because additional restrictions are needed (like only enabling
2388 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562389 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2390 // the empty string to CompileShader and this is not a valid shader.
2391 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002392 CommandLine::ForCurrentProcess()->HasSwitch(
2393 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152394 use_shader_translator_ = false;
2395 }
[email protected]96449d2c2009-11-25 00:01:322396}
2397
[email protected]80eb6b52012-01-19 00:14:412398GLES2DecoderImpl::~GLES2DecoderImpl() {
2399}
2400
[email protected]c410da802011-03-14 19:17:412401bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382402 const scoped_refptr<gfx::GLSurface>& surface,
2403 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232404 bool offscreen,
[email protected]c410da802011-03-14 19:17:412405 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292406 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242407 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322408 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382409 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302410 DCHECK(!context_.get());
2411
jbaumana7604692014-10-17 02:00:392412 surfaceless_ = surface->IsSurfaceless() && !offscreen;
achaulkcf5316f2014-09-26 19:28:422413
[email protected]55e136f2013-04-03 18:50:062414 set_initialized();
[email protected]b4af07d2014-08-20 00:11:572415 gpu_tracer_.reset(new GPUTracer(this));
[email protected]8f9b8dd2013-09-12 18:05:132416 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142417
[email protected]e844ae22012-01-14 03:36:262418 if (CommandLine::ForCurrentProcess()->HasSwitch(
2419 switches::kEnableGPUDebugging)) {
2420 set_debug(true);
2421 }
2422
[email protected]39ba4f02012-03-26 01:16:002423 if (CommandLine::ForCurrentProcess()->HasSwitch(
2424 switches::kEnableGPUCommandLogging)) {
2425 set_log_commands(true);
2426 }
2427
[email protected]062c38b2012-01-18 03:25:102428 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2429 switches::kCompileShaderAlwaysSucceeds);
2430
[email protected]f62a5ab2011-05-23 20:34:152431
[email protected]63c9b052012-05-17 18:27:382432 // Take ownership of the context and surface. The surface can be replaced with
2433 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382434 context_ = context;
[email protected]63c9b052012-05-17 18:27:382435 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182436
[email protected]65f7efe2013-11-28 03:11:472437 ContextCreationAttribHelper attrib_parser;
2438 if (!attrib_parser.Parse(attribs))
2439 return false;
2440
[email protected]828a3932014-04-02 14:43:132441 // Save the loseContextWhenOutOfMemory context creation attribute.
2442 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402443 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132444
[email protected]65f7efe2013-11-28 03:11:472445 // If the failIfMajorPerformanceCaveat context creation attribute was true
2446 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402447 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472448 feature_info_->feature_flags().is_swiftshader) {
2449 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2450 Destroy(true);
2451 return false;
2452 }
2453
[email protected]956aec52013-09-05 15:41:192454 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222455 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392456 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422457 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382458 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032459 return false;
[email protected]a3ded6d2010-10-19 06:44:392460 }
[email protected]b64c24952012-04-19 03:20:272461 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282462
[email protected]e82fb792011-09-22 00:33:292463 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502464
[email protected]af6380962012-11-29 23:24:132465 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482466 vertex_array_manager_.reset(new VertexArrayManager());
2467
2468 GLuint default_vertex_attrib_service_id = 0;
2469 if (features().native_vertex_array_object) {
2470 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2471 glBindVertexArrayOES(default_vertex_attrib_service_id);
2472 }
2473
2474 state_.default_vertex_attrib_manager =
2475 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2476
[email protected]81f20a622014-04-18 01:54:522477 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002478 group_->max_vertex_attribs(),
2479 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462480
[email protected]81f20a622014-04-18 01:54:522481 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572482 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322483
[email protected]7cd76fd2013-06-02 21:11:112484 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532485
[email protected]b63f1d62014-07-18 15:40:592486 image_manager_.reset(new ImageManager);
2487
[email protected]302ce6d2011-07-07 23:28:112488 util_.set_num_compressed_texture_formats(
2489 validators_->compressed_texture_format.GetValues().size());
2490
[email protected]1071e572011-02-09 20:00:122491 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2492 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2493 // OpenGL ES 2.0 does not have this issue.
2494 glEnableVertexAttribArray(0);
2495 }
[email protected]b1122982010-05-17 23:04:242496 glGenBuffersARB(1, &attrib_0_buffer_id_);
2497 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2498 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2499 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402500 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082501
[email protected]1868a342012-11-07 15:56:022502 state_.texture_units.resize(group_->max_texture_units());
2503 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492504 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312505 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492506 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152507 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492508 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072509 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492510 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572511 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312512 }
[email protected]62e155e2012-10-23 22:43:152513 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492514 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072515 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492516 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572517 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462518 }
[email protected]370eaf12013-05-18 09:19:492519 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2520 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572521 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492522 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2523 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572524 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152525 }
[email protected]00f893d2010-08-24 18:55:492526 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502527 CHECK_GL_ERROR();
2528
[email protected]069944672012-04-25 20:52:232529 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402530 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542531 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022532 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432533 // max_sample_count must be initialized to a sane value. If
2534 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2535 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022536 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402537 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022538 max_sample_count);
2539 } else {
2540 offscreen_target_samples_ = 1;
2541 }
[email protected]845c4e32014-08-13 11:50:402542 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022543
2544 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2545 const bool rgb8_supported =
2546 context_->HasExtension("GL_OES_rgb8_rgba8");
2547 // The only available default render buffer formats in GLES2 have very
2548 // little precision. Don't enable multisampling unless 8-bit render
2549 // buffer formats are available--instead fall back to 8-bit textures.
2550 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402551 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022552 GL_RGBA8 : GL_RGB8;
2553 } else {
2554 offscreen_target_samples_ = 1;
[email protected]845c4e32014-08-13 11:50:402555 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022556 GL_RGBA : GL_RGB;
2557 }
2558
2559 // ANGLE only supports packed depth/stencil formats, so use it if it is
2560 // available.
2561 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182562 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272563 VLOG(1) << "GL_OES_packed_depth_stencil "
2564 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402565 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002566 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022567 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2568 offscreen_target_stencil_format_ = 0;
2569 } else {
2570 // It may be the case that this depth/stencil combination is not
2571 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402572 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022573 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402574 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022575 GL_STENCIL_INDEX8 : 0;
2576 }
2577 } else {
[email protected]845c4e32014-08-13 11:50:402578 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022579 GL_RGBA : GL_RGB;
2580
2581 // If depth is requested at all, use the packed depth stencil format if
2582 // it's available, as some desktop GL drivers don't support any non-packed
2583 // formats for depth attachments.
2584 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182585 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272586 VLOG(1) << "GL_EXT_packed_depth_stencil "
2587 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022588
[email protected]845c4e32014-08-13 11:50:402589 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002590 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022591 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2592 offscreen_target_stencil_format_ = 0;
2593 } else {
[email protected]845c4e32014-08-13 11:50:402594 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022595 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402596 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022597 GL_STENCIL_INDEX : 0;
2598 }
2599 }
2600
[email protected]845c4e32014-08-13 11:50:402601 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]97872062010-11-03 19:07:052602 GL_RGBA : GL_RGB;
2603
[email protected]6217d392010-03-25 22:08:352604 // Create the target frame buffer. This is the one that the client renders
2605 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352606 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352607 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022608 // Due to GLES2 format limitations, either the color texture (for
2609 // non-multisampling) or the color render buffer (for multisampling) will be
2610 // attached to the offscreen frame buffer. The render buffer has more
2611 // limited formats available to it, but the texture can't do multisampling.
2612 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402613 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2614 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022615 offscreen_target_color_render_buffer_->Create();
2616 } else {
[email protected]ce296892013-10-24 22:04:362617 offscreen_target_color_texture_.reset(new BackTexture(
2618 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022619 offscreen_target_color_texture_->Create();
2620 }
[email protected]d5a28e452013-10-10 01:01:402621 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2622 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152623 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402624 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2625 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152626 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352627
2628 // Create the saved offscreen texture. The target frame buffer is copied
2629 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352630 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022631 offscreen_saved_frame_buffer_->Create();
2632 //
[email protected]ce296892013-10-24 22:04:362633 offscreen_saved_color_texture_.reset(new BackTexture(
2634 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352635 offscreen_saved_color_texture_->Create();
2636
[email protected]6217d392010-03-25 22:08:352637 // Allocate the render buffers at their initial size and check the status
2638 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592639 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012640 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382641 Destroy(true);
[email protected]6217d392010-03-25 22:08:352642 return false;
2643 }
2644
[email protected]678a73f2012-12-19 19:22:092645 // Allocate the offscreen saved color texture.
2646 DCHECK(offscreen_saved_color_format_);
2647 offscreen_saved_color_texture_->AllocateStorage(
2648 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2649
2650 offscreen_saved_frame_buffer_->AttachRenderTexture(
2651 offscreen_saved_color_texture_.get());
2652 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2653 GL_FRAMEBUFFER_COMPLETE) {
2654 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2655 Destroy(true);
2656 return false;
2657 }
2658
[email protected]6217d392010-03-25 22:08:352659 // Bind to the new default frame buffer (the offscreen target frame buffer).
2660 // This should now be associated with ID zero.
2661 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102662 } else {
2663 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2664 // These are NOT if the back buffer has these proprorties. They are
2665 // if we want the command buffer to enforce them regardless of what
2666 // the real backbuffer is assuming the real back buffer gives us more than
2667 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2668 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2669 // can't do anything about that.
2670
achaulkcf5316f2014-09-26 19:28:422671 if (!surfaceless_) {
2672 GLint v = 0;
2673 glGetIntegerv(GL_ALPHA_BITS, &v);
2674 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2675 // the user requested RGB then RGB. If the user did not specify a
2676 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2677 back_buffer_color_format_ =
2678 (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
2679 glGetIntegerv(GL_DEPTH_BITS, &v);
2680 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
2681 glGetIntegerv(GL_STENCIL_BITS, &v);
2682 back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
2683 }
[email protected]6217d392010-03-25 22:08:352684 }
2685
[email protected]76a0ee102010-04-07 21:03:042686 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2687 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2688 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372689 // mailing list archives. It also implicitly enables the desktop GL
2690 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2691 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152692 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2693 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372694 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152695 }
[email protected]de17df392010-04-23 21:09:412696
[email protected]706b69f2012-07-27 04:59:302697 has_robustness_extension_ =
2698 context->HasExtension("GL_ARB_robustness") ||
oetuaho37cc50e2014-10-31 11:19:202699 context->HasExtension("GL_KHR_robustness") ||
[email protected]706b69f2012-07-27 04:59:302700 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432701
[email protected]c2f8c8402010-12-06 18:07:242702 if (!InitializeShaderTranslator()) {
2703 return false;
[email protected]de17df392010-04-23 21:09:412704 }
[email protected]76a0ee102010-04-07 21:03:042705
[email protected]e259eb412012-10-13 05:47:242706 state_.viewport_width = size.width();
2707 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282708
[email protected]5904806b2012-05-08 18:10:222709 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282710 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022711 viewport_max_width_ = viewport_params[0];
2712 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282713
[email protected]88a61bf2012-10-27 13:00:422714 state_.scissor_width = state_.viewport_width;
2715 state_.scissor_height = state_.viewport_height;
2716
[email protected]11f3e702012-06-19 19:00:012717 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342718 state_.InitCapabilities(NULL);
2719 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242720 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012721
2722 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2723 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2724 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2725 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
orglofchcad5a6742014-11-07 19:51:122726 DoBindValueBufferCHROMIUM(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, 0);
[email protected]11f3e702012-06-19 19:00:012727
achaulkcf5316f2014-09-26 19:28:422728 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002729#if defined(OS_ANDROID)
2730 // Temporary workaround for Android WebView because this clear ignores the
2731 // clip and corrupts that external UI of the App. Not calling glClear is ok
2732 // because the system already clears the buffer before each draw. Proper
2733 // fix might be setting the scissor clip properly before initialize. See
2734 // crbug.com/259023 for details.
2735 call_gl_clear = surface_->GetHandle();
2736#endif
2737 if (call_gl_clear) {
2738 // Clear the backbuffer.
2739 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2740 }
[email protected]561cc0a62013-05-07 18:34:452741
[email protected]b381ee32014-03-22 02:43:432742 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2743 if (feature_info_->workarounds()
2744 .disable_post_sub_buffers_for_onscreen_surfaces &&
2745 !surface->IsOffscreen())
2746 supports_post_sub_buffer_ = false;
2747
[email protected]62e155e2012-10-23 22:43:152748 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462749 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2750 }
[email protected]dd289a5d62012-06-30 22:05:462751
[email protected]9b753992013-04-27 02:04:412752 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2753 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242754 }
[email protected]85cb4682013-04-20 00:54:242755
[email protected]97419c02013-04-10 02:52:382756 // Only compositor contexts are known to use only the subset of GL
2757 // that can be safely migrated between the iGPU and the dGPU. Mark
2758 // those contexts as safe to forcibly transition between the GPUs.
2759 // http://crbug.com/180876, http://crbug.com/227228
2760 if (!offscreen)
2761 context_->SetSafeToForceGpuSwitch();
2762
[email protected]85a4ac22013-05-31 01:58:472763 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072764 AsyncPixelTransferManager::Create(context.get()));
2765 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592766
[email protected]91c94eb2013-10-22 10:32:542767 framebuffer_manager()->AddObserver(this);
2768
[email protected]246a70452010-03-05 21:53:502769 return true;
[email protected]96449d2c2009-11-25 00:01:322770}
2771
[email protected]6d668892013-12-04 21:37:122772Capabilities GLES2DecoderImpl::GetCapabilities() {
2773 DCHECK(initialized());
2774
2775 Capabilities caps;
2776
[email protected]6d668892013-12-04 21:37:122777 caps.egl_image_external =
2778 feature_info_->feature_flags().oes_egl_image_external;
2779 caps.texture_format_bgra8888 =
2780 feature_info_->feature_flags().ext_texture_format_bgra8888;
2781 caps.texture_format_etc1 =
2782 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:202783 caps.texture_format_etc1_npot =
2784 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:122785 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2786 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2787 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2788 caps.discard_framebuffer =
2789 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352790 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122791
2792#if defined(OS_MACOSX)
2793 // This is unconditionally true on mac, no need to test for it at runtime.
2794 caps.iosurface = true;
2795#endif
2796
[email protected]b381ee32014-03-22 02:43:432797 caps.post_sub_buffer = supports_post_sub_buffer_;
reveman340109182014-09-30 15:36:452798 caps.image = true;
[email protected]6d668892013-12-04 21:37:122799
ed9198b422014-10-23 15:01:372800 caps.blend_equation_advanced =
2801 feature_info_->feature_flags().blend_equation_advanced;
2802 caps.blend_equation_advanced_coherent =
2803 feature_info_->feature_flags().blend_equation_advanced_coherent;
[email protected]6d668892013-12-04 21:37:122804 return caps;
2805}
2806
[email protected]302ce6d2011-07-07 23:28:112807void GLES2DecoderImpl::UpdateCapabilities() {
2808 util_.set_num_compressed_texture_formats(
2809 validators_->compressed_texture_format.GetValues().size());
2810 util_.set_num_shader_binary_formats(
2811 validators_->shader_binary_format.GetValues().size());
2812}
2813
[email protected]c2f8c8402010-12-06 18:07:242814bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442815 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2816
[email protected]c2f8c8402010-12-06 18:07:242817 if (!use_shader_translator_) {
2818 return true;
2819 }
2820 ShBuiltInResources resources;
2821 ShInitBuiltInResources(&resources);
2822 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2823 resources.MaxVertexUniformVectors =
2824 group_->max_vertex_uniform_vectors();
2825 resources.MaxVaryingVectors = group_->max_varying_vectors();
2826 resources.MaxVertexTextureImageUnits =
2827 group_->max_vertex_texture_image_units();
2828 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2829 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2830 resources.MaxFragmentUniformVectors =
2831 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492832 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242833 resources.MaxExpressionComplexity = 256;
2834 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042835
[email protected]46c86752013-05-21 05:08:392836 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212837 GLint precision = 0;
2838 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2839 range, &precision);
[email protected]448e459e2013-06-12 17:00:412840 resources.FragmentPrecisionHigh =
2841 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142842
[email protected]f0d74742011-10-03 16:31:042843 if (force_webgl_glsl_validation_) {
2844 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492845 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132846 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442847 if (!draw_buffers_explicitly_enabled_)
2848 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:062849 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
oetuaho0decd442014-10-13 08:40:462850 resources.NV_draw_buffers =
2851 draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
[email protected]f0d74742011-10-03 16:31:042852 } else {
2853 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152854 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462855 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152856 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062857 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152858 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492859 resources.EXT_draw_buffers =
2860 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492861 resources.EXT_frag_depth =
2862 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:062863 resources.EXT_shader_texture_lod =
2864 features().ext_shader_texture_lod ? 1 : 0;
oetuaho0decd442014-10-13 08:40:462865 resources.NV_draw_buffers =
2866 features().nv_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042867 }
2868
[email protected]26b61442013-03-17 16:12:012869 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2870 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052871 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022872 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:052873 else
2874 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122875 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2876 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2877 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212878 int driver_bug_workarounds = 0;
2879 if (workarounds().needs_glsl_built_in_function_emulation)
2880 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542881 if (workarounds().init_gl_position_in_vertex_shader)
2882 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112883 if (workarounds().unfold_short_circuit_as_ternary_operation)
2884 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:052885 if (workarounds().init_varyings_without_static_use)
2886 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:062887 if (workarounds().unroll_for_loop_with_sampler_array_index)
2888 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:252889 if (workarounds().scalarize_vec_and_mat_constructor_args)
2890 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:272891 if (workarounds().regenerate_struct_names)
2892 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
[email protected]87fb6ab2012-06-13 22:28:042893
[email protected]03cef9b2014-04-03 15:58:142894 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262895 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:142896 shader_spec,
2897 &resources,
[email protected]a6739bc2013-09-07 04:45:212898 implementation_type,
2899 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042900 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242901 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382902 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242903 return false;
2904 }
[email protected]87fb6ab2012-06-13 22:28:042905
[email protected]03cef9b2014-04-03 15:58:142906 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262907 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:142908 shader_spec,
2909 &resources,
[email protected]a6739bc2013-09-07 04:45:212910 implementation_type,
2911 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042912 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242913 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382914 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242915 return false;
2916 }
2917 return true;
2918}
2919
[email protected]ae51d192010-04-27 00:48:032920bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472921 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352922 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032923 return false;
2924 }
2925 }
[email protected]40d90a22013-04-09 03:39:552926 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032927 glGenBuffersARB(n, service_ids.get());
2928 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352929 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032930 }
2931 return true;
2932}
2933
2934bool GLES2DecoderImpl::GenFramebuffersHelper(
2935 GLsizei n, const GLuint* client_ids) {
2936 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352937 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032938 return false;
2939 }
2940 }
[email protected]40d90a22013-04-09 03:39:552941 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032942 glGenFramebuffersEXT(n, service_ids.get());
2943 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352944 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032945 }
2946 return true;
2947}
2948
2949bool GLES2DecoderImpl::GenRenderbuffersHelper(
2950 GLsizei n, const GLuint* client_ids) {
2951 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352952 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032953 return false;
2954 }
2955 }
[email protected]40d90a22013-04-09 03:39:552956 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032957 glGenRenderbuffersEXT(n, service_ids.get());
2958 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352959 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032960 }
2961 return true;
2962}
2963
orglofchcad5a6742014-11-07 19:51:122964bool GLES2DecoderImpl::GenValuebuffersCHROMIUMHelper(GLsizei n,
2965 const GLuint* client_ids) {
2966 for (GLsizei ii = 0; ii < n; ++ii) {
2967 if (GetValuebuffer(client_ids[ii])) {
2968 return false;
2969 }
2970 }
2971 for (GLsizei ii = 0; ii < n; ++ii) {
2972 CreateValuebuffer(client_ids[ii]);
2973 }
2974 return true;
2975}
2976
[email protected]ae51d192010-04-27 00:48:032977bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2978 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352979 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032980 return false;
2981 }
2982 }
[email protected]40d90a22013-04-09 03:39:552983 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032984 glGenTextures(n, service_ids.get());
2985 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352986 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032987 }
2988 return true;
2989}
2990
2991void GLES2DecoderImpl::DeleteBuffersHelper(
2992 GLsizei n, const GLuint* client_ids) {
2993 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212994 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102995 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242996 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112997 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242998 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102999 }
[email protected]ed9f9cd2013-02-27 21:12:353000 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033001 }
[email protected]a93bb842010-02-16 23:03:473002 }
[email protected]07f54fcc2009-12-22 02:46:303003}
3004
[email protected]ae51d192010-04-27 00:48:033005void GLES2DecoderImpl::DeleteFramebuffersHelper(
3006 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453007 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153008 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:113009
[email protected]a25fa872010-03-25 02:57:583010 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353011 Framebuffer* framebuffer =
3012 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103013 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:343014 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
3015 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:443016 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:453017 GLenum target = supports_separate_framebuffer_binds ?
3018 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113019 glBindFramebufferEXT(target, GetBackbufferServiceId());
3020 }
[email protected]9d3b2e12013-10-02 01:04:343021 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
3022 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:453023 GLenum target = supports_separate_framebuffer_binds ?
3024 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113025 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:463026 }
[email protected]70d34263c2013-01-09 00:27:453027 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:353028 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033029 }
[email protected]a25fa872010-03-25 02:57:583030 }
[email protected]07f54fcc2009-12-22 02:46:303031}
3032
[email protected]ae51d192010-04-27 00:48:033033void GLES2DecoderImpl::DeleteRenderbuffersHelper(
3034 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453035 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153036 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:583037 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353038 Renderbuffer* renderbuffer =
3039 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103040 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:113041 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:243042 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103043 }
3044 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453045 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343046 if (framebuffer_state_.bound_read_framebuffer.get()) {
3047 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113048 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103049 }
[email protected]9d3b2e12013-10-02 01:04:343050 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3051 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113052 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103053 }
3054 } else {
[email protected]9d3b2e12013-10-02 01:04:343055 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3056 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113057 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103058 }
3059 }
[email protected]c986af502013-08-14 01:04:443060 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:353061 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033062 }
[email protected]a25fa872010-03-25 02:57:583063 }
[email protected]07f54fcc2009-12-22 02:46:303064}
3065
orglofchcad5a6742014-11-07 19:51:123066void GLES2DecoderImpl::DeleteValuebuffersCHROMIUMHelper(
3067 GLsizei n,
3068 const GLuint* client_ids) {
3069 for (GLsizei ii = 0; ii < n; ++ii) {
3070 Valuebuffer* valuebuffer = GetValuebuffer(client_ids[ii]);
3071 if (valuebuffer) {
3072 if (state_.bound_valuebuffer.get() == valuebuffer) {
3073 state_.bound_valuebuffer = NULL;
3074 }
3075 RemoveValuebuffer(client_ids[ii]);
3076 }
3077 }
3078}
3079
[email protected]ae51d192010-04-27 00:48:033080void GLES2DecoderImpl::DeleteTexturesHelper(
3081 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453082 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153083 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:473084 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:493085 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3086 if (texture_ref) {
3087 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103088 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443089 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463090 }
[email protected]370eaf12013-05-18 09:19:493091 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023092 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493093 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103094 }
3095 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453096 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343097 if (framebuffer_state_.bound_read_framebuffer.get()) {
3098 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113099 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103100 }
[email protected]9d3b2e12013-10-02 01:04:343101 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3102 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113103 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103104 }
3105 } else {
[email protected]9d3b2e12013-10-02 01:04:343106 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3107 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113108 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103109 }
3110 }
[email protected]e51bdf32011-11-23 22:21:463111#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073112 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463113 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3114 ReleaseIOSurfaceForTexture(service_id);
3115 }
3116#endif
[email protected]ed9f9cd2013-02-27 21:12:353117 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033118 }
[email protected]a93bb842010-02-16 23:03:473119 }
[email protected]07f54fcc2009-12-22 02:46:303120}
3121
[email protected]43f28f832010-02-03 02:28:483122// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323123
[email protected]eb54a562010-01-20 21:55:183124bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343125 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383126 return false;
3127
[email protected]177d1342013-12-07 04:20:343128 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:433129 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:293130
jbauman7a059312014-10-16 19:30:543131 MaybeExitOnContextLost();
[email protected]e9f0ca82013-04-01 23:52:293132
[email protected]63c9b052012-05-17 18:27:383133 return false;
[email protected]38d139d2011-07-14 00:38:433134 }
3135
[email protected]69a8701e2013-03-07 21:31:093136 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093137
[email protected]9b753992013-04-27 02:04:413138 // Rebind the FBO if it was unbound by the context.
3139 if (workarounds().unbind_fbo_on_context_switch)
3140 RestoreFramebufferBindings();
3141
[email protected]c986af502013-08-14 01:04:443142 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493143
[email protected]69a8701e2013-03-07 21:31:093144 return true;
3145}
3146
3147void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553148 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323149 if (engine() && query_manager_.get())
3150 query_manager_->ProcessPendingTransferQueries();
3151
[email protected]5b3a8e02013-03-13 05:36:443152 // TODO(epenner): Is there a better place to do this?
3153 // This needs to occur before we execute any batch of commands
3154 // from the client, as the client may have recieved an async
3155 // completion while issuing those commands.
3156 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483157 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183158}
3159
[email protected]8e3e0662010-08-23 18:46:303160static void RebindCurrentFramebuffer(
3161 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063162 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243163 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063164 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463165
[email protected]a3783712012-01-20 22:18:243166 if (framebuffer_id == 0) {
3167 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303168 }
[email protected]297ca1c2011-06-20 23:08:463169
[email protected]8e3e0662010-08-23 18:46:303170 glBindFramebufferEXT(target, framebuffer_id);
3171}
3172
3173void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443174 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463175
[email protected]62e155e2012-10-23 22:43:153176 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303177 RebindCurrentFramebuffer(
3178 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343179 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243180 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303181 } else {
3182 RebindCurrentFramebuffer(
3183 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343184 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243185 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303186 RebindCurrentFramebuffer(
3187 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343188 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243189 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303190 }
[email protected]70d34263c2013-01-09 00:27:453191 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303192}
3193
[email protected]0d6bfdc2011-11-02 01:32:203194bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353195 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203196 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103197 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423198 if (surfaceless_)
3199 return false;
[email protected]60f22d32012-12-12 00:31:583200 if (backbuffer_needs_clear_bits_) {
3201 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323202 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453203 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583204 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473205 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3206 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583207 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453208 state_.SetDeviceDepthMask(GL_TRUE);
3209 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423210 bool reset_draw_buffer = false;
brucedawson18249152014-10-31 23:02:323211 if ((backbuffer_needs_clear_bits_ & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]ee757922014-06-06 05:21:423212 group_->draw_buffer() == GL_NONE) {
3213 reset_draw_buffer = true;
3214 GLenum buf = GL_BACK;
3215 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3216 buf = GL_COLOR_ATTACHMENT0;
3217 glDrawBuffersARB(1, &buf);
3218 }
[email protected]60f22d32012-12-12 00:31:583219 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423220 if (reset_draw_buffer) {
3221 GLenum buf = GL_NONE;
3222 glDrawBuffersARB(1, &buf);
3223 }
[email protected]60f22d32012-12-12 00:31:583224 backbuffer_needs_clear_bits_ = 0;
3225 RestoreClearState();
3226 }
[email protected]0d6bfdc2011-11-02 01:32:203227 return true;
3228 }
3229
[email protected]968351b2011-12-20 08:26:513230 if (framebuffer_manager()->IsComplete(framebuffer)) {
3231 return true;
3232 }
3233
[email protected]0d6bfdc2011-11-02 01:32:203234 GLenum completeness = framebuffer->IsPossiblyComplete();
3235 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513236 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433237 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273238 return false;
3239 }
[email protected]0d6bfdc2011-11-02 01:32:203240
3241 // Are all the attachments cleared?
3242 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3243 texture_manager()->HaveUnclearedMips()) {
3244 if (!framebuffer->IsCleared()) {
3245 // Can we clear them?
[email protected]73276522012-11-09 05:50:203246 if (framebuffer->GetStatus(texture_manager(), target) !=
3247 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513248 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433249 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3250 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203251 return false;
3252 }
3253 ClearUnclearedAttachments(target, framebuffer);
3254 }
3255 }
3256
[email protected]968351b2011-12-20 08:26:513257 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203258 if (framebuffer->GetStatus(texture_manager(), target) !=
3259 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513260 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433261 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3262 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513263 return false;
3264 }
3265 framebuffer_manager()->MarkAsComplete(framebuffer);
3266 }
3267
[email protected]0d6bfdc2011-11-02 01:32:203268 // NOTE: At this point we don't know if the framebuffer is complete but
3269 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273270 return true;
3271}
3272
[email protected]0d6bfdc2011-11-02 01:32:203273bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153274 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513275 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343276 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3277 func_name);
[email protected]28718a92013-04-04 12:12:513278
3279 if (valid)
3280 OnUseFramebuffer();
3281
3282 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203283 }
[email protected]9d3b2e12013-10-02 01:04:343284 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113285 GL_DRAW_FRAMEBUFFER_EXT,
3286 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343287 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113288 GL_READ_FRAMEBUFFER_EXT,
3289 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203290}
3291
[email protected]2ea5950d2014-07-09 18:20:343292bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3293 const char* func_name) {
3294 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3295 framebuffer_state_.bound_read_framebuffer.get() :
3296 framebuffer_state_.bound_draw_framebuffer.get();
3297 if (!framebuffer)
3298 return true;
3299 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3300 LOCAL_SET_GL_ERROR(
3301 GL_INVALID_OPERATION, func_name, "no color image attached");
3302 return false;
3303 }
3304 return true;
3305}
3306
zmo383512cf2014-10-14 00:11:003307bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
3308 TextureRef* texture, GLint level) {
3309 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3310 framebuffer_state_.bound_read_framebuffer.get() :
3311 framebuffer_state_.bound_draw_framebuffer.get();
3312 if (!framebuffer)
3313 return false;
3314 const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
3315 GL_COLOR_ATTACHMENT0);
3316 if (!attachment)
3317 return false;
3318 return attachment->FormsFeedbackLoop(texture, level);
3319}
3320
[email protected]8e3e0662010-08-23 18:46:303321gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353322 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453323 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203324 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353325 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203326 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263327 if (attachment) {
3328 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503329 }
[email protected]9edc6b22010-12-23 02:00:263330 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023331 } else if (offscreen_target_frame_buffer_.get()) {
3332 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353333 } else {
[email protected]f62a5ab2011-05-23 20:34:153334 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023335 }
[email protected]246a70452010-03-05 21:53:503336}
3337
[email protected]68586372013-12-11 01:27:593338GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3339 Framebuffer* framebuffer =
3340 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3341 if (framebuffer != NULL) {
3342 return framebuffer->GetColorAttachmentTextureType();
3343 } else {
3344 return GL_UNSIGNED_BYTE;
3345 }
3346}
3347
[email protected]9edc6b22010-12-23 02:00:263348GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353349 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453350 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203351 if (framebuffer != NULL) {
3352 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463353 } else if (offscreen_target_frame_buffer_.get()) {
3354 return offscreen_target_color_format_;
3355 } else {
3356 return back_buffer_color_format_;
3357 }
3358}
3359
3360GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353361 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453362 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203363 if (framebuffer != NULL) {
3364 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263365 } else if (offscreen_target_frame_buffer_.get()) {
3366 return offscreen_target_color_format_;
3367 } else {
[email protected]32fe9aa2011-01-21 23:47:133368 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263369 }
3370}
3371
[email protected]9a5afa432011-07-22 18:16:393372void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513373 if (!offscreen_saved_color_texture_info_.get())
3374 return;
3375 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3376 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3377 texture_manager()->SetLevelInfo(
3378 offscreen_saved_color_texture_info_.get(),
3379 GL_TEXTURE_2D,
3380 0, // level
3381 GL_RGBA,
3382 offscreen_size_.width(),
3383 offscreen_size_.height(),
3384 1, // depth
3385 0, // border
3386 GL_RGBA,
3387 GL_UNSIGNED_BYTE,
3388 true);
[email protected]737191ee72014-03-09 08:02:423389 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513390 "UpdateParentTextureInfo",
3391 GetErrorState(),
3392 offscreen_saved_color_texture_info_.get(),
3393 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263394 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423395 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513396 "UpdateParentTextureInfo",
3397 GetErrorState(),
3398 offscreen_saved_color_texture_info_.get(),
3399 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263400 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423401 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513402 "UpdateParentTextureInfo",
3403 GetErrorState(),
3404 offscreen_saved_color_texture_info_.get(),
3405 GL_TEXTURE_WRAP_S,
3406 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423407 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513408 "UpdateParentTextureInfo",
3409 GetErrorState(),
3410 offscreen_saved_color_texture_info_.get(),
3411 GL_TEXTURE_WRAP_T,
3412 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443413 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3414 &state_, target);
[email protected]2ad674132013-06-05 07:48:513415 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353416}
3417
[email protected]799b4b22011-08-22 17:09:593418void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073419 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523420 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003421}
3422
[email protected]1d82e822013-04-10 21:32:323423Logger* GLES2DecoderImpl::GetLogger() {
3424 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523425}
3426
[email protected]cac16542014-01-15 17:53:513427void GLES2DecoderImpl::BeginDecoding() {
3428 gpu_tracer_->BeginDecoding();
3429 gpu_trace_commands_ = gpu_tracer_->IsTracing();
vmiura1c2b1de2014-09-19 19:03:243430 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3431 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513432}
3433
3434void GLES2DecoderImpl::EndDecoding() {
3435 gpu_tracer_->EndDecoding();
3436}
3437
[email protected]d3eba342013-04-18 21:11:503438ErrorState* GLES2DecoderImpl::GetErrorState() {
3439 return state_.GetErrorState();
3440}
3441
[email protected]e3932abb2013-03-13 00:01:373442void GLES2DecoderImpl::SetShaderCacheCallback(
3443 const ShaderCacheCallback& callback) {
3444 shader_cache_callback_ = callback;
3445}
3446
[email protected]840a7e462013-02-27 01:29:513447void GLES2DecoderImpl::SetWaitSyncPointCallback(
3448 const WaitSyncPointCallback& callback) {
3449 wait_sync_point_callback_ = callback;
3450}
3451
[email protected]85a4ac22013-05-31 01:58:473452AsyncPixelTransferManager*
3453 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3454 return async_pixel_transfer_manager_.get();
3455}
3456
3457void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3458 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593459}
3460
[email protected]498b5c072013-06-04 19:30:073461void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3462 AsyncPixelTransferManager* manager) {
3463 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3464}
3465
[email protected]1318e922010-09-17 22:03:163466bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3467 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493468 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3469 if (texture_ref) {
3470 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163471 return true;
3472 }
3473 return false;
3474}
3475
[email protected]63b465922012-09-06 02:04:523476uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443477 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483478 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523479}
3480
3481base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443482 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483483 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523484}
3485
3486base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3487 return total_processing_commands_time_;
3488}
3489
[email protected]dc25dda2012-09-27 21:36:303490void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3491 total_processing_commands_time_ += time;
3492}
3493
[email protected]63c9b052012-05-17 18:27:383494void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063495 if (!initialized())
3496 return;
3497
[email protected]63c9b052012-05-17 18:27:383498 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053499
[email protected]80eb6b52012-01-19 00:14:413500 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243501 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523502 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023503 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243504 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133505 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343506 framebuffer_state_.bound_read_framebuffer = NULL;
3507 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243508 state_.bound_renderbuffer = NULL;
orglofchcad5a6742014-11-07 19:51:123509 state_.bound_valuebuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413510
[email protected]cadac622013-06-11 16:46:363511 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513512 DCHECK(offscreen_target_color_texture_);
3513 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3514 offscreen_saved_color_texture_->id());
3515 offscreen_saved_color_texture_->Invalidate();
3516 offscreen_saved_color_texture_info_ = NULL;
3517 }
[email protected]eadc96792010-10-27 19:39:393518 if (have_context) {
[email protected]c322e882012-05-23 18:06:183519 if (copy_texture_CHROMIUM_.get()) {
3520 copy_texture_CHROMIUM_->Destroy();
3521 copy_texture_CHROMIUM_.reset();
3522 }
[email protected]43410e92012-04-20 17:06:283523
[email protected]7cd76fd2013-06-02 21:11:113524 if (state_.current_program.get()) {
3525 program_manager()->UnuseProgram(shader_manager(),
3526 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143527 }
3528
[email protected]b1122982010-05-17 23:04:243529 if (attrib_0_buffer_id_) {
3530 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3531 }
[email protected]8fbedc02010-11-18 18:43:403532 if (fixed_attrib_buffer_id_) {
3533 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3534 }
[email protected]b1122982010-05-17 23:04:243535
[email protected]4a4c18b2013-09-13 22:50:103536 if (validation_texture_) {
3537 glDeleteTextures(1, &validation_texture_);
3538 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3539 glDeleteFramebuffersEXT(1, &validation_fbo_);
3540 }
3541
[email protected]97872062010-11-03 19:07:053542 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543543 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053544 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543545 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053546 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023547 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053548 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153549 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053550 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153551 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053552 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023553 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053554 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543555 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273556 if (offscreen_resolved_frame_buffer_.get())
3557 offscreen_resolved_frame_buffer_->Destroy();
3558 if (offscreen_resolved_color_texture_.get())
3559 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053560 } else {
3561 if (offscreen_target_frame_buffer_.get())
3562 offscreen_target_frame_buffer_->Invalidate();
3563 if (offscreen_target_color_texture_.get())
3564 offscreen_target_color_texture_->Invalidate();
3565 if (offscreen_target_color_render_buffer_.get())
3566 offscreen_target_color_render_buffer_->Invalidate();
3567 if (offscreen_target_depth_render_buffer_.get())
3568 offscreen_target_depth_render_buffer_->Invalidate();
3569 if (offscreen_target_stencil_render_buffer_.get())
3570 offscreen_target_stencil_render_buffer_->Invalidate();
3571 if (offscreen_saved_frame_buffer_.get())
3572 offscreen_saved_frame_buffer_->Invalidate();
3573 if (offscreen_saved_color_texture_.get())
3574 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273575 if (offscreen_resolved_frame_buffer_.get())
3576 offscreen_resolved_frame_buffer_->Invalidate();
3577 if (offscreen_resolved_color_texture_.get())
3578 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023579 }
[email protected]83a52d032013-07-24 10:30:373580
3581 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3582 // Otherwise, we can leak objects. http://crbug.com/258772.
3583 // state_.current_program must be reset before group_ is reset because
3584 // the later deletes the ProgramManager object that referred by
3585 // state_.current_program object.
3586 state_.current_program = NULL;
3587
[email protected]43410e92012-04-20 17:06:283588 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053589
[email protected]882ba1e22012-03-08 19:02:533590 if (query_manager_.get()) {
3591 query_manager_->Destroy(have_context);
3592 query_manager_.reset();
3593 }
3594
[email protected]944b62f32012-09-27 02:20:463595 if (vertex_array_manager_ .get()) {
3596 vertex_array_manager_->Destroy(have_context);
3597 vertex_array_manager_.reset();
3598 }
3599
[email protected]d2eaf52f2014-07-31 15:01:243600 if (image_manager_.get()) {
3601 image_manager_->Destroy(have_context);
3602 image_manager_.reset();
3603 }
3604
[email protected]97872062010-11-03 19:07:053605 offscreen_target_frame_buffer_.reset();
3606 offscreen_target_color_texture_.reset();
3607 offscreen_target_color_render_buffer_.reset();
3608 offscreen_target_depth_render_buffer_.reset();
3609 offscreen_target_stencil_render_buffer_.reset();
3610 offscreen_saved_frame_buffer_.reset();
3611 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273612 offscreen_resolved_frame_buffer_.reset();
3613 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463614
[email protected]03cef9b2014-04-03 15:58:143615 // Need to release these before releasing |group_| which may own the
3616 // ShaderTranslatorCache.
3617 fragment_translator_ = NULL;
3618 vertex_translator_ = NULL;
3619
[email protected]85a4ac22013-05-31 01:58:473620 // Should destroy the transfer manager before the texture manager held
3621 // by the context group.
3622 async_pixel_transfer_manager_.reset();
3623
[email protected]7cd76fd2013-06-02 21:11:113624 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393625 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233626 group_->Destroy(this, have_context);
3627 group_ = NULL;
3628 }
3629
3630 if (context_.get()) {
3631 context_->ReleaseCurrent(NULL);
3632 context_ = NULL;
3633 }
3634
[email protected]e51bdf32011-11-23 22:21:463635#if defined(OS_MACOSX)
3636 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3637 it != texture_to_io_surface_map_.end(); ++it) {
3638 CFRelease(it->second);
3639 }
3640 texture_to_io_surface_map_.clear();
3641#endif
[email protected]96449d2c2009-11-25 00:01:323642}
3643
[email protected]63c9b052012-05-17 18:27:383644void GLES2DecoderImpl::SetSurface(
3645 const scoped_refptr<gfx::GLSurface>& surface) {
3646 DCHECK(context_->IsCurrent(NULL));
3647 DCHECK(surface_.get());
3648 surface_ = surface;
3649 RestoreCurrentFramebufferBindings();
3650}
3651
[email protected]aba551b2014-02-08 03:38:323652void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3653 if (!offscreen_saved_color_texture_.get()) {
3654 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3655 return;
3656 }
[email protected]2ad674132013-06-05 07:48:513657 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243658 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073659 offscreen_saved_color_texture_info_ = TextureRef::Create(
3660 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513661 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3662 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393663 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243664 }
[email protected]aba551b2014-02-08 03:38:323665 mailbox_manager()->ProduceTexture(
sievers8b373ec52014-10-24 23:04:063666 mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243667}
3668
[email protected]799b4b22011-08-22 17:09:593669bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3670 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3671 if (!is_offscreen) {
3672 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3673 << " with an onscreen framebuffer.";
3674 return false;
3675 }
3676
3677 if (offscreen_size_ == size)
3678 return true;
3679
3680 offscreen_size_ = size;
3681 int w = offscreen_size_.width();
3682 int h = offscreen_size_.height();
3683 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3684 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3685 << "to allocate storage due to excessive dimensions.";
3686 return false;
3687 }
3688
3689 // Reallocate the offscreen target buffers.
3690 DCHECK(offscreen_target_color_format_);
3691 if (IsOffscreenBufferMultisampled()) {
3692 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253693 feature_info_.get(),
3694 offscreen_size_,
3695 offscreen_target_color_format_,
3696 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593697 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3698 << "to allocate storage for offscreen target color buffer.";
3699 return false;
3700 }
3701 } else {
3702 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093703 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593704 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3705 << "to allocate storage for offscreen target color texture.";
3706 return false;
3707 }
3708 }
3709 if (offscreen_target_depth_format_ &&
3710 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253711 feature_info_.get(),
3712 offscreen_size_,
3713 offscreen_target_depth_format_,
3714 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593715 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3716 << "to allocate storage for offscreen target depth buffer.";
3717 return false;
3718 }
3719 if (offscreen_target_stencil_format_ &&
3720 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253721 feature_info_.get(),
3722 offscreen_size_,
3723 offscreen_target_stencil_format_,
3724 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593725 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3726 << "to allocate storage for offscreen target stencil buffer.";
3727 return false;
3728 }
3729
3730 // Attach the offscreen target buffers to the target frame buffer.
3731 if (IsOffscreenBufferMultisampled()) {
3732 offscreen_target_frame_buffer_->AttachRenderBuffer(
3733 GL_COLOR_ATTACHMENT0,
3734 offscreen_target_color_render_buffer_.get());
3735 } else {
3736 offscreen_target_frame_buffer_->AttachRenderTexture(
3737 offscreen_target_color_texture_.get());
3738 }
3739 if (offscreen_target_depth_format_) {
3740 offscreen_target_frame_buffer_->AttachRenderBuffer(
3741 GL_DEPTH_ATTACHMENT,
3742 offscreen_target_depth_render_buffer_.get());
3743 }
3744 const bool packed_depth_stencil =
3745 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3746 if (packed_depth_stencil) {
3747 offscreen_target_frame_buffer_->AttachRenderBuffer(
3748 GL_STENCIL_ATTACHMENT,
3749 offscreen_target_depth_render_buffer_.get());
3750 } else if (offscreen_target_stencil_format_) {
3751 offscreen_target_frame_buffer_->AttachRenderBuffer(
3752 GL_STENCIL_ATTACHMENT,
3753 offscreen_target_stencil_render_buffer_.get());
3754 }
3755
3756 if (offscreen_target_frame_buffer_->CheckStatus() !=
3757 GL_FRAMEBUFFER_COMPLETE) {
3758 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3759 << "because offscreen FBO was incomplete.";
3760 return false;
3761 }
3762
3763 // Clear the target frame buffer.
3764 {
3765 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3766 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323767 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453768 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593769 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473770 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3771 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:593772 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:453773 state_.SetDeviceDepthMask(GL_TRUE);
3774 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:593775 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3776 RestoreClearState();
3777 }
[email protected]d85ef76d2011-09-08 22:21:433778
3779 // Destroy the offscreen resolved framebuffers.
3780 if (offscreen_resolved_frame_buffer_.get())
3781 offscreen_resolved_frame_buffer_->Destroy();
3782 if (offscreen_resolved_color_texture_.get())
3783 offscreen_resolved_color_texture_->Destroy();
3784 offscreen_resolved_color_texture_.reset();
3785 offscreen_resolved_frame_buffer_.reset();
3786
[email protected]799b4b22011-08-22 17:09:593787 return true;
[email protected]6217d392010-03-25 22:08:353788}
3789
vmiuracd108592014-09-08 14:36:343790error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
3791 const void* cmd_data) {
3792 const gles2::cmds::ResizeCHROMIUM& c =
3793 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:443794 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023795 return error::kDeferCommandUntilLater;
3796
[email protected]799b4b22011-08-22 17:09:593797 GLuint width = static_cast<GLuint>(c.width);
3798 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073799 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593800 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413801
3802 width = std::max(1U, width);
3803 height = std::max(1U, height);
3804
[email protected]a0d989162011-11-22 13:15:073805#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3806 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003807 // Make sure that we are done drawing to the back buffer before resizing.
3808 glFinish();
3809#endif
[email protected]799b4b22011-08-22 17:09:593810 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3811 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493812 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3813 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3814 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593815 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493816 }
[email protected]7ff86b92010-11-25 17:50:003817 }
[email protected]799b4b22011-08-22 17:09:593818
[email protected]9d37f062011-11-22 01:24:523819 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073820 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443821 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493822 if (!context_->IsCurrent(surface_.get())) {
3823 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3824 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053825 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493826 }
[email protected]658f7562011-09-09 05:24:053827 }
[email protected]799b4b22011-08-22 17:09:593828
3829 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393830}
3831
[email protected]96449d2c2009-11-25 00:01:323832const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3833 if (command_id > kStartPoint && command_id < kNumCommands) {
3834 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3835 }
3836 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3837}
3838
vmiura8266ca72014-09-09 21:37:003839// Decode a command, and call the corresponding GL functions.
3840// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
3841// of commands at once, and is now only used for tests that need to track
3842// individual commands.
3843error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
3844 unsigned int arg_count,
3845 const void* cmd_data) {
3846 return DoCommands(1, cmd_data, arg_count + 1, 0);
3847}
3848
3849// Decode multiple commands, and call the corresponding GL functions.
3850// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
3851// changed by a (malicious) client at any time, so if validation has to happen,
3852// it should operate on a copy of them.
3853// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
3854// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:243855template <bool DebugImpl>
3856error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
3857 const void* buffer,
3858 int num_entries,
3859 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:003860 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:143861 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:003862 const CommandBufferEntry* cmd_data =
3863 static_cast<const CommandBufferEntry*>(buffer);
3864 int process_pos = 0;
3865 unsigned int command = 0;
3866
3867 while (process_pos < num_entries && result == error::kNoError &&
3868 commands_to_process_--) {
3869 const unsigned int size = cmd_data->value_header.size;
3870 command = cmd_data->value_header.command;
3871
3872 if (size == 0) {
3873 result = error::kInvalidSize;
3874 break;
3875 }
3876
3877 if (static_cast<int>(size) + process_pos > num_entries) {
3878 result = error::kOutOfBounds;
3879 break;
3880 }
3881
vmiura1c2b1de2014-09-19 19:03:243882 if (DebugImpl) {
3883 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3884 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:003885
vmiura1c2b1de2014-09-19 19:03:243886 if (log_commands()) {
3887 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
3888 << "cmd: " << GetCommandName(command);
3889 }
vmiura8266ca72014-09-09 21:37:003890 }
3891
3892 const unsigned int arg_count = size - 1;
3893 unsigned int command_index = command - kStartPoint - 1;
3894 if (command_index < arraysize(command_info)) {
3895 const CommandInfo& info = command_info[command_index];
3896 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3897 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3898 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
3899 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:243900 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:003901 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3902 doing_gpu_trace = true;
3903 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3904 }
[email protected]cac16542014-01-15 17:53:513905 }
[email protected]cac16542014-01-15 17:53:513906
vmiura8266ca72014-09-09 21:37:003907 uint32 immediate_data_size = (arg_count - info_arg_count) *
3908 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323909
vmiura8266ca72014-09-09 21:37:003910 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:513911
vmiura1c2b1de2014-09-19 19:03:243912 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:003913 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:513914
vmiura1c2b1de2014-09-19 19:03:243915 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:003916 GLenum error;
3917 while ((error = glGetError()) != GL_NO_ERROR) {
3918 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
3919 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
3920 << " : " << GetCommandName(command);
3921 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
3922 }
[email protected]b9849abf2009-11-25 19:13:193923 }
vmiura8266ca72014-09-09 21:37:003924 } else {
3925 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323926 }
3927 } else {
vmiura8266ca72014-09-09 21:37:003928 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323929 }
vmiura1c2b1de2014-09-19 19:03:243930
3931 if (DebugImpl) {
3932 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3933 GetCommandName(command));
3934 }
3935
vmiura8266ca72014-09-09 21:37:003936 if (result == error::kNoError &&
3937 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:563938 result = current_decoder_error_;
3939 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:003940 }
3941
3942 if (result != error::kDeferCommandUntilLater) {
3943 process_pos += size;
3944 cmd_data += size;
3945 }
[email protected]a3a93e7b2010-08-28 00:48:563946 }
vmiura8266ca72014-09-09 21:37:003947
3948 if (entries_processed)
3949 *entries_processed = process_pos;
3950
3951 if (error::IsError(result)) {
3952 LOG(ERROR) << "Error: " << result << " for Command "
3953 << GetCommandName(command);
3954 }
3955
[email protected]b9849abf2009-11-25 19:13:193956 return result;
[email protected]96449d2c2009-11-25 00:01:323957}
3958
vmiura1c2b1de2014-09-19 19:03:243959error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
3960 const void* buffer,
3961 int num_entries,
3962 int* entries_processed) {
3963 if (gpu_debug_commands_) {
3964 return DoCommandsImpl<true>(
3965 num_commands, buffer, num_entries, entries_processed);
3966 } else {
3967 return DoCommandsImpl<false>(
3968 num_commands, buffer, num_entries, entries_processed);
3969 }
3970}
3971
[email protected]ed9f9cd2013-02-27 21:12:353972void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3973 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503974}
3975
[email protected]ae51d192010-04-27 00:48:033976bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353977 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033978 return false;
3979 }
[email protected]96449d2c2009-11-25 00:01:323980 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033981 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353982 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323983 }
[email protected]ae51d192010-04-27 00:48:033984 return true;
[email protected]96449d2c2009-11-25 00:01:323985}
3986
[email protected]ae51d192010-04-27 00:48:033987bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353988 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033989 return false;
[email protected]96449d2c2009-11-25 00:01:323990 }
[email protected]ae51d192010-04-27 00:48:033991 GLuint service_id = glCreateShader(type);
3992 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353993 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033994 }
3995 return true;
[email protected]96449d2c2009-11-25 00:01:323996}
3997
[email protected]882ba1e22012-03-08 19:02:533998void GLES2DecoderImpl::DoFinish() {
3999 glFinish();
[email protected]5a36dc132013-07-23 23:17:554000 ProcessPendingReadPixels();
revemancc241eb2014-11-11 03:30:374001 ProcessPendingQueries(true);
[email protected]882ba1e22012-03-08 19:02:534002}
4003
4004void GLES2DecoderImpl::DoFlush() {
4005 glFlush();
revemancc241eb2014-11-11 03:30:374006 ProcessPendingQueries(false);
[email protected]882ba1e22012-03-08 19:02:534007}
4008
[email protected]3916c97e2010-02-25 03:20:504009void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:454010 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:024011 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:514012 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:534013 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:504014 return;
4015 }
[email protected]e259eb412012-10-13 05:47:244016 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:454017 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:504018}
4019
[email protected]051b1372010-04-12 02:42:084020void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:074021 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:084022 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034023 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:074024 buffer = GetBuffer(client_id);
4025 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:354026 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224027 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4028 "glBindBuffer",
4029 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:354030 return;
4031 }
4032
[email protected]b10492f2013-03-08 05:24:074033 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:034034 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354035 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:074036 buffer = GetBuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034037 }
[email protected]051b1372010-04-12 02:42:084038 }
[email protected]b10492f2013-03-08 05:24:074039 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
4040 if (buffer) {
4041 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:514042 LOCAL_SET_GL_ERROR(
4043 GL_INVALID_OPERATION,
4044 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:474045 return;
4046 }
[email protected]b10492f2013-03-08 05:24:074047 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:474048 }
[email protected]96449d2c2009-11-25 00:01:324049 switch (target) {
4050 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074051 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:324052 break;
4053 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074054 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:324055 break;
4056 default:
[email protected]a93bb842010-02-16 23:03:474057 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:324058 break;
4059 }
[email protected]051b1372010-04-12 02:42:084060 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:324061}
4062
[email protected]f3b191b2013-06-19 03:43:544063bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
4064 bool all_draw_buffers) {
4065 Framebuffer* framebuffer =
4066 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4067 if (!all_draw_buffers || !framebuffer) {
4068 return (GLES2Util::GetChannelsForFormat(
4069 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
4070 }
4071 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:464072}
4073
4074bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354075 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454076 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204077 if (framebuffer) {
4078 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:464079 }
4080 if (offscreen_target_frame_buffer_.get()) {
4081 return offscreen_target_depth_format_ != 0;
4082 }
4083 return back_buffer_has_depth_;
4084}
4085
4086bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354087 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454088 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204089 if (framebuffer) {
4090 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464091 }
4092 if (offscreen_target_frame_buffer_.get()) {
4093 return offscreen_target_stencil_format_ != 0 ||
4094 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4095 }
4096 return back_buffer_has_stencil_;
4097}
4098
4099void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444100 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454101 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4102 state_.SetDeviceColorMask(state_.color_mask_red,
4103 state_.color_mask_green,
4104 state_.color_mask_blue,
4105 state_.color_mask_alpha && have_alpha);
4106
[email protected]297ca1c2011-06-20 23:08:464107 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454108 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4109
[email protected]297ca1c2011-06-20 23:08:464110 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454111 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424112 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454113 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424114 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454115
4116 state_.SetDeviceCapabilityState(
4117 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4118 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224119 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444120 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464121 }
4122}
4123
[email protected]1868a342012-11-07 15:56:024124GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114125 return (offscreen_target_frame_buffer_.get())
4126 ? offscreen_target_frame_buffer_->id()
4127 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024128}
4129
[email protected]8875a5f2014-06-27 08:33:474130void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144131 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4132 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064133 // Restore the Framebuffer first because of bugs in Intel drivers.
4134 // Intel drivers incorrectly clip the viewport settings to
4135 // the size of the current framebuffer object.
4136 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164137 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064138}
4139
4140void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344141 GLuint service_id =
4142 framebuffer_state_.bound_draw_framebuffer.get()
4143 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4144 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064145 if (!features().chromium_framebuffer_multisample) {
4146 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4147 } else {
4148 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344149 service_id = framebuffer_state_.bound_read_framebuffer.get()
4150 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114151 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064152 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4153 }
[email protected]70d34263c2013-01-09 00:27:454154 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064155}
4156
[email protected]8875a5f2014-06-27 08:33:474157void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4158 state_.RestoreRenderbufferBindings();
4159}
4160
[email protected]29a4d902013-02-26 20:18:064161void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104162 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4163 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254164 GLenum target = texture->target();
4165 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064166 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254167 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064168 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254169 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064170 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254171 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064172 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254173 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064174 RestoreTextureUnitBindings(state_.active_texture_unit);
4175 }
[email protected]70d34263c2013-01-09 00:27:454176}
4177
[email protected]cd2ef752014-02-12 23:16:034178void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524179 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4180 // other VAOs.
4181 if (feature_info_->feature_flags().native_vertex_array_object)
4182 glBindVertexArrayOES(0);
4183
[email protected]cd2ef752014-02-12 23:16:034184 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
4185 if (i != 0) // Never disable attribute 0
4186 glDisableVertexAttribArray(i);
4187 if(features().angle_instanced_arrays)
4188 glVertexAttribDivisorANGLE(i, 0);
4189 }
4190}
4191
4192void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524193 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034194}
4195
[email protected]454157e2014-05-03 02:49:454196void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4197 state_.SetIgnoreCachedStateForTest(ignore);
4198}
4199
[email protected]70d34263c2013-01-09 00:27:454200void GLES2DecoderImpl::OnFboChanged() const {
4201 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:514202 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
4203}
4204
4205// Called after the FBO is checked for completeness.
4206void GLES2DecoderImpl::OnUseFramebuffer() const {
4207 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
4208 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:324209 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514210 glScissor(state_.scissor_x,
4211 state_.scissor_y,
4212 state_.scissor_width,
4213 state_.scissor_height);
4214
4215 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4216 // it's unclear how this bug works.
4217 glFlush();
4218 }
[email protected]b177ae22011-11-01 03:29:114219}
4220
[email protected]051b1372010-04-12 02:42:084221void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064222 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084223 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034224 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064225 framebuffer = GetFramebuffer(client_id);
4226 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354227 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224228 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4229 "glBindFramebuffer",
4230 "id not generated by glGenFramebuffers");
4231 return;
[email protected]bf5a8d132011-08-16 08:39:354232 }
4233
[email protected]4d8f0dd2013-03-09 14:37:064234 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034235 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354236 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064237 framebuffer = GetFramebuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034238 } else {
[email protected]4d8f0dd2013-03-09 14:37:064239 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084240 }
[email protected]4d8f0dd2013-03-09 14:37:064241 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084242 }
[email protected]4d8f0dd2013-03-09 14:37:064243 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304244
4245 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344246 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304247 }
[email protected]cac16542014-01-15 17:53:514248
4249 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304250 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344251 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304252 }
[email protected]6217d392010-03-25 22:08:354253
[email protected]c986af502013-08-14 01:04:444254 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464255
[email protected]b177ae22011-11-01 03:29:114256 // If we are rendering to the backbuffer get the FBO id for any simulated
4257 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064258 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114259 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464260 }
[email protected]6217d392010-03-25 22:08:354261
[email protected]051b1372010-04-12 02:42:084262 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454263 OnFboChanged();
[email protected]86093972010-03-11 00:13:564264}
4265
[email protected]051b1372010-04-12 02:42:084266void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274267 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084268 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034269 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274270 renderbuffer = GetRenderbuffer(client_id);
4271 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354272 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224273 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4274 "glBindRenderbuffer",
4275 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354276 return;
4277 }
4278
[email protected]8875a5f2014-06-27 08:33:474279 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034280 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354281 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274282 renderbuffer = GetRenderbuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034283 } else {
[email protected]ee2a79c32013-03-10 03:50:274284 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084285 }
[email protected]ee2a79c32013-03-10 03:50:274286 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084287 }
[email protected]caa13ed2014-02-17 11:29:204288 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274289 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474290 state_.bound_renderbuffer_valid = true;
4291 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564292}
4293
[email protected]051b1372010-04-12 02:42:084294void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494295 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084296 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034297 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494298 texture_ref = GetTexture(client_id);
4299 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354300 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224301 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4302 "glBindTexture",
4303 "id not generated by glGenTextures");
4304 return;
[email protected]bf5a8d132011-08-16 08:39:354305 }
4306
[email protected]02965c22013-03-09 02:40:074307 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034308 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414309 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354310 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494311 texture_ref = GetTexture(client_id);
[email protected]ae51d192010-04-27 00:48:034312 }
4313 } else {
[email protected]370eaf12013-05-18 09:19:494314 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084315 }
[email protected]ae51d192010-04-27 00:48:034316
[email protected]1958e0e2010-04-22 05:17:154317 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574318 if (texture_ref) {
4319 Texture* texture = texture_ref->texture();
4320 // Check that we are not trying to bind it to a different target.
4321 if (texture->target() != 0 && texture->target() != target) {
4322 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4323 "glBindTexture",
4324 "texture bound to more than 1 target.");
4325 return;
4326 }
4327 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4328 if (texture->target() == 0) {
4329 texture_manager()->SetTarget(texture_ref, target);
4330 }
4331 glBindTexture(target, texture->service_id());
4332 } else {
4333 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154334 }
[email protected]32145a92012-12-17 09:01:594335
[email protected]e259eb412012-10-13 05:47:244336 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504337 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474338 switch (target) {
4339 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494340 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474341 break;
4342 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494343 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474344 break;
[email protected]61eeb33f2011-07-26 15:30:314345 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494346 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314347 break;
[email protected]e51bdf32011-11-23 22:21:464348 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494349 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464350 break;
[email protected]a93bb842010-02-16 23:03:474351 default:
4352 NOTREACHED(); // Validation should prevent us getting here.
4353 break;
4354 }
4355}
4356
[email protected]07f54fcc2009-12-22 02:46:304357void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244358 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124359 if (index != 0 ||
4360 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244361 glDisableVertexAttribArray(index);
4362 }
[email protected]07f54fcc2009-12-22 02:46:304363 } else {
[email protected]ab09b612013-03-11 22:11:514364 LOCAL_SET_GL_ERROR(
4365 GL_INVALID_VALUE,
4366 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304367 }
4368}
4369
[email protected]60f22d32012-12-12 00:31:584370void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4371 GLsizei numAttachments,
4372 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:354373 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584374 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4375
4376 // Validates the attachments. If one of them fails
4377 // the whole command fails.
4378 for (GLsizei i = 0; i < numAttachments; ++i) {
4379 if ((framebuffer &&
4380 !validators_->attachment.IsValid(attachments[i])) ||
4381 (!framebuffer &&
4382 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514383 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4384 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584385 return;
4386 }
4387 }
4388
4389 // Marks each one of them as not cleared
4390 for (GLsizei i = 0; i < numAttachments; ++i) {
4391 if (framebuffer) {
4392 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4393 texture_manager(),
4394 attachments[i],
4395 false);
4396 } else {
4397 switch (attachments[i]) {
4398 case GL_COLOR_EXT:
4399 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4400 break;
4401 case GL_DEPTH_EXT:
4402 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4403 case GL_STENCIL_EXT:
4404 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4405 break;
4406 default:
4407 NOTREACHED();
4408 break;
4409 }
4410 }
4411 }
4412
[email protected]d49c5402013-09-11 15:39:024413 // If the default framebuffer is bound but we are still rendering to an
4414 // FBO, translate attachment names that refer to default framebuffer
4415 // channels to corresponding framebuffer attachments.
4416 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4417 for (GLsizei i = 0; i < numAttachments; ++i) {
4418 GLenum attachment = attachments[i];
4419 if (!framebuffer && GetBackbufferServiceId()) {
4420 switch (attachment) {
4421 case GL_COLOR_EXT:
4422 attachment = GL_COLOR_ATTACHMENT0;
4423 break;
4424 case GL_DEPTH_EXT:
4425 attachment = GL_DEPTH_ATTACHMENT;
4426 break;
4427 case GL_STENCIL_EXT:
4428 attachment = GL_STENCIL_ATTACHMENT;
4429 break;
4430 default:
4431 NOTREACHED();
4432 return;
4433 }
4434 }
4435 translated_attachments[i] = attachment;
4436 }
4437
boliu2e7d8a7a2014-10-16 20:35:204438 ScopedRenderTo do_render(framebuffer);
[email protected]d49c5402013-09-11 15:39:024439 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
[email protected]60f22d32012-12-12 00:31:584440}
4441
[email protected]07f54fcc2009-12-22 02:46:304442void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244443 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304444 glEnableVertexAttribArray(index);
4445 } else {
[email protected]ab09b612013-03-11 22:11:514446 LOCAL_SET_GL_ERROR(
4447 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304448 }
4449}
4450
[email protected]a93bb842010-02-16 23:03:474451void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444452 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4453 &state_, target);
[email protected]370eaf12013-05-18 09:19:494454 if (!texture_ref ||
4455 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514456 LOCAL_SET_GL_ERROR(
4457 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474458 return;
4459 }
[email protected]38c0a972012-05-12 00:48:024460
[email protected]12d95352012-12-14 07:23:544461 if (target == GL_TEXTURE_CUBE_MAP) {
4462 for (int i = 0; i < 6; ++i) {
4463 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494464 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514465 LOCAL_SET_GL_ERROR(
4466 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544467 return;
4468 }
4469 }
4470 } else {
[email protected]370eaf12013-05-18 09:19:494471 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514472 LOCAL_SET_GL_ERROR(
4473 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544474 return;
4475 }
[email protected]7687479c2012-05-14 23:54:044476 }
4477
[email protected]ab09b612013-03-11 22:11:514478 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194479 // Workaround for Mac driver bug. In the large scheme of things setting
4480 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564481 // hit so there's probably no need to make this conditional. The bug appears
4482 // to be that if the filtering mode is set to something that doesn't require
4483 // mipmaps for rendering, or is never set to something other than the default,
4484 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154485 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194486 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4487 }
[email protected]a93bb842010-02-16 23:03:474488 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154489 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494490 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4491 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194492 }
[email protected]ab09b612013-03-11 22:11:514493 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024494 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494495 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024496 }
[email protected]a93bb842010-02-16 23:03:474497}
4498
[email protected]b273e432010-04-12 17:23:584499bool GLES2DecoderImpl::GetHelper(
4500 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584501 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154502 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4503 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434504 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4505 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214506 // Return the GL implementation's preferred format and (see below type)
4507 // if we have the GL extension that exposes this. This allows the GPU
4508 // client to use the implementation's preferred format for glReadPixels
4509 // for optimisation.
4510 //
4511 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4512 // case when requested on integer/floating point buffers but which is
4513 // acceptable on GLES2 and with the GL_OES_read_format extension.
4514 //
4515 // Therefore if an error occurs we swallow the error and use the
4516 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434517 if (params) {
[email protected]c959a09a2014-03-27 11:44:214518 if (context_->HasExtension("GL_OES_read_format")) {
4519 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4520 GetErrorState());
4521 glGetIntegerv(pname, params);
4522 if (glGetError() == GL_NO_ERROR)
4523 return true;
4524 }
[email protected]68586372013-12-11 01:27:594525 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4526 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434527 }
4528 return true;
4529 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4530 *num_written = 1;
4531 if (params) {
[email protected]c959a09a2014-03-27 11:44:214532 if (context_->HasExtension("GL_OES_read_format")) {
4533 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4534 GetErrorState());
4535 glGetIntegerv(pname, params);
4536 if (glGetError() == GL_NO_ERROR)
4537 return true;
4538 }
[email protected]68586372013-12-11 01:27:594539 *params = GLES2Util::GetPreferredGLReadPixelsType(
4540 GetBoundReadFrameBufferInternalFormat(),
4541 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434542 }
4543 return true;
4544 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4545 *num_written = 1;
4546 if (params) {
4547 *params = group_->max_fragment_uniform_vectors();
4548 }
4549 return true;
4550 case GL_MAX_VARYING_VECTORS:
4551 *num_written = 1;
4552 if (params) {
4553 *params = group_->max_varying_vectors();
4554 }
4555 return true;
4556 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4557 *num_written = 1;
4558 if (params) {
4559 *params = group_->max_vertex_uniform_vectors();
4560 }
4561 return true;
[email protected]4e8a5b122010-05-08 22:00:104562 }
[email protected]5cb735d2011-10-13 01:37:234563 }
4564 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244565 case GL_MAX_VIEWPORT_DIMS:
4566 if (offscreen_target_frame_buffer_.get()) {
4567 *num_written = 2;
4568 if (params) {
4569 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4570 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4571 }
4572 return true;
4573 }
[email protected]5cb735d2011-10-13 01:37:234574 return false;
[email protected]84afefa2011-10-19 21:45:534575 case GL_MAX_SAMPLES:
4576 *num_written = 1;
4577 if (params) {
4578 params[0] = renderbuffer_manager()->max_samples();
4579 }
4580 return true;
4581 case GL_MAX_RENDERBUFFER_SIZE:
4582 *num_written = 1;
4583 if (params) {
4584 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4585 }
4586 return true;
[email protected]5cb735d2011-10-13 01:37:234587 case GL_MAX_TEXTURE_SIZE:
4588 *num_written = 1;
4589 if (params) {
4590 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4591 }
4592 return true;
4593 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4594 *num_written = 1;
4595 if (params) {
4596 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4597 }
4598 return true;
[email protected]2f143d482013-03-14 18:04:494599 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4600 *num_written = 1;
4601 if (params) {
4602 params[0] = group_->max_color_attachments();
4603 }
4604 return true;
4605 case GL_MAX_DRAW_BUFFERS_ARB:
4606 *num_written = 1;
4607 if (params) {
4608 params[0] = group_->max_draw_buffers();
4609 }
4610 return true;
[email protected]297ca1c2011-06-20 23:08:464611 case GL_ALPHA_BITS:
4612 *num_written = 1;
4613 if (params) {
4614 GLint v = 0;
4615 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544616 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464617 }
4618 return true;
4619 case GL_DEPTH_BITS:
4620 *num_written = 1;
4621 if (params) {
4622 GLint v = 0;
4623 glGetIntegerv(GL_DEPTH_BITS, &v);
4624 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4625 }
4626 return true;
4627 case GL_STENCIL_BITS:
4628 *num_written = 1;
4629 if (params) {
4630 GLint v = 0;
4631 glGetIntegerv(GL_STENCIL_BITS, &v);
4632 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4633 }
4634 return true;
[email protected]656dcaad2010-05-07 17:18:374635 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114636 *num_written = validators_->compressed_texture_format.GetValues().size();
4637 if (params) {
4638 for (GLint ii = 0; ii < *num_written; ++ii) {
4639 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4640 }
4641 }
[email protected]656dcaad2010-05-07 17:18:374642 return true;
[email protected]b273e432010-04-12 17:23:584643 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4644 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104645 if (params) {
[email protected]302ce6d2011-07-07 23:28:114646 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104647 }
[email protected]b273e432010-04-12 17:23:584648 return true;
4649 case GL_NUM_SHADER_BINARY_FORMATS:
4650 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104651 if (params) {
[email protected]302ce6d2011-07-07 23:28:114652 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104653 }
[email protected]b273e432010-04-12 17:23:584654 return true;
4655 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114656 *num_written = validators_->shader_binary_format.GetValues().size();
4657 if (params) {
4658 for (GLint ii = 0; ii < *num_written; ++ii) {
4659 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4660 }
4661 }
4662 return true;
[email protected]b273e432010-04-12 17:23:584663 case GL_SHADER_COMPILER:
4664 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104665 if (params) {
4666 *params = GL_TRUE;
4667 }
[email protected]b273e432010-04-12 17:23:584668 return true;
[email protected]6b8cf1a2010-05-06 16:13:584669 case GL_ARRAY_BUFFER_BINDING:
4670 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104671 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114672 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104673 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244674 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104675 &client_id);
4676 *params = client_id;
4677 } else {
4678 *params = 0;
4679 }
[email protected]6b8cf1a2010-05-06 16:13:584680 }
4681 return true;
4682 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4683 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104684 if (params) {
[email protected]e259eb412012-10-13 05:47:244685 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104686 GLuint client_id = 0;
4687 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254688 state_.vertex_attrib_manager->element_array_buffer()->
4689 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104690 *params = client_id;
4691 } else {
4692 *params = 0;
4693 }
[email protected]6b8cf1a2010-05-06 16:13:584694 }
4695 return true;
4696 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304697 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584698 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104699 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354700 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454701 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204702 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104703 GLuint client_id = 0;
4704 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204705 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304706 *params = client_id;
4707 } else {
4708 *params = 0;
4709 }
4710 }
4711 return true;
[email protected]ebfb73c2012-08-15 02:37:454712 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304713 *num_written = 1;
4714 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354715 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454716 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204717 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304718 GLuint client_id = 0;
4719 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204720 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104721 *params = client_id;
4722 } else {
4723 *params = 0;
4724 }
[email protected]6b8cf1a2010-05-06 16:13:584725 }
4726 return true;
4727 case GL_RENDERBUFFER_BINDING:
4728 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104729 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354730 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204731 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4732 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104733 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104734 } else {
4735 *params = 0;
4736 }
[email protected]6b8cf1a2010-05-06 16:13:584737 }
4738 return true;
4739 case GL_CURRENT_PROGRAM:
4740 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104741 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114742 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104743 GLuint client_id = 0;
4744 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244745 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104746 *params = client_id;
4747 } else {
4748 *params = 0;
4749 }
[email protected]6b8cf1a2010-05-06 16:13:584750 }
4751 return true;
[email protected]bf835842012-11-19 15:21:514752 case GL_VERTEX_ARRAY_BINDING_OES:
4753 *num_written = 1;
4754 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114755 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:524756 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:514757 GLuint client_id = 0;
4758 vertex_array_manager_->GetClientId(
4759 state_.vertex_attrib_manager->service_id(), &client_id);
4760 *params = client_id;
4761 } else {
4762 *params = 0;
4763 }
4764 }
4765 return true;
[email protected]4e8a5b122010-05-08 22:00:104766 case GL_TEXTURE_BINDING_2D:
4767 *num_written = 1;
4768 if (params) {
[email protected]e259eb412012-10-13 05:47:244769 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114770 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104771 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584772 } else {
4773 *params = 0;
4774 }
[email protected]6b8cf1a2010-05-06 16:13:584775 }
[email protected]4e8a5b122010-05-08 22:00:104776 return true;
4777 case GL_TEXTURE_BINDING_CUBE_MAP:
4778 *num_written = 1;
4779 if (params) {
[email protected]e259eb412012-10-13 05:47:244780 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114781 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104782 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584783 } else {
4784 *params = 0;
4785 }
[email protected]6b8cf1a2010-05-06 16:13:584786 }
[email protected]4e8a5b122010-05-08 22:00:104787 return true;
[email protected]61eeb33f2011-07-26 15:30:314788 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4789 *num_written = 1;
4790 if (params) {
[email protected]e259eb412012-10-13 05:47:244791 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114792 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104793 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314794 } else {
4795 *params = 0;
4796 }
4797 }
4798 return true;
[email protected]e51bdf32011-11-23 22:21:464799 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4800 *num_written = 1;
4801 if (params) {
[email protected]e259eb412012-10-13 05:47:244802 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114803 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104804 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464805 } else {
4806 *params = 0;
4807 }
4808 }
4809 return true;
[email protected]6c75c712012-06-19 15:43:174810 case GL_UNPACK_FLIP_Y_CHROMIUM:
4811 *num_written = 1;
4812 if (params) {
4813 params[0] = unpack_flip_y_;
4814 }
4815 return true;
4816 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4817 *num_written = 1;
4818 if (params) {
4819 params[0] = unpack_premultiply_alpha_;
4820 }
4821 return true;
4822 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4823 *num_written = 1;
4824 if (params) {
4825 params[0] = unpack_unpremultiply_alpha_;
4826 }
4827 return true;
[email protected]6eda6822014-04-03 23:00:504828 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4829 *num_written = 1;
4830 if (params) {
4831 params[0] = group_->bind_generates_resource() ? 1 : 0;
4832 }
4833 return true;
[email protected]b273e432010-04-12 17:23:584834 default:
[email protected]2f143d482013-03-14 18:04:494835 if (pname >= GL_DRAW_BUFFER0_ARB &&
4836 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4837 *num_written = 1;
4838 if (params) {
4839 Framebuffer* framebuffer =
4840 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4841 if (framebuffer) {
4842 params[0] = framebuffer->GetDrawBuffer(pname);
4843 } else { // backbuffer
4844 if (pname == GL_DRAW_BUFFER0_ARB)
4845 params[0] = group_->draw_buffer();
4846 else
4847 params[0] = GL_NONE;
4848 }
4849 }
4850 return true;
4851 }
[email protected]4e8a5b122010-05-08 22:00:104852 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534853 return false;
[email protected]b273e432010-04-12 17:23:584854 }
4855}
4856
[email protected]4e8a5b122010-05-08 22:00:104857bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4858 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264859 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534860 return true;
4861 }
[email protected]4e8a5b122010-05-08 22:00:104862 return GetHelper(pname, NULL, num_values);
4863}
4864
[email protected]7d3c36e2013-07-12 14:13:164865GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4866 if (GL_MAX_SAMPLES == pname &&
4867 features().use_img_for_multisampled_render_to_texture) {
4868 return GL_MAX_SAMPLES_IMG;
4869 }
4870 return pname;
4871}
4872
[email protected]b273e432010-04-12 17:23:584873void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4874 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104875 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534876 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554877 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264878 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534879 GetHelper(pname, values.get(), &num_written);
4880 }
[email protected]b273e432010-04-12 17:23:584881 for (GLsizei ii = 0; ii < num_written; ++ii) {
4882 params[ii] = static_cast<GLboolean>(values[ii]);
4883 }
4884 } else {
[email protected]7d3c36e2013-07-12 14:13:164885 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584886 glGetBooleanv(pname, params);
4887 }
4888}
4889
4890void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4891 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104892 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264893 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534894 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554895 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534896 GetHelper(pname, values.get(), &num_written);
4897 for (GLsizei ii = 0; ii < num_written; ++ii) {
4898 params[ii] = static_cast<GLfloat>(values[ii]);
4899 }
4900 } else {
[email protected]7d3c36e2013-07-12 14:13:164901 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534902 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584903 }
[email protected]b273e432010-04-12 17:23:584904 }
4905}
4906
4907void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4908 DCHECK(params);
4909 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264910 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534911 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164912 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584913 glGetIntegerv(pname, params);
4914 }
4915}
4916
[email protected]a0c3e972010-04-21 00:49:134917void GLES2DecoderImpl::DoGetProgramiv(
4918 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424919 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4920 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134921 return;
4922 }
[email protected]df37b9932013-03-08 05:21:424923 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134924}
4925
[email protected]17cfbe0e2013-03-07 01:26:084926void GLES2DecoderImpl::DoGetBufferParameteriv(
4927 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134928 // Just delegate it. Some validation is actually done before this.
4929 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4930 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084931}
4932
[email protected]258a3313f2011-10-18 20:13:574933void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424934 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574935 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514936 LOCAL_SET_GL_ERROR(
4937 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574938 return;
4939 }
[email protected]68dcb1f2012-04-07 00:14:564940 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514941 LOCAL_SET_GL_ERROR(
4942 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564943 return;
4944 }
4945 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514946 LOCAL_SET_GL_ERROR(
4947 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564948 return;
4949 }
[email protected]df37b9932013-03-08 05:21:424950 Program* program = GetProgramInfoNotShader(
4951 program_id, "glBindAttribLocation");
4952 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574953 return;
[email protected]558847a2010-03-24 07:02:544954 }
zmo460b593e2014-10-13 23:07:454955 // At this point, the program's shaders may not be translated yet,
4956 // therefore, we may not find the hashed attribute name.
4957 // glBindAttribLocation call with original name is useless.
4958 // So instead, we should simply cache the binding, and then call
4959 // Program::ExecuteBindAttribLocationCalls() right before link.
[email protected]df37b9932013-03-08 05:21:424960 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
zmo460b593e2014-10-13 23:07:454961 // TODO(zmo): Get rid of the following glBindAttribLocation call.
[email protected]df37b9932013-03-08 05:21:424962 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574963}
4964
[email protected]558847a2010-03-24 07:02:544965error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:344966 uint32 immediate_data_size,
4967 const void* cmd_data) {
4968 const gles2::cmds::BindAttribLocationBucket& c =
4969 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:584970 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544971 GLuint index = static_cast<GLuint>(c.index);
4972 Bucket* bucket = GetBucket(c.name_bucket_id);
4973 if (!bucket || bucket->size() == 0) {
4974 return error::kInvalidArguments;
4975 }
4976 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184977 if (!bucket->GetAsString(&name_str)) {
4978 return error::kInvalidArguments;
4979 }
[email protected]258a3313f2011-10-18 20:13:574980 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544981 return error::kNoError;
4982}
4983
[email protected]2be6abf32012-06-26 00:28:334984void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424985 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334986 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514987 LOCAL_SET_GL_ERROR(
4988 GL_INVALID_VALUE,
4989 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334990 return;
4991 }
4992 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514993 LOCAL_SET_GL_ERROR(
4994 GL_INVALID_OPERATION,
4995 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334996 return;
4997 }
4998 if (location < 0 || static_cast<uint32>(location) >=
4999 (group_->max_fragment_uniform_vectors() +
5000 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:515001 LOCAL_SET_GL_ERROR(
5002 GL_INVALID_VALUE,
5003 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335004 return;
5005 }
[email protected]df37b9932013-03-08 05:21:425006 Program* program = GetProgramInfoNotShader(
5007 program_id, "glBindUniformLocationCHROMIUM");
5008 if (!program) {
[email protected]2be6abf32012-06-26 00:28:335009 return;
5010 }
[email protected]df37b9932013-03-08 05:21:425011 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:515012 LOCAL_SET_GL_ERROR(
5013 GL_INVALID_VALUE,
5014 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335015 }
5016}
5017
[email protected]2be6abf32012-06-26 00:28:335018error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
5019 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:345020 const void* cmd_data) {
5021 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
5022 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
5023 cmd_data);
[email protected]2be6abf32012-06-26 00:28:335024 GLuint program = static_cast<GLuint>(c.program);
5025 GLint location = static_cast<GLint>(c.location);
5026 Bucket* bucket = GetBucket(c.name_bucket_id);
5027 if (!bucket || bucket->size() == 0) {
5028 return error::kInvalidArguments;
5029 }
5030 std::string name_str;
5031 if (!bucket->GetAsString(&name_str)) {
5032 return error::kInvalidArguments;
5033 }
5034 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
5035 return error::kNoError;
5036}
5037
vmiuracd108592014-09-08 14:36:345038error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
5039 const void* cmd_data) {
5040 const gles2::cmds::DeleteShader& c =
5041 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035042 GLuint client_id = c.shader;
5043 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425044 Shader* shader = GetShader(client_id);
5045 if (shader) {
5046 if (!shader->IsDeleted()) {
5047 glDeleteShader(shader->service_id());
5048 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:145049 }
[email protected]ae51d192010-04-27 00:48:035050 } else {
[email protected]ab09b612013-03-11 22:11:515051 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:035052 }
[email protected]96449d2c2009-11-25 00:01:325053 }
[email protected]f7a64ee2010-02-01 22:24:145054 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325055}
5056
vmiuracd108592014-09-08 14:36:345057error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
5058 const void* cmd_data) {
5059 const gles2::cmds::DeleteProgram& c =
5060 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035061 GLuint client_id = c.program;
5062 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425063 Program* program = GetProgram(client_id);
5064 if (program) {
5065 if (!program->IsDeleted()) {
5066 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:145067 }
[email protected]ae51d192010-04-27 00:48:035068 } else {
[email protected]ab09b612013-03-11 22:11:515069 LOCAL_SET_GL_ERROR(
5070 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:035071 }
[email protected]96449d2c2009-11-25 00:01:325072 }
[email protected]f7a64ee2010-02-01 22:24:145073 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325074}
5075
[email protected]a7266a92012-06-28 02:11:085076error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:445077 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:205078 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:465079 ApplyDirtyState();
boliu2e7d8a7a2014-10-16 20:35:205080 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]3a03a8f2011-03-19 00:51:275081 glClear(mask);
5082 }
[email protected]a7266a92012-06-28 02:11:085083 return error::kNoError;
5084}
5085
[email protected]36cef8ce2010-03-16 07:34:455086void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5087 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035088 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065089 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5090 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515091 LOCAL_SET_GL_ERROR(
5092 GL_INVALID_OPERATION,
5093 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455094 return;
5095 }
[email protected]ae51d192010-04-27 00:48:035096 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275097 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035098 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275099 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5100 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515101 LOCAL_SET_GL_ERROR(
5102 GL_INVALID_OPERATION,
5103 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035104 return;
5105 }
[email protected]ee2a79c32013-03-10 03:50:275106 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035107 }
[email protected]ab09b612013-03-11 22:11:515108 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035109 glFramebufferRenderbufferEXT(
5110 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515111 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265112 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275113 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285114 }
[email protected]9d3b2e12013-10-02 01:04:345115 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445116 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465117 }
[email protected]81fc9d02013-03-14 23:53:325118 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285119}
5120
[email protected]3a2e7c7b2010-08-06 01:12:285121void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465122 if (SetCapabilityState(cap, false)) {
5123 glDisable(cap);
5124 }
[email protected]3a2e7c7b2010-08-06 01:12:285125}
5126
5127void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465128 if (SetCapabilityState(cap, true)) {
5129 glEnable(cap);
5130 }
[email protected]3a2e7c7b2010-08-06 01:12:285131}
5132
[email protected]88a61bf2012-10-27 13:00:425133void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5134 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5135 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5136 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285137}
5138
[email protected]b04e24c2013-01-08 18:35:255139void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425140 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5141 state_.sample_coverage_invert = (invert != 0);
5142 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285143}
5144
[email protected]0d6bfdc2011-11-02 01:32:205145// Assumes framebuffer is complete.
5146void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065147 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305148 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205149 // bind this to the DRAW point, clear then bind back to READ
5150 // TODO(gman): I don't think there is any guarantee that an FBO that
5151 // is complete on the READ attachment will be complete as a DRAW
5152 // attachment.
5153 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065154 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305155 }
[email protected]3a2e7c7b2010-08-06 01:12:285156 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425157 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465158 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205159 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465160 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065161 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5162 1.0f);
[email protected]454157e2014-05-03 02:49:455163 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285164 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535165 if (feature_info_->feature_flags().ext_draw_buffers)
5166 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285167 }
5168
[email protected]4d8f0dd2013-03-09 14:37:065169 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5170 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285171 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475172 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5173 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285174 clear_bits |= GL_STENCIL_BUFFER_BIT;
5175 }
5176
[email protected]4d8f0dd2013-03-09 14:37:065177 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5178 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285179 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455180 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285181 clear_bits |= GL_DEPTH_BUFFER_BIT;
5182 }
5183
[email protected]454157e2014-05-03 02:49:455184 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285185 glClear(clear_bits);
5186
brucedawson18249152014-10-31 23:02:325187 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]0e58af82014-08-08 14:02:535188 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425189 framebuffer->RestoreDrawBuffersAfterClear();
5190
[email protected]968351b2011-12-20 08:26:515191 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065192 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285193
[email protected]c007aa02010-09-02 22:22:405194 RestoreClearState();
5195
5196 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065197 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5198 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485199 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065200 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5201 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485202 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405203 }
5204}
5205
5206void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445207 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245208 glClearColor(
5209 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5210 state_.color_clear_alpha);
5211 glClearStencil(state_.stencil_clear);
5212 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225213 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455214 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285215 }
[email protected]36cef8ce2010-03-16 07:34:455216}
5217
5218GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355219 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305220 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205221 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455222 return GL_FRAMEBUFFER_COMPLETE;
5223 }
[email protected]0d6bfdc2011-11-02 01:32:205224 GLenum completeness = framebuffer->IsPossiblyComplete();
5225 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5226 return completeness;
5227 }
[email protected]73276522012-11-09 05:50:205228 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455229}
5230
5231void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035232 GLenum target, GLenum attachment, GLenum textarget,
5233 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165234 DoFramebufferTexture2DCommon(
5235 "glFramebufferTexture2D", target, attachment,
5236 textarget, client_texture_id, level, 0);
5237}
5238
5239void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5240 GLenum target, GLenum attachment, GLenum textarget,
5241 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165242 DoFramebufferTexture2DCommon(
5243 "glFramebufferTexture2DMultisample", target, attachment,
5244 textarget, client_texture_id, level, samples);
5245}
5246
5247void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5248 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5249 GLuint client_texture_id, GLint level, GLsizei samples) {
5250 if (samples > renderbuffer_manager()->max_samples()) {
5251 LOCAL_SET_GL_ERROR(
5252 GL_INVALID_VALUE,
5253 "glFramebufferTexture2DMultisample", "samples too large");
5254 return;
5255 }
[email protected]4d8f0dd2013-03-09 14:37:065256 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5257 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515258 LOCAL_SET_GL_ERROR(
5259 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165260 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455261 return;
5262 }
[email protected]ae51d192010-04-27 00:48:035263 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495264 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035265 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495266 texture_ref = GetTexture(client_texture_id);
5267 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515268 LOCAL_SET_GL_ERROR(
5269 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165270 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035271 return;
5272 }
[email protected]370eaf12013-05-18 09:19:495273 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035274 }
[email protected]0d6bfdc2011-11-02 01:32:205275
[email protected]80eb6b52012-01-19 00:14:415276 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515277 LOCAL_SET_GL_ERROR(
5278 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165279 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205280 return;
5281 }
5282
[email protected]91c94eb2013-10-22 10:32:545283 if (texture_ref)
5284 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5285
[email protected]7d3c36e2013-07-12 14:13:165286 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5287 if (0 == samples) {
5288 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5289 } else {
5290 if (features().use_img_for_multisampled_render_to_texture) {
5291 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5292 service_id, level, samples);
5293 } else {
5294 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5295 service_id, level, samples);
5296 }
5297 }
5298 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265299 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165300 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5301 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285302 }
[email protected]9d3b2e12013-10-02 01:04:345303 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445304 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465305 }
[email protected]91c94eb2013-10-22 10:32:545306
5307 if (texture_ref)
5308 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5309
[email protected]81fc9d02013-03-14 23:53:325310 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455311}
5312
5313void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5314 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065315 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5316 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515317 LOCAL_SET_GL_ERROR(
5318 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205319 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455320 return;
5321 }
[email protected]74c1ec42010-08-12 01:55:575322 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105323 const Framebuffer::Attachment* attachment_object =
5324 framebuffer->GetAttachment(attachment);
5325 *params = attachment_object ? attachment_object->object_name() : 0;
5326 } else {
[email protected]7d3c36e2013-07-12 14:13:165327 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5328 features().use_img_for_multisampled_render_to_texture) {
5329 pname = GL_TEXTURE_SAMPLES_IMG;
5330 }
[email protected]62e65f02013-05-29 22:28:105331 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575332 }
[email protected]36cef8ce2010-03-16 07:34:455333}
5334
5335void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5336 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355337 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205338 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5339 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515340 LOCAL_SET_GL_ERROR(
5341 GL_INVALID_OPERATION,
5342 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455343 return;
5344 }
[email protected]8875a5f2014-06-27 08:33:475345
5346 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275347 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435348 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5349 *params = renderbuffer->internal_format();
5350 break;
5351 case GL_RENDERBUFFER_WIDTH:
5352 *params = renderbuffer->width();
5353 break;
5354 case GL_RENDERBUFFER_HEIGHT:
5355 *params = renderbuffer->height();
5356 break;
[email protected]7d3c36e2013-07-12 14:13:165357 case GL_RENDERBUFFER_SAMPLES_EXT:
5358 if (features().use_img_for_multisampled_render_to_texture) {
5359 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5360 params);
5361 } else {
5362 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5363 params);
5364 }
[email protected]ad84a3a2012-06-08 21:42:435365 default:
5366 glGetRenderbufferParameterivEXT(target, pname, params);
5367 break;
[email protected]b71f52c2010-06-18 22:20:205368 }
[email protected]36cef8ce2010-03-16 07:34:455369}
5370
[email protected]49cabed2013-11-13 18:15:185371void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305372 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5373 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5374 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445375 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165376
[email protected]49cabed2013-11-13 18:15:185377 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165378 return;
5379 }
5380
[email protected]454157e2014-05-03 02:49:455381 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
boliu2e7d8a7a2014-10-16 20:35:205382 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]f42f05b2013-11-15 21:46:185383 BlitFramebufferHelper(
5384 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455385 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5386 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185387}
5388
[email protected]8875a5f2014-06-27 08:33:475389void GLES2DecoderImpl::EnsureRenderbufferBound() {
5390 if (!state_.bound_renderbuffer_valid) {
5391 state_.bound_renderbuffer_valid = true;
5392 glBindRenderbufferEXT(GL_RENDERBUFFER,
5393 state_.bound_renderbuffer.get()
5394 ? state_.bound_renderbuffer->service_id()
5395 : 0);
5396 }
5397}
5398
[email protected]f42f05b2013-11-15 21:46:185399void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5400 const FeatureInfo* feature_info,
5401 GLenum target,
5402 GLsizei samples,
5403 GLenum internal_format,
5404 GLsizei width,
5405 GLsizei height) {
5406 // TODO(sievers): This could be resolved at the GL binding level, but the
5407 // binding process is currently a bit too 'brute force'.
5408 if (feature_info->feature_flags().is_angle) {
5409 glRenderbufferStorageMultisampleANGLE(
5410 target, samples, internal_format, width, height);
5411 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5412 glRenderbufferStorageMultisample(
5413 target, samples, internal_format, width, height);
5414 } else {
5415 glRenderbufferStorageMultisampleEXT(
5416 target, samples, internal_format, width, height);
5417 }
5418}
5419
5420void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5421 GLint srcY0,
5422 GLint srcX1,
5423 GLint srcY1,
5424 GLint dstX0,
5425 GLint dstY0,
5426 GLint dstX1,
5427 GLint dstY1,
5428 GLbitfield mask,
5429 GLenum filter) {
5430 // TODO(sievers): This could be resolved at the GL binding level, but the
5431 // binding process is currently a bit too 'brute force'.
5432 if (feature_info_->feature_flags().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245433 glBlitFramebufferANGLE(
5434 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185435 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5436 glBlitFramebuffer(
5437 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245438 } else {
5439 glBlitFramebufferEXT(
5440 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5441 }
[email protected]8e3e0662010-08-23 18:46:305442}
5443
[email protected]49cabed2013-11-13 18:15:185444bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5445 GLsizei samples,
5446 GLenum internalformat,
5447 GLsizei width,
5448 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535449 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515450 LOCAL_SET_GL_ERROR(
5451 GL_INVALID_VALUE,
5452 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185453 return false;
[email protected]84afefa2011-10-19 21:45:535454 }
5455
5456 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5457 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515458 LOCAL_SET_GL_ERROR(
5459 GL_INVALID_VALUE,
5460 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185461 return false;
[email protected]84afefa2011-10-19 21:45:535462 }
5463
[email protected]7989c9e2013-01-23 06:39:265464 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235465 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5466 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515467 LOCAL_SET_GL_ERROR(
5468 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205469 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185470 return false;
[email protected]8e3e0662010-08-23 18:46:305471 }
5472
[email protected]7989c9e2013-01-23 06:39:265473 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515474 LOCAL_SET_GL_ERROR(
5475 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205476 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185477 return false;
5478 }
5479
5480 return true;
5481}
5482
5483void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5484 GLenum target, GLsizei samples, GLenum internalformat,
5485 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185486 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5487 if (!renderbuffer) {
5488 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5489 "glRenderbufferStorageMultisampleCHROMIUM",
5490 "no renderbuffer bound");
5491 return;
5492 }
5493
5494 if (!ValidateRenderbufferStorageMultisample(
5495 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265496 return;
5497 }
5498
[email protected]8875a5f2014-06-27 08:33:475499 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235500 GLenum impl_format =
5501 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5502 internalformat);
[email protected]49cabed2013-11-13 18:15:185503 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5504 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185505 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:255506 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185507 GLenum error =
5508 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265509 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105510
5511 if (workarounds().validate_multisample_buffer_allocation) {
5512 if (!VerifyMultisampleRenderbufferIntegrity(
5513 renderbuffer->service_id(), impl_format)) {
5514 LOCAL_SET_GL_ERROR(
5515 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185516 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105517 return;
5518 }
5519 }
5520
[email protected]968351b2011-12-20 08:26:515521 // TODO(gman): If renderbuffers tracked which framebuffers they were
5522 // attached to we could just mark those framebuffers as not complete.
5523 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205524 renderbuffer_manager()->SetInfo(
5525 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265526 }
[email protected]8e3e0662010-08-23 18:46:305527}
5528
[email protected]49cabed2013-11-13 18:15:185529// This is the handler for multisampled_render_to_texture extensions.
5530void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5531 GLenum target, GLsizei samples, GLenum internalformat,
5532 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185533 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5534 if (!renderbuffer) {
5535 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5536 "glRenderbufferStorageMultisampleEXT",
5537 "no renderbuffer bound");
5538 return;
5539 }
5540
5541 if (!ValidateRenderbufferStorageMultisample(
5542 samples, internalformat, width, height)) {
5543 return;
5544 }
5545
[email protected]8875a5f2014-06-27 08:33:475546 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185547 GLenum impl_format =
5548 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5549 internalformat);
5550 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5551 if (features().use_img_for_multisampled_render_to_texture) {
5552 glRenderbufferStorageMultisampleIMG(
5553 target, samples, impl_format, width, height);
5554 } else {
5555 glRenderbufferStorageMultisampleEXT(
5556 target, samples, impl_format, width, height);
5557 }
5558 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5559 if (error == GL_NO_ERROR) {
5560 // TODO(gman): If renderbuffers tracked which framebuffers they were
5561 // attached to we could just mark those framebuffers as not complete.
5562 framebuffer_manager()->IncFramebufferStateChangeCount();
5563 renderbuffer_manager()->SetInfo(
5564 renderbuffer, samples, internalformat, width, height);
5565 }
5566}
5567
[email protected]4a4c18b2013-09-13 22:50:105568// This function validates the allocation of a multisampled renderbuffer
5569// by clearing it to a key color, blitting the contents to a texture, and
5570// reading back the color to ensure it matches the key.
5571bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5572 GLuint renderbuffer, GLenum format) {
5573
5574 // Only validate color buffers.
5575 // These formats have been selected because they are very common or are known
5576 // to be used by the WebGL backbuffer. If problems are observed with other
5577 // color formats they can be added here.
5578 switch(format) {
5579 case GL_RGB:
5580 case GL_RGB8:
5581 case GL_RGBA:
5582 case GL_RGBA8:
5583 break;
5584 default:
5585 return true;
5586 }
5587
5588 GLint draw_framebuffer, read_framebuffer;
5589
5590 // Cache framebuffer and texture bindings.
5591 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5592 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5593
5594 if (!validation_texture_) {
5595 GLint bound_texture;
5596 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5597
5598 // Create additional resources needed for the verification.
5599 glGenTextures(1, &validation_texture_);
5600 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5601 glGenFramebuffersEXT(1, &validation_fbo_);
5602
5603 // Texture only needs to be 1x1.
5604 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5605 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5606 GL_UNSIGNED_BYTE, NULL);
5607
5608 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5609 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5610 GL_TEXTURE_2D, validation_texture_, 0);
5611
5612 glBindTexture(GL_TEXTURE_2D, bound_texture);
5613 }
5614
5615 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5616 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5617 GL_RENDERBUFFER, renderbuffer);
5618
5619 // Cache current state and reset it to the values we require.
5620 GLboolean scissor_enabled = false;
5621 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5622 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455623 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105624
[email protected]454157e2014-05-03 02:49:455625 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105626 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455627 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105628
5629 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5630 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5631 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5632
5633 // Clear the buffer to the desired key color.
5634 glClear(GL_COLOR_BUFFER_BIT);
5635
5636 // Blit from the multisample buffer to a standard texture.
5637 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5638 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5639
[email protected]f42f05b2013-11-15 21:46:185640 BlitFramebufferHelper(
5641 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105642
5643 // Read a pixel from the buffer.
5644 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5645
5646 unsigned char pixel[3] = {0, 0, 0};
5647 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5648
5649 // Detach the renderbuffer.
5650 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5651 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5652 GL_RENDERBUFFER, 0);
5653
5654 // Restore cached state.
5655 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455656 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105657
[email protected]454157e2014-05-03 02:49:455658 state_.SetDeviceColorMask(
5659 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105660 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5661 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5662 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5663
5664 // Return true if the pixel matched the desired key color.
5665 return (pixel[0] == 0xFF &&
5666 pixel[1] == 0x00 &&
5667 pixel[2] == 0xFF);
5668}
5669
[email protected]36cef8ce2010-03-16 07:34:455670void GLES2DecoderImpl::DoRenderbufferStorage(
5671 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355672 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205673 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5674 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515675 LOCAL_SET_GL_ERROR(
5676 GL_INVALID_OPERATION,
5677 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455678 return;
5679 }
[email protected]876f6fee2010-08-02 23:10:325680
[email protected]84afefa2011-10-19 21:45:535681 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5682 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515683 LOCAL_SET_GL_ERROR(
5684 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535685 return;
5686 }
5687
[email protected]7989c9e2013-01-23 06:39:265688 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235689 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5690 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515691 LOCAL_SET_GL_ERROR(
5692 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265693 return;
5694 }
5695
5696 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515697 LOCAL_SET_GL_ERROR(
5698 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265699 return;
[email protected]b71f52c2010-06-18 22:20:205700 }
[email protected]876f6fee2010-08-02 23:10:325701
[email protected]8875a5f2014-06-27 08:33:475702 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:515703 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265704 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235705 target,
5706 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5707 internalformat),
5708 width,
5709 height);
[email protected]ab09b612013-03-11 22:11:515710 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265711 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515712 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5713 // we could just mark those framebuffers as not complete.
5714 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205715 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265716 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265717 }
[email protected]36cef8ce2010-03-16 07:34:455718}
5719
[email protected]df37b9932013-03-08 05:21:425720void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385721 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425722 Program* program = GetProgramInfoNotShader(
5723 program_id, "glLinkProgram");
5724 if (!program) {
[email protected]a93bb842010-02-16 23:03:475725 return;
5726 }
[email protected]05afda12011-01-20 00:17:345727
[email protected]df37b9932013-03-08 05:21:425728 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395729 ShaderTranslator* vertex_translator = NULL;
5730 ShaderTranslator* fragment_translator = NULL;
5731 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115732 vertex_translator = vertex_translator_.get();
5733 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395734 }
[email protected]df37b9932013-03-08 05:21:425735 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115736 vertex_translator,
5737 fragment_translator,
[email protected]008401532014-02-07 00:10:505738 workarounds().count_all_in_varyings_packing ?
5739 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115740 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425741 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185742 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425743 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185744 if (workarounds().clear_uniforms_before_first_program_use)
5745 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545746 }
5747 }
vmiura8266ca72014-09-09 21:37:005748
5749 // LinkProgram can be very slow. Exit command processing to allow for
5750 // context preemption and GPU watchdog checks.
5751 ExitCommandProcessingEarly();
[email protected]07f54fcc2009-12-22 02:46:305752};
5753
[email protected]3916c97e2010-02-25 03:20:505754void GLES2DecoderImpl::DoTexParameterf(
5755 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445756 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5757 &state_, target);
[email protected]02965c22013-03-09 02:40:075758 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515759 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245760 return;
[email protected]07f54fcc2009-12-22 02:46:305761 }
[email protected]cbb22e42011-05-12 23:36:245762
[email protected]737191ee72014-03-09 08:02:425763 texture_manager()->SetParameterf(
5764 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305765}
5766
[email protected]3916c97e2010-02-25 03:20:505767void GLES2DecoderImpl::DoTexParameteri(
5768 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445769 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5770 &state_, target);
[email protected]02965c22013-03-09 02:40:075771 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515772 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245773 return;
[email protected]3916c97e2010-02-25 03:20:505774 }
[email protected]cbb22e42011-05-12 23:36:245775
[email protected]737191ee72014-03-09 08:02:425776 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505777 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505778}
5779
5780void GLES2DecoderImpl::DoTexParameterfv(
5781 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445782 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5783 &state_, target);
[email protected]02965c22013-03-09 02:40:075784 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515785 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245786 return;
[email protected]3916c97e2010-02-25 03:20:505787 }
[email protected]cbb22e42011-05-12 23:36:245788
[email protected]737191ee72014-03-09 08:02:425789 texture_manager()->SetParameterf(
5790 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505791}
5792
5793void GLES2DecoderImpl::DoTexParameteriv(
5794 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445795 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5796 &state_, target);
[email protected]02965c22013-03-09 02:40:075797 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515798 LOCAL_SET_GL_ERROR(
5799 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245800 return;
[email protected]3916c97e2010-02-25 03:20:505801 }
[email protected]cbb22e42011-05-12 23:36:245802
[email protected]737191ee72014-03-09 08:02:425803 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505804 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505805}
5806
orglofchcad5a6742014-11-07 19:51:125807bool GLES2DecoderImpl::CheckCurrentValuebuffer(const char* function_name) {
5808 if (!state_.bound_valuebuffer.get()) {
5809 // There is no valuebuffer bound
5810 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5811 "no valuebuffer in use");
5812 return false;
5813 }
5814 return true;
5815}
5816
5817bool GLES2DecoderImpl::CheckCurrentValuebufferForSubscription(
5818 GLenum subscription,
5819 const char* function_name) {
5820 if (!CheckCurrentValuebuffer(function_name)) {
5821 return false;
5822 }
5823 if (!state_.bound_valuebuffer.get()->IsSubscribed(subscription)) {
5824 // The valuebuffer is not subscribed to the target
5825 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5826 "valuebuffer is not subscribed");
5827 return false;
5828 }
5829 return true;
5830}
5831
5832bool GLES2DecoderImpl::CheckSubscriptionTarget(GLint location,
5833 GLenum subscription,
5834 const char* function_name) {
5835 if (!CheckCurrentProgramForUniform(location, function_name)) {
5836 return false;
5837 }
5838 GLint real_location = -1;
5839 GLint array_index = -1;
5840 const Program::UniformInfo* info =
5841 state_.current_program->GetUniformInfoByFakeLocation(
5842 location, &real_location, &array_index);
5843 if (!info) {
5844 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "unknown location");
5845 return false;
5846 }
5847 if ((ValuebufferManager::ApiTypeForSubscriptionTarget(subscription) &
5848 info->accepts_api_type) == 0) {
5849 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5850 "wrong type for subscription");
5851 return false;
5852 }
5853 return true;
5854}
5855
[email protected]939e7362010-05-13 20:49:105856bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115857 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435858 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515859 LOCAL_SET_GL_ERROR(
5860 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435861 return false;
[email protected]939e7362010-05-13 20:49:105862 }
[email protected]e259eb412012-10-13 05:47:245863 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515864 LOCAL_SET_GL_ERROR(
5865 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105866 return false;
5867 }
5868 return true;
5869}
5870
5871bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5872 GLint location, const char* function_name) {
5873 if (!CheckCurrentProgram(function_name)) {
5874 return false;
5875 }
5876 return location != -1;
5877}
5878
zmof9a81360f2014-10-17 00:06:145879bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
5880 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
5881 if (!framebuffer)
5882 return false;
5883 const Framebuffer::Attachment* attachment =
5884 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
5885 if (!attachment)
5886 return false;
5887
5888 DCHECK(state_.current_program.get());
5889 const Program::SamplerIndices& sampler_indices =
5890 state_.current_program->sampler_indices();
5891 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5892 const Program::UniformInfo* uniform_info =
5893 state_.current_program->GetUniformInfo(sampler_indices[ii]);
5894 DCHECK(uniform_info);
5895 if (uniform_info->type != GL_SAMPLER_2D)
5896 continue;
5897 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5898 GLuint texture_unit_index = uniform_info->texture_units[jj];
5899 if (texture_unit_index >= state_.texture_units.size())
5900 continue;
5901 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
5902 TextureRef* texture_ref =
5903 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
5904 if (attachment->IsTexture(texture_ref))
5905 return true;
5906 }
5907 }
5908 return false;
5909}
5910
orglofchcad5a6742014-11-07 19:51:125911bool GLES2DecoderImpl::CheckUniformForApiType(
5912 const Program::UniformInfo* info,
5913 const char* function_name,
5914 Program::UniformApiType api_type) {
5915 DCHECK(info);
5916 if ((api_type & info->accepts_api_type) == 0) {
5917 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5918 "wrong uniform function for type");
5919 return false;
5920 }
5921 return true;
5922}
5923
[email protected]43c2f1f2011-03-25 18:35:365924bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:135925 GLint fake_location,
5926 const char* function_name,
5927 Program::UniformApiType api_type,
5928 GLint* real_location,
5929 GLenum* type,
5930 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365931 DCHECK(type);
5932 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125933 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525934
[email protected]1b0a6752012-02-22 03:44:125935 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105936 return false;
5937 }
[email protected]43c2f1f2011-03-25 18:35:365938 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355939 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245940 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125941 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365942 if (!info) {
[email protected]ab09b612013-03-11 22:11:515943 LOCAL_SET_GL_ERROR(
5944 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105945 return false;
5946 }
orglofchcad5a6742014-11-07 19:51:125947 if (!CheckUniformForApiType(info, function_name, api_type)) {
[email protected]476ccb72012-12-06 15:52:525948 return false;
5949 }
[email protected]43c2f1f2011-03-25 18:35:365950 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515951 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435952 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365953 return false;
5954 }
5955 *count = std::min(info->size - array_index, *count);
5956 if (*count <= 0) {
5957 return false;
5958 }
5959 *type = info->type;
[email protected]939e7362010-05-13 20:49:105960 return true;
5961}
5962
[email protected]1b0a6752012-02-22 03:44:125963void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5964 GLenum type = 0;
5965 GLsizei count = 1;
5966 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135967 if (!PrepForSetUniformByLocation(fake_location,
5968 "glUniform1i",
5969 Program::kUniform1i,
5970 &real_location,
5971 &type,
5972 &count)) {
[email protected]3916c97e2010-02-25 03:20:505973 return;
5974 }
[email protected]e259eb412012-10-13 05:47:245975 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025976 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515977 LOCAL_SET_GL_ERROR(
5978 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465979 return;
5980 }
[email protected]1b0a6752012-02-22 03:44:125981 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505982}
5983
5984void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125985 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365986 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125987 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135988 if (!PrepForSetUniformByLocation(fake_location,
5989 "glUniform1iv",
5990 Program::kUniform1i,
5991 &real_location,
5992 &type,
5993 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365994 return;
5995 }
[email protected]74727112012-06-13 21:18:085996 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5997 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245998 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025999 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:516000 LOCAL_SET_GL_ERROR(
6001 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466002 return;
6003 }
[email protected]43c2f1f2011-03-25 18:35:366004 }
[email protected]1b0a6752012-02-22 03:44:126005 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:506006}
6007
[email protected]939e7362010-05-13 20:49:106008void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:126009 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366010 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126011 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136012 if (!PrepForSetUniformByLocation(fake_location,
6013 "glUniform1fv",
6014 Program::kUniform1f,
6015 &real_location,
6016 &type,
6017 &count)) {
[email protected]939e7362010-05-13 20:49:106018 return;
6019 }
6020 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:556021 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:106022 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:536023 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106024 }
[email protected]1b0a6752012-02-22 03:44:126025 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106026 } else {
[email protected]1b0a6752012-02-22 03:44:126027 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106028 }
6029}
6030
6031void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:126032 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366033 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126034 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136035 if (!PrepForSetUniformByLocation(fake_location,
6036 "glUniform2fv",
6037 Program::kUniform2f,
6038 &real_location,
6039 &type,
6040 &count)) {
[email protected]939e7362010-05-13 20:49:106041 return;
6042 }
6043 if (type == GL_BOOL_VEC2) {
6044 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:556045 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106046 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536047 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106048 }
[email protected]1b0a6752012-02-22 03:44:126049 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106050 } else {
[email protected]1b0a6752012-02-22 03:44:126051 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106052 }
6053}
6054
6055void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:126056 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366057 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126058 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136059 if (!PrepForSetUniformByLocation(fake_location,
6060 "glUniform3fv",
6061 Program::kUniform3f,
6062 &real_location,
6063 &type,
6064 &count)) {
[email protected]939e7362010-05-13 20:49:106065 return;
6066 }
6067 if (type == GL_BOOL_VEC3) {
6068 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:556069 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106070 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536071 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106072 }
[email protected]1b0a6752012-02-22 03:44:126073 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106074 } else {
[email protected]1b0a6752012-02-22 03:44:126075 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106076 }
6077}
6078
6079void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:126080 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366081 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126082 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136083 if (!PrepForSetUniformByLocation(fake_location,
6084 "glUniform4fv",
6085 Program::kUniform4f,
6086 &real_location,
6087 &type,
6088 &count)) {
[email protected]939e7362010-05-13 20:49:106089 return;
6090 }
6091 if (type == GL_BOOL_VEC4) {
6092 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:556093 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106094 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536095 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106096 }
[email protected]1b0a6752012-02-22 03:44:126097 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106098 } else {
[email protected]1b0a6752012-02-22 03:44:126099 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106100 }
6101}
6102
[email protected]43c2f1f2011-03-25 18:35:366103void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:126104 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366105 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126106 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136107 if (!PrepForSetUniformByLocation(fake_location,
6108 "glUniform2iv",
6109 Program::kUniform2i,
6110 &real_location,
6111 &type,
6112 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366113 return;
6114 }
[email protected]1b0a6752012-02-22 03:44:126115 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366116}
6117
6118void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:126119 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366120 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126121 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136122 if (!PrepForSetUniformByLocation(fake_location,
6123 "glUniform3iv",
6124 Program::kUniform3i,
6125 &real_location,
6126 &type,
6127 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366128 return;
6129 }
[email protected]1b0a6752012-02-22 03:44:126130 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366131}
6132
6133void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:126134 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366135 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126136 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136137 if (!PrepForSetUniformByLocation(fake_location,
6138 "glUniform4iv",
6139 Program::kUniform4i,
6140 &real_location,
6141 &type,
6142 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366143 return;
6144 }
[email protected]1b0a6752012-02-22 03:44:126145 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366146}
6147
6148void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126149 GLint fake_location, GLsizei count, GLboolean transpose,
6150 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366151 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126152 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136153 if (!PrepForSetUniformByLocation(fake_location,
6154 "glUniformMatrix2fv",
6155 Program::kUniformMatrix2f,
6156 &real_location,
6157 &type,
6158 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366159 return;
6160 }
[email protected]1b0a6752012-02-22 03:44:126161 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366162}
6163
6164void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126165 GLint fake_location, GLsizei count, GLboolean transpose,
6166 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366167 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126168 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136169 if (!PrepForSetUniformByLocation(fake_location,
6170 "glUniformMatrix3fv",
6171 Program::kUniformMatrix3f,
6172 &real_location,
6173 &type,
6174 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366175 return;
6176 }
[email protected]1b0a6752012-02-22 03:44:126177 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366178}
6179
6180void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126181 GLint fake_location, GLsizei count, GLboolean transpose,
6182 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366183 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126184 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136185 if (!PrepForSetUniformByLocation(fake_location,
6186 "glUniformMatrix4fv",
6187 Program::kUniformMatrix4f,
6188 &real_location,
6189 &type,
6190 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366191 return;
6192 }
[email protected]1b0a6752012-02-22 03:44:126193 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366194}
6195
[email protected]df37b9932013-03-08 05:21:426196void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036197 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426198 Program* program = NULL;
6199 if (program_id) {
6200 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6201 if (!program) {
[email protected]ae51d192010-04-27 00:48:036202 return;
6203 }
[email protected]df37b9932013-03-08 05:21:426204 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506205 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516206 LOCAL_SET_GL_ERROR(
6207 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506208 return;
6209 }
[email protected]df37b9932013-03-08 05:21:426210 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506211 }
[email protected]7cd76fd2013-06-02 21:11:116212 if (state_.current_program.get()) {
6213 program_manager()->UnuseProgram(shader_manager(),
6214 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146215 }
[email protected]df37b9932013-03-08 05:21:426216 state_.current_program = program;
6217 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546218 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116219 if (state_.current_program.get()) {
6220 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186221 if (workarounds().clear_uniforms_before_first_program_use)
6222 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146223 }
[email protected]3916c97e2010-02-25 03:20:506224}
6225
[email protected]ab09b612013-03-11 22:11:516226void GLES2DecoderImpl::RenderWarning(
6227 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326228 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016229}
6230
[email protected]ab09b612013-03-11 22:11:516231void GLES2DecoderImpl::PerformanceWarning(
6232 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506233 logger_.LogMessage(filename, line,
6234 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016235}
6236
[email protected]91c94eb2013-10-22 10:32:546237void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6238 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546239 // Image is already in use if texture is attached to a framebuffer.
6240 if (texture && !texture->IsAttachedToFramebuffer()) {
6241 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6242 if (image) {
6243 ScopedGLErrorSuppressor suppressor(
6244 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6245 GetErrorState());
6246 glBindTexture(textarget, texture->service_id());
6247 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026248 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546249 }
6250 }
6251}
6252
6253void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6254 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546255 // Image is still in use if texture is attached to a framebuffer.
6256 if (texture && !texture->IsAttachedToFramebuffer()) {
6257 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6258 if (image) {
6259 ScopedGLErrorSuppressor suppressor(
6260 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6261 GetErrorState());
6262 glBindTexture(textarget, texture->service_id());
6263 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026264 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546265 }
6266 }
6267}
6268
[email protected]e56131d22013-07-28 16:14:116269bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116270 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546271 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556272 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116273 return true;
[email protected]ef526492010-06-02 23:12:256274 }
[email protected]e2367b42013-05-31 03:37:216275
[email protected]ef526492010-06-02 23:12:256276 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356277 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246278 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506279 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356280 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246281 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506282 DCHECK(uniform_info);
6283 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6284 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026285 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246286 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546287 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366288 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546289 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6290 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256291 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506292 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6293 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546294 textarget,
[email protected]00f893d2010-08-24 18:55:496295 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:516296 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:016297 std::string("texture bound to texture unit ") +
6298 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:296299 " is not renderable. It maybe non-power-of-2 and have"
6300 " incompatible texture filtering or is not"
6301 " 'texture complete'");
[email protected]91c94eb2013-10-22 10:32:546302 continue;
[email protected]3916c97e2010-02-25 03:20:506303 }
[email protected]91c94eb2013-10-22 10:32:546304
[email protected]4e7b89202014-01-28 01:44:066305 if (textarget != GL_TEXTURE_CUBE_MAP) {
6306 Texture* texture = texture_ref->texture();
6307 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6308 if (image && !texture->IsAttachedToFramebuffer()) {
6309 ScopedGLErrorSuppressor suppressor(
6310 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6311 textures_set = true;
6312 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6313 image->WillUseTexImage();
6314 continue;
6315 }
[email protected]91c94eb2013-10-22 10:32:546316 }
[email protected]3916c97e2010-02-25 03:20:506317 }
6318 // else: should this be an error?
6319 }
6320 }
[email protected]e56131d22013-07-28 16:14:116321 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506322}
6323
[email protected]91c94eb2013-10-22 10:32:546324void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116325 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356326 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116327 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506328 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356329 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246330 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506331 DCHECK(uniform_info);
6332 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6333 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026334 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246335 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116336 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546337 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496338 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506339 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496340 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116341 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6342 ? texture_unit.bound_texture_2d.get()
6343 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506344 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496345 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546346 continue;
6347 }
6348
[email protected]4e7b89202014-01-28 01:44:066349 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6350 Texture* texture = texture_ref->texture();
6351 gfx::GLImage* image =
6352 texture->GetLevelImage(texture_unit.bind_target, 0);
6353 if (image && !texture->IsAttachedToFramebuffer()) {
6354 ScopedGLErrorSuppressor suppressor(
6355 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6356 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6357 image->DidUseTexImage();
6358 continue;
6359 }
[email protected]3916c97e2010-02-25 03:20:506360 }
6361 }
6362 }
6363 }
6364 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246365 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306366}
6367
[email protected]0d6bfdc2011-11-02 01:32:206368bool GLES2DecoderImpl::ClearUnclearedTextures() {
6369 // Only check if there are some uncleared textures.
6370 if (!texture_manager()->HaveUnsafeTextures()) {
6371 return true;
6372 }
6373
6374 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116375 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356376 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116377 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206378 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356379 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246380 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206381 DCHECK(uniform_info);
6382 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6383 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026384 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246385 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496386 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366387 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496388 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6389 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206390 return false;
6391 }
6392 }
6393 }
6394 }
6395 }
6396 }
6397 return true;
6398}
6399
[email protected]c6aef902012-02-14 03:31:426400bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106401 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6402 GLsizei primcount) {
6403 DCHECK(instanced || primcount == 1);
6404
[email protected]689fa1c52010-06-09 18:35:036405 // NOTE: We specifically do not check current_program->IsValid() because
6406 // it could never be invalid since glUseProgram would have failed. While
6407 // glLinkProgram could later mark the program as invalid the previous
6408 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116409 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506410 // The program does not exist.
6411 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516412 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506413 return false;
6414 }
[email protected]c6aef902012-02-14 03:31:426415
zmof9a81360f2014-10-17 00:06:146416 if (CheckDrawingFeedbackLoops()) {
6417 LOCAL_SET_GL_ERROR(
6418 GL_INVALID_OPERATION, function_name,
6419 "Source and destination textures of the draw are the same.");
6420 return false;
6421 }
6422
[email protected]7cd76fd2013-06-02 21:11:116423 return state_.vertex_attrib_manager
6424 ->ValidateBindings(function_name,
6425 this,
6426 feature_info_.get(),
6427 state_.current_program.get(),
6428 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106429 instanced,
[email protected]7cd76fd2013-06-02 21:11:116430 primcount);
[email protected]b1122982010-05-17 23:04:246431}
6432
[email protected]c13e1da62011-09-09 21:48:306433bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436434 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306435 DCHECK(simulated);
6436 *simulated = false;
6437
[email protected]876f6fee2010-08-02 23:10:326438 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306439 return true;
[email protected]876f6fee2010-08-02 23:10:326440
[email protected]ac77603c72013-03-08 13:52:066441 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356442 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246443 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246444 bool attrib_0_used =
6445 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066446 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306447 return true;
[email protected]b1122982010-05-17 23:04:246448 }
6449
[email protected]b1122982010-05-17 23:04:246450 // Make a buffer with a single repeated vec4 value enough to
6451 // simulate the constant value that is supposed to be here.
6452 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306453 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476454 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306455
6456 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476457 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306458 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516459 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306460 return false;
6461 }
6462
[email protected]ab09b612013-03-11 22:11:516463 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016464 "Attribute 0 is disabled. This has signficant performance penalty");
6465
[email protected]ab09b612013-03-11 22:11:516466 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306467 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6468
[email protected]8f0b86c2f2012-04-10 05:48:286469 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6470 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496471 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306472 GLenum error = glGetError();
6473 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516474 LOCAL_SET_GL_ERROR(
6475 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306476 return false;
6477 }
[email protected]fc753442011-02-04 19:49:496478 }
[email protected]af6380962012-11-29 23:24:136479
6480 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286481 if (new_buffer ||
6482 (attrib_0_used &&
6483 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136484 (value.v[0] != attrib_0_value_.v[0] ||
6485 value.v[1] != attrib_0_value_.v[1] ||
6486 value.v[2] != attrib_0_value_.v[2] ||
6487 value.v[3] != attrib_0_value_.v[3])))) {
6488 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496489 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6490 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136491 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246492 attrib_0_size_ = size_needed;
6493 }
6494
6495 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6496
[email protected]ac77603c72013-03-08 13:52:066497 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426498 glVertexAttribDivisorANGLE(0, 0);
6499
[email protected]c13e1da62011-09-09 21:48:306500 *simulated = true;
[email protected]b1122982010-05-17 23:04:246501 return true;
[email protected]b1122982010-05-17 23:04:246502}
6503
[email protected]3fc38e22014-05-30 00:13:236504void GLES2DecoderImpl::RestoreStateForAttrib(
6505 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066506 const VertexAttrib* attrib =
6507 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236508 if (restore_array_binding) {
6509 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6510 Buffer* buffer = attrib->buffer();
6511 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6512 glVertexAttribPointer(
6513 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6514 attrib->gl_stride(), ptr);
6515 }
[email protected]ac77603c72013-03-08 13:52:066516 if (attrib->divisor())
6517 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246518 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236519 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6520 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286521
[email protected]265f8992012-07-20 01:03:146522 // Never touch vertex attribute 0's state (in particular, never
6523 // disable it) when running on desktop GL because it will never be
6524 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066525 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146526 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066527 if (attrib->enabled()) {
6528 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146529 } else {
[email protected]ac77603c72013-03-08 13:52:066530 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146531 }
[email protected]43410e92012-04-20 17:06:286532 }
[email protected]b1122982010-05-17 23:04:246533}
[email protected]07f54fcc2009-12-22 02:46:306534
[email protected]8fbedc02010-11-18 18:43:406535bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436536 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426537 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406538 DCHECK(simulated);
6539 *simulated = false;
6540 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6541 return true;
6542
[email protected]e259eb412012-10-13 05:47:246543 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406544 return true;
6545 }
6546
[email protected]ab09b612013-03-11 22:11:516547 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016548 "GL_FIXED attributes have a signficant performance penalty");
6549
[email protected]8fbedc02010-11-18 18:43:406550 // NOTE: we could be smart and try to check if a buffer is used
6551 // twice in 2 different attribs, find the overlapping parts and therefore
6552 // duplicate the minimum amount of data but this whole code path is not meant
6553 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6554 // tests so we just add to the buffer attrib used.
6555
[email protected]c13e1da62011-09-09 21:48:306556 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066557 const VertexAttribManager::VertexAttribList& enabled_attribs =
6558 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6559 for (VertexAttribManager::VertexAttribList::const_iterator it =
6560 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6561 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356562 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066563 state_.current_program->GetAttribInfoByLocation(attrib->index());
6564 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6565 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426566 GLuint num_vertices = max_accessed + 1;
6567 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516568 LOCAL_SET_GL_ERROR(
6569 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426570 return false;
6571 }
[email protected]8fbedc02010-11-18 18:43:406572 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066573 attrib->CanAccess(max_accessed) &&
6574 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476575 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066576 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476577 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516578 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436579 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406580 return false;
6581 }
6582 }
6583 }
6584
[email protected]3aad1a32012-09-07 20:54:476585 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6586 uint32 size_needed = 0;
6587 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306588 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516589 LOCAL_SET_GL_ERROR(
6590 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406591 return false;
6592 }
6593
[email protected]ab09b612013-03-11 22:11:516594 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406595
6596 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306597 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406598 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306599 GLenum error = glGetError();
6600 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516601 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436602 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306603 return false;
6604 }
[email protected]8fbedc02010-11-18 18:43:406605 }
6606
6607 // Copy the elements and convert to float
6608 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066609 for (VertexAttribManager::VertexAttribList::const_iterator it =
6610 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6611 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356612 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066613 state_.current_program->GetAttribInfoByLocation(attrib->index());
6614 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426615 max_vertex_accessed);
6616 GLuint num_vertices = max_accessed + 1;
6617 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516618 LOCAL_SET_GL_ERROR(
6619 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426620 return false;
6621 }
[email protected]8fbedc02010-11-18 18:43:406622 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066623 attrib->CanAccess(max_accessed) &&
6624 attrib->type() == GL_FIXED) {
penghuang5a3210b2014-10-29 18:24:366625 int num_elements = attrib->size() * num_vertices;
6626 const int src_size = num_elements * sizeof(int32);
6627 const int dst_size = num_elements * sizeof(float);
6628 scoped_ptr<float[]> data(new float[num_elements]);
[email protected]8fbedc02010-11-18 18:43:406629 const int32* src = reinterpret_cast<const int32 *>(
penghuang5a3210b2014-10-29 18:24:366630 attrib->buffer()->GetRange(attrib->offset(), src_size));
[email protected]8fbedc02010-11-18 18:43:406631 const int32* end = src + num_elements;
6632 float* dst = data.get();
6633 while (src != end) {
6634 *dst++ = static_cast<float>(*src++) / 65536.0f;
6635 }
penghuang5a3210b2014-10-29 18:24:366636 glBufferSubData(GL_ARRAY_BUFFER, offset, dst_size, data.get());
[email protected]8fbedc02010-11-18 18:43:406637 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066638 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406639 reinterpret_cast<GLvoid*>(offset));
penghuang5a3210b2014-10-29 18:24:366640 offset += dst_size;
[email protected]8fbedc02010-11-18 18:43:406641 }
6642 }
6643 *simulated = true;
6644 return true;
6645}
6646
6647void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6648 // There's no need to call glVertexAttribPointer because we shadow all the
6649 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246650 glBindBuffer(
6651 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116652 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6653 : 0);
[email protected]8fbedc02010-11-18 18:43:406654}
6655
[email protected]ad84a3a2012-06-08 21:42:436656error::Error GLES2DecoderImpl::DoDrawArrays(
6657 const char* function_name,
6658 bool instanced,
6659 GLenum mode,
6660 GLint first,
6661 GLsizei count,
6662 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226663 error::Error error = WillAccessBoundFramebufferForDraw();
6664 if (error != error::kNoError)
6665 return error;
[email protected]38d139d2011-07-14 00:38:436666 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516667 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436668 return error::kNoError;
6669 }
6670 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516671 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436672 return error::kNoError;
6673 }
[email protected]c6aef902012-02-14 03:31:426674 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516675 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426676 return error::kNoError;
6677 }
[email protected]ad84a3a2012-06-08 21:42:436678 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436679 return error::kNoError;
6680 }
6681 // We have to check this here because the prototype for glDrawArrays
6682 // is GLint not GLsizei.
6683 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516684 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436685 return error::kNoError;
6686 }
6687
[email protected]ac6904d62014-07-30 12:00:106688 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:516689 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436690 return error::kNoError;
6691 }
6692
6693 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:106694 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206695 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516696 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206697 return error::kNoError;
6698 }
[email protected]c13e1da62011-09-09 21:48:306699 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436700 if (!SimulateAttrib0(
6701 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306702 return error::kNoError;
6703 }
[email protected]38d139d2011-07-14 00:38:436704 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436705 if (SimulateFixedAttribs(
6706 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6707 primcount)) {
[email protected]e56131d22013-07-28 16:14:116708 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436709 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376710 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426711 if (!instanced) {
6712 glDrawArrays(mode, first, count);
6713 } else {
6714 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6715 }
[email protected]38d139d2011-07-14 00:38:436716 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546717 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436718 }
6719 if (simulated_fixed_attribs) {
6720 RestoreStateForSimulatedFixedAttribs();
6721 }
6722 }
6723 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236724 // We don't have to restore attrib 0 generic data at the end of this
6725 // function even if it is simulated. This is because we will simulate
6726 // it in each draw call, and attrib 0 generic data queries use cached
6727 // values instead of passing down to the underlying driver.
6728 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:436729 }
[email protected]38d139d2011-07-14 00:38:436730 }
6731 return error::kNoError;
6732}
6733
vmiuracd108592014-09-08 14:36:346734error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
6735 const void* cmd_data) {
6736 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436737 return DoDrawArrays("glDrawArrays",
6738 false,
[email protected]c6aef902012-02-14 03:31:426739 static_cast<GLenum>(c.mode),
6740 static_cast<GLint>(c.first),
6741 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:106742 1);
[email protected]c6aef902012-02-14 03:31:426743}
6744
6745error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:346746 uint32 immediate_data_size,
6747 const void* cmd_data) {
6748 const gles2::cmds::DrawArraysInstancedANGLE& c =
6749 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156750 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516751 LOCAL_SET_GL_ERROR(
6752 GL_INVALID_OPERATION,
6753 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426754 return error::kNoError;
6755 }
[email protected]ad84a3a2012-06-08 21:42:436756 return DoDrawArrays("glDrawArraysIntancedANGLE",
6757 true,
[email protected]c6aef902012-02-14 03:31:426758 static_cast<GLenum>(c.mode),
6759 static_cast<GLint>(c.first),
6760 static_cast<GLsizei>(c.count),
6761 static_cast<GLsizei>(c.primcount));
6762}
6763
[email protected]ad84a3a2012-06-08 21:42:436764error::Error GLES2DecoderImpl::DoDrawElements(
6765 const char* function_name,
6766 bool instanced,
6767 GLenum mode,
6768 GLsizei count,
6769 GLenum type,
6770 int32 offset,
6771 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226772 error::Error error = WillAccessBoundFramebufferForDraw();
6773 if (error != error::kNoError)
6774 return error;
[email protected]e259eb412012-10-13 05:47:246775 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516776 LOCAL_SET_GL_ERROR(
6777 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296778 return error::kNoError;
6779 }
6780
[email protected]8eee29c2010-04-29 03:38:296781 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516782 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296783 return error::kNoError;
6784 }
6785 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516786 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296787 return error::kNoError;
6788 }
[email protected]9438b012010-06-15 22:55:056789 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516790 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296791 return error::kNoError;
6792 }
[email protected]9438b012010-06-15 22:55:056793 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516794 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296795 return error::kNoError;
6796 }
[email protected]c6aef902012-02-14 03:31:426797 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516798 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426799 return error::kNoError;
6800 }
[email protected]8eee29c2010-04-29 03:38:296801
[email protected]ad84a3a2012-06-08 21:42:436802 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276803 return error::kNoError;
6804 }
6805
[email protected]ac6904d62014-07-30 12:00:106806 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:316807 return error::kNoError;
6808 }
6809
[email protected]8eee29c2010-04-29 03:38:296810 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086811 Buffer* element_array_buffer =
6812 state_.vertex_attrib_manager->element_array_buffer();
6813
6814 if (!element_array_buffer->GetMaxValueForRange(
6815 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516816 LOCAL_SET_GL_ERROR(
6817 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296818 return error::kNoError;
6819 }
6820
[email protected]ac6904d62014-07-30 12:00:106821 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206822 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516823 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206824 return error::kNoError;
6825 }
[email protected]c13e1da62011-09-09 21:48:306826 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436827 if (!SimulateAttrib0(
6828 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306829 return error::kNoError;
6830 }
[email protected]8fbedc02010-11-18 18:43:406831 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436832 if (SimulateFixedAttribs(
6833 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6834 primcount)) {
[email protected]e56131d22013-07-28 16:14:116835 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466836 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086837 // TODO(gman): Refactor to hide these details in BufferManager or
6838 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406839 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086840 bool used_client_side_array = false;
6841 if (element_array_buffer->IsClientSideArray()) {
6842 used_client_side_array = true;
6843 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6844 indices = element_array_buffer->GetRange(offset, 0);
6845 }
6846
[email protected]00c2cf92014-03-14 00:08:376847 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426848 if (!instanced) {
6849 glDrawElements(mode, count, type, indices);
6850 } else {
6851 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6852 }
[email protected]17cfbe0e2013-03-07 01:26:086853
6854 if (used_client_side_array) {
6855 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6856 element_array_buffer->service_id());
6857 }
6858
[email protected]8fbedc02010-11-18 18:43:406859 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546860 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406861 }
6862 if (simulated_fixed_attribs) {
6863 RestoreStateForSimulatedFixedAttribs();
6864 }
[email protected]ba3176a2009-12-16 18:19:466865 }
[email protected]b1122982010-05-17 23:04:246866 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236867 // We don't have to restore attrib 0 generic data at the end of this
6868 // function even if it is simulated. This is because we will simulate
6869 // it in each draw call, and attrib 0 generic data queries use cached
6870 // values instead of passing down to the underlying driver.
6871 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:246872 }
[email protected]96449d2c2009-11-25 00:01:326873 }
[email protected]f7a64ee2010-02-01 22:24:146874 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326875}
6876
vmiuracd108592014-09-08 14:36:346877error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
6878 const void* cmd_data) {
6879 const gles2::cmds::DrawElements& c =
6880 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436881 return DoDrawElements("glDrawElements",
6882 false,
[email protected]c6aef902012-02-14 03:31:426883 static_cast<GLenum>(c.mode),
6884 static_cast<GLsizei>(c.count),
6885 static_cast<GLenum>(c.type),
6886 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:106887 1);
[email protected]c6aef902012-02-14 03:31:426888}
6889
6890error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:346891 uint32 immediate_data_size,
6892 const void* cmd_data) {
6893 const gles2::cmds::DrawElementsInstancedANGLE& c =
6894 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156895 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516896 LOCAL_SET_GL_ERROR(
6897 GL_INVALID_OPERATION,
6898 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426899 return error::kNoError;
6900 }
[email protected]ad84a3a2012-06-08 21:42:436901 return DoDrawElements("glDrawElementsInstancedANGLE",
6902 true,
[email protected]c6aef902012-02-14 03:31:426903 static_cast<GLenum>(c.mode),
6904 static_cast<GLsizei>(c.count),
6905 static_cast<GLenum>(c.type),
6906 static_cast<int32>(c.index_offset),
6907 static_cast<GLsizei>(c.primcount));
6908}
6909
[email protected]269200b12010-11-18 22:53:066910GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236911 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6912 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076913 Buffer* buffer = GetBuffer(buffer_id);
6914 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036915 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516916 LOCAL_SET_GL_ERROR(
6917 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236918 } else {
[email protected]b10492f2013-03-08 05:24:076919 if (!buffer->GetMaxValueForRange(
6920 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036921 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516922 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066923 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436924 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236925 }
6926 }
6927 return max_vertex_accessed;
6928}
6929
[email protected]96449d2c2009-11-25 00:01:326930// Calls glShaderSource for the various versions of the ShaderSource command.
6931// Assumes that data / data_size points to a piece of memory that is in range
6932// of whatever context it came from (shared memory, immediate memory, bucket
6933// memory.)
[email protected]45bf5152010-02-12 00:11:316934error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036935 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576936 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426937 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6938 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316939 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326940 }
[email protected]45bf5152010-02-12 00:11:316941 // Note: We don't actually call glShaderSource here. We wait until
6942 // the call to glCompileShader.
zmo576a0492014-09-13 01:12:326943 shader->set_source(str);
[email protected]f7a64ee2010-02-01 22:24:146944 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326945}
6946
[email protected]558847a2010-03-24 07:02:546947error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
vmiuracd108592014-09-08 14:36:346948 uint32 immediate_data_size,
6949 const void* cmd_data) {
6950 const gles2::cmds::ShaderSourceBucket& c =
6951 *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data);
[email protected]558847a2010-03-24 07:02:546952 Bucket* bucket = GetBucket(c.data_bucket_id);
6953 if (!bucket || bucket->size() == 0) {
6954 return error::kInvalidArguments;
6955 }
6956 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036957 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546958 bucket->size() - 1);
6959}
6960
[email protected]ae51d192010-04-27 00:48:036961void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386962 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426963 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6964 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316965 return;
6966 }
[email protected]f57bb282010-11-12 00:51:346967 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186968 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426969 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456970 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416971 }
[email protected]de17df392010-04-23 21:09:416972
zmo576a0492014-09-13 01:12:326973 shader->DoCompile(
[email protected]b05955552014-02-06 18:41:186974 translator,
6975 feature_info_->feature_flags().angle_translated_shader_source ?
zmo576a0492014-09-13 01:12:326976 Shader::kANGLE : Shader::kGL);
vmiura8266ca72014-09-09 21:37:006977
6978 // CompileShader can be very slow. Exit command processing to allow for
6979 // context preemption and GPU watchdog checks.
6980 ExitCommandProcessingEarly();
6981}
[email protected]45bf5152010-02-12 00:11:316982
[email protected]ddd968b82010-03-02 00:44:296983void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426984 GLuint shader_id, GLenum pname, GLint* params) {
6985 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6986 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296987 return;
6988 }
[email protected]8f1ccdac2010-05-19 21:01:486989 switch (pname) {
6990 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:326991 *params = shader->source().size();
6992 if (*params)
6993 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:486994 return;
6995 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:326996 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:416997 return;
[email protected]8f1ccdac2010-05-19 21:01:486998 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:326999 *params = shader->log_info().size();
7000 if (*params)
7001 ++(*params);
[email protected]e5186162010-06-14 18:54:417002 return;
[email protected]d6a53e42011-10-05 00:09:367003 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:327004 *params = shader->translated_source().size();
7005 if (*params)
7006 ++(*params);
[email protected]d6a53e42011-10-05 00:09:367007 return;
[email protected]8f1ccdac2010-05-19 21:01:487008 default:
7009 break;
[email protected]ddd968b82010-03-02 00:44:297010 }
[email protected]df37b9932013-03-08 05:21:427011 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:297012}
7013
vmiuracd108592014-09-08 14:36:347014error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
7015 const void* cmd_data) {
7016 const gles2::cmds::GetShaderSource& c =
7017 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427018 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:037019 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7020 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427021 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:327022 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:297023 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:297024 return error::kNoError;
7025 }
zmo576a0492014-09-13 01:12:327026 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:037027 return error::kNoError;
7028}
7029
[email protected]d6a53e42011-10-05 00:09:367030error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
7031 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347032 const void* cmd_data) {
7033 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
7034 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
7035 cmd_data);
[email protected]df37b9932013-03-08 05:21:427036 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:367037 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7038 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427039 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:207040 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:427041 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:367042 bucket->SetSize(0);
7043 return error::kNoError;
7044 }
7045
zmo576a0492014-09-13 01:12:327046 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:367047 return error::kNoError;
7048}
7049
[email protected]ae51d192010-04-27 00:48:037050error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:347051 uint32 immediate_data_size,
7052 const void* cmd_data) {
7053 const gles2::cmds::GetProgramInfoLog& c =
7054 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427055 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:587056 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7057 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427058 Program* program = GetProgramInfoNotShader(
7059 program_id, "glGetProgramInfoLog");
7060 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:467061 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037062 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:317063 }
[email protected]df37b9932013-03-08 05:21:427064 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:037065 return error::kNoError;
7066}
7067
7068error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:347069 uint32 immediate_data_size,
7070 const void* cmd_data) {
7071 const gles2::cmds::GetShaderInfoLog& c =
7072 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427073 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:587074 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7075 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427076 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:327077 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:467078 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037079 return error::kNoError;
7080 }
zmo576a0492014-09-13 01:12:327081 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:037082 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327083}
7084
[email protected]d058bca2012-11-26 10:27:267085bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
7086 return state_.GetEnabled(cap);
7087}
7088
[email protected]1958e0e2010-04-22 05:17:157089bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:217090 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107091 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157092}
7093
7094bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357095 const Framebuffer* framebuffer =
7096 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107097 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157098}
7099
7100bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367101 // IsProgram is true for programs as soon as they are created, until they are
7102 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:357103 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:107104 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157105}
7106
7107bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357108 const Renderbuffer* renderbuffer =
7109 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107110 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157111}
7112
7113bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367114 // IsShader is true for shaders as soon as they are created, until they
7115 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:357116 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:107117 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157118}
7119
7120bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:497121 const TextureRef* texture_ref = GetTexture(client_id);
7122 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:037123}
7124
7125void GLES2DecoderImpl::DoAttachShader(
7126 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427127 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587128 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:427129 if (!program) {
[email protected]ae51d192010-04-27 00:48:037130 return;
[email protected]1958e0e2010-04-22 05:17:157131 }
[email protected]df37b9932013-03-08 05:21:427132 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
7133 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037134 return;
7135 }
[email protected]df37b9932013-03-08 05:21:427136 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517137 LOCAL_SET_GL_ERROR(
7138 GL_INVALID_OPERATION,
7139 "glAttachShader",
7140 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:317141 return;
7142 }
[email protected]df37b9932013-03-08 05:21:427143 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037144}
7145
7146void GLES2DecoderImpl::DoDetachShader(
7147 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427148 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587149 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427150 if (!program) {
[email protected]ae51d192010-04-27 00:48:037151 return;
7152 }
[email protected]df37b9932013-03-08 05:21:427153 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7154 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037155 return;
7156 }
[email protected]df37b9932013-03-08 05:21:427157 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517158 LOCAL_SET_GL_ERROR(
7159 GL_INVALID_OPERATION,
7160 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227161 return;
7162 }
[email protected]df37b9932013-03-08 05:21:427163 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037164}
7165
7166void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427167 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587168 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427169 if (!program) {
[email protected]ae51d192010-04-27 00:48:037170 return;
7171 }
[email protected]df37b9932013-03-08 05:21:427172 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157173}
7174
[email protected]ac77603c72013-03-08 13:52:067175void GLES2DecoderImpl::GetVertexAttribHelper(
7176 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247177 switch (pname) {
7178 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067179 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247180 if (buffer && !buffer->IsDeleted()) {
7181 GLuint client_id;
7182 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7183 *params = client_id;
7184 }
7185 break;
7186 }
7187 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067188 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247189 break;
7190 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067191 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247192 break;
7193 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067194 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247195 break;
7196 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067197 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247198 break;
7199 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067200 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247201 break;
[email protected]c6aef902012-02-14 03:31:427202 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067203 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427204 break;
[email protected]ac77603c72013-03-08 13:52:067205 default:
7206 NOTREACHED();
7207 break;
7208 }
7209}
7210
[email protected]4c6f5462014-03-05 00:26:567211void GLES2DecoderImpl::DoGetTexParameterfv(
7212 GLenum target, GLenum pname, GLfloat* params) {
7213 InitTextureMaxAnisotropyIfNeeded(target, pname);
7214 glGetTexParameterfv(target, pname, params);
7215}
7216
7217void GLES2DecoderImpl::DoGetTexParameteriv(
7218 GLenum target, GLenum pname, GLint* params) {
7219 InitTextureMaxAnisotropyIfNeeded(target, pname);
7220 glGetTexParameteriv(target, pname, params);
7221}
7222
7223void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7224 GLenum target, GLenum pname) {
7225 if (!workarounds().init_texture_max_anisotropy)
7226 return;
7227 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7228 !validators_->texture_parameter.IsValid(pname)) {
7229 return;
7230 }
7231
7232 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7233 &state_, target);
7234 if (!texture_ref) {
7235 LOCAL_SET_GL_ERROR(
7236 GL_INVALID_OPERATION,
7237 "glGetTexParamter{fi}v", "unknown texture for target");
7238 return;
7239 }
7240 Texture* texture = texture_ref->texture();
7241 texture->InitTextureMaxAnisotropyIfNeeded(target);
7242}
7243
[email protected]ac77603c72013-03-08 13:52:067244void GLES2DecoderImpl::DoGetVertexAttribfv(
7245 GLuint index, GLenum pname, GLfloat* params) {
7246 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7247 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517248 LOCAL_SET_GL_ERROR(
7249 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067250 return;
7251 }
7252 switch (pname) {
7253 case GL_CURRENT_VERTEX_ATTRIB: {
7254 const Vec4& value = state_.attrib_values[index];
7255 params[0] = value.v[0];
7256 params[1] = value.v[1];
7257 params[2] = value.v[2];
7258 params[3] = value.v[3];
7259 break;
7260 }
7261 default: {
7262 GLint value = 0;
7263 GetVertexAttribHelper(attrib, pname, &value);
7264 *params = static_cast<GLfloat>(value);
7265 break;
7266 }
7267 }
7268}
7269
7270void GLES2DecoderImpl::DoGetVertexAttribiv(
7271 GLuint index, GLenum pname, GLint* params) {
7272 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7273 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517274 LOCAL_SET_GL_ERROR(
7275 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067276 return;
7277 }
7278 switch (pname) {
[email protected]af6380962012-11-29 23:24:137279 case GL_CURRENT_VERTEX_ATTRIB: {
7280 const Vec4& value = state_.attrib_values[index];
7281 params[0] = static_cast<GLint>(value.v[0]);
7282 params[1] = static_cast<GLint>(value.v[1]);
7283 params[2] = static_cast<GLint>(value.v[2]);
7284 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247285 break;
[email protected]af6380962012-11-29 23:24:137286 }
[email protected]b1122982010-05-17 23:04:247287 default:
[email protected]ac77603c72013-03-08 13:52:067288 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247289 break;
7290 }
7291}
7292
[email protected]af6380962012-11-29 23:24:137293bool GLES2DecoderImpl::SetVertexAttribValue(
7294 const char* function_name, GLuint index, const GLfloat* value) {
7295 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517296 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137297 return false;
[email protected]b1122982010-05-17 23:04:247298 }
[email protected]af6380962012-11-29 23:24:137299 Vec4& v = state_.attrib_values[index];
7300 v.v[0] = value[0];
7301 v.v[1] = value[1];
7302 v.v[2] = value[2];
7303 v.v[3] = value[3];
7304 return true;
7305}
7306
7307void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7308 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7309 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7310 glVertexAttrib1f(index, v0);
7311 }
[email protected]b1122982010-05-17 23:04:247312}
7313
7314void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137315 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7316 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7317 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247318 }
[email protected]b1122982010-05-17 23:04:247319}
7320
7321void GLES2DecoderImpl::DoVertexAttrib3f(
7322 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137323 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7324 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7325 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247326 }
[email protected]b1122982010-05-17 23:04:247327}
7328
7329void GLES2DecoderImpl::DoVertexAttrib4f(
7330 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137331 GLfloat v[4] = { v0, v1, v2, v3, };
7332 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7333 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247334 }
[email protected]b1122982010-05-17 23:04:247335}
7336
7337void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137338 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7339 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7340 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247341 }
[email protected]b1122982010-05-17 23:04:247342}
7343
7344void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137345 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7346 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7347 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247348 }
[email protected]b1122982010-05-17 23:04:247349}
7350
7351void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137352 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7353 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7354 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247355 }
[email protected]b1122982010-05-17 23:04:247356}
7357
7358void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137359 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7360 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247361 }
[email protected]b1122982010-05-17 23:04:247362}
7363
[email protected]f7a64ee2010-02-01 22:24:147364error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347365 uint32 immediate_data_size,
7366 const void* cmd_data) {
7367 const gles2::cmds::VertexAttribPointer& c =
7368 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467369
[email protected]7cd76fd2013-06-02 21:11:117370 if (!state_.bound_array_buffer.get() ||
7371 state_.bound_array_buffer->IsDeleted()) {
7372 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527373 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517374 LOCAL_SET_GL_ERROR(
7375 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467376 return error::kNoError;
7377 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517378 LOCAL_SET_GL_ERROR(
7379 GL_INVALID_VALUE,
7380 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467381 return error::kNoError;
7382 }
[email protected]96449d2c2009-11-25 00:01:327383 }
[email protected]8eee29c2010-04-29 03:38:297384
7385 GLuint indx = c.indx;
7386 GLint size = c.size;
7387 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327388 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:297389 GLsizei stride = c.stride;
7390 GLsizei offset = c.offset;
7391 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057392 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517393 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297394 return error::kNoError;
7395 }
[email protected]9438b012010-06-15 22:55:057396 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517397 LOCAL_SET_GL_ERROR(
7398 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297399 return error::kNoError;
7400 }
7401 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517402 LOCAL_SET_GL_ERROR(
7403 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297404 return error::kNoError;
7405 }
7406 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517407 LOCAL_SET_GL_ERROR(
7408 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297409 return error::kNoError;
7410 }
7411 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517412 LOCAL_SET_GL_ERROR(
7413 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297414 return error::kNoError;
7415 }
7416 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517417 LOCAL_SET_GL_ERROR(
7418 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297419 return error::kNoError;
7420 }
7421 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317422 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127423 // component_size must be a power of two to use & as optimized modulo.
7424 DCHECK(GLES2Util::IsPOT(component_size));
7425 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517426 LOCAL_SET_GL_ERROR(
7427 GL_INVALID_OPERATION,
7428 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317429 return error::kNoError;
7430 }
[email protected]a07a23602014-08-05 11:36:127431 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517432 LOCAL_SET_GL_ERROR(
7433 GL_INVALID_OPERATION,
7434 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297435 return error::kNoError;
7436 }
[email protected]7cd76fd2013-06-02 21:11:117437 state_.vertex_attrib_manager
7438 ->SetAttribInfo(indx,
7439 state_.bound_array_buffer.get(),
7440 size,
7441 type,
7442 normalized,
7443 stride,
7444 stride != 0 ? stride : component_size * size,
7445 offset);
[email protected]8fbedc02010-11-18 18:43:407446 if (type != GL_FIXED) {
7447 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7448 }
[email protected]f7a64ee2010-02-01 22:24:147449 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327450}
7451
[email protected]43410e92012-04-20 17:06:287452void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7453 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247454 state_.viewport_x = x;
7455 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027456 state_.viewport_width = std::min(width, viewport_max_width_);
7457 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287458 glViewport(x, y, width, height);
7459}
7460
[email protected]c6aef902012-02-14 03:31:427461error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347462 uint32 immediate_data_size,
7463 const void* cmd_data) {
7464 const gles2::cmds::VertexAttribDivisorANGLE& c =
7465 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157466 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517467 LOCAL_SET_GL_ERROR(
7468 GL_INVALID_OPERATION,
7469 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537470 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427471 }
7472 GLuint index = c.index;
7473 GLuint divisor = c.divisor;
7474 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517475 LOCAL_SET_GL_ERROR(
7476 GL_INVALID_VALUE,
7477 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427478 return error::kNoError;
7479 }
7480
[email protected]e259eb412012-10-13 05:47:247481 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427482 index,
7483 divisor);
7484 glVertexAttribDivisorANGLE(index, divisor);
7485 return error::kNoError;
7486}
7487
[email protected]68586372013-12-11 01:27:597488template <typename pixel_data_type>
7489static void WriteAlphaData(
7490 void *pixels, uint32 row_count, uint32 channel_count,
7491 uint32 alpha_channel_index, uint32 unpadded_row_size,
7492 uint32 padded_row_size, pixel_data_type alpha_value) {
7493 DCHECK_GT(channel_count, 0U);
7494 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7495 uint32 unpadded_row_size_in_elements =
7496 unpadded_row_size / sizeof(pixel_data_type);
7497 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7498 uint32 padded_row_size_in_elements =
7499 padded_row_size / sizeof(pixel_data_type);
7500 pixel_data_type* dst =
7501 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7502 for (uint32 yy = 0; yy < row_count; ++yy) {
7503 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7504 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7505 *d = alpha_value;
7506 }
7507 dst += padded_row_size_in_elements;
7508 }
7509}
7510
[email protected]5a36dc132013-07-23 23:17:557511void GLES2DecoderImpl::FinishReadPixels(
7512 const cmds::ReadPixels& c,
7513 GLuint buffer) {
7514 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7515 GLsizei width = c.width;
7516 GLsizei height = c.height;
7517 GLenum format = c.format;
7518 GLenum type = c.type;
7519 typedef cmds::ReadPixels::Result Result;
7520 uint32 pixels_size;
7521 Result* result = NULL;
7522 if (c.result_shm_id != 0) {
7523 result = GetSharedMemoryAs<Result*>(
7524 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7525 if (!result) {
7526 if (buffer != 0) {
7527 glDeleteBuffersARB(1, &buffer);
7528 }
7529 return;
7530 }
7531 }
7532 GLES2Util::ComputeImageDataSizes(
7533 width, height, format, type, state_.pack_alignment, &pixels_size,
7534 NULL, NULL);
7535 void* pixels = GetSharedMemoryAs<void*>(
7536 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7537 if (!pixels) {
7538 if (buffer != 0) {
7539 glDeleteBuffersARB(1, &buffer);
7540 }
7541 return;
7542 }
7543
7544 if (buffer != 0) {
7545 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337546 void* data;
7547 if (features().map_buffer_range) {
7548 data = glMapBufferRange(
7549 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7550 } else {
7551 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7552 }
[email protected]5a36dc132013-07-23 23:17:557553 memcpy(pixels, data, pixels_size);
7554 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7555 // have to restore the state.
7556 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7557 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7558 glDeleteBuffersARB(1, &buffer);
7559 }
7560
7561 if (result != NULL) {
7562 *result = true;
7563 }
7564
7565 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7566 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7567 if ((channels_exist & 0x0008) == 0 &&
7568 workarounds().clear_alpha_in_readpixels) {
7569 // Set the alpha to 255 because some drivers are buggy in this regard.
7570 uint32 temp_size;
7571
7572 uint32 unpadded_row_size;
7573 uint32 padded_row_size;
7574 if (!GLES2Util::ComputeImageDataSizes(
7575 width, 2, format, type, state_.pack_alignment, &temp_size,
7576 &unpadded_row_size, &padded_row_size)) {
7577 return;
7578 }
[email protected]68586372013-12-11 01:27:597579
7580 uint32 channel_count = 0;
7581 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557582 switch (format) {
7583 case GL_RGBA:
7584 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597585 channel_count = 4;
7586 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557587 break;
[email protected]68586372013-12-11 01:27:597588 case GL_ALPHA:
7589 channel_count = 1;
7590 alpha_channel = 0;
7591 break;
7592 }
7593
7594 if (channel_count > 0) {
7595 switch (type) {
7596 case GL_UNSIGNED_BYTE:
7597 WriteAlphaData<uint8>(
7598 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7599 padded_row_size, 0xFF);
7600 break;
7601 case GL_FLOAT:
7602 WriteAlphaData<float>(
7603 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7604 padded_row_size, 1.0f);
7605 break;
7606 case GL_HALF_FLOAT:
7607 WriteAlphaData<uint16>(
7608 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7609 padded_row_size, 0x3C00);
7610 break;
[email protected]5a36dc132013-07-23 23:17:557611 }
[email protected]5a36dc132013-07-23 23:17:557612 }
7613 }
7614}
7615
vmiuracd108592014-09-08 14:36:347616error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7617 const void* cmd_data) {
7618 const gles2::cmds::ReadPixels& c =
7619 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:217620 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227621 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7622 if (fbo_error != error::kNoError)
7623 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317624 GLint x = c.x;
7625 GLint y = c.y;
7626 GLsizei width = c.width;
7627 GLsizei height = c.height;
7628 GLenum format = c.format;
7629 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327630 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:567631 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517632 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567633 return error::kNoError;
7634 }
[email protected]ed9f9cd2013-02-27 21:12:357635 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187636 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347637 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247638 width, height, format, type, state_.pack_alignment, &pixels_size,
7639 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187640 return error::kOutOfBounds;
7641 }
[email protected]612d2f82009-12-08 20:49:317642 void* pixels = GetSharedMemoryAs<void*>(
7643 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107644 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147645 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467646 }
[email protected]de43f082013-04-02 01:16:107647 Result* result = NULL;
7648 if (c.result_shm_id != 0) {
7649 result = GetSharedMemoryAs<Result*>(
7650 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7651 if (!result) {
7652 return error::kOutOfBounds;
7653 }
7654 }
[email protected]a51788e2010-02-24 21:54:257655
[email protected]9438b012010-06-15 22:55:057656 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517657 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297658 return error::kNoError;
7659 }
[email protected]68586372013-12-11 01:27:597660 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517661 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127662 return error::kNoError;
7663 }
[email protected]68586372013-12-11 01:27:597664 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7665 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7666 // format and type are acceptable enums but not guaranteed to be supported
7667 // for this framebuffer. Have to ask gl if they are valid.
7668 GLint preferred_format = 0;
7669 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7670 GLint preferred_type = 0;
7671 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7672 if (format != static_cast<GLenum>(preferred_format) ||
7673 type != static_cast<GLenum>(preferred_type)) {
7674 LOCAL_SET_GL_ERROR(
7675 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7676 "with the current read framebuffer");
7677 return error::kNoError;
7678 }
7679 }
[email protected]57f223832010-03-19 01:57:567680 if (width == 0 || height == 0) {
7681 return error::kNoError;
7682 }
7683
[email protected]57f223832010-03-19 01:57:567684 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307685 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567686
[email protected]3aad1a32012-09-07 20:54:477687 int32 max_x;
7688 int32 max_y;
7689 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517690 LOCAL_SET_GL_ERROR(
7691 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147692 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317693 }
[email protected]57f223832010-03-19 01:57:567694
[email protected]2ea5950d2014-07-09 18:20:347695 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
7696 return error::kNoError;
7697 }
7698
[email protected]0d6bfdc2011-11-02 01:32:207699 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7700 return error::kNoError;
7701 }
7702
[email protected]caa13ed2014-02-17 11:29:207703 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107704
7705 ScopedResolvedFrameBufferBinder binder(this, false, true);
7706
[email protected]d37231fa2010-04-09 21:16:027707 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567708 // The user requested an out of range area. Get the results 1 line
7709 // at a time.
7710 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347711 uint32 unpadded_row_size;
7712 uint32 padded_row_size;
7713 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247714 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347715 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517716 LOCAL_SET_GL_ERROR(
7717 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567718 return error::kNoError;
7719 }
7720
7721 GLint dest_x_offset = std::max(-x, 0);
7722 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347723 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247724 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7725 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517726 LOCAL_SET_GL_ERROR(
7727 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567728 return error::kNoError;
7729 }
7730
7731 // Copy each row into the larger dest rect.
7732 int8* dst = static_cast<int8*>(pixels);
7733 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027734 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567735 GLint read_width = read_end_x - read_x;
7736 for (GLint yy = 0; yy < height; ++yy) {
7737 GLint ry = y + yy;
7738
7739 // Clear the row.
7740 memset(dst, 0, unpadded_row_size);
7741
7742 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027743 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567744 glReadPixels(
7745 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7746 }
7747 dst += padded_row_size;
7748 }
7749 } else {
[email protected]5a36dc132013-07-23 23:17:557750 if (async && features().use_async_readpixels) {
miu50cef602014-11-11 01:35:417751 GLuint buffer = 0;
[email protected]5a36dc132013-07-23 23:17:557752 glGenBuffersARB(1, &buffer);
7753 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7754 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
7755 GLenum error = glGetError();
7756 if (error == GL_NO_ERROR) {
7757 glReadPixels(x, y, width, height, format, type, 0);
7758 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7759 new FenceCallback()));
7760 WaitForReadPixels(base::Bind(
7761 &GLES2DecoderImpl::FinishReadPixels,
7762 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7763 <GLES2DecoderImpl>(this),
7764 c, buffer));
7765 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7766 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597767 } else {
7768 // On error, unbind pack buffer and fall through to sync readpixels
7769 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
miu50cef602014-11-11 01:35:417770 glDeleteBuffersARB(1, &buffer);
[email protected]5a36dc132013-07-23 23:17:557771 }
7772 }
[email protected]57f223832010-03-19 01:57:567773 glReadPixels(x, y, width, height, format, type, pixels);
7774 }
[email protected]ab09b612013-03-11 22:11:517775 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257776 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107777 if (result != NULL) {
7778 *result = true;
7779 }
[email protected]5a36dc132013-07-23 23:17:557780 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257781 }
[email protected]4848b9f82011-03-10 18:37:567782
[email protected]f7a64ee2010-02-01 22:24:147783 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327784}
7785
vmiuracd108592014-09-08 14:36:347786error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
7787 const void* cmd_data) {
7788 const gles2::cmds::PixelStorei& c =
7789 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:197790 GLenum pname = c.pname;
7791 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057792 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517793 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127794 return error::kNoError;
7795 }
[email protected]222471d2011-11-30 18:06:397796 switch (pname) {
7797 case GL_PACK_ALIGNMENT:
7798 case GL_UNPACK_ALIGNMENT:
7799 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517800 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207801 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397802 return error::kNoError;
7803 }
[email protected]164d6d52012-05-05 00:55:037804 break;
[email protected]0a1e9ad2012-05-04 21:13:037805 case GL_UNPACK_FLIP_Y_CHROMIUM:
7806 unpack_flip_y_ = (param != 0);
7807 return error::kNoError;
7808 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7809 unpack_premultiply_alpha_ = (param != 0);
7810 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177811 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7812 unpack_unpremultiply_alpha_ = (param != 0);
7813 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397814 default:
7815 break;
[email protected]b9849abf2009-11-25 19:13:197816 }
7817 glPixelStorei(pname, param);
7818 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437819 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247820 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437821 break;
7822 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427823 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437824 break;
7825 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247826 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437827 break;
7828 default:
7829 // Validation should have prevented us from getting here.
7830 NOTREACHED();
7831 break;
[email protected]b9849abf2009-11-25 19:13:197832 }
[email protected]f7a64ee2010-02-01 22:24:147833 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197834}
7835
[email protected]1c75a3702011-11-11 14:15:287836error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:347837 uint32 immediate_data_size,
7838 const void* cmd_data) {
7839 const gles2::cmds::PostSubBufferCHROMIUM& c =
7840 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:387841 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:277842 {
7843 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
7844 }
[email protected]b381ee32014-03-22 02:43:437845 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:517846 LOCAL_SET_GL_ERROR(
7847 GL_INVALID_OPERATION,
7848 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287849 return error::kNoError;
7850 }
[email protected]8f9b8dd2013-09-12 18:05:137851 bool is_tracing;
7852 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7853 &is_tracing);
7854 if (is_tracing) {
7855 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7856 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7857 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7858 is_offscreen ? offscreen_size_ : surface_->GetSize());
7859 }
[email protected]7794d512012-04-17 20:36:497860 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287861 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497862 } else {
7863 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287864 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497865 }
[email protected]1c75a3702011-11-11 14:15:287866}
7867
[email protected]957f0642014-04-09 16:50:017868error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
7869 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347870 const void* cmd_data) {
7871 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
7872 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:107873 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
7874 if (!ref) {
7875 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7876 "glScheduleOverlayPlaneCHROMIUM",
7877 "unknown texture");
7878 return error::kNoError;
7879 }
7880 gfx::GLImage* image =
7881 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
7882 if (!image) {
7883 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7884 "glScheduleOverlayPlaneCHROMIUM",
7885 "unsupported texture format");
7886 return error::kNoError;
7887 }
7888 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
7889 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
7890 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
7891 "glScheduleOverlayPlaneCHROMIUM",
7892 "invalid transform enum");
7893 return error::kNoError;
7894 }
7895 if (!surface_->ScheduleOverlayPlane(
7896 c.plane_z_order,
7897 transform,
7898 image,
7899 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
7900 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
7901 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
7902 "glScheduleOverlayPlaneCHROMIUM",
7903 "failed to schedule overlay");
7904 }
[email protected]957f0642014-04-09 16:50:017905 return error::kNoError;
7906}
7907
[email protected]558847a2010-03-24 07:02:547908error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7909 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7910 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577911 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517912 LOCAL_SET_GL_ERROR(
7913 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577914 return error::kNoError;
7915 }
[email protected]df37b9932013-03-08 05:21:427916 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587917 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427918 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147919 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197920 }
[email protected]df37b9932013-03-08 05:21:427921 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517922 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437923 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257924 return error::kNoError;
7925 }
[email protected]b9849abf2009-11-25 19:13:197926 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547927 location_shm_id, location_shm_offset, sizeof(GLint));
7928 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147929 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197930 }
[email protected]558847a2010-03-24 07:02:547931 // Require the client to init this incase the context is lost and we are no
7932 // longer executing commands.
7933 if (*location != -1) {
7934 return error::kGenericError;
7935 }
[email protected]df37b9932013-03-08 05:21:427936 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147937 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197938}
7939
[email protected]558847a2010-03-24 07:02:547940error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:347941 uint32 immediate_data_size,
7942 const void* cmd_data) {
7943 const gles2::cmds::GetAttribLocation& c =
7944 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:547945 Bucket* bucket = GetBucket(c.name_bucket_id);
7946 if (!bucket) {
7947 return error::kInvalidArguments;
7948 }
7949 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187950 if (!bucket->GetAsString(&name_str)) {
7951 return error::kInvalidArguments;
7952 }
[email protected]558847a2010-03-24 07:02:547953 return GetAttribLocationHelper(
7954 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7955}
7956
7957error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7958 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7959 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577960 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517961 LOCAL_SET_GL_ERROR(
7962 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577963 return error::kNoError;
7964 }
[email protected]df37b9932013-03-08 05:21:427965 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:207966 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:427967 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147968 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197969 }
[email protected]df37b9932013-03-08 05:21:427970 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517971 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437972 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257973 return error::kNoError;
7974 }
[email protected]b9849abf2009-11-25 19:13:197975 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547976 location_shm_id, location_shm_offset, sizeof(GLint));
7977 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147978 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197979 }
[email protected]558847a2010-03-24 07:02:547980 // Require the client to init this incase the context is lost an we are no
7981 // longer executing commands.
7982 if (*location != -1) {
7983 return error::kGenericError;
7984 }
[email protected]df37b9932013-03-08 05:21:427985 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147986 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197987}
7988
[email protected]f7a64ee2010-02-01 22:24:147989error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:347990 uint32 immediate_data_size,
7991 const void* cmd_data) {
7992 const gles2::cmds::GetUniformLocation& c =
7993 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:547994 Bucket* bucket = GetBucket(c.name_bucket_id);
7995 if (!bucket) {
7996 return error::kInvalidArguments;
7997 }
7998 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187999 if (!bucket->GetAsString(&name_str)) {
8000 return error::kInvalidArguments;
8001 }
[email protected]558847a2010-03-24 07:02:548002 return GetUniformLocationHelper(
8003 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:198004}
8005
vmiuracd108592014-09-08 14:36:348006error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
8007 const void* cmd_data) {
8008 const gles2::cmds::GetString& c =
8009 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:298010 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:058011 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:518012 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:298013 return error::kNoError;
8014 }
[email protected]959e9072013-09-20 16:58:388015 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:048016 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:158017 switch (name) {
8018 case GL_VERSION:
8019 str = "OpenGL ES 2.0 Chromium";
8020 break;
8021 case GL_SHADING_LANGUAGE_VERSION:
8022 str = "OpenGL ES GLSL ES 1.0 Chromium";
8023 break;
[email protected]32939602012-05-09 06:25:168024 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:168025 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:388026 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
8027 // They are used by WEBGL_debug_renderer_info.
8028 if (!force_webgl_glsl_validation_)
8029 str = "Chromium";
[email protected]32939602012-05-09 06:25:168030 break;
[email protected]1958e0e2010-04-22 05:17:158031 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:048032 {
[email protected]70dc60932013-06-04 03:33:498033 // For WebGL contexts, strip out the OES derivatives and
8034 // EXT frag depth extensions if they have not been enabled.
8035 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:048036 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:498037 if (!derivatives_explicitly_enabled_) {
8038 size_t offset = extensions.find(kOESDerivativeExtension);
8039 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098040 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:498041 std::string());
8042 }
8043 }
8044 if (!frag_depth_explicitly_enabled_) {
8045 size_t offset = extensions.find(kEXTFragDepthExtension);
8046 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098047 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:498048 std::string());
8049 }
[email protected]f0d74742011-10-03 16:31:048050 }
[email protected]aff39ac82013-06-08 04:53:138051 if (!draw_buffers_explicitly_enabled_) {
8052 size_t offset = extensions.find(kEXTDrawBuffersExtension);
8053 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098054 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:138055 std::string());
8056 }
8057 }
[email protected]93c2fd82014-04-16 02:46:068058 if (!shader_texture_lod_explicitly_enabled_) {
8059 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
8060 if (std::string::npos != offset) {
8061 extensions.replace(offset,
8062 arraysize(kEXTShaderTextureLodExtension),
8063 std::string());
8064 }
8065 }
[email protected]f0d74742011-10-03 16:31:048066 } else {
[email protected]6f5fac9d12012-06-26 21:02:458067 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:048068 }
[email protected]b381ee32014-03-22 02:43:438069 if (supports_post_sub_buffer_)
8070 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:458071 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:048072 }
[email protected]1958e0e2010-04-22 05:17:158073 break;
8074 default:
[email protected]1958e0e2010-04-22 05:17:158075 break;
8076 }
[email protected]ddd968b82010-03-02 00:44:298077 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:158078 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:298079 return error::kNoError;
8080}
8081
vmiuracd108592014-09-08 14:36:348082error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
8083 const void* cmd_data) {
8084 const gles2::cmds::BufferData& c =
8085 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:118086 GLenum target = static_cast<GLenum>(c.target);
8087 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
8088 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8089 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8090 GLenum usage = static_cast<GLenum>(c.usage);
8091 const void* data = NULL;
8092 if (data_shm_id != 0 || data_shm_offset != 0) {
8093 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
8094 if (!data) {
8095 return error::kOutOfBounds;
8096 }
8097 }
[email protected]0fbba3732013-07-17 15:40:138098 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:148099 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198100}
8101
[email protected]0c86dbf2010-03-05 08:14:118102void GLES2DecoderImpl::DoBufferSubData(
8103 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:138104 // Just delegate it. Some validation is actually done before this.
8105 buffer_manager()->ValidateAndDoBufferSubData(
8106 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:198107}
8108
[email protected]0d6bfdc2011-11-02 01:32:208109bool GLES2DecoderImpl::ClearLevel(
8110 unsigned service_id,
8111 unsigned bind_target,
8112 unsigned target,
8113 int level,
[email protected]d8e6c9242014-02-20 16:56:258114 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:208115 unsigned format,
8116 unsigned type,
8117 int width,
[email protected]4502e6492011-12-14 19:39:158118 int height,
8119 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:008120 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:008121 if (feature_info_->feature_flags().angle_depth_texture &&
8122 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:008123 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
8124 // on depth formats.
8125 GLuint fb = 0;
8126 glGenFramebuffersEXT(1, &fb);
8127 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
8128
8129 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
8130 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
8131 GL_DEPTH_ATTACHMENT;
8132
8133 glFramebufferTexture2DEXT(
8134 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
8135 // ANGLE promises a depth only attachment ok.
8136 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8137 GL_FRAMEBUFFER_COMPLETE) {
8138 return false;
8139 }
8140 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:478141 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8142 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008143 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458144 state_.SetDeviceDepthMask(GL_TRUE);
8145 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:008146 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8147
8148 RestoreClearState();
8149
8150 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358151 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008152 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8153 GLuint fb_service_id =
8154 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8155 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8156 return true;
8157 }
8158
[email protected]45d15a62012-04-18 14:33:178159 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8160
8161 uint32 size;
8162 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348163 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248164 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178165 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208166 return false;
8167 }
[email protected]45d15a62012-04-18 14:33:178168
[email protected]a5d3dad2012-05-26 04:34:448169 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8170
[email protected]45d15a62012-04-18 14:33:178171 int tile_height;
8172
8173 if (size > kMaxZeroSize) {
8174 if (kMaxZeroSize < padded_row_size) {
8175 // That'd be an awfully large texture.
8176 return false;
8177 }
8178 // We should never have a large total size with a zero row size.
8179 DCHECK_GT(padded_row_size, 0U);
8180 tile_height = kMaxZeroSize / padded_row_size;
8181 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248182 width, tile_height, format, type, state_.unpack_alignment, &size,
8183 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178184 return false;
8185 }
[email protected]4502e6492011-12-14 19:39:158186 } else {
[email protected]45d15a62012-04-18 14:33:178187 tile_height = height;
8188 }
8189
8190 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558191 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178192 memset(zero.get(), 0, size);
8193 glBindTexture(bind_target, service_id);
8194
8195 GLint y = 0;
8196 while (y < height) {
8197 GLint h = y + tile_height > height ? height - y : tile_height;
8198 if (is_texture_immutable || h != height) {
8199 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8200 } else {
[email protected]8f1d2aa2013-05-10 23:45:388201 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258202 target, level, internal_format, width, h, 0, format, type,
8203 zero.get());
[email protected]45d15a62012-04-18 14:33:178204 }
8205 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158206 }
[email protected]c986af502013-08-14 01:04:448207 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
8208 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:078209 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208210 return true;
8211}
8212
[email protected]ad84a3a2012-06-08 21:42:438213namespace {
8214
8215const int kS3TCBlockWidth = 4;
8216const int kS3TCBlockHeight = 4;
8217const int kS3TCDXT1BlockSize = 8;
8218const int kS3TCDXT3AndDXT5BlockSize = 16;
8219
8220bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518221 return (size == 1) ||
8222 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438223}
8224
[email protected]8aec81ec2014-04-29 01:04:518225bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128226 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518227}
8228
[email protected]ad84a3a2012-06-08 21:42:438229} // anonymous namespace.
8230
8231bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8232 const char* function_name,
8233 GLsizei width, GLsizei height, GLenum format, size_t size) {
8234 unsigned int bytes_required = 0;
8235
8236 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518237 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438238 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518239 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8240 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438241 int num_blocks_across =
8242 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8243 int num_blocks_down =
8244 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8245 int num_blocks = num_blocks_across * num_blocks_down;
8246 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8247 break;
8248 }
[email protected]8aec81ec2014-04-29 01:04:518249 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8250 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438251 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8252 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8253 int num_blocks_across =
8254 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8255 int num_blocks_down =
8256 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8257 int num_blocks = num_blocks_across * num_blocks_down;
8258 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8259 break;
8260 }
[email protected]8aec81ec2014-04-29 01:04:518261 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8262 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8263 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8264 break;
8265 }
8266 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8267 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8268 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078269 break;
8270 }
[email protected]ad84a3a2012-06-08 21:42:438271 default:
[email protected]ab09b612013-03-11 22:11:518272 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438273 return false;
8274 }
8275
8276 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518277 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438278 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8279 return false;
8280 }
8281
8282 return true;
8283}
8284
8285bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8286 const char* function_name,
8287 GLint level, GLsizei width, GLsizei height, GLenum format) {
8288 switch (format) {
8289 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8290 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8291 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8292 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8293 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518294 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438295 GL_INVALID_OPERATION, function_name,
8296 "width or height invalid for level");
8297 return false;
8298 }
8299 return true;
8300 }
[email protected]8aec81ec2014-04-29 01:04:518301 case GL_ATC_RGB_AMD:
8302 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8303 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8304 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078305 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518306 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078307 GL_INVALID_OPERATION, function_name,
8308 "width or height invalid for level");
8309 return false;
8310 }
8311 return true;
[email protected]8aec81ec2014-04-29 01:04:518312 }
8313 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8314 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8315 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8316 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8317 if (!IsValidPVRTCSize(level, width) ||
8318 !IsValidPVRTCSize(level, height)) {
8319 LOCAL_SET_GL_ERROR(
8320 GL_INVALID_OPERATION, function_name,
8321 "width or height invalid for level");
8322 return false;
8323 }
8324 return true;
8325 }
[email protected]ad84a3a2012-06-08 21:42:438326 default:
8327 return false;
8328 }
8329}
8330
8331bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8332 const char* function_name,
8333 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8334 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358335 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438336 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518337 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438338 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8339 return false;
8340 }
8341
8342 switch (format) {
8343 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8344 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8345 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8346 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8347 const int kBlockWidth = 4;
8348 const int kBlockHeight = 4;
8349 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518350 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438351 GL_INVALID_OPERATION, function_name,
8352 "xoffset or yoffset not multiple of 4");
8353 return false;
8354 }
8355 GLsizei tex_width = 0;
8356 GLsizei tex_height = 0;
8357 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8358 width - xoffset > tex_width ||
8359 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518360 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438361 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8362 return false;
8363 }
8364 return ValidateCompressedTexDimensions(
8365 function_name, level, width, height, format);
8366 }
[email protected]8aec81ec2014-04-29 01:04:518367 case GL_ATC_RGB_AMD:
8368 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8369 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8370 LOCAL_SET_GL_ERROR(
8371 GL_INVALID_OPERATION, function_name,
8372 "not supported for ATC textures");
8373 return false;
8374 }
[email protected]2d3765b2012-10-03 00:31:078375 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518376 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078377 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208378 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078379 return false;
8380 }
[email protected]8aec81ec2014-04-29 01:04:518381 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8382 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8383 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8384 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8385 if ((xoffset != 0) || (yoffset != 0)) {
8386 LOCAL_SET_GL_ERROR(
8387 GL_INVALID_OPERATION, function_name,
8388 "xoffset and yoffset must be zero");
8389 return false;
8390 }
8391 GLsizei tex_width = 0;
8392 GLsizei tex_height = 0;
8393 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8394 width != tex_width ||
8395 height != tex_height) {
8396 LOCAL_SET_GL_ERROR(
8397 GL_INVALID_OPERATION, function_name,
8398 "dimensions must match existing texture level dimensions");
8399 return false;
8400 }
8401 return ValidateCompressedTexDimensions(
8402 function_name, level, width, height, format);
8403 }
[email protected]ad84a3a2012-06-08 21:42:438404 default:
8405 return false;
8406 }
8407}
8408
[email protected]a93bb842010-02-16 23:03:478409error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8410 GLenum target,
8411 GLint level,
8412 GLenum internal_format,
8413 GLsizei width,
8414 GLsizei height,
8415 GLint border,
8416 GLsizei image_size,
8417 const void* data) {
[email protected]a93bb842010-02-16 23:03:478418 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058419 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518420 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8421 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298422 return error::kNoError;
8423 }
[email protected]9438b012010-06-15 22:55:058424 if (!validators_->compressed_texture_format.IsValid(
8425 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518426 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538427 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478428 return error::kNoError;
8429 }
[email protected]80eb6b52012-01-19 00:14:418430 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478431 border != 0) {
[email protected]ab09b612013-03-11 22:11:518432 LOCAL_SET_GL_ERROR(
8433 GL_INVALID_VALUE,
8434 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478435 return error::kNoError;
8436 }
[email protected]c986af502013-08-14 01:04:448437 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8438 &state_, target);
[email protected]370eaf12013-05-18 09:19:498439 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518440 LOCAL_SET_GL_ERROR(
8441 GL_INVALID_VALUE,
8442 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478443 return error::kNoError;
8444 }
[email protected]370eaf12013-05-18 09:19:498445 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078446 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518447 LOCAL_SET_GL_ERROR(
8448 GL_INVALID_OPERATION,
8449 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438450 return error::kNoError;
8451 }
8452
8453 if (!ValidateCompressedTexDimensions(
8454 "glCompressedTexImage2D", level, width, height, internal_format) ||
8455 !ValidateCompressedTexFuncData(
8456 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178457 return error::kNoError;
8458 }
[email protected]968351b2011-12-20 08:26:518459
[email protected]7989c9e2013-01-23 06:39:268460 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518461 LOCAL_SET_GL_ERROR(
8462 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268463 return error::kNoError;
8464 }
8465
[email protected]02965c22013-03-09 02:40:078466 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448467 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518468 }
8469
[email protected]40d90a22013-04-09 03:39:558470 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478471 if (!data) {
8472 zero.reset(new int8[image_size]);
8473 memset(zero.get(), 0, image_size);
8474 data = zero.get();
8475 }
[email protected]ab09b612013-03-11 22:11:518476 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478477 glCompressedTexImage2D(
8478 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518479 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438480 if (error == GL_NO_ERROR) {
8481 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498482 texture_ref, target, level, internal_format,
8483 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438484 }
vmiura8266ca72014-09-09 21:37:008485
8486 // This may be a slow command. Exit command processing to allow for
8487 // context preemption and GPU watchdog checks.
8488 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:478489 return error::kNoError;
8490}
8491
[email protected]f7a64ee2010-02-01 22:24:148492error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:348493 uint32 immediate_data_size,
8494 const void* cmd_data) {
8495 const gles2::cmds::CompressedTexImage2D& c =
8496 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198497 GLenum target = static_cast<GLenum>(c.target);
8498 GLint level = static_cast<GLint>(c.level);
8499 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8500 GLsizei width = static_cast<GLsizei>(c.width);
8501 GLsizei height = static_cast<GLsizei>(c.height);
8502 GLint border = static_cast<GLint>(c.border);
8503 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8504 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8505 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8506 const void* data = NULL;
8507 if (data_shm_id != 0 || data_shm_offset != 0) {
8508 data = GetSharedMemoryAs<const void*>(
8509 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468510 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148511 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198512 }
8513 }
[email protected]a93bb842010-02-16 23:03:478514 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198515 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198516}
8517
[email protected]b6140d02010-05-17 14:47:168518error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:348519 uint32 immediate_data_size,
8520 const void* cmd_data) {
8521 const gles2::cmds::CompressedTexImage2DBucket& c =
8522 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168523 GLenum target = static_cast<GLenum>(c.target);
8524 GLint level = static_cast<GLint>(c.level);
8525 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8526 GLsizei width = static_cast<GLsizei>(c.width);
8527 GLsizei height = static_cast<GLsizei>(c.height);
8528 GLint border = static_cast<GLint>(c.border);
8529 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288530 if (!bucket) {
8531 return error::kInvalidArguments;
8532 }
8533 uint32 data_size = bucket->size();
8534 GLsizei imageSize = data_size;
8535 const void* data = bucket->GetData(0, data_size);
8536 if (!data) {
8537 return error::kInvalidArguments;
8538 }
[email protected]b6140d02010-05-17 14:47:168539 return DoCompressedTexImage2D(
8540 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288541 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168542}
8543
8544error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8545 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348546 const void* cmd_data) {
8547 const gles2::cmds::CompressedTexSubImage2DBucket& c =
8548 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168549 GLenum target = static_cast<GLenum>(c.target);
8550 GLint level = static_cast<GLint>(c.level);
8551 GLint xoffset = static_cast<GLint>(c.xoffset);
8552 GLint yoffset = static_cast<GLint>(c.yoffset);
8553 GLsizei width = static_cast<GLsizei>(c.width);
8554 GLsizei height = static_cast<GLsizei>(c.height);
8555 GLenum format = static_cast<GLenum>(c.format);
8556 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288557 if (!bucket) {
8558 return error::kInvalidArguments;
8559 }
[email protected]b6140d02010-05-17 14:47:168560 uint32 data_size = bucket->size();
8561 GLsizei imageSize = data_size;
8562 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288563 if (!data) {
8564 return error::kInvalidArguments;
8565 }
[email protected]9438b012010-06-15 22:55:058566 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518567 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538568 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168569 return error::kNoError;
8570 }
[email protected]9438b012010-06-15 22:55:058571 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518572 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8573 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058574 return error::kNoError;
8575 }
[email protected]b6140d02010-05-17 14:47:168576 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518577 LOCAL_SET_GL_ERROR(
8578 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168579 return error::kNoError;
8580 }
8581 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518582 LOCAL_SET_GL_ERROR(
8583 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168584 return error::kNoError;
8585 }
8586 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518587 LOCAL_SET_GL_ERROR(
8588 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168589 return error::kNoError;
8590 }
[email protected]cadde4a2010-07-31 17:10:438591 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168592 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8593 return error::kNoError;
8594}
8595
vmiuracd108592014-09-08 14:36:348596error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
8597 const void* cmd_data) {
8598 const gles2::cmds::TexImage2D& c =
8599 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138600 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8601 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:448602 // Set as failed for now, but if it successed, this will be set to not failed.
8603 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198604 GLenum target = static_cast<GLenum>(c.target);
8605 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448606 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8607 // for internalformat.
8608 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198609 GLsizei width = static_cast<GLsizei>(c.width);
8610 GLsizei height = static_cast<GLsizei>(c.height);
8611 GLint border = static_cast<GLint>(c.border);
8612 GLenum format = static_cast<GLenum>(c.format);
8613 GLenum type = static_cast<GLenum>(c.type);
8614 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8615 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188616 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348617 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248618 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:348619 NULL)) {
[email protected]a76b0052010-03-05 00:33:188620 return error::kOutOfBounds;
8621 }
[email protected]b9849abf2009-11-25 19:13:198622 const void* pixels = NULL;
8623 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8624 pixels = GetSharedMemoryAs<const void*>(
8625 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468626 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148627 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198628 }
8629 }
[email protected]f598f422012-12-07 08:30:038630
[email protected]c986af502013-08-14 01:04:448631 TextureManager::DoTextImage2DArguments args = {
8632 target, level, internal_format, width, height, border, format, type,
8633 pixels, pixels_size};
8634 texture_manager()->ValidateAndDoTexImage2D(
8635 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:008636
8637 // This may be a slow command. Exit command processing to allow for
8638 // context preemption and GPU watchdog checks.
8639 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038640 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198641}
8642
[email protected]cadde4a2010-07-31 17:10:438643void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8644 GLenum target,
8645 GLint level,
8646 GLint xoffset,
8647 GLint yoffset,
8648 GLsizei width,
8649 GLsizei height,
8650 GLenum format,
8651 GLsizei image_size,
8652 const void * data) {
[email protected]c986af502013-08-14 01:04:448653 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8654 &state_, target);
[email protected]370eaf12013-05-18 09:19:498655 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518656 LOCAL_SET_GL_ERROR(
8657 GL_INVALID_OPERATION,
8658 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438659 return;
8660 }
[email protected]370eaf12013-05-18 09:19:498661 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438662 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528663 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078664 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518665 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528666 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438667 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528668 return;
8669 }
8670 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518671 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528672 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438673 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528674 return;
8675 }
[email protected]02965c22013-03-09 02:40:078676 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528677 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518678 LOCAL_SET_GL_ERROR(
8679 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438680 return;
8681 }
[email protected]ad84a3a2012-06-08 21:42:438682
8683 if (!ValidateCompressedTexFuncData(
8684 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8685 !ValidateCompressedTexSubDimensions(
8686 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078687 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438688 return;
8689 }
8690
8691
[email protected]0d6bfdc2011-11-02 01:32:208692 // Note: There is no need to deal with texture cleared tracking here
8693 // because the validation above means you can only get here if the level
8694 // is already a matching compressed format and in that case
8695 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438696 glCompressedTexSubImage2D(
8697 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:008698
8699 // This may be a slow command. Exit command processing to allow for
8700 // context preemption and GPU watchdog checks.
8701 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438702}
8703
[email protected]6e288612010-12-21 20:45:038704static void Clip(
8705 GLint start, GLint range, GLint sourceRange,
8706 GLint* out_start, GLint* out_range) {
8707 DCHECK(out_start);
8708 DCHECK(out_range);
8709 if (start < 0) {
8710 range += start;
8711 start = 0;
8712 }
8713 GLint end = start + range;
8714 if (end > sourceRange) {
8715 range -= end - sourceRange;
8716 }
8717 *out_start = start;
8718 *out_range = range;
8719}
8720
[email protected]cadde4a2010-07-31 17:10:438721void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448722 GLenum target,
8723 GLint level,
8724 GLenum internal_format,
8725 GLint x,
8726 GLint y,
8727 GLsizei width,
8728 GLsizei height,
8729 GLint border) {
[email protected]09e17272012-11-30 10:30:448730 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448731 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8732 &state_, target);
[email protected]370eaf12013-05-18 09:19:498733 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518734 LOCAL_SET_GL_ERROR(
8735 GL_INVALID_OPERATION,
8736 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438737 return;
8738 }
[email protected]370eaf12013-05-18 09:19:498739 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078740 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518741 LOCAL_SET_GL_ERROR(
8742 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:538743 return;
[email protected]97dc7cbe2011-12-06 17:26:178744 }
[email protected]80eb6b52012-01-19 00:14:418745 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188746 border != 0) {
[email protected]ab09b612013-03-11 22:11:518747 LOCAL_SET_GL_ERROR(
8748 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188749 return;
8750 }
[email protected]17a961192014-02-14 15:20:528751 if (!texture_manager()->ValidateFormatAndTypeCombination(
8752 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
8753 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:008754 return;
8755 }
[email protected]f5719fb2010-08-04 18:27:188756
[email protected]9edc6b22010-12-23 02:00:268757 // Check we have compatible formats.
8758 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8759 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8760 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8761
8762 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518763 LOCAL_SET_GL_ERROR(
8764 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268765 return;
8766 }
8767
[email protected]81375742012-06-08 00:04:008768 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518769 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008770 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268771 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8772 return;
8773 }
8774
8775 uint32 estimated_size = 0;
8776 if (!GLES2Util::ComputeImageDataSizes(
8777 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8778 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518779 LOCAL_SET_GL_ERROR(
8780 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268781 return;
8782 }
8783
8784 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518785 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008786 return;
8787 }
8788
[email protected]2ea5950d2014-07-09 18:20:348789 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
8790 return;
8791 }
8792
zmo383512cf2014-10-14 00:11:008793 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
8794 LOCAL_SET_GL_ERROR(
8795 GL_INVALID_OPERATION,
8796 "glCopyTexImage2D", "source and destination textures are the same");
8797 return;
8798 }
8799
[email protected]a0b78dc2011-11-11 10:43:108800 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8801 return;
8802 }
8803
[email protected]ab09b612013-03-11 22:11:518804 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278805 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038806 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268807
[email protected]02965c22013-03-09 02:40:078808 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448809 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:468810 }
8811
[email protected]9edc6b22010-12-23 02:00:268812 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038813 GLint copyX = 0;
8814 GLint copyY = 0;
8815 GLint copyWidth = 0;
8816 GLint copyHeight = 0;
8817 Clip(x, width, size.width(), &copyX, &copyWidth);
8818 Clip(y, height, size.height(), &copyY, &copyHeight);
8819
8820 if (copyX != x ||
8821 copyY != y ||
8822 copyWidth != width ||
8823 copyHeight != height) {
8824 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208825 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078826 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:258827 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
8828 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518829 LOCAL_SET_GL_ERROR(
8830 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038831 return;
8832 }
[email protected]6e288612010-12-21 20:45:038833 if (copyHeight > 0 && copyWidth > 0) {
8834 GLint dx = copyX - x;
8835 GLint dy = copyY - y;
8836 GLint destX = dx;
8837 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:378838 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038839 glCopyTexSubImage2D(target, level,
8840 destX, destY, copyX, copyY,
8841 copyWidth, copyHeight);
8842 }
8843 } else {
[email protected]00c2cf92014-03-14 00:08:378844 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038845 glCopyTexImage2D(target, level, internal_format,
8846 copyX, copyY, copyWidth, copyHeight, border);
8847 }
[email protected]ab09b612013-03-11 22:11:518848 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438849 if (error == GL_NO_ERROR) {
8850 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498851 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208852 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438853 }
vmiura8266ca72014-09-09 21:37:008854
8855 // This may be a slow command. Exit command processing to allow for
8856 // context preemption and GPU watchdog checks.
8857 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438858}
8859
8860void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448861 GLenum target,
8862 GLint level,
8863 GLint xoffset,
8864 GLint yoffset,
8865 GLint x,
8866 GLint y,
8867 GLsizei width,
8868 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448869 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448870 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8871 &state_, target);
[email protected]370eaf12013-05-18 09:19:498872 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518873 LOCAL_SET_GL_ERROR(
8874 GL_INVALID_OPERATION,
8875 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438876 return;
8877 }
[email protected]370eaf12013-05-18 09:19:498878 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438879 GLenum type = 0;
8880 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078881 if (!texture->GetLevelType(target, level, &type, &format) ||
8882 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528883 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518884 LOCAL_SET_GL_ERROR(
8885 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438886 return;
8887 }
[email protected]85a4ac22013-05-31 01:58:478888 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518889 LOCAL_SET_GL_ERROR(
8890 GL_INVALID_OPERATION,
8891 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598892 return;
8893 }
[email protected]9edc6b22010-12-23 02:00:268894
8895 // Check we have compatible formats.
8896 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8897 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8898 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8899
[email protected]2d3765b2012-10-03 00:31:078900 if (!channels_needed ||
8901 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518902 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438903 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268904 return;
8905 }
8906
[email protected]81375742012-06-08 00:04:008907 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518908 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008909 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438910 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008911 return;
8912 }
8913
[email protected]2ea5950d2014-07-09 18:20:348914 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
8915 return;
8916 }
8917
zmo383512cf2014-10-14 00:11:008918 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
8919 LOCAL_SET_GL_ERROR(
8920 GL_INVALID_OPERATION,
8921 "glCopyTexSubImage2D", "source and destination textures are the same");
8922 return;
8923 }
8924
[email protected]a0b78dc2011-11-11 10:43:108925 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8926 return;
8927 }
8928
[email protected]de26b3c2011-08-03 21:54:278929 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038930 gfx::Size size = GetBoundReadFrameBufferSize();
8931 GLint copyX = 0;
8932 GLint copyY = 0;
8933 GLint copyWidth = 0;
8934 GLint copyHeight = 0;
8935 Clip(x, width, size.width(), &copyX, &copyWidth);
8936 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208937
[email protected]370eaf12013-05-18 09:19:498938 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518939 LOCAL_SET_GL_ERROR(
8940 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208941 return;
8942 }
8943
[email protected]6e288612010-12-21 20:45:038944 if (copyX != x ||
8945 copyY != y ||
8946 copyWidth != width ||
8947 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208948 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038949 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348950 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248951 width, height, format, type, state_.unpack_alignment, &pixels_size,
8952 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518953 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438954 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038955 return;
8956 }
[email protected]40d90a22013-04-09 03:39:558957 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038958 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:378959 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038960 glTexSubImage2D(
8961 target, level, xoffset, yoffset, width, height,
8962 format, type, zero.get());
8963 }
[email protected]0d6bfdc2011-11-02 01:32:208964
[email protected]6e288612010-12-21 20:45:038965 if (copyHeight > 0 && copyWidth > 0) {
8966 GLint dx = copyX - x;
8967 GLint dy = copyY - y;
8968 GLint destX = xoffset + dx;
8969 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:378970 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038971 glCopyTexSubImage2D(target, level,
8972 destX, destY, copyX, copyY,
8973 copyWidth, copyHeight);
8974 }
vmiura8266ca72014-09-09 21:37:008975
8976 // This may be a slow command. Exit command processing to allow for
8977 // context preemption and GPU watchdog checks.
8978 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438979}
8980
[email protected]f598f422012-12-07 08:30:038981bool GLES2DecoderImpl::ValidateTexSubImage2D(
8982 error::Error* error,
8983 const char* function_name,
8984 GLenum target,
8985 GLint level,
8986 GLint xoffset,
8987 GLint yoffset,
8988 GLsizei width,
8989 GLsizei height,
8990 GLenum format,
8991 GLenum type,
8992 const void * data) {
8993 (*error) = error::kNoError;
8994 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518995 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038996 return false;
8997 }
8998 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518999 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:039000 return false;
9001 }
9002 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:519003 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:039004 return false;
9005 }
[email protected]c986af502013-08-14 01:04:449006 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9007 &state_, target);
[email protected]370eaf12013-05-18 09:19:499008 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519009 LOCAL_SET_GL_ERROR(
9010 GL_INVALID_OPERATION,
9011 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:039012 return false;
[email protected]cadde4a2010-07-31 17:10:439013 }
[email protected]370eaf12013-05-18 09:19:499014 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:529015 GLenum current_type = 0;
9016 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079017 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519018 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:039019 GL_INVALID_OPERATION, function_name, "level does not exist.");
9020 return false;
[email protected]df6cf1ad2011-01-29 01:20:529021 }
[email protected]17a961192014-02-14 15:20:529022 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
9023 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:039024 return false;
[email protected]df6cf1ad2011-01-29 01:20:529025 }
9026 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:519027 LOCAL_SET_GL_ERROR(
9028 GL_INVALID_OPERATION,
9029 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:039030 return false;
[email protected]df6cf1ad2011-01-29 01:20:529031 }
[email protected]85a4ac22013-05-31 01:58:479032 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519033 LOCAL_SET_GL_ERROR(
9034 GL_INVALID_OPERATION,
9035 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599036 return false;
9037 }
[email protected]02965c22013-03-09 02:40:079038 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529039 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519040 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:039041 return false;
[email protected]cadde4a2010-07-31 17:10:439042 }
[email protected]81375742012-06-08 00:04:009043 if ((GLES2Util::GetChannelsForFormat(format) &
9044 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519045 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009046 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:039047 function_name, "can not supply data for depth or stencil textures");
9048 return false;
[email protected]81375742012-06-08 00:04:009049 }
[email protected]f598f422012-12-07 08:30:039050 if (data == NULL) {
9051 (*error) = error::kOutOfBounds;
9052 return false;
9053 }
9054 return true;
9055}
[email protected]81375742012-06-08 00:04:009056
[email protected]f598f422012-12-07 08:30:039057error::Error GLES2DecoderImpl::DoTexSubImage2D(
9058 GLenum target,
9059 GLint level,
9060 GLint xoffset,
9061 GLint yoffset,
9062 GLsizei width,
9063 GLsizei height,
9064 GLenum format,
9065 GLenum type,
9066 const void * data) {
9067 error::Error error = error::kNoError;
9068 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
9069 xoffset, yoffset, width, height, format, type, data)) {
9070 return error;
9071 }
[email protected]c986af502013-08-14 01:04:449072 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9073 &state_, target);
[email protected]370eaf12013-05-18 09:19:499074 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:159075 GLsizei tex_width = 0;
9076 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:079077 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:159078 DCHECK(ok);
9079 if (xoffset != 0 || yoffset != 0 ||
9080 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:499081 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
9082 target, level)) {
[email protected]ab09b612013-03-11 22:11:519083 LOCAL_SET_GL_ERROR(
9084 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:039085 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:309086 }
[email protected]c986af502013-08-14 01:04:449087 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159088 glTexSubImage2D(
9089 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:039090 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:209091 }
[email protected]4502e6492011-12-14 19:39:159092
[email protected]345ba902013-11-14 21:39:009093 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:449094 !texture->IsImmutable()) {
9095 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:259096 GLenum internal_format;
9097 GLenum tex_type;
9098 texture->GetLevelType(target, level, &tex_type, &internal_format);
9099 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
9100 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:389101 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:259102 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:159103 } else {
[email protected]c986af502013-08-14 01:04:449104 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159105 glTexSubImage2D(
9106 target, level, xoffset, yoffset, width, height, format, type, data);
9107 }
[email protected]370eaf12013-05-18 09:19:499108 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:009109
9110 // This may be a slow command. Exit command processing to allow for
9111 // context preemption and GPU watchdog checks.
9112 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039113 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:439114}
9115
vmiuracd108592014-09-08 14:36:349116error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
9117 const void* cmd_data) {
9118 const gles2::cmds::TexSubImage2D& c =
9119 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139120 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
9121 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:009122 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:449123 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:009124 return error::kNoError;
9125
9126 GLenum target = static_cast<GLenum>(c.target);
9127 GLint level = static_cast<GLint>(c.level);
9128 GLint xoffset = static_cast<GLint>(c.xoffset);
9129 GLint yoffset = static_cast<GLint>(c.yoffset);
9130 GLsizei width = static_cast<GLsizei>(c.width);
9131 GLsizei height = static_cast<GLsizei>(c.height);
9132 GLenum format = static_cast<GLenum>(c.format);
9133 GLenum type = static_cast<GLenum>(c.type);
9134 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:349135 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:249136 width, height, format, type, state_.unpack_alignment, &data_size,
9137 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:009138 return error::kOutOfBounds;
9139 }
9140 const void* pixels = GetSharedMemoryAs<const void*>(
9141 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:039142 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:009143 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:009144}
9145
[email protected]f7a64ee2010-02-01 22:24:149146error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349147 uint32 immediate_data_size,
9148 const void* cmd_data) {
9149 const gles2::cmds::GetVertexAttribPointerv& c =
9150 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369151 GLuint index = static_cast<GLuint>(c.index);
9152 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359153 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259154 Result* result = GetSharedMemoryAs<Result*>(
9155 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369156 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149157 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369158 }
[email protected]07d0cc82010-02-17 04:51:409159 // Check that the client initialized the result.
9160 if (result->size != 0) {
9161 return error::kInvalidArguments;
9162 }
[email protected]9438b012010-06-15 22:55:059163 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519164 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9165 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149166 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369167 }
[email protected]3916c97e2010-02-25 03:20:509168 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519169 LOCAL_SET_GL_ERROR(
9170 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149171 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369172 }
[email protected]0bfd9882010-02-05 23:02:259173 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089174 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359175 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149176 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329177}
9178
[email protected]f7b85372010-02-03 01:11:379179bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:429180 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:379181 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:129182 error::Error* error, GLint* real_location,
9183 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:109184 DCHECK(error);
9185 DCHECK(service_id);
9186 DCHECK(result_pointer);
9187 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129188 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379189 *error = error::kNoError;
9190 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259191 SizedResult<GLint>* result;
9192 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9193 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9194 if (!result) {
[email protected]f7b85372010-02-03 01:11:379195 *error = error::kOutOfBounds;
9196 return false;
9197 }
[email protected]0bfd9882010-02-05 23:02:259198 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379199 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259200 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429201 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9202 if (!program) {
[email protected]ae51d192010-04-27 00:48:039203 return false;
9204 }
[email protected]df37b9932013-03-08 05:21:429205 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379206 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519207 LOCAL_SET_GL_ERROR(
9208 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379209 return false;
9210 }
[email protected]df37b9932013-03-08 05:21:429211 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369212 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359213 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429214 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129215 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369216 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379217 // No such location.
[email protected]ab09b612013-03-11 22:11:519218 LOCAL_SET_GL_ERROR(
9219 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379220 return false;
9221 }
[email protected]43c2f1f2011-03-25 18:35:369222 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509223 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379224 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519225 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379226 return false;
9227 }
[email protected]0bfd9882010-02-05 23:02:259228 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9229 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9230 if (!result) {
[email protected]f7b85372010-02-03 01:11:379231 *error = error::kOutOfBounds;
9232 return false;
9233 }
[email protected]0bfd9882010-02-05 23:02:259234 result->size = size;
[email protected]939e7362010-05-13 20:49:109235 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379236 return true;
9237}
9238
vmiuracd108592014-09-08 14:36:349239error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9240 const void* cmd_data) {
9241 const gles2::cmds::GetUniformiv& c =
9242 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379243 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339244 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379245 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109246 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:129247 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379248 Error error;
[email protected]0bfd9882010-02-05 23:02:259249 void* result;
[email protected]f7b85372010-02-03 01:11:379250 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129251 program, fake_location, c.params_shm_id, c.params_shm_offset,
9252 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:259253 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129254 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359255 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379256 }
9257 return error;
[email protected]96449d2c2009-11-25 00:01:329258}
9259
vmiuracd108592014-09-08 14:36:349260error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9261 const void* cmd_data) {
9262 const gles2::cmds::GetUniformfv& c =
9263 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379264 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339265 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379266 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129267 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379268 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359269 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109270 Result* result;
9271 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:379272 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129273 program, fake_location, c.params_shm_id, c.params_shm_offset,
9274 &error, &real_location, &service_id,
9275 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:109276 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9277 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
9278 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:559279 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129280 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109281 GLfloat* dst = result->GetData();
9282 for (GLsizei ii = 0; ii < num_values; ++ii) {
9283 dst[ii] = (temp[ii] != 0);
9284 }
9285 } else {
[email protected]1b0a6752012-02-22 03:44:129286 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109287 }
[email protected]f7b85372010-02-03 01:11:379288 }
9289 return error;
[email protected]96449d2c2009-11-25 00:01:329290}
9291
[email protected]f7a64ee2010-02-01 22:24:149292error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349293 uint32 immediate_data_size,
9294 const void* cmd_data) {
9295 const gles2::cmds::GetShaderPrecisionFormat& c =
9296 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259297 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9298 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359299 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259300 Result* result = GetSharedMemoryAs<Result*>(
9301 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9302 if (!result) {
9303 return error::kOutOfBounds;
9304 }
[email protected]07d0cc82010-02-17 04:51:409305 // Check that the client initialized the result.
9306 if (result->success != 0) {
9307 return error::kInvalidArguments;
9308 }
[email protected]9438b012010-06-15 22:55:059309 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519310 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539311 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299312 return error::kNoError;
9313 }
[email protected]9438b012010-06-15 22:55:059314 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519315 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539316 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299317 return error::kNoError;
9318 }
9319
9320 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409321
[email protected]46c86752013-05-21 05:08:399322 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409323 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219324 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409325
9326 result->min_range = range[0];
9327 result->max_range = range[1];
9328 result->precision = precision;
9329
[email protected]f7a64ee2010-02-01 22:24:149330 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329331}
9332
[email protected]f7a64ee2010-02-01 22:24:149333error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349334 uint32 immediate_data_size,
9335 const void* cmd_data) {
9336 const gles2::cmds::GetAttachedShaders& c =
9337 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259338 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429339 GLuint program_id = static_cast<GLuint>(c.program);
9340 Program* program = GetProgramInfoNotShader(
9341 program_id, "glGetAttachedShaders");
9342 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259343 return error::kNoError;
9344 }
[email protected]ed9f9cd2013-02-27 21:12:359345 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259346 uint32 max_count = Result::ComputeMaxResults(result_size);
9347 Result* result = GetSharedMemoryAs<Result*>(
9348 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9349 if (!result) {
9350 return error::kOutOfBounds;
9351 }
[email protected]07d0cc82010-02-17 04:51:409352 // Check that the client initialized the result.
9353 if (result->size != 0) {
9354 return error::kInvalidArguments;
9355 }
[email protected]0bfd9882010-02-05 23:02:259356 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039357 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429358 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259359 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039360 if (!shader_manager()->GetClientId(result->GetData()[ii],
9361 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259362 NOTREACHED();
9363 return error::kGenericError;
9364 }
9365 }
9366 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149367 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329368}
9369
[email protected]f7a64ee2010-02-01 22:24:149370error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349371 uint32 immediate_data_size,
9372 const void* cmd_data) {
9373 const gles2::cmds::GetActiveUniform& c =
9374 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429375 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259376 GLuint index = c.index;
9377 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359378 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259379 Result* result = GetSharedMemoryAs<Result*>(
9380 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9381 if (!result) {
9382 return error::kOutOfBounds;
9383 }
[email protected]07d0cc82010-02-17 04:51:409384 // Check that the client initialized the result.
9385 if (result->success != 0) {
9386 return error::kInvalidArguments;
9387 }
[email protected]df37b9932013-03-08 05:21:429388 Program* program = GetProgramInfoNotShader(
9389 program_id, "glGetActiveUniform");
9390 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259391 return error::kNoError;
9392 }
[email protected]ed9f9cd2013-02-27 21:12:359393 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429394 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:259395 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:519396 LOCAL_SET_GL_ERROR(
9397 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259398 return error::kNoError;
9399 }
9400 result->success = 1; // true.
9401 result->size = uniform_info->size;
9402 result->type = uniform_info->type;
9403 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299404 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149405 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329406}
9407
vmiuracd108592014-09-08 14:36:349408error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
9409 const void* cmd_data) {
9410 const gles2::cmds::GetActiveAttrib& c =
9411 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429412 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259413 GLuint index = c.index;
9414 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359415 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:259416 Result* result = GetSharedMemoryAs<Result*>(
9417 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9418 if (!result) {
9419 return error::kOutOfBounds;
9420 }
[email protected]07d0cc82010-02-17 04:51:409421 // Check that the client initialized the result.
9422 if (result->success != 0) {
9423 return error::kInvalidArguments;
9424 }
[email protected]df37b9932013-03-08 05:21:429425 Program* program = GetProgramInfoNotShader(
9426 program_id, "glGetActiveAttrib");
9427 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259428 return error::kNoError;
9429 }
[email protected]ed9f9cd2013-02-27 21:12:359430 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:429431 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:259432 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:519433 LOCAL_SET_GL_ERROR(
9434 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259435 return error::kNoError;
9436 }
9437 result->success = 1; // true.
9438 result->size = attrib_info->size;
9439 result->type = attrib_info->type;
9440 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299441 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149442 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329443}
9444
vmiuracd108592014-09-08 14:36:349445error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
9446 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:589447#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:519448 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:589449 return error::kNoError;
9450#else
9451 GLsizei n = static_cast<GLsizei>(c.n);
9452 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:519453 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:589454 return error::kNoError;
9455 }
9456 GLsizei length = static_cast<GLsizei>(c.length);
9457 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:519458 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:589459 return error::kNoError;
9460 }
9461 uint32 data_size;
9462 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
9463 return error::kOutOfBounds;
9464 }
9465 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
9466 c.shaders_shm_id, c.shaders_shm_offset, data_size);
9467 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
9468 const void* binary = GetSharedMemoryAs<const void*>(
9469 c.binary_shm_id, c.binary_shm_offset, length);
9470 if (shaders == NULL || binary == NULL) {
9471 return error::kOutOfBounds;
9472 }
[email protected]0782b14b2014-05-24 13:04:169473 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:589474 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:429475 Shader* shader = GetShader(shaders[ii]);
9476 if (!shader) {
[email protected]ab09b612013-03-11 22:11:519477 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:589478 return error::kNoError;
9479 }
[email protected]df37b9932013-03-08 05:21:429480 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:589481 }
9482 // TODO(gman): call glShaderBinary
9483 return error::kNoError;
9484#endif
9485}
9486
[email protected]6d792ee12013-05-15 00:40:569487void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:499488 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:089489
[email protected]64ace852011-05-19 21:49:499490 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:429491 // TRACE_EVENT for gpu tests:
9492 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:429493 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:429494 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
9495 "width", (is_offscreen ? offscreen_size_.width() :
9496 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:569497 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:499498 "offscreen", is_offscreen,
9499 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:159500 {
[email protected]a36ed4832014-04-24 16:40:279501 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:159502 }
9503
[email protected]8f9b8dd2013-09-12 18:05:139504 bool is_tracing;
9505 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
9506 &is_tracing);
9507 if (is_tracing) {
9508 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
9509 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
9510 is_offscreen ? offscreen_size_ : surface_->GetSize());
9511 }
9512
[email protected]6217d392010-03-25 22:08:359513 // If offscreen then don't actually SwapBuffers to the display. Just copy
9514 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:499515 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:319516 TRACE_EVENT2("gpu", "Offscreen",
9517 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:539518 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
9519 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9520 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9521 // fix this.
[email protected]62e155e2012-10-23 22:43:159522 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:539523 offscreen_saved_frame_buffer_->Create();
9524 glFinish();
9525 }
9526
9527 // Allocate the offscreen saved color texture.
9528 DCHECK(offscreen_saved_color_format_);
9529 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:099530 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:539531
9532 offscreen_saved_frame_buffer_->AttachRenderTexture(
9533 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:059534 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9535 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9536 GL_FRAMEBUFFER_COMPLETE) {
9537 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9538 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:569539 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9540 return;
[email protected]f0cfe752013-01-14 01:09:059541 }
[email protected]1fb8c482011-08-31 01:01:539542
[email protected]f0cfe752013-01-14 01:09:059543 // Clear the offscreen color texture.
9544 // TODO(piman): Is this still necessary?
9545 {
9546 ScopedFrameBufferBinder binder(this,
9547 offscreen_saved_frame_buffer_->id());
9548 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:459549 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9550 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:059551 glClear(GL_COLOR_BUFFER_BIT);
9552 RestoreClearState();
9553 }
[email protected]1fb8c482011-08-31 01:01:539554 }
9555
9556 UpdateParentTextureInfo();
9557 }
9558
[email protected]f0cfe752013-01-14 01:09:059559 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:569560 return;
[email protected]ab09b612013-03-11 22:11:519561 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:309562 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:359563
[email protected]34ff8b0c2010-10-01 20:06:029564 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:139565 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:279566 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:489567 } else {
[email protected]069944672012-04-25 20:52:239568 ScopedFrameBufferBinder binder(this,
9569 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:139570
[email protected]069944672012-04-25 20:52:239571 if (offscreen_target_buffer_preserved_) {
9572 // Copy the target frame buffer to the saved offscreen texture.
9573 offscreen_saved_color_texture_->Copy(
9574 offscreen_saved_color_texture_->size(),
9575 offscreen_saved_color_format_);
9576 } else {
9577 // Flip the textures in the parent context via the texture manager.
9578 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:499579 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:239580 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:569581
[email protected]069944672012-04-25 20:52:239582 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9583 offscreen_target_frame_buffer_->AttachRenderTexture(
9584 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:489585 }
[email protected]069944672012-04-25 20:52:239586
9587 // Ensure the side effects of the copy are visible to the parent
9588 // context. There is no need to do this for ANGLE because it uses a
9589 // single D3D device for all contexts.
[email protected]f42f05b2013-11-15 21:46:189590 if (!feature_info_->feature_flags().is_angle)
[email protected]069944672012-04-25 20:52:239591 glFlush();
[email protected]0c8c9d22010-06-25 17:36:399592 }
[email protected]6217d392010-03-25 22:08:359593 } else {
[email protected]f62a5ab2011-05-23 20:34:159594 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019595 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:569596 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:019597 }
[email protected]6217d392010-03-25 22:08:359598 }
vmiura8266ca72014-09-09 21:37:009599
9600 // This may be a slow command. Exit command processing to allow for
9601 // context preemption and GPU watchdog checks.
9602 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:359603}
9604
[email protected]d4239852011-08-12 04:51:229605error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:349606 uint32 immediate_data_size,
9607 const void* cmd_data) {
9608 const gles2::cmds::EnableFeatureCHROMIUM& c =
9609 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:189610 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289611 if (!bucket || bucket->size() == 0) {
9612 return error::kInvalidArguments;
9613 }
[email protected]ed9f9cd2013-02-27 21:12:359614 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189615 Result* result = GetSharedMemoryAs<Result*>(
9616 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9617 if (!result) {
9618 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109619 }
[email protected]b1d2dcb2010-05-17 19:24:189620 // Check that the client initialized the result.
9621 if (*result != 0) {
9622 return error::kInvalidArguments;
9623 }
9624 std::string feature_str;
9625 if (!bucket->GetAsString(&feature_str)) {
9626 return error::kInvalidArguments;
9627 }
9628
9629 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229630 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189631 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229632 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:409633 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9634 // TODO(gman): decide how to remove the need for this const_cast.
9635 // I could make validators_ non const but that seems bad as this is the only
9636 // place it is needed. I could make some special friend class of validators
9637 // just to allow this to set them. That seems silly. I could refactor this
9638 // code to use the extension mechanism or the initialization attributes to
9639 // turn this feature on. Given that the only real point of this is to make
9640 // the conformance tests pass and given that there is lots of real work that
9641 // needs to be done it seems like refactoring for one to one of those
9642 // methods is a very low priority.
9643 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049644 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9645 force_webgl_glsl_validation_ = true;
9646 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189647 } else {
9648 return error::kNoError;
9649 }
9650
9651 *result = 1; // true.
9652 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109653}
9654
[email protected]c2f8c8402010-12-06 18:07:249655error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9656 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:349657 const void* cmd_data) {
9658 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
9659 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
9660 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249661 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359662 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:199663 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:249664 bucket->SetFromString(info->extensions().c_str());
9665 return error::kNoError;
9666}
9667
9668error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:349669 uint32 immediate_data_size,
9670 const void* cmd_data) {
9671 const gles2::cmds::RequestExtensionCHROMIUM& c =
9672 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249673 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289674 if (!bucket || bucket->size() == 0) {
9675 return error::kInvalidArguments;
9676 }
[email protected]c2f8c8402010-12-06 18:07:249677 std::string feature_str;
9678 if (!bucket->GetAsString(&feature_str)) {
9679 return error::kInvalidArguments;
9680 }
9681
[email protected]4b7eba92013-01-08 02:23:569682 bool desire_webgl_glsl_validation =
9683 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9684 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:499685 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:139686 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:069687 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:569688 if (force_webgl_glsl_validation_) {
9689 desire_standard_derivatives =
9690 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:499691 desire_frag_depth =
9692 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:139693 desire_draw_buffers =
9694 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:069695 desire_shader_texture_lod =
9696 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049697 }
9698
[email protected]4b7eba92013-01-08 02:23:569699 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:499700 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:139701 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9702 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:499703 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9704 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9705 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:139706 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:069707 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:249708 InitializeShaderTranslator();
9709 }
9710
[email protected]302ce6d2011-07-07 23:28:119711 UpdateCapabilities();
9712
[email protected]c2f8c8402010-12-06 18:07:249713 return error::kNoError;
9714}
9715
[email protected]372e0412011-06-28 16:08:569716error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
vmiuracd108592014-09-08 14:36:349717 uint32 immediate_data_size,
9718 const void* cmd_data) {
9719 const gles2::cmds::GetMultipleIntegervCHROMIUM& c =
9720 *static_cast<const gles2::cmds::GetMultipleIntegervCHROMIUM*>(cmd_data);
[email protected]372e0412011-06-28 16:08:569721 GLuint count = c.count;
9722 uint32 pnames_size;
9723 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
9724 return error::kOutOfBounds;
9725 }
9726 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
9727 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
9728 if (pnames == NULL) {
9729 return error::kOutOfBounds;
9730 }
9731
9732 // We have to copy them since we use them twice so the client
9733 // can't change them between the time we validate them and the time we use
9734 // them.
[email protected]40d90a22013-04-09 03:39:559735 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:569736 memcpy(enums.get(), pnames, pnames_size);
9737
9738 // Count up the space needed for the result.
9739 uint32 num_results = 0;
9740 for (GLuint ii = 0; ii < count; ++ii) {
9741 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
9742 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:519743 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]caa13ed2014-02-17 11:29:209744 "glGetMultipleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:569745 return error::kNoError;
9746 }
9747 // Num will never be more than 4.
9748 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:479749 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:569750 return error::kOutOfBounds;
9751 }
9752 }
9753
9754 uint32 result_size = 0;
9755 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
9756 return error::kOutOfBounds;
9757 }
9758
9759 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:519760 LOCAL_SET_GL_ERROR(
9761 GL_INVALID_VALUE,
[email protected]caa13ed2014-02-17 11:29:209762 "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:569763 return error::kNoError;
9764 }
9765
9766 GLint* results = GetSharedMemoryAs<GLint*>(
9767 c.results_shm_id, c.results_shm_offset, result_size);
9768 if (results == NULL) {
9769 return error::kOutOfBounds;
9770 }
9771
9772 // Check the results have been cleared in case the context was lost.
9773 for (uint32 ii = 0; ii < num_results; ++ii) {
9774 if (results[ii]) {
9775 return error::kInvalidArguments;
9776 }
9777 }
9778
9779 // Get each result.
9780 GLint* start = results;
9781 for (GLuint ii = 0; ii < count; ++ii) {
9782 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:269783 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:539784 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:489785 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:569786 }
9787 results += num_written;
9788 }
9789
9790 // Just to verify. Should this be a DCHECK?
9791 if (static_cast<uint32>(results - start) != num_results) {
9792 return error::kOutOfBounds;
9793 }
9794
9795 return error::kNoError;
9796}
9797
[email protected]2318d342011-07-11 22:27:429798error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:349799 uint32 immediate_data_size,
9800 const void* cmd_data) {
9801 const gles2::cmds::GetProgramInfoCHROMIUM& c =
9802 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429803 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429804 uint32 bucket_id = c.bucket_id;
9805 Bucket* bucket = CreateBucket(bucket_id);
9806 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429807 Program* program = NULL;
9808 program = GetProgram(program_id);
9809 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469810 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429811 }
[email protected]df37b9932013-03-08 05:21:429812 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429813 return error::kNoError;
9814}
9815
[email protected]38d139d2011-07-14 00:38:439816error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9817 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439818 case GL_NO_ERROR:
9819 // TODO(kbr): improve the precision of the error code in this case.
9820 // Consider delegating to context for error code if MakeCurrent fails.
9821 return error::kUnknown;
9822 case GL_GUILTY_CONTEXT_RESET_ARB:
9823 return error::kGuilty;
9824 case GL_INNOCENT_CONTEXT_RESET_ARB:
9825 return error::kInnocent;
9826 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9827 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439828 }
9829
9830 NOTREACHED();
9831 return error::kUnknown;
9832}
9833
jbauman7a059312014-10-16 19:30:549834void GLES2DecoderImpl::MaybeExitOnContextLost() {
9835 // Some D3D drivers cannot recover from device lost in the GPU process
9836 // sandbox. Allow a new GPU process to launch.
9837 if (workarounds().exit_on_context_lost) {
9838 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
9839 << " a D3D device in the Chrome GPU process sandbox.";
9840#if defined(OS_WIN)
9841 base::win::SetShouldCrashOnProcessDetach(false);
9842#endif
9843 exit(0);
9844 }
9845}
9846
[email protected]38d139d2011-07-14 00:38:439847bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099848 if (reset_status_ != GL_NO_ERROR) {
jbauman7a059312014-10-16 19:30:549849 MaybeExitOnContextLost();
[email protected]c4485aad62012-12-17 10:19:099850 return true;
9851 }
[email protected]706b69f2012-07-27 04:59:309852 if (context_->WasAllocatedUsingRobustnessExtension()) {
9853 GLenum status = GL_NO_ERROR;
9854 if (has_robustness_extension_)
9855 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439856 if (status != GL_NO_ERROR) {
9857 // The graphics card was reset. Signal a lost context to the application.
9858 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229859 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439860 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099861 << " context lost via ARB/EXT_robustness. Reset status = "
9862 << GLES2Util::GetStringEnum(status);
jbauman7a059312014-10-16 19:30:549863 MaybeExitOnContextLost();
[email protected]38d139d2011-07-14 00:38:439864 return true;
9865 }
9866 }
9867 return false;
9868}
9869
[email protected]93a7d98f2013-07-11 00:04:229870bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9871 return WasContextLost() && reset_by_robustness_extension_;
9872}
9873
[email protected]c4485aad62012-12-17 10:19:099874void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9875 // Only loses the context once.
9876 if (reset_status_ != GL_NO_ERROR) {
9877 return;
9878 }
9879
oetuaho37cc50e2014-10-31 11:19:209880 if (workarounds().use_virtualized_gl_contexts) {
9881 // If the context is virtual, the real context being guilty does not ensure
9882 // that the virtual context is guilty.
9883 if (reset_status == GL_GUILTY_CONTEXT_RESET_ARB) {
9884 reset_status = GL_UNKNOWN_CONTEXT_RESET_ARB;
9885 }
9886 } else if (reset_status == GL_UNKNOWN_CONTEXT_RESET_ARB &&
9887 has_robustness_extension_) {
9888 // If the reason for the call was a GL error, we can try to determine the
9889 // reset status more accurately.
9890 GLenum driver_status = glGetGraphicsResetStatusARB();
9891 if (driver_status == GL_GUILTY_CONTEXT_RESET_ARB ||
9892 driver_status == GL_INNOCENT_CONTEXT_RESET_ARB) {
9893 reset_status = driver_status;
9894 }
9895 }
9896
[email protected]c4485aad62012-12-17 10:19:099897 // Marks this context as lost.
9898 reset_status_ = reset_status;
9899 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099900}
9901
[email protected]b096d032013-03-08 03:08:019902error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:349903 uint32 immediate_data_size,
9904 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:019905 return error::kUnknownCommand;
9906}
9907
[email protected]840a7e462013-02-27 01:29:519908error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:349909 uint32 immediate_data_size,
9910 const void* cmd_data) {
9911 const gles2::cmds::WaitSyncPointCHROMIUM& c =
9912 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
sievers173a20d2014-10-22 18:19:329913 uint32 sync_point = c.sync_point;
[email protected]840a7e462013-02-27 01:29:519914 if (wait_sync_point_callback_.is_null())
9915 return error::kNoError;
9916
sievers173a20d2014-10-22 18:19:329917 return wait_sync_point_callback_.Run(sync_point) ?
[email protected]840a7e462013-02-27 01:29:519918 error::kNoError : error::kDeferCommandUntilLater;
9919}
9920
[email protected]5dfc457b2013-12-13 11:13:079921error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:349922 uint32 immediate_data_size,
9923 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:079924 if (surface_->DeferDraws())
9925 return error::kDeferCommandUntilLater;
9926 if (!surface_->SetBackbufferAllocation(false))
9927 return error::kLostContext;
9928 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
9929 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
9930 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
9931 return error::kNoError;
9932}
9933
[email protected]882ba1e22012-03-08 19:02:539934bool GLES2DecoderImpl::GenQueriesEXTHelper(
9935 GLsizei n, const GLuint* client_ids) {
9936 for (GLsizei ii = 0; ii < n; ++ii) {
9937 if (query_manager_->GetQuery(client_ids[ii])) {
9938 return false;
9939 }
9940 }
[email protected]4eea7e62014-04-22 21:14:439941 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:539942 return true;
9943}
9944
9945void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9946 GLsizei n, const GLuint* client_ids) {
9947 for (GLsizei ii = 0; ii < n; ++ii) {
9948 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9949 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:139950 ContextState::QueryMap::iterator it =
9951 state_.current_queries.find(query->target());
9952 if (it != state_.current_queries.end())
9953 state_.current_queries.erase(it);
9954
[email protected]c45f1972012-03-14 07:27:369955 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539956 }
[email protected]4eea7e62014-04-22 21:14:439957 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:539958 }
9959}
9960
revemancc241eb2014-11-11 03:30:379961bool GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
[email protected]22e3f552012-03-13 01:54:199962 if (query_manager_.get() == NULL) {
9963 return false;
9964 }
revemancc241eb2014-11-11 03:30:379965 if (!query_manager_->ProcessPendingQueries(did_finish)) {
[email protected]22e3f552012-03-13 01:54:199966 current_decoder_error_ = error::kOutOfBounds;
9967 }
9968 return query_manager_->HavePendingQueries();
9969}
9970
[email protected]5a36dc132013-07-23 23:17:559971// Note that if there are no pending readpixels right now,
9972// this function will call the callback immediately.
9973void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9974 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9975 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9976 } else {
9977 callback.Run();
9978 }
9979}
9980
9981void GLES2DecoderImpl::ProcessPendingReadPixels() {
9982 while (!pending_readpixel_fences_.empty() &&
9983 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9984 std::vector<base::Closure> callbacks =
9985 pending_readpixel_fences_.front()->callbacks;
9986 pending_readpixel_fences_.pop();
9987 for (size_t i = 0; i < callbacks.size(); i++) {
9988 callbacks[i].Run();
9989 }
9990 }
9991}
9992
[email protected]2b1767cf2013-03-16 09:25:059993bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559994 return !pending_readpixel_fences_.empty() ||
9995 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059996}
9997
9998void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559999 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:4810000 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:0510001 return;
[email protected]b68b100752013-06-05 08:34:4810002 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510003 ProcessFinishedAsyncTransfers();
10004}
10005
vmiuracd108592014-09-08 14:36:3410006error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
10007 const void* cmd_data) {
10008 const gles2::cmds::BeginQueryEXT& c =
10009 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310010 GLenum target = static_cast<GLenum>(c.target);
10011 GLuint client_id = static_cast<GLuint>(c.id);
10012 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
10013 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10014
[email protected]c45f1972012-03-14 07:27:3610015 switch (target) {
10016 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:5510017 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:3110018 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
10019 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:0010020 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:3610021 break;
[email protected]6a25ae422014-04-17 23:48:2710022 case GL_COMMANDS_COMPLETED_CHROMIUM:
10023 if (!features().chromium_sync_query) {
10024 LOCAL_SET_GL_ERROR(
10025 GL_INVALID_OPERATION, "glBeginQueryEXT",
10026 "not enabled for commands completed queries");
10027 return error::kNoError;
10028 }
10029 break;
[email protected]c45f1972012-03-14 07:27:3610030 default:
[email protected]62e155e2012-10-23 22:43:1510031 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:5110032 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:0010033 GL_INVALID_OPERATION, "glBeginQueryEXT",
10034 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:3610035 return error::kNoError;
10036 }
10037 break;
[email protected]882ba1e22012-03-08 19:02:5310038 }
10039
[email protected]8ebd46c2014-01-08 12:06:1310040 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110041 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310042 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:5310043 return error::kNoError;
10044 }
10045
10046 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:5110047 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:5310048 return error::kNoError;
10049 }
10050
10051 QueryManager::Query* query = query_manager_->GetQuery(client_id);
10052 if (!query) {
[email protected]4eea7e62014-04-22 21:14:4310053 if (!query_manager_->IsValidQuery(client_id)) {
10054 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10055 "glBeginQueryEXT",
10056 "id not made by glGenQueriesEXT");
10057 return error::kNoError;
10058 }
[email protected]c45f1972012-03-14 07:27:3610059 query = query_manager_->CreateQuery(
10060 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:5310061 }
10062
[email protected]c45f1972012-03-14 07:27:3610063 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110064 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310065 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:5310066 return error::kNoError;
10067 } else if (query->shm_id() != sync_shm_id ||
10068 query->shm_offset() != sync_shm_offset) {
10069 DLOG(ERROR) << "Shared memory used by query not the same as before";
10070 return error::kInvalidArguments;
10071 }
10072
[email protected]c45f1972012-03-14 07:27:3610073 if (!query_manager_->BeginQuery(query)) {
10074 return error::kOutOfBounds;
10075 }
[email protected]882ba1e22012-03-08 19:02:5310076
[email protected]8ebd46c2014-01-08 12:06:1310077 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:5310078 return error::kNoError;
10079}
10080
vmiuracd108592014-09-08 14:36:3410081error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
10082 const void* cmd_data) {
10083 const gles2::cmds::EndQueryEXT& c =
10084 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310085 GLenum target = static_cast<GLenum>(c.target);
10086 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:1310087 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:5310088
[email protected]8ebd46c2014-01-08 12:06:1310089 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110090 LOCAL_SET_GL_ERROR(
10091 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:5310092 return error::kNoError;
10093 }
[email protected]882ba1e22012-03-08 19:02:5310094
[email protected]8ebd46c2014-01-08 12:06:1310095 QueryManager::Query* query = it->second.get();
10096 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:3610097 return error::kOutOfBounds;
10098 }
10099
[email protected]fe8d73c2013-02-16 22:37:3210100 query_manager_->ProcessPendingTransferQueries();
10101
[email protected]8ebd46c2014-01-08 12:06:1310102 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:5310103 return error::kNoError;
10104}
10105
[email protected]944b62f32012-09-27 02:20:4610106bool GLES2DecoderImpl::GenVertexArraysOESHelper(
10107 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610108 for (GLsizei ii = 0; ii < n; ++ii) {
10109 if (GetVertexAttribManager(client_ids[ii])) {
10110 return false;
10111 }
10112 }
[email protected]ab4fd7282012-10-12 16:25:5710113
[email protected]62e155e2012-10-23 22:43:1510114 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710115 // Emulated VAO
10116 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810117 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:5710118 }
10119 } else {
[email protected]40d90a22013-04-09 03:39:5510120 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:5710121
10122 glGenVertexArraysOES(n, service_ids.get());
10123 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810124 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:5710125 }
[email protected]944b62f32012-09-27 02:20:4610126 }
[email protected]ab4fd7282012-10-12 16:25:5710127
[email protected]944b62f32012-09-27 02:20:4610128 return true;
10129}
10130
10131void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
10132 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610133 for (GLsizei ii = 0; ii < n; ++ii) {
10134 VertexAttribManager* vao =
10135 GetVertexAttribManager(client_ids[ii]);
10136 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:1110137 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:1110138 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:4610139 }
10140 RemoveVertexAttribManager(client_ids[ii]);
10141 }
10142 }
10143}
10144
10145void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610146 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:4610147 if (client_id != 0) {
10148 vao = GetVertexAttribManager(client_id);
10149 if (!vao) {
10150 // Unlike most Bind* methods, the spec explicitly states that VertexArray
10151 // only allows names that have been previously generated. As such, we do
10152 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:5110153 LOCAL_SET_GL_ERROR(
10154 GL_INVALID_OPERATION,
10155 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:4610156 current_decoder_error_ = error::kNoError;
10157 return;
[email protected]944b62f32012-09-27 02:20:4610158 }
[email protected]944b62f32012-09-27 02:20:4610159 } else {
[email protected]81f20a622014-04-18 01:54:5210160 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4610161 }
10162
[email protected]ab4fd7282012-10-12 16:25:5710163 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110164 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2410165 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1510166 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710167 EmulateVertexArrayState();
10168 } else {
[email protected]da364812014-05-09 21:39:4810169 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5710170 glBindVertexArrayOES(service_id);
10171 }
10172 }
10173}
10174
10175// Used when OES_vertex_array_object isn't natively supported
10176void GLES2DecoderImpl::EmulateVertexArrayState() {
10177 // Setup the Vertex attribute state
10178 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2310179 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5710180 }
10181
10182 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2110183 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2410184 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5710185 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
10186 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4610187}
10188
10189bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610190 const VertexAttribManager* vao =
10191 GetVertexAttribManager(client_id);
10192 return vao && vao->IsValid() && !vao->IsDeleted();
10193}
10194
[email protected]e51bdf32011-11-23 22:21:4610195#if defined(OS_MACOSX)
10196void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
10197 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
10198 texture_id);
10199 if (it != texture_to_io_surface_map_.end()) {
10200 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5310201 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4610202 CFRelease(surface);
10203 texture_to_io_surface_map_.erase(it);
10204 }
10205}
10206#endif
10207
10208void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
10209 GLenum target, GLsizei width, GLsizei height,
10210 GLuint io_surface_id, GLuint plane) {
10211#if defined(OS_MACOSX)
10212 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5110213 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310214 GL_INVALID_OPERATION,
10215 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4610216 return;
10217 }
10218
[email protected]e51bdf32011-11-23 22:21:4610219 if (target != GL_TEXTURE_RECTANGLE_ARB) {
10220 // This might be supported in the future, and if we could require
10221 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
10222 // could delete a lot of code. For now, perform strict validation so we
10223 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5110224 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610225 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310226 "glTexImageIOSurface2DCHROMIUM",
10227 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4610228 return;
10229 }
10230
[email protected]09d50362012-10-18 20:54:3710231 // Default target might be conceptually valid, but disallow it to avoid
10232 // accidents.
[email protected]c986af502013-08-14 01:04:4410233 TextureRef* texture_ref =
10234 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910235 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110236 LOCAL_SET_GL_ERROR(
10237 GL_INVALID_OPERATION,
10238 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4610239 return;
10240 }
[email protected]e51bdf32011-11-23 22:21:4610241
10242 // Look up the new IOSurface. Note that because of asynchrony
10243 // between processes this might fail; during live resizing the
10244 // plugin process might allocate and release an IOSurface before
10245 // this process gets a chance to look it up. Hold on to any old
10246 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5310247 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4610248 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5110249 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310250 GL_INVALID_OPERATION,
10251 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4610252 return;
10253 }
10254
10255 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4910256 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4610257
10258 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
10259 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4910260 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4610261
10262 CGLContextObj context =
10263 static_cast<CGLContextObj>(context_->GetHandle());
10264
[email protected]c3a6b4a2014-06-04 09:25:5310265 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4610266 context,
10267 target,
10268 GL_RGBA,
10269 width,
10270 height,
10271 GL_BGRA,
10272 GL_UNSIGNED_INT_8_8_8_8_REV,
10273 surface,
10274 plane);
10275
10276 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5110277 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610278 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310279 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4610280 return;
10281 }
10282
10283 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910284 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4610285 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
10286
10287#else
[email protected]ab09b612013-03-11 22:11:5110288 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310289 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4610290#endif
10291}
10292
[email protected]97dc7cbe2011-12-06 17:26:1710293static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
10294 switch (internalformat) {
10295 case GL_RGB565:
10296 return GL_RGB;
10297 case GL_RGBA4:
10298 return GL_RGBA;
10299 case GL_RGB5_A1:
10300 return GL_RGBA;
10301 case GL_RGB8_OES:
10302 return GL_RGB;
10303 case GL_RGBA8_OES:
10304 return GL_RGBA;
10305 case GL_LUMINANCE8_ALPHA8_EXT:
10306 return GL_LUMINANCE_ALPHA;
10307 case GL_LUMINANCE8_EXT:
10308 return GL_LUMINANCE;
10309 case GL_ALPHA8_EXT:
10310 return GL_ALPHA;
10311 case GL_RGBA32F_EXT:
10312 return GL_RGBA;
10313 case GL_RGB32F_EXT:
10314 return GL_RGB;
10315 case GL_ALPHA32F_EXT:
10316 return GL_ALPHA;
10317 case GL_LUMINANCE32F_EXT:
10318 return GL_LUMINANCE;
10319 case GL_LUMINANCE_ALPHA32F_EXT:
10320 return GL_LUMINANCE_ALPHA;
10321 case GL_RGBA16F_EXT:
10322 return GL_RGBA;
10323 case GL_RGB16F_EXT:
10324 return GL_RGB;
10325 case GL_ALPHA16F_EXT:
10326 return GL_ALPHA;
10327 case GL_LUMINANCE16F_EXT:
10328 return GL_LUMINANCE;
10329 case GL_LUMINANCE_ALPHA16F_EXT:
10330 return GL_LUMINANCE_ALPHA;
10331 case GL_BGRA8_EXT:
10332 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5910333 case GL_SRGB8_ALPHA8_EXT:
10334 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1710335 default:
10336 return GL_NONE;
10337 }
10338}
10339
[email protected]43410e92012-04-20 17:06:2810340void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:0310341 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:5410342 GLenum internal_format, GLenum dest_type) {
[email protected]1e24dc7f2014-04-14 02:40:0810343 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
10344
[email protected]370eaf12013-05-18 09:19:4910345 TextureRef* dest_texture_ref = GetTexture(dest_id);
10346 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:2810347
[email protected]370eaf12013-05-18 09:19:4910348 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110349 LOCAL_SET_GL_ERROR(
10350 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:2810351 return;
10352 }
10353
10354 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110355 LOCAL_SET_GL_ERROR(
10356 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:2810357 return;
10358 }
10359
[email protected]370eaf12013-05-18 09:19:4910360 Texture* source_texture = source_texture_ref->texture();
10361 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710362 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2510363 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3410364 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
10365 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:0010366 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10367 "glCopyTextureCHROMIUM",
10368 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:0310369 return;
10370 }
10371
[email protected]43410e92012-04-20 17:06:2810372 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:2810373
[email protected]3e0dfd72014-02-21 06:28:4110374 gfx::GLImage* image =
10375 source_texture->GetLevelImage(source_texture->target(), 0);
10376 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5510377 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5610378 source_width = size.width();
10379 source_height = size.height();
10380 if (source_width <= 0 || source_height <= 0) {
10381 LOCAL_SET_GL_ERROR(
10382 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5510383 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5610384 return;
10385 }
[email protected]3ecc1052013-09-26 08:59:0010386 } else {
10387 if (!source_texture->GetLevelSize(
10388 source_texture->target(), 0, &source_width, &source_height)) {
10389 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10390 "glCopyTextureChromium",
10391 "source texture has no level 0");
10392 return;
10393 }
10394
10395 // Check that this type of texture is allowed.
10396 if (!texture_manager()->ValidForTarget(
10397 source_texture->target(), level, source_width, source_height, 1)) {
10398 LOCAL_SET_GL_ERROR(
10399 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
10400 return;
10401 }
[email protected]377976552013-05-14 23:32:5610402 }
10403
[email protected]04b5b37d2014-02-07 02:11:5110404 // Clear the source texture if necessary.
10405 if (!texture_manager()->ClearTextureLevel(
10406 this, source_texture_ref, source_texture->target(), 0)) {
10407 LOCAL_SET_GL_ERROR(
10408 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
10409 return;
10410 }
10411
[email protected]a6e3d282014-08-22 22:20:4410412 GLenum source_type = 0;
10413 GLenum source_internal_format = 0;
10414 source_texture->GetLevelType(
10415 source_texture->target(), 0, &source_type, &source_internal_format);
10416
10417 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
10418 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
10419 // renderable on some platforms.
reveman6b0fbe42014-09-04 00:55:0310420 bool valid_dest_format = internal_format == GL_RGB ||
10421 internal_format == GL_RGBA ||
10422 internal_format == GL_BGRA_EXT;
[email protected]a6e3d282014-08-22 22:20:4410423 bool valid_source_format = source_internal_format == GL_ALPHA ||
10424 source_internal_format == GL_RGB ||
10425 source_internal_format == GL_RGBA ||
10426 source_internal_format == GL_LUMINANCE ||
10427 source_internal_format == GL_LUMINANCE_ALPHA ||
10428 source_internal_format == GL_BGRA_EXT;
10429 if (!valid_source_format || !valid_dest_format) {
10430 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10431 "glCopyTextureCHROMIUM",
10432 "invalid internal format");
10433 return;
10434 }
10435
[email protected]cf6b8f62012-05-25 21:43:3710436 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
10437 // needed because it takes 10s of milliseconds to initialize.
10438 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5110439 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3710440 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2710441 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3710442 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5110443 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3710444 return;
10445 }
10446
[email protected]efc87712014-07-09 00:22:4710447 GLenum dest_type_previous = dest_type;
10448 GLenum dest_internal_format = internal_format;
[email protected]02965c22013-03-09 02:40:0710449 bool dest_level_defined = dest_texture->GetLevelSize(
10450 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2810451
[email protected]0a1e9ad2012-05-04 21:13:0310452 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:5410453 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0710454 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0310455 }
10456
10457 // Resize the destination texture to the dimensions of the source texture.
10458 if (!dest_level_defined || dest_width != source_width ||
10459 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5410460 dest_internal_format != internal_format ||
10461 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2810462 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5110463 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0710464 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:3810465 glTexImage2D(
[email protected]43410e92012-04-20 17:06:2810466 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:0310467 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5110468 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0310469 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0210470 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2810471 return;
[email protected]0a1e9ad2012-05-04 21:13:0310472 }
[email protected]43410e92012-04-20 17:06:2810473
10474 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910475 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0310476 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2510477 } else {
[email protected]02965c22013-03-09 02:40:0710478 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:4910479 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:2810480 }
10481
[email protected]00c2cf92014-03-14 00:08:3710482 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5410483
revemance8fbe82014-09-05 02:19:5210484 // Try using GLImage::CopyTexImage when possible.
10485 bool unpack_premultiply_alpha_change =
10486 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
10487 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
10488 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
10489 if (image->CopyTexImage(GL_TEXTURE_2D))
10490 return;
10491 }
10492
10493 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
10494
[email protected]5394a4102013-04-18 05:41:3710495 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
10496 // before presenting.
10497 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
10498 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
10499 // instead of using default matrix crbug.com/226218.
10500 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
10501 0.0f, 1.0f, 0.0f, 0.0f,
10502 0.0f, 0.0f, 1.0f, 0.0f,
10503 0.0f, 0.0f, 0.0f, 1.0f};
10504 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
10505 this,
10506 source_texture->target(),
[email protected]5394a4102013-04-18 05:41:3710507 source_texture->service_id(),
[email protected]90f7d30d2014-08-13 02:51:5710508 dest_texture->service_id(),
10509 level,
10510 source_width,
10511 source_height,
[email protected]5394a4102013-04-18 05:41:3710512 unpack_flip_y_,
10513 unpack_premultiply_alpha_,
10514 unpack_unpremultiply_alpha_,
10515 default_matrix);
10516 } else {
[email protected]90f7d30d2014-08-13 02:51:5710517 copy_texture_CHROMIUM_->DoCopyTexture(this,
10518 source_texture->target(),
10519 source_texture->service_id(),
10520 source_internal_format,
10521 dest_texture->service_id(),
10522 level,
10523 internal_format,
10524 source_width,
10525 source_height,
10526 unpack_flip_y_,
10527 unpack_premultiply_alpha_,
10528 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3710529 }
[email protected]91c94eb2013-10-22 10:32:5410530
10531 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2810532}
10533
[email protected]97dc7cbe2011-12-06 17:26:1710534static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
10535 switch (internalformat) {
10536 case GL_RGB565:
10537 return GL_UNSIGNED_SHORT_5_6_5;
10538 case GL_RGBA4:
10539 return GL_UNSIGNED_SHORT_4_4_4_4;
10540 case GL_RGB5_A1:
10541 return GL_UNSIGNED_SHORT_5_5_5_1;
10542 case GL_RGB8_OES:
10543 return GL_UNSIGNED_BYTE;
10544 case GL_RGBA8_OES:
10545 return GL_UNSIGNED_BYTE;
10546 case GL_LUMINANCE8_ALPHA8_EXT:
10547 return GL_UNSIGNED_BYTE;
10548 case GL_LUMINANCE8_EXT:
10549 return GL_UNSIGNED_BYTE;
10550 case GL_ALPHA8_EXT:
10551 return GL_UNSIGNED_BYTE;
10552 case GL_RGBA32F_EXT:
10553 return GL_FLOAT;
10554 case GL_RGB32F_EXT:
10555 return GL_FLOAT;
10556 case GL_ALPHA32F_EXT:
10557 return GL_FLOAT;
10558 case GL_LUMINANCE32F_EXT:
10559 return GL_FLOAT;
10560 case GL_LUMINANCE_ALPHA32F_EXT:
10561 return GL_FLOAT;
10562 case GL_RGBA16F_EXT:
10563 return GL_HALF_FLOAT_OES;
10564 case GL_RGB16F_EXT:
10565 return GL_HALF_FLOAT_OES;
10566 case GL_ALPHA16F_EXT:
10567 return GL_HALF_FLOAT_OES;
10568 case GL_LUMINANCE16F_EXT:
10569 return GL_HALF_FLOAT_OES;
10570 case GL_LUMINANCE_ALPHA16F_EXT:
10571 return GL_HALF_FLOAT_OES;
10572 case GL_BGRA8_EXT:
10573 return GL_UNSIGNED_BYTE;
10574 default:
10575 return GL_NONE;
10576 }
10577}
10578
10579void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4410580 GLenum target,
10581 GLint levels,
10582 GLenum internal_format,
10583 GLsizei width,
10584 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1310585 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
10586 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4110587 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0010588 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5110589 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310590 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1710591 return;
10592 }
[email protected]c986af502013-08-14 01:04:4410593 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10594 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910595 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110596 LOCAL_SET_GL_ERROR(
10597 GL_INVALID_OPERATION,
10598 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1710599 return;
10600 }
[email protected]370eaf12013-05-18 09:19:4910601 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710602 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4410603 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1710604 }
[email protected]02965c22013-03-09 02:40:0710605 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5110606 LOCAL_SET_GL_ERROR(
10607 GL_INVALID_OPERATION,
10608 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1710609 return;
10610 }
[email protected]7989c9e2013-01-23 06:39:2610611
10612 GLenum format = ExtractFormatFromStorageFormat(internal_format);
10613 GLenum type = ExtractTypeFromStorageFormat(internal_format);
10614
10615 {
10616 GLsizei level_width = width;
10617 GLsizei level_height = height;
10618 uint32 estimated_size = 0;
10619 for (int ii = 0; ii < levels; ++ii) {
10620 uint32 level_size = 0;
10621 if (!GLES2Util::ComputeImageDataSizes(
10622 level_width, level_height, format, type, state_.unpack_alignment,
10623 &estimated_size, NULL, NULL) ||
10624 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110625 LOCAL_SET_GL_ERROR(
10626 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2610627 return;
10628 }
10629 level_width = std::max(1, level_width >> 1);
10630 level_height = std::max(1, level_height >> 1);
10631 }
10632 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110633 LOCAL_SET_GL_ERROR(
10634 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610635 return;
10636 }
10637 }
10638
[email protected]ab09b612013-03-11 22:11:5110639 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3810640 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5110641 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1710642 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1510643 GLsizei level_width = width;
10644 GLsizei level_height = height;
10645 for (int ii = 0; ii < levels; ++ii) {
10646 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910647 texture_ref, target, ii, format,
10648 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1510649 level_width = std::max(1, level_width >> 1);
10650 level_height = std::max(1, level_height >> 1);
10651 }
[email protected]02965c22013-03-09 02:40:0710652 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1710653 }
[email protected]97dc7cbe2011-12-06 17:26:1710654}
[email protected]e51bdf32011-11-23 22:21:4610655
[email protected]78b514b2012-05-01 21:50:5910656error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3410657 uint32 immediate_data_size,
10658 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3510659 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5910660}
10661
10662void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710663 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210664 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210665 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710666 "mailbox[0]", static_cast<unsigned char>(data[0]));
10667
[email protected]43f253da2014-06-10 17:51:2210668 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10669 &state_, target);
10670 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
10671}
10672
10673void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
10674 GLenum target, const GLbyte* data) {
10675 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
10676 "context", logger_.GetLogPrefix(),
10677 "mailbox[0]", static_cast<unsigned char>(data[0]));
10678
10679 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
10680 target, data);
10681}
10682
10683void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
10684 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3710685 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2210686 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3710687 "mailbox that was not generated by "
10688 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210689
[email protected]370eaf12013-05-18 09:19:4910690 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110691 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210692 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910693 return;
10694 }
10695
[email protected]62e65f02013-05-29 22:28:1010696 Texture* produced = texture_manager()->Produce(texture_ref);
10697 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5110698 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210699 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
10700 return;
10701 }
10702
10703 if (produced->target() != target) {
10704 LOCAL_SET_GL_ERROR(
10705 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5910706 return;
10707 }
10708
sievers8b373ec52014-10-24 23:04:0610709 group_->mailbox_manager()->ProduceTexture(mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5910710}
10711
10712void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710713 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210714 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210715 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710716 "mailbox[0]", static_cast<unsigned char>(data[0]));
10717 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10718 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
10719 "mailbox that was not generated by "
10720 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210721
[email protected]62e65f02013-05-29 22:28:1010722 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4410723 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1110724 if (!texture_ref.get()) {
10725 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10726 "glConsumeTextureCHROMIUM",
10727 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910728 return;
10729 }
[email protected]62e65f02013-05-29 22:28:1010730 GLuint client_id = texture_ref->client_id();
10731 if (!client_id) {
10732 LOCAL_SET_GL_ERROR(
10733 GL_INVALID_OPERATION,
10734 "glConsumeTextureCHROMIUM", "unknown texture for target");
10735 return;
10736 }
sievers8b373ec52014-10-24 23:04:0610737 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]62e65f02013-05-29 22:28:1010738 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110739 LOCAL_SET_GL_ERROR(
10740 GL_INVALID_OPERATION,
10741 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910742 return;
10743 }
[email protected]62e65f02013-05-29 22:28:1010744 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110745 LOCAL_SET_GL_ERROR(
10746 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1010747 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5910748 return;
10749 }
[email protected]62e65f02013-05-29 22:28:1010750
10751 DeleteTexturesHelper(1, &client_id);
10752 texture_ref = texture_manager()->Consume(client_id, texture);
10753 glBindTexture(target, texture_ref->service_id());
10754
10755 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10756 unit.bind_target = target;
10757 switch (target) {
10758 case GL_TEXTURE_2D:
10759 unit.bound_texture_2d = texture_ref;
10760 break;
10761 case GL_TEXTURE_CUBE_MAP:
10762 unit.bound_texture_cube_map = texture_ref;
10763 break;
10764 case GL_TEXTURE_EXTERNAL_OES:
10765 unit.bound_texture_external_oes = texture_ref;
10766 break;
10767 case GL_TEXTURE_RECTANGLE_ARB:
10768 unit.bound_texture_rectangle_arb = texture_ref;
10769 break;
10770 default:
10771 NOTREACHED(); // Validation should prevent us getting here.
10772 break;
10773 }
[email protected]78b514b2012-05-01 21:50:5910774}
10775
[email protected]43f253da2014-06-10 17:51:2210776error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
10777 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3410778 const void* cmd_data) {
10779 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
10780 *static_cast<
10781 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
10782 cmd_data);
[email protected]43f253da2014-06-10 17:51:2210783 GLenum target = static_cast<GLenum>(c.target);
10784 uint32_t data_size;
10785 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
10786 return error::kOutOfBounds;
10787 }
10788 if (data_size > immediate_data_size) {
10789 return error::kOutOfBounds;
10790 }
10791 const GLbyte* mailbox =
10792 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
10793 if (!validators_->texture_bind_target.IsValid(target)) {
10794 LOCAL_SET_GL_ERROR_INVALID_ENUM(
10795 "glCreateAndConsumeTextureCHROMIUM", target, "target");
10796 return error::kNoError;
10797 }
10798 if (mailbox == NULL) {
10799 return error::kOutOfBounds;
10800 }
10801 uint32_t client_id = c.client_id;
10802 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
10803 return error::kNoError;
10804}
10805
10806void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
10807 const GLbyte* data, GLuint client_id) {
10808 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
10809 "context", logger_.GetLogPrefix(),
10810 "mailbox[0]", static_cast<unsigned char>(data[0]));
10811 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10812 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
10813 "passed a mailbox that was not "
10814 "generated by GenMailboxCHROMIUM.";
10815
10816 TextureRef* texture_ref = GetTexture(client_id);
10817 if (texture_ref) {
10818 LOCAL_SET_GL_ERROR(
10819 GL_INVALID_OPERATION,
10820 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
10821 return;
10822 }
sievers8b373ec52014-10-24 23:04:0610823 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]43f253da2014-06-10 17:51:2210824 if (!texture) {
10825 LOCAL_SET_GL_ERROR(
10826 GL_INVALID_OPERATION,
10827 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
10828 return;
10829 }
10830 if (texture->target() != target) {
10831 LOCAL_SET_GL_ERROR(
10832 GL_INVALID_OPERATION,
10833 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
10834 return;
10835 }
10836
[email protected]43f253da2014-06-10 17:51:2210837 texture_ref = texture_manager()->Consume(client_id, texture);
10838}
10839
orglofchcad5a6742014-11-07 19:51:1210840bool GLES2DecoderImpl::DoIsValuebufferCHROMIUM(GLuint client_id) {
10841 const Valuebuffer* valuebuffer = GetValuebuffer(client_id);
10842 return valuebuffer && valuebuffer->IsValid();
10843}
10844
10845void GLES2DecoderImpl::DoBindValueBufferCHROMIUM(GLenum target,
10846 GLuint client_id) {
10847 Valuebuffer* valuebuffer = NULL;
10848 if (client_id != 0) {
10849 valuebuffer = GetValuebuffer(client_id);
10850 if (!valuebuffer) {
10851 if (!group_->bind_generates_resource()) {
10852 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindValuebufferCHROMIUM",
10853 "id not generated by glBindValuebufferCHROMIUM");
10854 return;
10855 }
10856
10857 // It's a new id so make a valuebuffer for it.
10858 CreateValuebuffer(client_id);
10859 valuebuffer = GetValuebuffer(client_id);
10860 }
10861 valuebuffer->MarkAsValid();
10862 }
10863 state_.bound_valuebuffer = valuebuffer;
10864}
10865
10866void GLES2DecoderImpl::DoSubscribeValueCHROMIUM(GLenum target,
10867 GLenum subscription) {
10868 if (!CheckCurrentValuebuffer("glSubscribeValueCHROMIUM")) {
10869 return;
10870 }
10871 state_.bound_valuebuffer.get()->AddSubscription(subscription);
10872}
10873
10874void GLES2DecoderImpl::DoPopulateSubscribedValuesCHROMIUM(GLenum target) {
10875 if (!CheckCurrentValuebuffer("glPopulateSubscribedValuesCHROMIUM")) {
10876 return;
10877 }
10878 valuebuffer_manager()->UpdateValuebufferState(state_.bound_valuebuffer.get());
10879}
10880
10881void GLES2DecoderImpl::DoUniformValueBufferCHROMIUM(GLint location,
10882 GLenum target,
10883 GLenum subscription) {
10884 if (!CheckCurrentValuebufferForSubscription(
10885 subscription, "glPopulateSubscribedValuesCHROMIUM")) {
10886 return;
10887 }
10888 if (!CheckSubscriptionTarget(location, subscription,
10889 "glPopulateSubscribedValuesCHROMIUM")) {
10890 return;
10891 }
10892 const ValueState* state =
10893 state_.bound_valuebuffer.get()->GetState(subscription);
10894 if (state) {
10895 switch (subscription) {
10896 case GL_MOUSE_POSITION_CHROMIUM:
10897 DoUniform2iv(location, 1, state->int_value);
10898 break;
10899 default:
10900 NOTREACHED() << "Unhandled uniform subscription target "
10901 << subscription;
10902 break;
10903 }
10904 }
10905}
10906
[email protected]d2a0e1a2012-08-12 02:25:0110907void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10908 GLsizei length, const GLchar* marker) {
10909 if (!marker) {
10910 marker = "";
10911 }
10912 debug_marker_manager_.SetMarker(
10913 length ? std::string(marker, length) : std::string(marker));
10914}
10915
10916void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10917 GLsizei length, const GLchar* marker) {
10918 if (!marker) {
10919 marker = "";
10920 }
[email protected]cac16542014-01-15 17:53:5110921 std::string name = length ? std::string(marker, length) : std::string(marker);
10922 debug_marker_manager_.PushGroup(name);
10923 gpu_tracer_->Begin(name, kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110924}
10925
10926void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10927 debug_marker_manager_.PopGroup();
[email protected]cac16542014-01-15 17:53:5110928 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110929}
10930
[email protected]09d50362012-10-18 20:54:3710931void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10932 GLenum target, GLint image_id) {
10933 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710934
[email protected]bc26e8d2014-01-29 00:40:3010935 if (target == GL_TEXTURE_CUBE_MAP) {
10936 LOCAL_SET_GL_ERROR(
10937 GL_INVALID_ENUM,
10938 "glBindTexImage2DCHROMIUM", "invalid target");
10939 return;
10940 }
10941
[email protected]09d50362012-10-18 20:54:3710942 // Default target might be conceptually valid, but disallow it to avoid
10943 // accidents.
[email protected]c986af502013-08-14 01:04:4410944 TextureRef* texture_ref =
10945 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910946 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110947 LOCAL_SET_GL_ERROR(
10948 GL_INVALID_OPERATION,
10949 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710950 return;
10951 }
10952
10953 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10954 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110955 LOCAL_SET_GL_ERROR(
10956 GL_INVALID_OPERATION,
10957 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710958 return;
10959 }
10960
[email protected]b8160812013-04-09 00:41:0410961 {
10962 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010963 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610964 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0410965 LOCAL_SET_GL_ERROR(
10966 GL_INVALID_OPERATION,
10967 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10968 return;
10969 }
[email protected]09d50362012-10-18 20:54:3710970 }
10971
10972 gfx::Size size = gl_image->GetSize();
10973 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910974 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710975 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910976 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710977}
10978
10979void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10980 GLenum target, GLint image_id) {
10981 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710982
10983 // Default target might be conceptually valid, but disallow it to avoid
10984 // accidents.
[email protected]c986af502013-08-14 01:04:4410985 TextureRef* texture_ref =
10986 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910987 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110988 LOCAL_SET_GL_ERROR(
10989 GL_INVALID_OPERATION,
10990 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710991 return;
10992 }
10993
10994 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10995 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110996 LOCAL_SET_GL_ERROR(
10997 GL_INVALID_OPERATION,
10998 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710999 return;
11000 }
11001
11002 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4911003 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3711004 return;
11005
[email protected]b8160812013-04-09 00:41:0411006 {
11007 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011008 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611009 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0411010 }
[email protected]09d50362012-10-18 20:54:3711011
11012 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911013 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3711014 GL_RGBA, GL_UNSIGNED_BYTE, false);
11015}
[email protected]d2a0e1a2012-08-12 02:25:0111016
[email protected]94307712012-11-16 23:26:1111017error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3411018 uint32 immediate_data_size,
11019 const void* cmd_data) {
11020 const gles2::cmds::TraceBeginCHROMIUM& c =
11021 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
[email protected]94307712012-11-16 23:26:1111022 Bucket* bucket = GetBucket(c.bucket_id);
11023 if (!bucket || bucket->size() == 0) {
11024 return error::kInvalidArguments;
11025 }
11026 std::string command_name;
11027 if (!bucket->GetAsString(&command_name)) {
11028 return error::kInvalidArguments;
11029 }
[email protected]fb97b662013-02-20 23:02:1411030 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
[email protected]cac16542014-01-15 17:53:5111031 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5111032 LOCAL_SET_GL_ERROR(
11033 GL_INVALID_OPERATION,
11034 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1411035 return error::kNoError;
11036 }
[email protected]94307712012-11-16 23:26:1111037 return error::kNoError;
11038}
11039
11040void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1411041 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5111042 LOCAL_SET_GL_ERROR(
11043 GL_INVALID_OPERATION,
11044 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1111045 return;
11046 }
[email protected]fb97b662013-02-20 23:02:1411047 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
[email protected]cac16542014-01-15 17:53:5111048 gpu_tracer_->End(kTraceCHROMIUM);
[email protected]94307712012-11-16 23:26:1111049}
11050
[email protected]2f143d482013-03-14 18:04:4911051void GLES2DecoderImpl::DoDrawBuffersEXT(
11052 GLsizei count, const GLenum* bufs) {
11053 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
11054 LOCAL_SET_GL_ERROR(
11055 GL_INVALID_VALUE,
11056 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
11057 return;
11058 }
11059
11060 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
11061 if (framebuffer) {
11062 for (GLsizei i = 0; i < count; ++i) {
11063 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
11064 bufs[i] != GL_NONE) {
11065 LOCAL_SET_GL_ERROR(
11066 GL_INVALID_OPERATION,
11067 "glDrawBuffersEXT",
11068 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
11069 return;
11070 }
11071 }
11072 glDrawBuffersARB(count, bufs);
11073 framebuffer->SetDrawBuffers(count, bufs);
11074 } else { // backbuffer
11075 if (count > 1 ||
11076 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
11077 LOCAL_SET_GL_ERROR(
11078 GL_INVALID_OPERATION,
11079 "glDrawBuffersEXT",
11080 "more than one buffer or bufs not GL_NONE or GL_BACK");
11081 return;
11082 }
11083 GLenum mapped_buf = bufs[0];
11084 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
11085 bufs[0] == GL_BACK) {
11086 mapped_buf = GL_COLOR_ATTACHMENT0;
11087 }
11088 glDrawBuffersARB(count, &mapped_buf);
11089 group_->set_draw_buffer(bufs[0]);
11090 }
11091}
11092
[email protected]a6a09f852014-05-23 13:05:0311093void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
11094 group_->LoseContexts(other);
11095 reset_status_ = current;
11096 current_decoder_error_ = error::kLostContext;
11097}
11098
kkinnunen337d59632014-08-26 10:19:5711099void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
11100 const GLfloat* matrix) {
11101 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11102 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11103 if (!features().chromium_path_rendering) {
11104 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11105 "glMatrixLoadfCHROMIUM",
11106 "function not available");
11107 return;
11108 }
11109
11110 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11111 ? state_.projection_matrix
11112 : state_.modelview_matrix;
11113 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
11114 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11115 // since the values of the _NV and _CHROMIUM tokens match.
11116 glMatrixLoadfEXT(matrix_mode, matrix);
11117}
11118
11119void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
11120 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11121 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11122
11123 if (!features().chromium_path_rendering) {
11124 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11125 "glMatrixLoadIdentityCHROMIUM",
11126 "function not available");
11127 return;
11128 }
11129
11130 static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
11131 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
11132 0.0f, 0.0f, 0.0f, 1.0f};
11133
11134 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11135 ? state_.projection_matrix
11136 : state_.modelview_matrix;
11137 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
11138 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11139 // since the values of the _NV and _CHROMIUM tokens match.
11140 glMatrixLoadIdentityEXT(matrix_mode);
11141}
11142
[email protected]32145a92012-12-17 09:01:5911143bool GLES2DecoderImpl::ValidateAsyncTransfer(
11144 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4711145 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5911146 GLenum target,
11147 GLint level,
11148 const void * data) {
11149 // We only support async uploads to 2D textures for now.
11150 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111151 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5911152 return false;
11153 }
11154 // We only support uploads to level zero for now.
11155 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5111156 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5911157 return false;
11158 }
11159 // A transfer buffer must be bound, even for asyncTexImage2D.
11160 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5111161 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5911162 return false;
11163 }
11164 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4711165 if (!texture_ref ||
11166 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5111167 LOCAL_SET_GL_ERROR(
11168 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911169 function_name, "transfer already in progress");
11170 return false;
11171 }
11172 return true;
11173}
11174
[email protected]e3c4a9ab2014-03-31 09:07:0211175base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
11176 uint32 async_upload_token,
11177 uint32 sync_data_shm_id,
11178 uint32 sync_data_shm_offset) {
11179 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2511180 if (!buffer.get() ||
11181 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0211182 return base::Closure();
11183
11184 AsyncMemoryParams mem_params(buffer,
11185 sync_data_shm_offset,
11186 sizeof(AsyncUploadSync));
11187
11188 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
11189 new AsyncUploadTokenCompletionObserver(async_upload_token));
11190
11191 return base::Bind(
11192 &AsyncPixelTransferManager::AsyncNotifyCompletion,
11193 base::Unretained(GetAsyncPixelTransferManager()),
11194 mem_params,
11195 observer);
11196}
11197
[email protected]69023942012-11-30 19:57:1611198error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411199 uint32 immediate_data_size,
11200 const void* cmd_data) {
11201 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
11202 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611203 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611204 GLenum target = static_cast<GLenum>(c.target);
11205 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4411206 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1611207 GLsizei width = static_cast<GLsizei>(c.width);
11208 GLsizei height = static_cast<GLsizei>(c.height);
11209 GLint border = static_cast<GLint>(c.border);
11210 GLenum format = static_cast<GLenum>(c.format);
11211 GLenum type = static_cast<GLenum>(c.type);
11212 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
11213 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
11214 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0211215 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11216 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11217 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11218
11219 base::ScopedClosureRunner scoped_completion_callback;
11220 if (async_upload_token) {
11221 base::Closure completion_closure =
11222 AsyncUploadTokenCompletionClosure(async_upload_token,
11223 sync_data_shm_id,
11224 sync_data_shm_offset);
11225 if (completion_closure.is_null())
11226 return error::kInvalidArguments;
11227
11228 scoped_completion_callback.Reset(completion_closure);
11229 }
[email protected]32145a92012-12-17 09:01:5911230
11231 // TODO(epenner): Move this and copies of this memory validation
11232 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1611233 if (!GLES2Util::ComputeImageDataSizes(
11234 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
11235 NULL)) {
11236 return error::kOutOfBounds;
11237 }
11238 const void* pixels = NULL;
11239 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
11240 pixels = GetSharedMemoryAs<const void*>(
11241 pixels_shm_id, pixels_shm_offset, pixels_size);
11242 if (!pixels) {
11243 return error::kOutOfBounds;
11244 }
11245 }
11246
[email protected]c986af502013-08-14 01:04:4411247 TextureManager::DoTextImage2DArguments args = {
11248 target, level, internal_format, width, height, border, format, type,
11249 pixels, pixels_size};
11250 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5911251 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4411252 if (!texture_manager()->ValidateTexImage2D(
11253 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5911254 return error::kNoError;
11255 }
11256
11257 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4911258 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911259 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711260 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911261 return error::kNoError;
11262
11263 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0711264 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5111265 LOCAL_SET_GL_ERROR(
11266 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911267 "glAsyncTexImage2DCHROMIUM", "already defined");
11268 return error::kNoError;
11269 }
11270
[email protected]7989c9e2013-01-23 06:39:2611271 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5111272 LOCAL_SET_GL_ERROR(
11273 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611274 return error::kNoError;
11275 }
11276
[email protected]5b3a8e02013-03-13 05:36:4411277 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3811278 AsyncTexImage2DParams tex_params = {
11279 target, level, static_cast<GLenum>(internal_format),
11280 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1211281 AsyncMemoryParams mem_params(
11282 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5911283
[email protected]5b3a8e02013-03-13 05:36:4411284 // Set up the async state if needed, and make the texture
11285 // immutable so the async state stays valid. The level info
11286 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1811287 AsyncPixelTransferDelegate* delegate =
11288 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
11289 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4411290 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5911291
[email protected]896425e2013-06-12 17:27:1811292 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4411293 tex_params,
11294 mem_params,
11295 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4911296 // The callback is only invoked if the transfer delegate still
11297 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4411298 // ownership that both of these pointers are valid.
11299 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4911300 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4411301 tex_params));
[email protected]f598f422012-12-07 08:30:0311302 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611303}
11304
11305error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411306 uint32 immediate_data_size,
11307 const void* cmd_data) {
11308 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
11309 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611310 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611311 GLenum target = static_cast<GLenum>(c.target);
11312 GLint level = static_cast<GLint>(c.level);
11313 GLint xoffset = static_cast<GLint>(c.xoffset);
11314 GLint yoffset = static_cast<GLint>(c.yoffset);
11315 GLsizei width = static_cast<GLsizei>(c.width);
11316 GLsizei height = static_cast<GLsizei>(c.height);
11317 GLenum format = static_cast<GLenum>(c.format);
11318 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0211319 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11320 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11321 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11322
11323 base::ScopedClosureRunner scoped_completion_callback;
11324 if (async_upload_token) {
11325 base::Closure completion_closure =
11326 AsyncUploadTokenCompletionClosure(async_upload_token,
11327 sync_data_shm_id,
11328 sync_data_shm_offset);
11329 if (completion_closure.is_null())
11330 return error::kInvalidArguments;
11331
11332 scoped_completion_callback.Reset(completion_closure);
11333 }
[email protected]32145a92012-12-17 09:01:5911334
11335 // TODO(epenner): Move this and copies of this memory validation
11336 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1611337 uint32 data_size;
11338 if (!GLES2Util::ComputeImageDataSizes(
11339 width, height, format, type, state_.unpack_alignment, &data_size,
11340 NULL, NULL)) {
11341 return error::kOutOfBounds;
11342 }
11343 const void* pixels = GetSharedMemoryAs<const void*>(
11344 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5911345
11346 // All the normal glTexSubImage2D validation.
11347 error::Error error = error::kNoError;
11348 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
11349 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
11350 return error;
[email protected]69023942012-11-30 19:57:1611351 }
11352
[email protected]32145a92012-12-17 09:01:5911353 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4411354 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11355 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911356 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911357 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711358 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911359 return error::kNoError;
11360
11361 // Guarantee async textures are always 'cleared' as follows:
11362 // - AsyncTexImage2D can not redefine an existing texture
11363 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
11364 // - AsyncTexSubImage2D clears synchronously if not already cleared.
11365 // - Textures become immutable after an async call.
11366 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0711367 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4911368 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
11369 target, level)) {
[email protected]ab09b612013-03-11 22:11:5111370 LOCAL_SET_GL_ERROR(
11371 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2511372 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5911373 return error::kNoError;
11374 }
11375 }
11376
[email protected]5b3a8e02013-03-13 05:36:4411377 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0311378 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5911379 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1211380 AsyncMemoryParams mem_params(
11381 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1811382 AsyncPixelTransferDelegate* delegate =
11383 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11384 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4411385 // TODO(epenner): We may want to enforce exclusive use
11386 // of async APIs in which case this should become an error,
11387 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0311388 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4411389 0, 0, 0, 0, 0, 0};
11390 texture->GetLevelSize(target, level, &define_params.width,
11391 &define_params.height);
11392 texture->GetLevelType(target, level, &define_params.type,
11393 &define_params.internal_format);
11394 // Set up the async state if needed, and make the texture
11395 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1811396 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4711397 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4411398 texture->SetImmutable(true);
11399 }
11400
[email protected]896425e2013-06-12 17:27:1811401 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5911402 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611403}
11404
[email protected]a00c1f742013-03-05 17:02:1611405error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411406 uint32 immediate_data_size,
11407 const void* cmd_data) {
11408 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
11409 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1611410 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11411 GLenum target = static_cast<GLenum>(c.target);
11412
11413 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111414 LOCAL_SET_GL_ERROR(
11415 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1611416 return error::kNoError;
11417 }
[email protected]c986af502013-08-14 01:04:4411418 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11419 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911420 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111421 LOCAL_SET_GL_ERROR(
11422 GL_INVALID_OPERATION,
11423 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1611424 return error::kNoError;
11425 }
[email protected]896425e2013-06-12 17:27:1811426 AsyncPixelTransferDelegate* delegate =
11427 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11428 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4911429 LOCAL_SET_GL_ERROR(
11430 GL_INVALID_OPERATION,
11431 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
11432 return error::kNoError;
11433 }
[email protected]896425e2013-06-12 17:27:1811434 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0911435 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1611436 return error::kNoError;
11437}
11438
[email protected]e3c4a9ab2014-03-31 09:07:0211439error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411440 uint32 immediate_data_size,
11441 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0211442 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11443
11444 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
11445 ProcessFinishedAsyncTransfers();
11446 return error::kNoError;
11447}
11448
[email protected]91c94eb2013-10-22 10:32:5411449void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
11450 TextureRef* texture_ref) {
11451 Texture* texture = texture_ref->texture();
11452 DoDidUseTexImageIfNeeded(texture, texture->target());
11453}
11454
oetuaho37cc50e2014-10-31 11:19:2011455void GLES2DecoderImpl::OnContextLostError() {
11456 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
11457}
11458
[email protected]828a3932014-04-02 14:43:1311459void GLES2DecoderImpl::OnOutOfMemoryError() {
11460 if (lose_context_when_out_of_memory_) {
11461 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]828a3932014-04-02 14:43:1311462 }
11463}
11464
[email protected]96449d2c2009-11-25 00:01:3211465// Include the auto-generated part of this file. We split this because it means
11466// we can easily edit the non-auto generated parts right here in this file
11467// instead of having to edit some template or the code generator.
11468#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
11469
11470} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2511471} // namespace gpu