blob: 0b8d68d80f362255cdd347cf5335a116dd0ed0b9 [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"
[email protected]944b62f32012-09-27 02:20:4659#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2260#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]6896d7f2014-04-28 20:24:1561#include "third_party/smhasher/src/City.h"
[email protected]5a36dc132013-07-23 23:17:5562#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3763#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2764#include "ui/gl/gl_implementation.h"
65#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2766
[email protected]e51bdf32011-11-23 22:21:4667#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:5368#include <IOSurface/IOSurfaceAPI.h>
69// Note that this must be included after gl_bindings.h to avoid conflicts.
70#include <OpenGL/CGLIOSurface.h>
[email protected]e51bdf32011-11-23 22:21:4671#endif
[email protected]de17df392010-04-23 21:09:4172
[email protected]6eb775352013-08-27 05:57:1673#if defined(OS_WIN)
74#include "base/win/win_util.h"
75#endif
76
[email protected]a7a27ace2009-12-12 00:11:2577namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3278namespace gles2 {
79
[email protected]f0d74742011-10-03 16:31:0480namespace {
[email protected]693ca512012-11-13 18:09:1381
[email protected]f0d74742011-10-03 16:31:0482static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4983static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1384static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]93c2fd82014-04-16 02:46:0685static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
[email protected]693ca512012-11-13 18:09:1386
[email protected]448e459e2013-06-12 17:00:4187static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
88 GLint rangeMax,
89 GLint precision) {
90 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
91}
92
[email protected]8dc1bf92013-03-12 03:58:2193static void GetShaderPrecisionFormatImpl(GLenum shader_type,
94 GLenum precision_type,
95 GLint *range, GLint *precision) {
96 switch (precision_type) {
97 case GL_LOW_INT:
98 case GL_MEDIUM_INT:
99 case GL_HIGH_INT:
100 // These values are for a 32-bit twos-complement integer format.
101 range[0] = 31;
102 range[1] = 30;
103 *precision = 0;
104 break;
105 case GL_LOW_FLOAT:
106 case GL_MEDIUM_FLOAT:
107 case GL_HIGH_FLOAT:
108 // These values are for an IEEE single-precision floating-point format.
109 range[0] = 127;
110 range[1] = 127;
111 *precision = 23;
112 break;
113 default:
114 NOTREACHED();
115 break;
116 }
117
[email protected]8af4d5e2013-03-15 23:55:33118 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
119 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21120 // This function is sometimes defined even though it's really just
121 // a stub, so we need to set range and precision as if it weren't
122 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44123 // On Mac OS with some GPUs, calling this generates a
124 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
125 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21126 glGetShaderPrecisionFormat(shader_type, precision_type,
127 range, precision);
[email protected]448e459e2013-06-12 17:00:41128
129 // TODO(brianderson): Make the following official workarounds.
130
131 // Some drivers have bugs where they report the ranges as a negative number.
132 // Taking the absolute value here shouldn't hurt because negative numbers
133 // aren't expected anyway.
134 range[0] = abs(range[0]);
135 range[1] = abs(range[1]);
136
137 // If the driver reports a precision for highp float that isn't actually
138 // highp, don't pretend like it's supported because shader compilation will
139 // fail anyway.
140 if (precision_type == GL_HIGH_FLOAT &&
141 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
142 range[0] = 0;
143 range[1] = 0;
144 *precision = 0;
145 }
[email protected]8dc1bf92013-03-12 03:58:21146 }
147}
148
[email protected]d286ebbc2014-07-03 17:19:10149static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
150 switch (plane_transform) {
151 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
152 return gfx::OVERLAY_TRANSFORM_NONE;
153 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
154 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
155 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
156 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
157 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
158 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
159 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
160 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
161 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
162 return gfx::OVERLAY_TRANSFORM_ROTATE_270;
163 default:
164 return gfx::OVERLAY_TRANSFORM_INVALID;
165 }
166}
167
[email protected]b04e24c2013-01-08 18:35:25168} // namespace
[email protected]f0d74742011-10-03 16:31:04169
[email protected]6217d392010-03-25 22:08:35170class GLES2DecoderImpl;
171
[email protected]ab09b612013-03-11 22:11:51172// Local versions of the SET_GL_ERROR macros
173#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50174 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51175#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50176 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
177 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51178#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50179 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
180 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51181#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50182 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
183 function_name)
[email protected]ab09b612013-03-11 22:11:51184#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50185 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51186#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50187 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51188#define LOCAL_PERFORMANCE_WARNING(msg) \
189 PerformanceWarning(__FILE__, __LINE__, msg)
190#define LOCAL_RENDER_WARNING(msg) \
191 RenderWarning(__FILE__, __LINE__, msg)
192
[email protected]07f54fcc2009-12-22 02:46:30193// Check that certain assumptions the code makes are true. There are places in
194// the code where shared memory is passed direclty to GL. Example, glUniformiv,
195// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
196// a few others) are 32bits. If they are not 32bits the code will have to change
197// to call those GL functions with service side memory and then copy the results
198// to shared memory, converting the sizes.
199COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
200 GLint_not_same_size_as_uint32);
201COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
202 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37203COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
204 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30205
[email protected]43f28f832010-02-03 02:28:48206// TODO(kbr): the use of this anonymous namespace core dumps the
207// linker on Mac OS X 10.6 when the symbol ordering file is used
208// namespace {
[email protected]96449d2c2009-11-25 00:01:32209
210// Returns the address of the first byte after a struct.
211template <typename T>
212const void* AddressAfterStruct(const T& pod) {
213 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
214}
215
[email protected]07f54fcc2009-12-22 02:46:30216// Returns the address of the frst byte after the struct or NULL if size >
217// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32218template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30219RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
220 uint32 size,
221 uint32 immediate_data_size) {
222 return (size <= immediate_data_size) ?
223 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
224 NULL;
[email protected]96449d2c2009-11-25 00:01:32225}
226
[email protected]07f54fcc2009-12-22 02:46:30227// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18228bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32229 GLuint count,
230 size_t size,
[email protected]a76b0052010-03-05 00:33:18231 unsigned int elements_per_unit,
232 uint32* dst) {
233 uint32 value;
234 if (!SafeMultiplyUint32(count, size, &value)) {
235 return false;
236 }
237 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
238 return false;
239 }
240 *dst = value;
241 return true;
[email protected]96449d2c2009-11-25 00:01:32242}
243
[email protected]258a3313f2011-10-18 20:13:57244// Return true if a character belongs to the ASCII subset as defined in
245// GLSL ES 1.0 spec section 3.1.
246static bool CharacterIsValidForGLES(unsigned char c) {
247 // Printing characters are valid except " $ ` @ \ ' DEL.
248 if (c >= 32 && c <= 126 &&
249 c != '"' &&
250 c != '$' &&
251 c != '`' &&
252 c != '@' &&
253 c != '\\' &&
254 c != '\'') {
255 return true;
256 }
257 // Horizontal tab, line feed, vertical tab, form feed, carriage return
258 // are also valid.
259 if (c >= 9 && c <= 13) {
260 return true;
261 }
262
263 return false;
264}
265
266static bool StringIsValidForGLES(const char* str) {
267 for (; *str; ++str) {
268 if (!CharacterIsValidForGLES(*str)) {
269 return false;
270 }
271 }
272 return true;
273}
274
[email protected]6217d392010-03-25 22:08:35275// This class prevents any GL errors that occur when it is in scope from
276// being reported to the client.
277class ScopedGLErrorSuppressor {
278 public:
[email protected]ab09b612013-03-11 22:11:51279 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30280 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35281 ~ScopedGLErrorSuppressor();
282 private:
[email protected]ab09b612013-03-11 22:11:51283 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30284 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35285 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
286};
287
[email protected]2b10c02d2014-01-29 16:43:02288// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35289// object goes out of scope. Also temporarily switches to using active texture
290// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02291class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35292 public:
[email protected]00c2cf92014-03-14 00:08:37293 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02294 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35295
296 private:
[email protected]ce296892013-10-24 22:04:36297 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02298 GLenum target_;
299 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35300};
301
302// Temporarily changes a decoder's bound render buffer and restore it when this
303// object goes out of scope.
304class ScopedRenderBufferBinder {
305 public:
[email protected]00c2cf92014-03-14 00:08:37306 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35307 ~ScopedRenderBufferBinder();
308
309 private:
[email protected]18e785a2013-10-09 03:29:41310 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35311 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
312};
313
314// Temporarily changes a decoder's bound frame buffer and restore it when this
315// object goes out of scope.
316class ScopedFrameBufferBinder {
317 public:
[email protected]00c2cf92014-03-14 00:08:37318 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35319 ~ScopedFrameBufferBinder();
320
321 private:
322 GLES2DecoderImpl* decoder_;
323 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
324};
325
[email protected]34ff8b0c2010-10-01 20:06:02326// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52327// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27328// if it is bound or enforce_internal_framebuffer is true. If internal is
329// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02330class ScopedResolvedFrameBufferBinder {
331 public:
[email protected]00c2cf92014-03-14 00:08:37332 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
333 bool enforce_internal_framebuffer,
334 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02335 ~ScopedResolvedFrameBufferBinder();
336
337 private:
338 GLES2DecoderImpl* decoder_;
339 bool resolve_and_bind_;
340 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
341};
342
[email protected]00c2cf92014-03-14 00:08:37343class ScopedModifyPixels {
344 public:
345 explicit ScopedModifyPixels(TextureRef* ref);
346 ~ScopedModifyPixels();
347
348 private:
349 TextureRef* ref_;
350};
351
352ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
353 if (ref_)
354 ref_->texture()->OnWillModifyPixels();
355}
356
357ScopedModifyPixels::~ScopedModifyPixels() {
358 if (ref_)
359 ref_->texture()->OnDidModifyPixels();
360}
361
362class ScopedRenderTo {
363 public:
364 explicit ScopedRenderTo(Framebuffer* framebuffer);
365 ~ScopedRenderTo();
366
367 private:
368 const Framebuffer* framebuffer_;
369};
370
371ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
372 : framebuffer_(framebuffer) {
373 if (framebuffer)
374 framebuffer_->OnWillRenderTo();
375}
376
377ScopedRenderTo::~ScopedRenderTo() {
378 if (framebuffer_)
379 framebuffer_->OnDidRenderTo();
380}
381
[email protected]6217d392010-03-25 22:08:35382// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35383class BackTexture {
[email protected]6217d392010-03-25 22:08:35384 public:
[email protected]ce296892013-10-24 22:04:36385 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35386 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35387
388 // Create a new render texture.
389 void Create();
390
391 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09392 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35393
394 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58395 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35396
397 // Destroy the render texture. This must be explicitly called before
398 // destroying this object.
399 void Destroy();
400
[email protected]97872062010-11-03 19:07:05401 // Invalidate the texture. This can be used when a context is lost and it is
402 // not possible to make it current in order to free the resource.
403 void Invalidate();
404
[email protected]6217d392010-03-25 22:08:35405 GLuint id() const {
406 return id_;
407 }
408
[email protected]d37231fa2010-04-09 21:16:02409 gfx::Size size() const {
410 return size_;
411 }
412
[email protected]6217d392010-03-25 22:08:35413 private:
[email protected]ff6493f2012-07-31 19:52:25414 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36415 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48416 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35417 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02418 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35419 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35420};
421
422// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35423class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35424 public:
[email protected]d5a28e452013-10-10 01:01:40425 explicit BackRenderbuffer(
426 RenderbufferManager* renderbuffer_manager,
427 MemoryTracker* memory_tracker,
428 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35429 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35430
431 // Create a new render buffer.
432 void Create();
433
434 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18435 bool AllocateStorage(const FeatureInfo* feature_info,
436 const gfx::Size& size,
437 GLenum format,
438 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35439
440 // Destroy the render buffer. This must be explicitly called before destroying
441 // this object.
442 void Destroy();
443
[email protected]97872062010-11-03 19:07:05444 // Invalidate the render buffer. This can be used when a context is lost and
445 // it is not possible to make it current in order to free the resource.
446 void Invalidate();
447
[email protected]6217d392010-03-25 22:08:35448 GLuint id() const {
449 return id_;
450 }
451
452 private:
[email protected]d5a28e452013-10-10 01:01:40453 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25454 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40455 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48456 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35457 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35458 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35459};
460
461// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35462class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35463 public:
[email protected]ed9f9cd2013-02-27 21:12:35464 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
465 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35466
467 // Create a new frame buffer.
468 void Create();
469
470 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35471 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35472
[email protected]b9363b22010-06-09 22:06:15473 // Attach a render buffer to a frame buffer. Note that this unbinds any
474 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35475 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35476
[email protected]6217d392010-03-25 22:08:35477 // Destroy the frame buffer. This must be explicitly called before destroying
478 // this object.
479 void Destroy();
480
[email protected]97872062010-11-03 19:07:05481 // Invalidate the frame buffer. This can be used when a context is lost and it
482 // is not possible to make it current in order to free the resource.
483 void Invalidate();
484
[email protected]6217d392010-03-25 22:08:35485 // See glCheckFramebufferStatusEXT.
486 GLenum CheckStatus();
487
488 GLuint id() const {
489 return id_;
490 }
491
492 private:
493 GLES2DecoderImpl* decoder_;
494 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35495 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35496};
[email protected]34ff8b0c2010-10-01 20:06:02497
[email protected]5a36dc132013-07-23 23:17:55498struct FenceCallback {
499 explicit FenceCallback()
500 : fence(gfx::GLFence::Create()) {
501 DCHECK(fence);
502 }
[email protected]5a36dc132013-07-23 23:17:55503 std::vector<base::Closure> callbacks;
504 scoped_ptr<gfx::GLFence> fence;
505};
506
[email protected]e3c4a9ab2014-03-31 09:07:02507class AsyncUploadTokenCompletionObserver
508 : public AsyncPixelTransferCompletionObserver {
509 public:
510 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
511 : async_upload_token_(async_upload_token) {
512 }
513
dcheng1f4d1d72014-10-21 16:21:58514 void DidComplete(const AsyncMemoryParams& mem_params) override {
dcheng6ef3c5552014-08-30 05:34:19515 DCHECK(mem_params.buffer().get());
[email protected]e3c4a9ab2014-03-31 09:07:02516 void* data = mem_params.GetDataAddress();
517 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
518 sync->SetAsyncUploadToken(async_upload_token_);
519 }
520
521 private:
dcheng1f4d1d72014-10-21 16:21:58522 ~AsyncUploadTokenCompletionObserver() override {}
[email protected]e3c4a9ab2014-03-31 09:07:02523
524 uint32 async_upload_token_;
525
526 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
527};
528
[email protected]43f28f832010-02-03 02:28:48529// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32530
[email protected]efc87712014-07-09 00:22:47531// static
532const unsigned int GLES2Decoder::kDefaultStencilMask =
533 static_cast<unsigned int>(-1);
534
[email protected]ddb1e5a2010-12-13 20:10:45535bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
536 uint32* service_texture_id) {
537 return false;
538}
539
[email protected]a3ded6d2010-10-19 06:44:39540GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06541 : initialized_(false),
542 debug_(false),
[email protected]1d82e822013-04-10 21:32:32543 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32544}
545
[email protected]3916c97e2010-02-25 03:20:50546GLES2Decoder::~GLES2Decoder() {
547}
548
[email protected]cac16542014-01-15 17:53:51549void GLES2Decoder::BeginDecoding() {}
550
551void GLES2Decoder::EndDecoding() {}
552
[email protected]f39f4b3f2010-05-12 17:04:08553// This class implements GLES2Decoder so we don't have to expose all the GLES2
554// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54555class GLES2DecoderImpl : public GLES2Decoder,
[email protected]828a3932014-04-02 14:43:13556 public FramebufferManager::TextureDetachObserver,
557 public ErrorStateClient {
[email protected]f39f4b3f2010-05-12 17:04:08558 public:
[email protected]aa7666122011-09-02 19:45:52559 explicit GLES2DecoderImpl(ContextGroup* group);
dcheng1f4d1d72014-10-21 16:21:58560 ~GLES2DecoderImpl() override;
[email protected]f39f4b3f2010-05-12 17:04:08561
[email protected]96449d2c2009-11-25 00:01:32562 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58563 Error DoCommand(unsigned int command,
564 unsigned int arg_count,
565 const void* args) override;
[email protected]96449d2c2009-11-25 00:01:32566
dcheng1f4d1d72014-10-21 16:21:58567 error::Error DoCommands(unsigned int num_commands,
568 const void* buffer,
569 int num_entries,
570 int* entries_processed) override;
vmiura8266ca72014-09-09 21:37:00571
vmiura1c2b1de2014-09-19 19:03:24572 template <bool DebugImpl>
573 error::Error DoCommandsImpl(unsigned int num_commands,
574 const void* buffer,
575 int num_entries,
576 int* entries_processed);
577
[email protected]96449d2c2009-11-25 00:01:32578 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58579 const char* GetCommandName(unsigned int command_id) const override;
[email protected]96449d2c2009-11-25 00:01:32580
581 // Overridden from GLES2Decoder.
dcheng1f4d1d72014-10-21 16:21:58582 bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
583 const scoped_refptr<gfx::GLContext>& context,
584 bool offscreen,
585 const gfx::Size& size,
586 const DisallowedFeatures& disallowed_features,
587 const std::vector<int32>& attribs) override;
588 void Destroy(bool have_context) override;
589 void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
590 void ProduceFrontBuffer(const Mailbox& mailbox) override;
591 bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
[email protected]9a5afa432011-07-22 18:16:39592 void UpdateParentTextureInfo();
dcheng1f4d1d72014-10-21 16:21:58593 bool MakeCurrent() override;
594 GLES2Util* GetGLES2Util() override { return &util_; }
595 gfx::GLContext* GetGLContext() override { return context_.get(); }
596 ContextGroup* GetContextGroup() override { return group_.get(); }
597 Capabilities GetCapabilities() override;
598 void RestoreState(const ContextState* prev_state) override;
[email protected]29a4d902013-02-26 20:18:06599
dcheng1f4d1d72014-10-21 16:21:58600 void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); }
601 void RestoreAllTextureUnitBindings(
mohan.reddy5e1b8952014-10-08 01:38:17602 const ContextState* prev_state) const override {
[email protected]5baa86bc2014-01-16 04:33:16603 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55604 }
dcheng1f4d1d72014-10-21 16:21:58605 void RestoreActiveTextureUnitBinding(unsigned int target) const override {
[email protected]4b2d2b262014-03-21 22:05:27606 state_.RestoreActiveTextureUnitBinding(target);
607 }
dcheng1f4d1d72014-10-21 16:21:58608 void RestoreBufferBindings() const override {
[email protected]29a4d902013-02-26 20:18:06609 state_.RestoreBufferBindings();
610 }
dcheng1f4d1d72014-10-21 16:21:58611 void RestoreGlobalState() const override { state_.RestoreGlobalState(NULL); }
612 void RestoreProgramBindings() const override {
[email protected]29a4d902013-02-26 20:18:06613 state_.RestoreProgramBindings();
614 }
dcheng1f4d1d72014-10-21 16:21:58615 void RestoreTextureUnitBindings(unsigned unit) const override {
[email protected]5baa86bc2014-01-16 04:33:16616 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06617 }
dcheng1f4d1d72014-10-21 16:21:58618 void RestoreFramebufferBindings() const override;
619 void RestoreRenderbufferBindings() override;
620 void RestoreTextureState(unsigned service_id) const override;
[email protected]29a4d902013-02-26 20:18:06621
dcheng1f4d1d72014-10-21 16:21:58622 void ClearAllAttributes() const override;
623 void RestoreAllAttributes() const override;
[email protected]cd2ef752014-02-12 23:16:03624
dcheng1f4d1d72014-10-21 16:21:58625 QueryManager* GetQueryManager() override { return query_manager_.get(); }
626 VertexArrayManager* GetVertexArrayManager() override {
[email protected]944b62f32012-09-27 02:20:46627 return vertex_array_manager_.get();
628 }
dcheng1f4d1d72014-10-21 16:21:58629 ImageManager* GetImageManager() override { return image_manager_.get(); }
630 bool ProcessPendingQueries() override;
631 bool HasMoreIdleWork() override;
632 void PerformIdleWork() override;
[email protected]43f28f832010-02-03 02:28:48633
dcheng1f4d1d72014-10-21 16:21:58634 void WaitForReadPixels(base::Closure callback) override;
[email protected]5a36dc132013-07-23 23:17:55635
dcheng1f4d1d72014-10-21 16:21:58636 void SetResizeCallback(
mohan.reddy5e1b8952014-10-08 01:38:17637 const base::Callback<void(gfx::Size, float)>& callback) override;
[email protected]22f320a2011-08-30 01:17:00638
dcheng1f4d1d72014-10-21 16:21:58639 Logger* GetLogger() override;
[email protected]cac16542014-01-15 17:53:51640
dcheng1f4d1d72014-10-21 16:21:58641 void BeginDecoding() override;
642 void EndDecoding() override;
[email protected]cac16542014-01-15 17:53:51643
dcheng1f4d1d72014-10-21 16:21:58644 ErrorState* GetErrorState() override;
645 const ContextState* GetContextState() override { return &state_; }
[email protected]1d82e822013-04-10 21:32:32646
dcheng1f4d1d72014-10-21 16:21:58647 void SetShaderCacheCallback(const ShaderCacheCallback& callback) override;
648 void SetWaitSyncPointCallback(const WaitSyncPointCallback& callback) override;
[email protected]22f320a2011-08-30 01:17:00649
dcheng1f4d1d72014-10-21 16:21:58650 AsyncPixelTransferManager* GetAsyncPixelTransferManager() override;
651 void ResetAsyncPixelTransferManagerForTest() override;
652 void SetAsyncPixelTransferManagerForTest(
mohan.reddy5e1b8952014-10-08 01:38:17653 AsyncPixelTransferManager* manager) override;
dcheng1f4d1d72014-10-21 16:21:58654 void SetIgnoreCachedStateForTest(bool ignore) override;
[email protected]69a8701e2013-03-07 21:31:09655 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59656
dcheng1f4d1d72014-10-21 16:21:58657 bool GetServiceTextureId(uint32 client_texture_id,
658 uint32* service_texture_id) override;
[email protected]43f28f832010-02-03 02:28:48659
dcheng1f4d1d72014-10-21 16:21:58660 uint32 GetTextureUploadCount() override;
661 base::TimeDelta GetTotalTextureUploadTime() override;
662 base::TimeDelta GetTotalProcessingCommandsTime() override;
663 void AddProcessingCommandsTime(base::TimeDelta) override;
[email protected]63b465922012-09-06 02:04:52664
[email protected]8e3e0662010-08-23 18:46:30665 // Restores the current state to the user's settings.
666 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30667
[email protected]297ca1c2011-06-20 23:08:46668 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
669 void ApplyDirtyState();
670
671 // These check the state of the currently bound framebuffer or the
672 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54673 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
674 // check with all attached and enabled color attachments.
675 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46676 bool BoundFramebufferHasDepthAttachment();
677 bool BoundFramebufferHasStencilAttachment();
678
dcheng1f4d1d72014-10-21 16:21:58679 error::ContextLostReason GetContextLostReason() override;
[email protected]38d139d2011-07-14 00:38:43680
[email protected]91c94eb2013-10-22 10:32:54681 // Overridden from FramebufferManager::TextureDetachObserver:
dcheng1f4d1d72014-10-21 16:21:58682 void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) override;
[email protected]91c94eb2013-10-22 10:32:54683
[email protected]828a3932014-04-02 14:43:13684 // Overriden from ErrorStateClient.
dcheng1f4d1d72014-10-21 16:21:58685 void OnOutOfMemoryError() override;
[email protected]828a3932014-04-02 14:43:13686
[email protected]8875a5f2014-06-27 08:33:47687 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
688 void EnsureRenderbufferBound();
689
[email protected]f42f05b2013-11-15 21:46:18690 // Helpers to facilitate calling into compatible extensions.
691 static void RenderbufferStorageMultisampleHelper(
692 const FeatureInfo* feature_info,
693 GLenum target,
694 GLsizei samples,
695 GLenum internal_format,
696 GLsizei width,
697 GLsizei height);
698
699 void BlitFramebufferHelper(GLint srcX0,
700 GLint srcY0,
701 GLint srcX1,
702 GLint srcY1,
703 GLint dstX0,
704 GLint dstY0,
705 GLint dstX1,
706 GLint dstY1,
707 GLbitfield mask,
708 GLenum filter);
[email protected]345ba902013-11-14 21:39:00709
[email protected]96449d2c2009-11-25 00:01:32710 private:
[email protected]70d34263c2013-01-09 00:27:45711 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02712 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35713 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35714
[email protected]c2f8c8402010-12-06 18:07:24715 // Initialize or re-initialize the shader translator.
716 bool InitializeShaderTranslator();
717
[email protected]302ce6d2011-07-07 23:28:11718 void UpdateCapabilities();
719
[email protected]ae51d192010-04-27 00:48:03720 // Helpers for the glGen and glDelete functions.
721 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
722 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
723 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
724 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
725 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
726 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
727 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
728 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53729 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
730 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46731 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
732 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47733
[email protected]e3c4a9ab2014-03-31 09:07:02734 // Helper for async upload token completion notification callback.
735 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
736 uint32 sync_data_shm_id,
737 uint32 sync_data_shm_offset);
738
739
740
[email protected]70d34263c2013-01-09 00:27:45741 // Workarounds
742 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51743 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45744
[email protected]3916c97e2010-02-25 03:20:50745 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50746 BufferManager* buffer_manager() {
747 return group_->buffer_manager();
748 }
749
[email protected]a25fa872010-03-25 02:57:58750 RenderbufferManager* renderbuffer_manager() {
751 return group_->renderbuffer_manager();
752 }
753
754 FramebufferManager* framebuffer_manager() {
755 return group_->framebuffer_manager();
756 }
757
[email protected]3916c97e2010-02-25 03:20:50758 ProgramManager* program_manager() {
759 return group_->program_manager();
760 }
761
762 ShaderManager* shader_manager() {
763 return group_->shader_manager();
764 }
765
[email protected]03cef9b2014-04-03 15:58:14766 ShaderTranslatorCache* shader_translator_cache() {
767 return group_->shader_translator_cache();
768 }
769
[email protected]29a4d902013-02-26 20:18:06770 const TextureManager* texture_manager() const {
771 return group_->texture_manager();
772 }
773
[email protected]3916c97e2010-02-25 03:20:50774 TextureManager* texture_manager() {
775 return group_->texture_manager();
776 }
777
[email protected]78b514b2012-05-01 21:50:59778 MailboxManager* mailbox_manager() {
779 return group_->mailbox_manager();
780 }
781
[email protected]b63f1d62014-07-18 15:40:59782 ImageManager* image_manager() { return image_manager_.get(); }
[email protected]09d50362012-10-18 20:54:37783
[email protected]944b62f32012-09-27 02:20:46784 VertexArrayManager* vertex_array_manager() {
785 return vertex_array_manager_.get();
786 }
787
[email protected]7989c9e2013-01-23 06:39:26788 MemoryTracker* memory_tracker() {
789 return group_->memory_tracker();
790 }
791
792 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
793 MemoryTracker* tracker = memory_tracker();
794 if (tracker) {
795 return tracker->EnsureGPUMemoryAvailable(estimated_size);
796 }
797 return true;
798 }
799
[email protected]34ff8b0c2010-10-01 20:06:02800 bool IsOffscreenBufferMultisampled() const {
801 return offscreen_target_samples_ > 1;
802 }
803
[email protected]ed9f9cd2013-02-27 21:12:35804 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49805 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03806 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35807 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47808 }
809
810 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49811 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07812 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47813 }
814
815 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35816 void RemoveTexture(GLuint client_id) {
817 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50818 }
[email protected]a93bb842010-02-16 23:03:47819
[email protected]d37231fa2010-04-09 21:16:02820 // Get the size (in pixels) of the currently bound frame buffer (either FBO
821 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30822 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02823
[email protected]9edc6b22010-12-23 02:00:26824 // Get the format of the currently bound frame buffer (either FBO or regular
825 // back buffer)
[email protected]68586372013-12-11 01:27:59826 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26827 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46828 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26829
[email protected]a93bb842010-02-16 23:03:47830 // Wrapper for CompressedTexImage2D commands.
831 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37832 GLenum target,
833 GLint level,
834 GLenum internal_format,
835 GLsizei width,
836 GLsizei height,
837 GLint border,
838 GLsizei image_size,
839 const void* data);
[email protected]a93bb842010-02-16 23:03:47840
[email protected]cadde4a2010-07-31 17:10:43841 // Wrapper for CompressedTexSubImage2D.
842 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37843 GLenum target,
844 GLint level,
845 GLint xoffset,
846 GLint yoffset,
847 GLsizei width,
848 GLsizei height,
849 GLenum format,
850 GLsizei imageSize,
851 const void * data);
[email protected]cadde4a2010-07-31 17:10:43852
853 // Wrapper for CopyTexImage2D.
854 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37855 GLenum target,
856 GLint level,
857 GLenum internal_format,
858 GLint x,
859 GLint y,
860 GLsizei width,
861 GLsizei height,
862 GLint border);
[email protected]cadde4a2010-07-31 17:10:43863
[email protected]6d792ee12013-05-15 00:40:56864 // Wrapper for SwapBuffers.
865 void DoSwapBuffers();
866
[email protected]cadde4a2010-07-31 17:10:43867 // Wrapper for CopyTexSubImage2D.
868 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37869 GLenum target,
870 GLint level,
871 GLint xoffset,
872 GLint yoffset,
873 GLint x,
874 GLint y,
875 GLsizei width,
876 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43877
[email protected]f598f422012-12-07 08:30:03878 // Validation for TexSubImage2D.
879 bool ValidateTexSubImage2D(
880 error::Error* error,
881 const char* function_name,
882 GLenum target,
883 GLint level,
884 GLint xoffset,
885 GLint yoffset,
886 GLsizei width,
887 GLsizei height,
888 GLenum format,
889 GLenum type,
890 const void * data);
891
[email protected]cadde4a2010-07-31 17:10:43892 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03893 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37894 GLenum target,
895 GLint level,
896 GLint xoffset,
897 GLint yoffset,
898 GLsizei width,
899 GLsizei height,
900 GLenum format,
901 GLenum type,
902 const void * data);
[email protected]cadde4a2010-07-31 17:10:43903
[email protected]32145a92012-12-17 09:01:59904 // Extra validation for async tex(Sub)Image2D.
905 bool ValidateAsyncTransfer(
906 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47907 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59908 GLenum target,
909 GLint level,
910 const void * data);
911
[email protected]e51bdf32011-11-23 22:21:46912 // Wrapper for TexImageIOSurface2DCHROMIUM.
913 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37914 GLenum target,
915 GLsizei width,
916 GLsizei height,
917 GLuint io_surface_id,
918 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46919
[email protected]43410e92012-04-20 17:06:28920 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37921 GLenum target,
922 GLuint source_id,
923 GLuint target_id,
924 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54925 GLenum internal_format,
926 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28927
[email protected]97dc7cbe2011-12-06 17:26:17928 // Wrapper for TexStorage2DEXT.
929 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37930 GLenum target,
931 GLint levels,
932 GLenum internal_format,
933 GLsizei width,
934 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17935
[email protected]78b514b2012-05-01 21:50:59936 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22937 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
938 const GLbyte* key);
939 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
940 GLenum target, const GLbyte* data);
941
[email protected]78b514b2012-05-01 21:50:59942 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22943 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
944 GLuint client_id);
[email protected]78b514b2012-05-01 21:50:59945
[email protected]09d50362012-10-18 20:54:37946 void DoBindTexImage2DCHROMIUM(
947 GLenum target,
948 GLint image_id);
949 void DoReleaseTexImage2DCHROMIUM(
950 GLenum target,
951 GLint image_id);
952
[email protected]94307712012-11-16 23:26:11953 void DoTraceEndCHROMIUM(void);
954
[email protected]2f143d482013-03-14 18:04:49955 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
956
[email protected]a6a09f852014-05-23 13:05:03957 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
958
kkinnunen337d59632014-08-26 10:19:57959 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
960 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
961
[email protected]ed9f9cd2013-02-27 21:12:35962 // Creates a Program for the given program.
963 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57964 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35965 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47966 }
967
[email protected]07f54fcc2009-12-22 02:46:30968 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35969 Program* GetProgram(GLuint client_id) {
970 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46971 }
[email protected]07f54fcc2009-12-22 02:46:30972
[email protected]cae20172012-12-07 00:06:19973#if defined(NDEBUG)
974 void LogClientServiceMapping(
975 const char* /* function_name */,
976 GLuint /* client_id */,
977 GLuint /* service_id */) {
978 }
979 template<typename T>
980 void LogClientServiceForInfo(
981 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
982 }
983#else
984 void LogClientServiceMapping(
985 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26986 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:47987 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
988 << ": client_id = " << client_id
989 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:26990 }
[email protected]cae20172012-12-07 00:06:19991 }
992 template<typename T>
993 void LogClientServiceForInfo(
994 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26995 if (info) {
[email protected]cae20172012-12-07 00:06:19996 LogClientServiceMapping(function_name, client_id, info->service_id());
997 }
998 }
999#endif
1000
[email protected]6b8cf1a2010-05-06 16:13:581001 // Gets the program info for the given program. If it's not a program
1002 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:351003 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:581004 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421005 Program* program = GetProgram(client_id);
1006 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351007 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511008 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431009 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581010 } else {
[email protected]ab09b612013-03-11 22:11:511011 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581012 }
1013 }
[email protected]df37b9932013-03-08 05:21:421014 LogClientServiceForInfo(program, client_id, function_name);
1015 return program;
[email protected]6b8cf1a2010-05-06 16:13:581016 }
1017
1018
[email protected]ed9f9cd2013-02-27 21:12:351019 // Creates a Shader for the given shader.
1020 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571021 GLuint client_id,
1022 GLuint service_id,
1023 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351024 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571025 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311026 }
1027
1028 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351029 Shader* GetShader(GLuint client_id) {
1030 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311031 }
1032
[email protected]6b8cf1a2010-05-06 16:13:581033 // Gets the shader info for the given shader. If it's not a shader generates a
1034 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351035 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581036 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421037 Shader* shader = GetShader(client_id);
1038 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351039 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511040 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431041 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581042 } else {
[email protected]ab09b612013-03-11 22:11:511043 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431044 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581045 }
1046 }
[email protected]df37b9932013-03-08 05:21:421047 LogClientServiceForInfo(shader, client_id, function_name);
1048 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581049 }
1050
[email protected]a93bb842010-02-16 23:03:471051 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351052 void CreateBuffer(GLuint client_id, GLuint service_id) {
1053 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471054 }
1055
[email protected]07f54fcc2009-12-22 02:46:301056 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211057 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071058 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1059 return buffer;
[email protected]1d32bc82010-01-13 22:06:461060 }
[email protected]07f54fcc2009-12-22 02:46:301061
[email protected]a93bb842010-02-16 23:03:471062 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1063 // on glDeleteBuffers so we can make sure the user does not try to render
1064 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351065 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471066
[email protected]a25fa872010-03-25 02:57:581067 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351068 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1069 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581070 }
1071
1072 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061073 Framebuffer* GetFramebuffer(GLuint client_id) {
1074 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581075 }
1076
1077 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351078 void RemoveFramebuffer(GLuint client_id) {
1079 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581080 }
1081
1082 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351083 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1084 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031085 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581086 }
1087
1088 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271089 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1090 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581091 }
1092
1093 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351094 void RemoveRenderbuffer(GLuint client_id) {
1095 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581096 }
1097
[email protected]944b62f32012-09-27 02:20:461098 // Gets the vertex attrib manager for the given vertex array.
1099 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1100 VertexAttribManager* info =
1101 vertex_array_manager()->GetVertexAttribManager(client_id);
1102 return info;
1103 }
1104
1105 // Removes the vertex attrib manager for the given vertex array.
1106 void RemoveVertexAttribManager(GLuint client_id) {
1107 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1108 }
1109
1110 // Creates a vertex attrib manager for the given vertex array.
[email protected]da364812014-05-09 21:39:481111 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1112 GLuint client_id,
1113 GLuint service_id,
1114 bool client_visible) {
1115 return vertex_array_manager()->CreateVertexAttribManager(
1116 client_id, service_id, group_->max_vertex_attribs(), client_visible);
[email protected]944b62f32012-09-27 02:20:461117 }
1118
[email protected]258a3313f2011-10-18 20:13:571119 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331120 void DoBindUniformLocationCHROMIUM(
1121 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571122
[email protected]558847a2010-03-24 07:02:541123 error::Error GetAttribLocationHelper(
1124 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1125 const std::string& name_str);
1126
1127 error::Error GetUniformLocationHelper(
1128 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1129 const std::string& name_str);
1130
[email protected]3916c97e2010-02-25 03:20:501131 // Helper for glShaderSource.
1132 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031133 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301134
[email protected]0d6bfdc2011-11-02 01:32:201135 // Clear any textures used by the current program.
1136 bool ClearUnclearedTextures();
1137
[email protected]0d6bfdc2011-11-02 01:32:201138 // Clears any uncleared attachments attached to the given frame buffer.
1139 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061140 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281141
[email protected]0d6bfdc2011-11-02 01:32:201142 // overridden from GLES2Decoder
dcheng1f4d1d72014-10-21 16:21:581143 bool ClearLevel(unsigned service_id,
1144 unsigned bind_target,
1145 unsigned target,
1146 int level,
1147 unsigned internal_format,
1148 unsigned format,
1149 unsigned type,
1150 int width,
1151 int height,
1152 bool is_texture_immutable) override;
[email protected]0d6bfdc2011-11-02 01:32:201153
[email protected]c007aa02010-09-02 22:22:401154 // Restore all GL state that affects clearing.
1155 void RestoreClearState();
1156
[email protected]3a2e7c7b2010-08-06 01:12:281157 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461158 // Returns: true if glEnable/glDisable should actually be called.
1159 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281160
[email protected]0d6bfdc2011-11-02 01:32:201161 // Check that the currently bound framebuffers are valid.
1162 // Generates GL error if not.
1163 bool CheckBoundFramebuffersValid(const char* func_name);
1164
[email protected]2ea5950d2014-07-09 18:20:341165 // Check that the currently bound read framebuffer has a color image
1166 // attached. Generates GL error if not.
1167 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1168
zmo383512cf2014-10-14 00:11:001169 // Check that the currently bound read framebuffer's color image
1170 // isn't the target texture of the glCopyTex{Sub}Image2D.
1171 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
1172
[email protected]0d6bfdc2011-11-02 01:32:201173 // Check if a framebuffer meets our requirements.
1174 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351175 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201176 GLenum target,
1177 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271178
[email protected]939e7362010-05-13 20:49:101179 // Checks if the current program exists and is valid. If not generates the
1180 // appropriate GL error. Returns true if the current program is in a usable
1181 // state.
1182 bool CheckCurrentProgram(const char* function_name);
1183
1184 // Checks if the current program exists and is valid and that location is not
1185 // -1. If the current program is not valid generates the appropriate GL
1186 // error. Returns true if the current program is in a usable state and
1187 // location is not -1.
1188 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1189
zmof9a81360f2014-10-17 00:06:141190 // Checks if the current program samples a texture that is also the color
1191 // image of the current bound framebuffer, i.e., the source and destination
1192 // of the draw operation are the same.
1193 bool CheckDrawingFeedbackLoops();
1194
[email protected]939e7362010-05-13 20:49:101195 // Gets the type of a uniform for a location in the current program. Sets GL
1196 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361197 // program is valid and the location exists. Adjusts count so it
1198 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131199 bool PrepForSetUniformByLocation(GLint fake_location,
1200 const char* function_name,
1201 Program::UniformApiType api_type,
1202 GLint* real_location,
1203 GLenum* type,
1204 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101205
[email protected]b177ae22011-11-01 03:29:111206 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021207 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111208
[email protected]b273e432010-04-12 17:23:581209 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1210 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1211
[email protected]ac77603c72013-03-08 13:52:061212 // Helper for glGetVertexAttrib
1213 void GetVertexAttribHelper(
1214 const VertexAttrib* attrib, GLenum pname, GLint* param);
1215
[email protected]96449d2c2009-11-25 00:01:321216 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031217 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321218
1219 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031220 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321221
[email protected]3916c97e2010-02-25 03:20:501222 // Wrapper for glActiveTexture
1223 void DoActiveTexture(GLenum texture_unit);
1224
[email protected]ae51d192010-04-27 00:48:031225 // Wrapper for glAttachShader
1226 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1227
[email protected]96449d2c2009-11-25 00:01:321228 // Wrapper for glBindBuffer since we need to track the current targets.
1229 void DoBindBuffer(GLenum target, GLuint buffer);
1230
[email protected]86093972010-03-11 00:13:561231 // Wrapper for glBindFramebuffer since we need to track the current targets.
1232 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1233
1234 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1235 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1236
[email protected]a93bb842010-02-16 23:03:471237 // Wrapper for glBindTexture since we need to track the current targets.
1238 void DoBindTexture(GLenum target, GLuint texture);
1239
[email protected]944b62f32012-09-27 02:20:461240 // Wrapper for glBindVertexArrayOES
1241 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571242 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461243
[email protected]49cabed2013-11-13 18:15:181244 // Wrapper for glBlitFramebufferCHROMIUM.
1245 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301246 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1247 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1248 GLbitfield mask, GLenum filter);
1249
[email protected]36cef8ce2010-03-16 07:34:451250 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111251 void DoBufferSubData(
1252 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1253
[email protected]36cef8ce2010-03-16 07:34:451254 // Wrapper for glCheckFramebufferStatus
1255 GLenum DoCheckFramebufferStatus(GLenum target);
1256
[email protected]3a03a8f2011-03-19 00:51:271257 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081258 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271259
[email protected]88a61bf2012-10-27 13:00:421260 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421261 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251262 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281263
[email protected]45bf5152010-02-12 00:11:311264 // Wrapper for glCompileShader.
1265 void DoCompileShader(GLuint shader);
1266
[email protected]ae51d192010-04-27 00:48:031267 // Wrapper for glDetachShader
1268 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1269
[email protected]3a2e7c7b2010-08-06 01:12:281270 // Wrapper for glDisable
1271 void DoDisable(GLenum cap);
1272
[email protected]07f54fcc2009-12-22 02:46:301273 // Wrapper for glDisableVertexAttribArray.
1274 void DoDisableVertexAttribArray(GLuint index);
1275
[email protected]60f22d32012-12-12 00:31:581276 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1277 // attachments.
1278 void DoDiscardFramebufferEXT(GLenum target,
1279 GLsizei numAttachments,
1280 const GLenum* attachments);
1281
[email protected]3a2e7c7b2010-08-06 01:12:281282 // Wrapper for glEnable
1283 void DoEnable(GLenum cap);
1284
[email protected]07f54fcc2009-12-22 02:46:301285 // Wrapper for glEnableVertexAttribArray.
1286 void DoEnableVertexAttribArray(GLuint index);
1287
[email protected]882ba1e22012-03-08 19:02:531288 // Wrapper for glFinish.
1289 void DoFinish();
1290
1291 // Wrapper for glFlush.
1292 void DoFlush();
1293
[email protected]36cef8ce2010-03-16 07:34:451294 // Wrapper for glFramebufferRenderbufffer.
1295 void DoFramebufferRenderbuffer(
1296 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1297 GLuint renderbuffer);
1298
1299 // Wrapper for glFramebufferTexture2D.
1300 void DoFramebufferTexture2D(
1301 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1302 GLint level);
1303
[email protected]7d3c36e2013-07-12 14:13:161304 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1305 void DoFramebufferTexture2DMultisample(
1306 GLenum target, GLenum attachment, GLenum textarget,
1307 GLuint texture, GLint level, GLsizei samples);
1308
1309 // Common implementation for both DoFramebufferTexture2D wrappers.
1310 void DoFramebufferTexture2DCommon(const char* name,
1311 GLenum target, GLenum attachment, GLenum textarget,
1312 GLuint texture, GLint level, GLsizei samples);
1313
[email protected]a93bb842010-02-16 23:03:471314 // Wrapper for glGenerateMipmap
1315 void DoGenerateMipmap(GLenum target);
1316
[email protected]7d3c36e2013-07-12 14:13:161317 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1318 // to account for different pname values defined in different extension
1319 // variants.
1320 GLenum AdjustGetPname(GLenum pname);
1321
[email protected]b273e432010-04-12 17:23:581322 // Wrapper for DoGetBooleanv.
1323 void DoGetBooleanv(GLenum pname, GLboolean* params);
1324
1325 // Wrapper for DoGetFloatv.
1326 void DoGetFloatv(GLenum pname, GLfloat* params);
1327
[email protected]36cef8ce2010-03-16 07:34:451328 // Wrapper for glGetFramebufferAttachmentParameteriv.
1329 void DoGetFramebufferAttachmentParameteriv(
1330 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1331
[email protected]a0c3e972010-04-21 00:49:131332 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581333 void DoGetIntegerv(GLenum pname, GLint* params);
1334
[email protected]29a9eb52010-04-13 09:04:231335 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061336 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231337 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1338
[email protected]17cfbe0e2013-03-07 01:26:081339 // Wrapper for glGetBufferParameteriv.
1340 void DoGetBufferParameteriv(
1341 GLenum target, GLenum pname, GLint* params);
1342
[email protected]a0c3e972010-04-21 00:49:131343 // Wrapper for glGetProgramiv.
1344 void DoGetProgramiv(
1345 GLuint program_id, GLenum pname, GLint* params);
1346
[email protected]36cef8ce2010-03-16 07:34:451347 // Wrapper for glRenderbufferParameteriv.
1348 void DoGetRenderbufferParameteriv(
1349 GLenum target, GLenum pname, GLint* params);
1350
[email protected]ddd968b82010-03-02 00:44:291351 // Wrapper for glGetShaderiv
1352 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1353
[email protected]4c6f5462014-03-05 00:26:561354 // Wrappers for glGetTexParameter.
1355 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1356 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1357 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1358
[email protected]b1122982010-05-17 23:04:241359 // Wrappers for glGetVertexAttrib.
1360 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1361 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1362
[email protected]1958e0e2010-04-22 05:17:151363 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241364 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151365 bool DoIsBuffer(GLuint client_id);
1366 bool DoIsFramebuffer(GLuint client_id);
1367 bool DoIsProgram(GLuint client_id);
1368 bool DoIsRenderbuffer(GLuint client_id);
1369 bool DoIsShader(GLuint client_id);
1370 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461371 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151372
[email protected]07f54fcc2009-12-22 02:46:301373 // Wrapper for glLinkProgram
1374 void DoLinkProgram(GLuint program);
1375
[email protected]36cef8ce2010-03-16 07:34:451376 // Wrapper for glRenderbufferStorage.
1377 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031378 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451379
[email protected]49cabed2013-11-13 18:15:181380 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1381 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301382 GLenum target, GLsizei samples, GLenum internalformat,
1383 GLsizei width, GLsizei height);
1384
[email protected]49cabed2013-11-13 18:15:181385 // Handler for glRenderbufferStorageMultisampleEXT
1386 // (multisampled_render_to_texture).
1387 void DoRenderbufferStorageMultisampleEXT(
1388 GLenum target, GLsizei samples, GLenum internalformat,
1389 GLsizei width, GLsizei height);
1390
1391 // Common validation for multisample extensions.
1392 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1393 GLenum internalformat,
1394 GLsizei width,
1395 GLsizei height);
1396
[email protected]4a4c18b2013-09-13 22:50:101397 // Verifies that the currently bound multisample renderbuffer is valid
1398 // Very slow! Only done on platforms with driver bugs that return invalid
1399 // buffers under memory pressure
1400 bool VerifyMultisampleRenderbufferIntegrity(
1401 GLuint renderbuffer, GLenum format);
1402
[email protected]b273e432010-04-12 17:23:581403 // Wrapper for glReleaseShaderCompiler.
1404 void DoReleaseShaderCompiler() { }
1405
[email protected]3916c97e2010-02-25 03:20:501406 // Wrappers for glTexParameter functions.
1407 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1408 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1409 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1410 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1411
1412 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1413 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121414 void DoUniform1i(GLint fake_location, GLint v0);
1415 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1416 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1417 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1418 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101419
1420 // Wrappers for glUniformfv because some drivers don't correctly accept
1421 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121422 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1423 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1424 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1425 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501426
[email protected]43c2f1f2011-03-25 18:35:361427 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121428 GLint fake_location, GLsizei count, GLboolean transpose,
1429 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361430 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121431 GLint fake_location, GLsizei count, GLboolean transpose,
1432 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361433 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121434 GLint fake_location, GLsizei count, GLboolean transpose,
1435 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361436
[email protected]af6380962012-11-29 23:24:131437 bool SetVertexAttribValue(
1438 const char* function_name, GLuint index, const GLfloat* value);
1439
[email protected]b1122982010-05-17 23:04:241440 // Wrappers for glVertexAttrib??
1441 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1442 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1443 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1444 void DoVertexAttrib4f(
1445 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1446 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1447 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1448 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1449 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1450
[email protected]43410e92012-04-20 17:06:281451 // Wrapper for glViewport
1452 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1453
[email protected]07f54fcc2009-12-22 02:46:301454 // Wrapper for glUseProgram
1455 void DoUseProgram(GLuint program);
1456
[email protected]ae51d192010-04-27 00:48:031457 // Wrapper for glValidateProgram.
1458 void DoValidateProgram(GLuint program_client_id);
1459
[email protected]d2a0e1a2012-08-12 02:25:011460 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1461 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1462 void DoPopGroupMarkerEXT(void);
1463
[email protected]4e8a5b122010-05-08 22:00:101464 // Gets the number of values that will be returned by glGetXXX. Returns
1465 // false if pname is unknown.
1466 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1467
[email protected]07f54fcc2009-12-22 02:46:301468 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431469 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101470 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1471 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301472
[email protected]c13e1da62011-09-09 21:48:301473 // Returns true if successful, simulated will be true if attrib0 was
1474 // simulated.
[email protected]c6aef902012-02-14 03:31:421475 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431476 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231477 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241478
[email protected]91c94eb2013-10-22 10:32:541479 // If an image is bound to texture, this will call Will/DidUseTexImage
1480 // if needed.
1481 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1482 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1483
1484 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111485 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541486 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501487
[email protected]8fbedc02010-11-18 18:43:401488 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421489 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431490 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421491 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401492 void RestoreStateForSimulatedFixedAttribs();
1493
[email protected]c6aef902012-02-14 03:31:421494 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101495 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421496 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431497 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421498 bool instanced, GLenum mode, GLint first, GLsizei count,
1499 GLsizei primcount);
1500 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431501 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421502 bool instanced, GLenum mode, GLsizei count, GLenum type,
1503 int32 offset, GLsizei primcount);
1504
[email protected]61eeb33f2011-07-26 15:30:311505 GLenum GetBindTargetForSamplerType(GLenum type) {
1506 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461507 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1508 switch (type) {
1509 case GL_SAMPLER_2D:
1510 return GL_TEXTURE_2D;
1511 case GL_SAMPLER_CUBE:
1512 return GL_TEXTURE_CUBE_MAP;
1513 case GL_SAMPLER_EXTERNAL_OES:
1514 return GL_TEXTURE_EXTERNAL_OES;
1515 case GL_SAMPLER_2D_RECT_ARB:
1516 return GL_TEXTURE_RECTANGLE_ARB;
1517 }
1518
1519 NOTREACHED();
1520 return 0;
[email protected]61eeb33f2011-07-26 15:30:311521 }
1522
[email protected]8e3e0662010-08-23 18:46:301523 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061524 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1525 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301526 switch (target) {
1527 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451528 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341529 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301530 break;
[email protected]ebfb73c2012-08-15 02:37:451531 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341532 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301533 break;
1534 default:
1535 NOTREACHED();
1536 break;
1537 }
[email protected]4d8f0dd2013-03-09 14:37:061538 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301539 }
1540
[email protected]ed9f9cd2013-02-27 21:12:351541 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201542 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271543 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201544 switch (target) {
1545 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111546 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201547 break;
1548 default:
1549 NOTREACHED();
1550 break;
1551 }
[email protected]ee2a79c32013-03-10 03:50:271552 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201553 }
1554
[email protected]f7b85372010-02-03 01:11:371555 // Validates the program and location for a glGetUniform call and returns
1556 // a SizeResult setup to receive the result. Returns true if glGetUniform
1557 // should be called.
1558 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121559 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371560 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121561 error::Error* error, GLint* real_location, GLuint* service_id,
1562 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371563
jbauman7a059312014-10-16 19:30:541564 void MaybeExitOnContextLost();
dcheng1f4d1d72014-10-21 16:21:581565 bool WasContextLost() override;
1566 bool WasContextLostByRobustnessExtension() override;
1567 void LoseContext(uint32 reset_status) override;
[email protected]38d139d2011-07-14 00:38:431568
[email protected]e51bdf32011-11-23 22:21:461569#if defined(OS_MACOSX)
1570 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1571#endif
1572
[email protected]ad84a3a2012-06-08 21:42:431573 bool ValidateCompressedTexDimensions(
1574 const char* function_name,
1575 GLint level, GLsizei width, GLsizei height, GLenum format);
1576 bool ValidateCompressedTexFuncData(
1577 const char* function_name,
1578 GLsizei width, GLsizei height, GLenum format, size_t size);
1579 bool ValidateCompressedTexSubDimensions(
1580 const char* function_name,
1581 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1582 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351583 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431584
[email protected]ab09b612013-03-11 22:11:511585 void RenderWarning(const char* filename, int line, const std::string& msg);
1586 void PerformanceWarning(
1587 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011588
[email protected]62e155e2012-10-23 22:43:151589 const FeatureInfo::FeatureFlags& features() const {
1590 return feature_info_->feature_flags();
1591 }
1592
1593 const FeatureInfo::Workarounds& workarounds() const {
1594 return feature_info_->workarounds();
1595 }
1596
[email protected]a7266a92012-06-28 02:11:081597 bool ShouldDeferDraws() {
1598 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341599 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081600 surface_->DeferDraws();
1601 }
1602
[email protected]09e17272012-11-30 10:30:441603 bool ShouldDeferReads() {
1604 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341605 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441606 surface_->DeferDraws();
1607 }
1608
[email protected]c76fe672013-12-13 23:30:221609 error::Error WillAccessBoundFramebufferForDraw() {
1610 if (ShouldDeferDraws())
1611 return error::kDeferCommandUntilLater;
1612 if (!offscreen_target_frame_buffer_.get() &&
1613 !framebuffer_state_.bound_draw_framebuffer.get() &&
1614 !surface_->SetBackbufferAllocation(true))
1615 return error::kLostContext;
1616 return error::kNoError;
1617 }
1618
1619 error::Error WillAccessBoundFramebufferForRead() {
1620 if (ShouldDeferReads())
1621 return error::kDeferCommandUntilLater;
1622 if (!offscreen_target_frame_buffer_.get() &&
1623 !framebuffer_state_.bound_read_framebuffer.get() &&
1624 !surface_->SetBackbufferAllocation(true))
1625 return error::kLostContext;
1626 return error::kNoError;
1627 }
1628
vmiura8266ca72014-09-09 21:37:001629 // Set remaining commands to process to 0 to force DoCommands to return
1630 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1631 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1632
[email protected]5a36dc132013-07-23 23:17:551633 void ProcessPendingReadPixels();
1634 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1635
[email protected]96449d2c2009-11-25 00:01:321636 // Generate a member function prototype for each command in an automated and
1637 // typesafe way.
vmiuracd108592014-09-08 14:36:341638#define GLES2_CMD_OP(name) \
1639 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321640
1641 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1642
1643 #undef GLES2_CMD_OP
1644
[email protected]2f2d7042010-04-14 21:45:581645 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381646 scoped_refptr<gfx::GLSurface> surface_;
1647 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021648
[email protected]a3ded6d2010-10-19 06:44:391649 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351650 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391651
[email protected]1d82e822013-04-10 21:32:321652 DebugMarkerManager debug_marker_manager_;
1653 Logger logger_;
1654
[email protected]e259eb412012-10-13 05:47:241655 // All the state for this context.
1656 ContextState state_;
1657
[email protected]34ff8b0c2010-10-01 20:06:021658 // Current width and height of the offscreen frame buffer.
1659 gfx::Size offscreen_size_;
1660
[email protected]96449d2c2009-11-25 00:01:321661 // Util to help with GL.
1662 GLES2Util util_;
1663
[email protected]43410e92012-04-20 17:06:281664 // unpack flip y as last set by glPixelStorei
1665 bool unpack_flip_y_;
1666
[email protected]6c75c712012-06-19 15:43:171667 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281668 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171669 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281670
[email protected]b1122982010-05-17 23:04:241671 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1672 GLuint attrib_0_buffer_id_;
1673
1674 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131675 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241676
[email protected]fc753442011-02-04 19:49:491677 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1678 bool attrib_0_buffer_matches_value_;
1679
[email protected]b1122982010-05-17 23:04:241680 // The size of attrib 0.
1681 GLsizei attrib_0_size_;
1682
[email protected]8fbedc02010-11-18 18:43:401683 // The buffer used to simulate GL_FIXED attribs.
1684 GLuint fixed_attrib_buffer_id_;
1685
1686 // The size of fiixed attrib buffer.
1687 GLsizei fixed_attrib_buffer_size_;
1688
[email protected]b9363b22010-06-09 22:06:151689 // The offscreen frame buffer that the client renders to. With EGL, the
1690 // depth and stencil buffers are separate. With regular GL there is a single
1691 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1692 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351693 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1694 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1695 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1696 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1697 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021698 GLenum offscreen_target_color_format_;
1699 GLenum offscreen_target_depth_format_;
1700 GLenum offscreen_target_stencil_format_;
1701 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561702 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351703
[email protected]de26b3c2011-08-03 21:54:271704 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351705 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1706 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491707 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351708 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271709
1710 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351711 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1712 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051713 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351714
[email protected]882ba1e22012-03-08 19:02:531715 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531716
[email protected]944b62f32012-09-27 02:20:461717 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1718
[email protected]b63f1d62014-07-18 15:40:591719 scoped_ptr<ImageManager> image_manager_;
1720
[email protected]729c0b42013-05-26 02:05:071721 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001722
[email protected]840a7e462013-02-27 01:29:511723 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481724
[email protected]e3932abb2013-03-13 00:01:371725 ShaderCacheCallback shader_cache_callback_;
1726
[email protected]85a4ac22013-05-31 01:58:471727 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421728
[email protected]32fe9aa2011-01-21 23:47:131729 // The format of the back buffer_
1730 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461731 bool back_buffer_has_depth_;
1732 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131733
achaulkcf5316f2014-09-26 19:28:421734 bool surfaceless_;
1735
[email protected]60f22d32012-12-12 00:31:581736 // Backbuffer attachments that are currently undefined.
1737 uint32 backbuffer_needs_clear_bits_;
1738
[email protected]a6a09f852014-05-23 13:05:031739 // The current decoder error communicates the decoder error through command
1740 // processing functions that do not return the error value. Should be set only
1741 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561742 error::Error current_decoder_error_;
1743
[email protected]b1d2dcb2010-05-17 19:24:181744 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041745 scoped_refptr<ShaderTranslator> vertex_translator_;
1746 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181747
[email protected]e82fb792011-09-22 00:33:291748 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411749
[email protected]915a59a12010-09-30 21:29:111750 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051751 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351752 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051753
[email protected]65225772011-05-12 21:10:241754 int frame_number_;
1755
vmiura8266ca72014-09-09 21:37:001756 // Number of commands remaining to be processed in DoCommands().
1757 int commands_to_process_;
1758
[email protected]706b69f2012-07-27 04:59:301759 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431760 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221761 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431762 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431763
[email protected]f0d74742011-10-03 16:31:041764 // These flags are used to override the state of the shared feature_info_
1765 // member. Because the same FeatureInfo instance may be shared among many
1766 // contexts, the assumptions on the availablity of extensions in WebGL
1767 // contexts may be broken. These flags override the shared state to preserve
1768 // WebGL semantics.
1769 bool force_webgl_glsl_validation_;
1770 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491771 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131772 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061773 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041774
[email protected]062c38b2012-01-18 03:25:101775 bool compile_shader_always_succeeds_;
1776
[email protected]828a3932014-04-02 14:43:131777 // An optional behaviour to lose the context and group when OOM.
1778 bool lose_context_when_out_of_memory_;
1779
[email protected]cae20172012-12-07 00:06:191780 // Log extra info.
1781 bool service_logging_;
1782
[email protected]e51bdf32011-11-23 22:21:461783#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531784 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461785 TextureToIOSurfaceMap texture_to_io_surface_map_;
1786#endif
1787
[email protected]43410e92012-04-20 17:06:281788 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1789
[email protected]1868a342012-11-07 15:56:021790 // Cached values of the currently assigned viewport dimensions.
1791 GLsizei viewport_max_width_;
1792 GLsizei viewport_max_height_;
1793
[email protected]63b465922012-09-06 02:04:521794 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521795 base::TimeDelta total_processing_commands_time_;
1796
[email protected]c986af502013-08-14 01:04:441797 // States related to each manager.
1798 DecoderTextureState texture_state_;
1799 DecoderFramebufferState framebuffer_state_;
1800
[email protected]fb97b662013-02-20 23:02:141801 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131802 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:241803 const unsigned char* cb_command_trace_category_;
[email protected]cac16542014-01-15 17:53:511804 int gpu_trace_level_;
1805 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:241806 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:111807
[email protected]5a36dc132013-07-23 23:17:551808 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1809
[email protected]4a4c18b2013-09-13 22:50:101810 // Used to validate multisample renderbuffers if needed
1811 GLuint validation_texture_;
1812 GLuint validation_fbo_multisample_;
1813 GLuint validation_fbo_;
1814
vmiuracd108592014-09-08 14:36:341815 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1816 uint32 immediate_data_size,
1817 const void* data);
1818
1819 // A struct to hold info about each command.
1820 struct CommandInfo {
1821 CmdHandler cmd_handler;
1822 uint8 arg_flags; // How to handle the arguments for this command
1823 uint8 cmd_flags; // How to handle this command
1824 uint16 arg_count; // How many arguments are expected for this command.
1825 };
1826
1827 // A table of CommandInfo for all the commands.
1828 static const CommandInfo command_info[kNumCommands - kStartPoint];
1829
[email protected]96449d2c2009-11-25 00:01:321830 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1831};
1832
vmiuracd108592014-09-08 14:36:341833const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1834#define GLES2_CMD_OP(name) \
1835 { \
1836 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
1837 cmds::name::cmd_flags, \
1838 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1839 } \
1840 , /* NOLINT */
1841 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1842#undef GLES2_CMD_OP
1843};
1844
[email protected]ab09b612013-03-11 22:11:511845ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301846 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511847 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301848 error_state_(error_state) {
1849 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351850}
1851
1852ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301853 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351854}
1855
[email protected]2b10c02d2014-01-29 16:43:021856static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361857 TextureUnit& info = state->texture_units[0];
1858 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021859 scoped_refptr<TextureRef> texture_ref;
1860 switch (target) {
1861 case GL_TEXTURE_2D:
1862 texture_ref = info.bound_texture_2d;
1863 break;
1864 case GL_TEXTURE_CUBE_MAP:
1865 texture_ref = info.bound_texture_cube_map;
1866 break;
1867 case GL_TEXTURE_EXTERNAL_OES:
1868 texture_ref = info.bound_texture_external_oes;
1869 break;
1870 case GL_TEXTURE_RECTANGLE_ARB:
1871 texture_ref = info.bound_texture_rectangle_arb;
1872 break;
1873 default:
1874 NOTREACHED();
1875 break;
1876 }
1877 if (texture_ref.get()) {
1878 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361879 } else {
1880 last_id = 0;
1881 }
1882
[email protected]2b10c02d2014-01-29 16:43:021883 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361884 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1885}
1886
[email protected]2b10c02d2014-01-29 16:43:021887ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1888 GLuint id,
1889 GLenum target)
1890 : state_(state),
1891 target_(target) {
[email protected]ab09b612013-03-11 22:11:511892 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021893 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351894
1895 // TODO(apatrick): Check if there are any other states that need to be reset
1896 // before binding a new texture.
1897 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021898 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351899}
1900
[email protected]2b10c02d2014-01-29 16:43:021901ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511902 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021903 "ScopedTextureBinder::dtor", state_->GetErrorState());
1904 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351905}
1906
[email protected]18e785a2013-10-09 03:29:411907ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351908 GLuint id)
[email protected]18e785a2013-10-09 03:29:411909 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511910 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411911 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351912 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1913}
1914
1915ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511916 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411917 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1918 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351919}
1920
1921ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1922 GLuint id)
1923 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511924 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301925 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351926 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451927 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351928}
1929
1930ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511931 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301932 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:301933 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351934}
1935
[email protected]34ff8b0c2010-10-01 20:06:021936ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271937 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521938 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:341939 resolve_and_bind_ = (
1940 decoder_->offscreen_target_frame_buffer_.get() &&
1941 decoder_->IsOffscreenBufferMultisampled() &&
1942 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1943 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021944 if (!resolve_and_bind_)
1945 return;
1946
[email protected]ab09b612013-03-11 22:11:511947 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301948 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021949 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1950 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271951 GLuint targetid;
1952 if (internal) {
1953 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1954 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351955 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271956 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351957 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:361958 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:271959 decoder_->offscreen_resolved_color_texture_->Create();
1960
1961 DCHECK(decoder_->offscreen_saved_color_format_);
1962 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091963 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1964 false);
[email protected]de26b3c2011-08-03 21:54:271965 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1966 decoder_->offscreen_resolved_color_texture_.get());
1967 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1968 GL_FRAMEBUFFER_COMPLETE) {
1969 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1970 << "because offscreen resolved FBO was incomplete.";
1971 return;
1972 }
1973 }
1974 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1975 } else {
1976 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1977 }
1978 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021979 const int width = decoder_->offscreen_size_.width();
1980 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:451981 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:181982 decoder->BlitFramebufferHelper(0,
1983 0,
1984 width,
1985 height,
1986 0,
1987 0,
1988 width,
1989 height,
1990 GL_COLOR_BUFFER_BIT,
1991 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:271992 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021993}
1994
1995ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1996 if (!resolve_and_bind_)
1997 return;
1998
[email protected]ab09b612013-03-11 22:11:511999 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302000 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022001 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222002 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452003 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182004 }
[email protected]34ff8b0c2010-10-01 20:06:022005}
2006
[email protected]ce296892013-10-24 22:04:362007BackTexture::BackTexture(
2008 MemoryTracker* memory_tracker,
2009 ContextState* state)
2010 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2011 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482012 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252013 id_(0) {
[email protected]6217d392010-03-25 22:08:352014}
2015
[email protected]ed9f9cd2013-02-27 21:12:352016BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352017 // This does not destroy the render texture because that would require that
2018 // the associated GL context was current. Just check that it was explicitly
2019 // destroyed.
2020 DCHECK_EQ(id_, 0u);
2021}
2022
[email protected]ed9f9cd2013-02-27 21:12:352023void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302024 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362025 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352026 Destroy();
2027 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022028 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262029 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2030 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582031 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2032 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162033
2034 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2035 // never called on an offscreen context, no data will ever be uploaded to the
2036 // saved offscreen color texture (it is deferred until to when SwapBuffers
2037 // is called). My idea is that some nvidia drivers might have a bug where
2038 // deleting a texture that has never been populated might cause a
2039 // crash.
2040 glTexImage2D(
2041 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482042
2043 bytes_allocated_ = 16u * 16u * 4u;
2044 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352045}
2046
[email protected]ed9f9cd2013-02-27 21:12:352047bool BackTexture::AllocateStorage(
2048 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352049 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302050 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362051 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022052 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092053 uint32 image_size = 0;
2054 GLES2Util::ComputeImageDataSizes(
2055 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
2056 NULL, NULL);
2057
[email protected]7989c9e2013-01-23 06:39:262058 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2059 return false;
2060 }
2061
[email protected]40d90a22013-04-09 03:39:552062 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092063 if (zero) {
2064 zero_data.reset(new char[image_size]);
2065 memset(zero_data.get(), 0, image_size);
2066 }
[email protected]6217d392010-03-25 22:08:352067
[email protected]8f1d2aa2013-05-10 23:45:382068 glTexImage2D(GL_TEXTURE_2D,
2069 0, // mip level
2070 format,
2071 size.width(),
2072 size.height(),
2073 0, // border
2074 format,
2075 GL_UNSIGNED_BYTE,
2076 zero_data.get());
[email protected]6217d392010-03-25 22:08:352077
[email protected]d37231fa2010-04-09 21:16:022078 size_ = size;
2079
[email protected]1078f912011-12-23 13:12:142080 bool success = glGetError() == GL_NO_ERROR;
2081 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482082 memory_tracker_.TrackMemFree(bytes_allocated_);
2083 bytes_allocated_ = image_size;
2084 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142085 }
2086 return success;
[email protected]6217d392010-03-25 22:08:352087}
2088
[email protected]ed9f9cd2013-02-27 21:12:352089void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352090 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302091 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362092 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022093 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352094 glCopyTexImage2D(GL_TEXTURE_2D,
2095 0, // level
[email protected]3a4d0c52011-06-29 23:11:582096 format,
[email protected]6217d392010-03-25 22:08:352097 0, 0,
2098 size.width(),
2099 size.height(),
2100 0); // border
2101}
2102
[email protected]ed9f9cd2013-02-27 21:12:352103void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352104 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302105 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362106 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352107 glDeleteTextures(1, &id_);
2108 id_ = 0;
2109 }
[email protected]68e81a4a62012-12-13 01:16:482110 memory_tracker_.TrackMemFree(bytes_allocated_);
2111 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352112}
2113
[email protected]ed9f9cd2013-02-27 21:12:352114void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052115 id_ = 0;
2116}
2117
[email protected]d5a28e452013-10-10 01:01:402118BackRenderbuffer::BackRenderbuffer(
2119 RenderbufferManager* renderbuffer_manager,
2120 MemoryTracker* memory_tracker,
2121 ContextState* state)
2122 : renderbuffer_manager_(renderbuffer_manager),
2123 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2124 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482125 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252126 id_(0) {
[email protected]6217d392010-03-25 22:08:352127}
2128
[email protected]ed9f9cd2013-02-27 21:12:352129BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352130 // This does not destroy the render buffer because that would require that
2131 // the associated GL context was current. Just check that it was explicitly
2132 // destroyed.
2133 DCHECK_EQ(id_, 0u);
2134}
2135
[email protected]ed9f9cd2013-02-27 21:12:352136void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302137 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402138 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352139 Destroy();
2140 glGenRenderbuffersEXT(1, &id_);
2141}
2142
[email protected]f42f05b2013-11-15 21:46:182143bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2144 const gfx::Size& size,
2145 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352146 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512147 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402148 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2149 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262150
2151 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402152 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232153 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262154 return false;
2155 }
2156
2157 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2158 return false;
2159 }
2160
[email protected]34ff8b0c2010-10-01 20:06:022161 if (samples <= 1) {
2162 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2163 format,
2164 size.width(),
2165 size.height());
2166 } else {
[email protected]f42f05b2013-11-15 21:46:182167 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2168 GL_RENDERBUFFER,
2169 samples,
2170 format,
2171 size.width(),
2172 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022173 }
[email protected]1078f912011-12-23 13:12:142174 bool success = glGetError() == GL_NO_ERROR;
2175 if (success) {
[email protected]d5a28e452013-10-10 01:01:402176 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482177 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262178 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402179 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482180 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142181 }
2182 return success;
[email protected]6217d392010-03-25 22:08:352183}
2184
[email protected]ed9f9cd2013-02-27 21:12:352185void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352186 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302187 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402188 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352189 glDeleteRenderbuffersEXT(1, &id_);
2190 id_ = 0;
2191 }
[email protected]68e81a4a62012-12-13 01:16:482192 memory_tracker_.TrackMemFree(bytes_allocated_);
2193 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352194}
2195
[email protected]ed9f9cd2013-02-27 21:12:352196void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052197 id_ = 0;
2198}
2199
[email protected]ed9f9cd2013-02-27 21:12:352200BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352201 : decoder_(decoder),
2202 id_(0) {
2203}
2204
[email protected]ed9f9cd2013-02-27 21:12:352205BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352206 // This does not destroy the frame buffer because that would require that
2207 // the associated GL context was current. Just check that it was explicitly
2208 // destroyed.
2209 DCHECK_EQ(id_, 0u);
2210}
2211
[email protected]ed9f9cd2013-02-27 21:12:352212void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302213 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2214 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352215 Destroy();
2216 glGenFramebuffersEXT(1, &id_);
2217}
2218
[email protected]ed9f9cd2013-02-27 21:12:352219void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352220 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512221 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302222 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352223 ScopedFrameBufferBinder binder(decoder_, id_);
2224 GLuint attach_id = texture ? texture->id() : 0;
2225 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2226 GL_COLOR_ATTACHMENT0,
2227 GL_TEXTURE_2D,
2228 attach_id,
2229 0);
2230}
2231
[email protected]ed9f9cd2013-02-27 21:12:352232void BackFramebuffer::AttachRenderBuffer(GLenum target,
2233 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352234 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512235 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302236 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352237 ScopedFrameBufferBinder binder(decoder_, id_);
2238 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2239 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152240 target,
[email protected]6217d392010-03-25 22:08:352241 GL_RENDERBUFFER,
2242 attach_id);
2243}
2244
[email protected]ed9f9cd2013-02-27 21:12:352245void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352246 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302247 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2248 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352249 glDeleteFramebuffersEXT(1, &id_);
2250 id_ = 0;
2251 }
2252}
2253
[email protected]ed9f9cd2013-02-27 21:12:352254void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052255 id_ = 0;
2256}
2257
[email protected]ed9f9cd2013-02-27 21:12:352258GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352259 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302260 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2261 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352262 ScopedFrameBufferBinder binder(decoder_, id_);
2263 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2264}
2265
[email protected]aa7666122011-09-02 19:45:522266GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2267 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322268}
2269
[email protected]aa7666122011-09-02 19:45:522270GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392271 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572272 group_(group),
[email protected]1d82e822013-04-10 21:32:322273 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132274 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282275 unpack_flip_y_(false),
2276 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172277 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242278 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492279 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242280 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402281 fixed_attrib_buffer_id_(0),
2282 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022283 offscreen_target_color_format_(0),
2284 offscreen_target_depth_format_(0),
2285 offscreen_target_stencil_format_(0),
2286 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562287 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052288 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132289 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462290 back_buffer_has_depth_(false),
2291 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422292 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582293 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562294 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052295 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112296 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002297 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432298 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302299 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512300 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222301 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432302 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042303 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102304 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492305 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132306 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062307 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282308 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132309 lose_context_when_out_of_memory_(false),
[email protected]cae20172012-12-07 00:06:192310 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2311 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022312 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102313 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002314 texture_state_(group_->feature_info()
2315 ->workarounds()
2316 .texsubimage2d_faster_than_teximage2d),
vmiura1c2b1de2014-09-19 19:03:242317 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2318 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
2319 gpu_trace_level_(2),
2320 gpu_trace_commands_(false),
2321 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102322 validation_texture_(0),
2323 validation_fbo_multisample_(0),
2324 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572325 DCHECK(group);
2326
[email protected]b1122982010-05-17 23:04:242327 attrib_0_value_.v[0] = 0.0f;
2328 attrib_0_value_.v[1] = 0.0f;
2329 attrib_0_value_.v[2] = 0.0f;
2330 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152331
[email protected]c2f8c8402010-12-06 18:07:242332 // The shader translator is used for WebGL even when running on EGL
2333 // because additional restrictions are needed (like only enabling
2334 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562335 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2336 // the empty string to CompileShader and this is not a valid shader.
2337 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002338 CommandLine::ForCurrentProcess()->HasSwitch(
2339 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152340 use_shader_translator_ = false;
2341 }
[email protected]96449d2c2009-11-25 00:01:322342}
2343
[email protected]80eb6b52012-01-19 00:14:412344GLES2DecoderImpl::~GLES2DecoderImpl() {
2345}
2346
[email protected]c410da802011-03-14 19:17:412347bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382348 const scoped_refptr<gfx::GLSurface>& surface,
2349 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232350 bool offscreen,
[email protected]c410da802011-03-14 19:17:412351 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292352 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242353 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322354 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382355 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302356 DCHECK(!context_.get());
2357
jbaumana7604692014-10-17 02:00:392358 surfaceless_ = surface->IsSurfaceless() && !offscreen;
achaulkcf5316f2014-09-26 19:28:422359
[email protected]55e136f2013-04-03 18:50:062360 set_initialized();
[email protected]b4af07d2014-08-20 00:11:572361 gpu_tracer_.reset(new GPUTracer(this));
[email protected]8f9b8dd2013-09-12 18:05:132362 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142363
[email protected]e844ae22012-01-14 03:36:262364 if (CommandLine::ForCurrentProcess()->HasSwitch(
2365 switches::kEnableGPUDebugging)) {
2366 set_debug(true);
2367 }
2368
[email protected]39ba4f02012-03-26 01:16:002369 if (CommandLine::ForCurrentProcess()->HasSwitch(
2370 switches::kEnableGPUCommandLogging)) {
2371 set_log_commands(true);
2372 }
2373
[email protected]062c38b2012-01-18 03:25:102374 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2375 switches::kCompileShaderAlwaysSucceeds);
2376
[email protected]f62a5ab2011-05-23 20:34:152377
[email protected]63c9b052012-05-17 18:27:382378 // Take ownership of the context and surface. The surface can be replaced with
2379 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382380 context_ = context;
[email protected]63c9b052012-05-17 18:27:382381 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182382
[email protected]65f7efe2013-11-28 03:11:472383 ContextCreationAttribHelper attrib_parser;
2384 if (!attrib_parser.Parse(attribs))
2385 return false;
2386
[email protected]828a3932014-04-02 14:43:132387 // Save the loseContextWhenOutOfMemory context creation attribute.
2388 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402389 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132390
[email protected]65f7efe2013-11-28 03:11:472391 // If the failIfMajorPerformanceCaveat context creation attribute was true
2392 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402393 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472394 feature_info_->feature_flags().is_swiftshader) {
2395 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2396 Destroy(true);
2397 return false;
2398 }
2399
[email protected]956aec52013-09-05 15:41:192400 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222401 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392402 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422403 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382404 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032405 return false;
[email protected]a3ded6d2010-10-19 06:44:392406 }
[email protected]b64c24952012-04-19 03:20:272407 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282408
[email protected]e82fb792011-09-22 00:33:292409 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502410
[email protected]af6380962012-11-29 23:24:132411 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482412 vertex_array_manager_.reset(new VertexArrayManager());
2413
2414 GLuint default_vertex_attrib_service_id = 0;
2415 if (features().native_vertex_array_object) {
2416 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2417 glBindVertexArrayOES(default_vertex_attrib_service_id);
2418 }
2419
2420 state_.default_vertex_attrib_manager =
2421 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2422
[email protected]81f20a622014-04-18 01:54:522423 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002424 group_->max_vertex_attribs(),
2425 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462426
[email protected]81f20a622014-04-18 01:54:522427 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572428 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322429
[email protected]7cd76fd2013-06-02 21:11:112430 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532431
[email protected]b63f1d62014-07-18 15:40:592432 image_manager_.reset(new ImageManager);
2433
[email protected]302ce6d2011-07-07 23:28:112434 util_.set_num_compressed_texture_formats(
2435 validators_->compressed_texture_format.GetValues().size());
2436
[email protected]1071e572011-02-09 20:00:122437 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2438 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2439 // OpenGL ES 2.0 does not have this issue.
2440 glEnableVertexAttribArray(0);
2441 }
[email protected]b1122982010-05-17 23:04:242442 glGenBuffersARB(1, &attrib_0_buffer_id_);
2443 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2444 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2445 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402446 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082447
[email protected]1868a342012-11-07 15:56:022448 state_.texture_units.resize(group_->max_texture_units());
2449 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492450 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312451 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492452 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152453 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492454 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072455 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492456 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572457 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312458 }
[email protected]62e155e2012-10-23 22:43:152459 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492460 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072461 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492462 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572463 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462464 }
[email protected]370eaf12013-05-18 09:19:492465 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2466 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572467 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492468 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2469 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572470 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152471 }
[email protected]00f893d2010-08-24 18:55:492472 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502473 CHECK_GL_ERROR();
2474
[email protected]069944672012-04-25 20:52:232475 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402476 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542477 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022478 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432479 // max_sample_count must be initialized to a sane value. If
2480 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2481 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022482 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402483 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022484 max_sample_count);
2485 } else {
2486 offscreen_target_samples_ = 1;
2487 }
[email protected]845c4e32014-08-13 11:50:402488 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022489
2490 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2491 const bool rgb8_supported =
2492 context_->HasExtension("GL_OES_rgb8_rgba8");
2493 // The only available default render buffer formats in GLES2 have very
2494 // little precision. Don't enable multisampling unless 8-bit render
2495 // buffer formats are available--instead fall back to 8-bit textures.
2496 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402497 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022498 GL_RGBA8 : GL_RGB8;
2499 } else {
2500 offscreen_target_samples_ = 1;
[email protected]845c4e32014-08-13 11:50:402501 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022502 GL_RGBA : GL_RGB;
2503 }
2504
2505 // ANGLE only supports packed depth/stencil formats, so use it if it is
2506 // available.
2507 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182508 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272509 VLOG(1) << "GL_OES_packed_depth_stencil "
2510 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402511 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002512 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022513 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2514 offscreen_target_stencil_format_ = 0;
2515 } else {
2516 // It may be the case that this depth/stencil combination is not
2517 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402518 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022519 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402520 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022521 GL_STENCIL_INDEX8 : 0;
2522 }
2523 } else {
[email protected]845c4e32014-08-13 11:50:402524 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022525 GL_RGBA : GL_RGB;
2526
2527 // If depth is requested at all, use the packed depth stencil format if
2528 // it's available, as some desktop GL drivers don't support any non-packed
2529 // formats for depth attachments.
2530 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182531 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272532 VLOG(1) << "GL_EXT_packed_depth_stencil "
2533 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022534
[email protected]845c4e32014-08-13 11:50:402535 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002536 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022537 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2538 offscreen_target_stencil_format_ = 0;
2539 } else {
[email protected]845c4e32014-08-13 11:50:402540 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022541 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402542 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022543 GL_STENCIL_INDEX : 0;
2544 }
2545 }
2546
[email protected]845c4e32014-08-13 11:50:402547 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]97872062010-11-03 19:07:052548 GL_RGBA : GL_RGB;
2549
[email protected]6217d392010-03-25 22:08:352550 // Create the target frame buffer. This is the one that the client renders
2551 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352552 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352553 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022554 // Due to GLES2 format limitations, either the color texture (for
2555 // non-multisampling) or the color render buffer (for multisampling) will be
2556 // attached to the offscreen frame buffer. The render buffer has more
2557 // limited formats available to it, but the texture can't do multisampling.
2558 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402559 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2560 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022561 offscreen_target_color_render_buffer_->Create();
2562 } else {
[email protected]ce296892013-10-24 22:04:362563 offscreen_target_color_texture_.reset(new BackTexture(
2564 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022565 offscreen_target_color_texture_->Create();
2566 }
[email protected]d5a28e452013-10-10 01:01:402567 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2568 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152569 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402570 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2571 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152572 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352573
2574 // Create the saved offscreen texture. The target frame buffer is copied
2575 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352576 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022577 offscreen_saved_frame_buffer_->Create();
2578 //
[email protected]ce296892013-10-24 22:04:362579 offscreen_saved_color_texture_.reset(new BackTexture(
2580 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352581 offscreen_saved_color_texture_->Create();
2582
[email protected]6217d392010-03-25 22:08:352583 // Allocate the render buffers at their initial size and check the status
2584 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592585 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012586 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382587 Destroy(true);
[email protected]6217d392010-03-25 22:08:352588 return false;
2589 }
2590
[email protected]678a73f2012-12-19 19:22:092591 // Allocate the offscreen saved color texture.
2592 DCHECK(offscreen_saved_color_format_);
2593 offscreen_saved_color_texture_->AllocateStorage(
2594 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2595
2596 offscreen_saved_frame_buffer_->AttachRenderTexture(
2597 offscreen_saved_color_texture_.get());
2598 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2599 GL_FRAMEBUFFER_COMPLETE) {
2600 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2601 Destroy(true);
2602 return false;
2603 }
2604
[email protected]6217d392010-03-25 22:08:352605 // Bind to the new default frame buffer (the offscreen target frame buffer).
2606 // This should now be associated with ID zero.
2607 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102608 } else {
2609 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2610 // These are NOT if the back buffer has these proprorties. They are
2611 // if we want the command buffer to enforce them regardless of what
2612 // the real backbuffer is assuming the real back buffer gives us more than
2613 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2614 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2615 // can't do anything about that.
2616
achaulkcf5316f2014-09-26 19:28:422617 if (!surfaceless_) {
2618 GLint v = 0;
2619 glGetIntegerv(GL_ALPHA_BITS, &v);
2620 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2621 // the user requested RGB then RGB. If the user did not specify a
2622 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2623 back_buffer_color_format_ =
2624 (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
2625 glGetIntegerv(GL_DEPTH_BITS, &v);
2626 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
2627 glGetIntegerv(GL_STENCIL_BITS, &v);
2628 back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
2629 }
[email protected]6217d392010-03-25 22:08:352630 }
2631
[email protected]76a0ee102010-04-07 21:03:042632 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2633 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2634 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372635 // mailing list archives. It also implicitly enables the desktop GL
2636 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2637 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152638 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2639 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372640 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152641 }
[email protected]de17df392010-04-23 21:09:412642
[email protected]706b69f2012-07-27 04:59:302643 has_robustness_extension_ =
2644 context->HasExtension("GL_ARB_robustness") ||
2645 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432646
[email protected]c2f8c8402010-12-06 18:07:242647 if (!InitializeShaderTranslator()) {
2648 return false;
[email protected]de17df392010-04-23 21:09:412649 }
[email protected]76a0ee102010-04-07 21:03:042650
[email protected]e259eb412012-10-13 05:47:242651 state_.viewport_width = size.width();
2652 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282653
[email protected]5904806b2012-05-08 18:10:222654 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282655 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022656 viewport_max_width_ = viewport_params[0];
2657 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282658
[email protected]88a61bf2012-10-27 13:00:422659 state_.scissor_width = state_.viewport_width;
2660 state_.scissor_height = state_.viewport_height;
2661
[email protected]11f3e702012-06-19 19:00:012662 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342663 state_.InitCapabilities(NULL);
2664 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242665 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012666
2667 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2668 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2669 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2670 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2671
achaulkcf5316f2014-09-26 19:28:422672 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002673#if defined(OS_ANDROID)
2674 // Temporary workaround for Android WebView because this clear ignores the
2675 // clip and corrupts that external UI of the App. Not calling glClear is ok
2676 // because the system already clears the buffer before each draw. Proper
2677 // fix might be setting the scissor clip properly before initialize. See
2678 // crbug.com/259023 for details.
2679 call_gl_clear = surface_->GetHandle();
2680#endif
2681 if (call_gl_clear) {
2682 // Clear the backbuffer.
2683 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2684 }
[email protected]561cc0a62013-05-07 18:34:452685
[email protected]b381ee32014-03-22 02:43:432686 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2687 if (feature_info_->workarounds()
2688 .disable_post_sub_buffers_for_onscreen_surfaces &&
2689 !surface->IsOffscreen())
2690 supports_post_sub_buffer_ = false;
2691
[email protected]62e155e2012-10-23 22:43:152692 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462693 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2694 }
[email protected]dd289a5d62012-06-30 22:05:462695
[email protected]9b753992013-04-27 02:04:412696 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2697 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242698 }
[email protected]85cb4682013-04-20 00:54:242699
[email protected]97419c02013-04-10 02:52:382700 // Only compositor contexts are known to use only the subset of GL
2701 // that can be safely migrated between the iGPU and the dGPU. Mark
2702 // those contexts as safe to forcibly transition between the GPUs.
2703 // http://crbug.com/180876, http://crbug.com/227228
2704 if (!offscreen)
2705 context_->SetSafeToForceGpuSwitch();
2706
[email protected]85a4ac22013-05-31 01:58:472707 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072708 AsyncPixelTransferManager::Create(context.get()));
2709 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592710
[email protected]91c94eb2013-10-22 10:32:542711 framebuffer_manager()->AddObserver(this);
2712
[email protected]246a70452010-03-05 21:53:502713 return true;
[email protected]96449d2c2009-11-25 00:01:322714}
2715
[email protected]6d668892013-12-04 21:37:122716Capabilities GLES2DecoderImpl::GetCapabilities() {
2717 DCHECK(initialized());
2718
2719 Capabilities caps;
2720
[email protected]6d668892013-12-04 21:37:122721 caps.egl_image_external =
2722 feature_info_->feature_flags().oes_egl_image_external;
2723 caps.texture_format_bgra8888 =
2724 feature_info_->feature_flags().ext_texture_format_bgra8888;
2725 caps.texture_format_etc1 =
2726 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:202727 caps.texture_format_etc1_npot =
2728 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:122729 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2730 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2731 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2732 caps.discard_framebuffer =
2733 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352734 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122735
2736#if defined(OS_MACOSX)
2737 // This is unconditionally true on mac, no need to test for it at runtime.
2738 caps.iosurface = true;
2739#endif
2740
[email protected]b381ee32014-03-22 02:43:432741 caps.post_sub_buffer = supports_post_sub_buffer_;
reveman340109182014-09-30 15:36:452742 caps.image = true;
[email protected]6d668892013-12-04 21:37:122743
edfad658b2014-10-10 08:59:522744 caps.blend_minmax = feature_info_->feature_flags().ext_blend_minmax;
[email protected]6d668892013-12-04 21:37:122745 return caps;
2746}
2747
[email protected]302ce6d2011-07-07 23:28:112748void GLES2DecoderImpl::UpdateCapabilities() {
2749 util_.set_num_compressed_texture_formats(
2750 validators_->compressed_texture_format.GetValues().size());
2751 util_.set_num_shader_binary_formats(
2752 validators_->shader_binary_format.GetValues().size());
2753}
2754
[email protected]c2f8c8402010-12-06 18:07:242755bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442756 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2757
[email protected]c2f8c8402010-12-06 18:07:242758 if (!use_shader_translator_) {
2759 return true;
2760 }
2761 ShBuiltInResources resources;
2762 ShInitBuiltInResources(&resources);
2763 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2764 resources.MaxVertexUniformVectors =
2765 group_->max_vertex_uniform_vectors();
2766 resources.MaxVaryingVectors = group_->max_varying_vectors();
2767 resources.MaxVertexTextureImageUnits =
2768 group_->max_vertex_texture_image_units();
2769 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2770 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2771 resources.MaxFragmentUniformVectors =
2772 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492773 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242774 resources.MaxExpressionComplexity = 256;
2775 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042776
[email protected]46c86752013-05-21 05:08:392777 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212778 GLint precision = 0;
2779 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2780 range, &precision);
[email protected]448e459e2013-06-12 17:00:412781 resources.FragmentPrecisionHigh =
2782 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142783
[email protected]f0d74742011-10-03 16:31:042784 if (force_webgl_glsl_validation_) {
2785 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492786 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132787 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442788 if (!draw_buffers_explicitly_enabled_)
2789 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:062790 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
oetuaho0decd442014-10-13 08:40:462791 resources.NV_draw_buffers =
2792 draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
[email protected]f0d74742011-10-03 16:31:042793 } else {
2794 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152795 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462796 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152797 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062798 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152799 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492800 resources.EXT_draw_buffers =
2801 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492802 resources.EXT_frag_depth =
2803 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:062804 resources.EXT_shader_texture_lod =
2805 features().ext_shader_texture_lod ? 1 : 0;
oetuaho0decd442014-10-13 08:40:462806 resources.NV_draw_buffers =
2807 features().nv_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042808 }
2809
[email protected]26b61442013-03-17 16:12:012810 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2811 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052812 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022813 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:052814 else
2815 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122816 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2817 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2818 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212819 int driver_bug_workarounds = 0;
2820 if (workarounds().needs_glsl_built_in_function_emulation)
2821 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542822 if (workarounds().init_gl_position_in_vertex_shader)
2823 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112824 if (workarounds().unfold_short_circuit_as_ternary_operation)
2825 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:052826 if (workarounds().init_varyings_without_static_use)
2827 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:062828 if (workarounds().unroll_for_loop_with_sampler_array_index)
2829 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:252830 if (workarounds().scalarize_vec_and_mat_constructor_args)
2831 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:272832 if (workarounds().regenerate_struct_names)
2833 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
[email protected]87fb6ab2012-06-13 22:28:042834
[email protected]03cef9b2014-04-03 15:58:142835 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262836 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:142837 shader_spec,
2838 &resources,
[email protected]a6739bc2013-09-07 04:45:212839 implementation_type,
2840 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042841 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242842 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382843 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242844 return false;
2845 }
[email protected]87fb6ab2012-06-13 22:28:042846
[email protected]03cef9b2014-04-03 15:58:142847 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262848 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:142849 shader_spec,
2850 &resources,
[email protected]a6739bc2013-09-07 04:45:212851 implementation_type,
2852 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042853 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242854 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382855 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242856 return false;
2857 }
2858 return true;
2859}
2860
[email protected]ae51d192010-04-27 00:48:032861bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472862 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352863 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032864 return false;
2865 }
2866 }
[email protected]40d90a22013-04-09 03:39:552867 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032868 glGenBuffersARB(n, service_ids.get());
2869 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352870 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032871 }
2872 return true;
2873}
2874
2875bool GLES2DecoderImpl::GenFramebuffersHelper(
2876 GLsizei n, const GLuint* client_ids) {
2877 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352878 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032879 return false;
2880 }
2881 }
[email protected]40d90a22013-04-09 03:39:552882 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032883 glGenFramebuffersEXT(n, service_ids.get());
2884 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352885 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032886 }
2887 return true;
2888}
2889
2890bool GLES2DecoderImpl::GenRenderbuffersHelper(
2891 GLsizei n, const GLuint* client_ids) {
2892 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352893 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032894 return false;
2895 }
2896 }
[email protected]40d90a22013-04-09 03:39:552897 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032898 glGenRenderbuffersEXT(n, service_ids.get());
2899 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352900 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032901 }
2902 return true;
2903}
2904
2905bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2906 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352907 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032908 return false;
2909 }
2910 }
[email protected]40d90a22013-04-09 03:39:552911 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032912 glGenTextures(n, service_ids.get());
2913 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352914 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032915 }
2916 return true;
2917}
2918
2919void GLES2DecoderImpl::DeleteBuffersHelper(
2920 GLsizei n, const GLuint* client_ids) {
2921 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212922 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102923 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242924 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112925 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242926 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102927 }
[email protected]ed9f9cd2013-02-27 21:12:352928 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032929 }
[email protected]a93bb842010-02-16 23:03:472930 }
[email protected]07f54fcc2009-12-22 02:46:302931}
2932
[email protected]ae51d192010-04-27 00:48:032933void GLES2DecoderImpl::DeleteFramebuffersHelper(
2934 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452935 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152936 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112937
[email protected]a25fa872010-03-25 02:57:582938 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352939 Framebuffer* framebuffer =
2940 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102941 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:342942 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
2943 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:442944 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:452945 GLenum target = supports_separate_framebuffer_binds ?
2946 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112947 glBindFramebufferEXT(target, GetBackbufferServiceId());
2948 }
[email protected]9d3b2e12013-10-02 01:04:342949 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
2950 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452951 GLenum target = supports_separate_framebuffer_binds ?
2952 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112953 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462954 }
[email protected]70d34263c2013-01-09 00:27:452955 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352956 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032957 }
[email protected]a25fa872010-03-25 02:57:582958 }
[email protected]07f54fcc2009-12-22 02:46:302959}
2960
[email protected]ae51d192010-04-27 00:48:032961void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2962 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452963 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152964 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582965 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352966 Renderbuffer* renderbuffer =
2967 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102968 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112969 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242970 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102971 }
2972 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452973 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342974 if (framebuffer_state_.bound_read_framebuffer.get()) {
2975 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112976 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102977 }
[email protected]9d3b2e12013-10-02 01:04:342978 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2979 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112980 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102981 }
2982 } else {
[email protected]9d3b2e12013-10-02 01:04:342983 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2984 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112985 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102986 }
2987 }
[email protected]c986af502013-08-14 01:04:442988 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:352989 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032990 }
[email protected]a25fa872010-03-25 02:57:582991 }
[email protected]07f54fcc2009-12-22 02:46:302992}
2993
[email protected]ae51d192010-04-27 00:48:032994void GLES2DecoderImpl::DeleteTexturesHelper(
2995 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452996 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152997 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472998 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:492999 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3000 if (texture_ref) {
3001 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103002 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443003 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463004 }
[email protected]370eaf12013-05-18 09:19:493005 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023006 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493007 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103008 }
3009 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453010 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343011 if (framebuffer_state_.bound_read_framebuffer.get()) {
3012 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113013 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103014 }
[email protected]9d3b2e12013-10-02 01:04:343015 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3016 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113017 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103018 }
3019 } else {
[email protected]9d3b2e12013-10-02 01:04:343020 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3021 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113022 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103023 }
3024 }
[email protected]e51bdf32011-11-23 22:21:463025#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073026 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463027 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3028 ReleaseIOSurfaceForTexture(service_id);
3029 }
3030#endif
[email protected]ed9f9cd2013-02-27 21:12:353031 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033032 }
[email protected]a93bb842010-02-16 23:03:473033 }
[email protected]07f54fcc2009-12-22 02:46:303034}
3035
[email protected]43f28f832010-02-03 02:28:483036// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323037
[email protected]eb54a562010-01-20 21:55:183038bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343039 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383040 return false;
3041
[email protected]177d1342013-12-07 04:20:343042 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:433043 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:293044
jbauman7a059312014-10-16 19:30:543045 MaybeExitOnContextLost();
[email protected]e9f0ca82013-04-01 23:52:293046
[email protected]63c9b052012-05-17 18:27:383047 return false;
[email protected]38d139d2011-07-14 00:38:433048 }
3049
[email protected]69a8701e2013-03-07 21:31:093050 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093051
[email protected]9b753992013-04-27 02:04:413052 // Rebind the FBO if it was unbound by the context.
3053 if (workarounds().unbind_fbo_on_context_switch)
3054 RestoreFramebufferBindings();
3055
[email protected]c986af502013-08-14 01:04:443056 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493057
[email protected]69a8701e2013-03-07 21:31:093058 return true;
3059}
3060
3061void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553062 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323063 if (engine() && query_manager_.get())
3064 query_manager_->ProcessPendingTransferQueries();
3065
[email protected]5b3a8e02013-03-13 05:36:443066 // TODO(epenner): Is there a better place to do this?
3067 // This needs to occur before we execute any batch of commands
3068 // from the client, as the client may have recieved an async
3069 // completion while issuing those commands.
3070 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483071 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183072}
3073
[email protected]8e3e0662010-08-23 18:46:303074static void RebindCurrentFramebuffer(
3075 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063076 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243077 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063078 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463079
[email protected]a3783712012-01-20 22:18:243080 if (framebuffer_id == 0) {
3081 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303082 }
[email protected]297ca1c2011-06-20 23:08:463083
[email protected]8e3e0662010-08-23 18:46:303084 glBindFramebufferEXT(target, framebuffer_id);
3085}
3086
3087void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443088 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463089
[email protected]62e155e2012-10-23 22:43:153090 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303091 RebindCurrentFramebuffer(
3092 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343093 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243094 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303095 } else {
3096 RebindCurrentFramebuffer(
3097 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343098 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243099 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303100 RebindCurrentFramebuffer(
3101 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343102 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243103 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303104 }
[email protected]70d34263c2013-01-09 00:27:453105 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303106}
3107
[email protected]0d6bfdc2011-11-02 01:32:203108bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353109 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203110 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103111 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423112 if (surfaceless_)
3113 return false;
[email protected]60f22d32012-12-12 00:31:583114 if (backbuffer_needs_clear_bits_) {
3115 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323116 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453117 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583118 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473119 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3120 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583121 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453122 state_.SetDeviceDepthMask(GL_TRUE);
3123 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423124 bool reset_draw_buffer = false;
3125 if ((backbuffer_needs_clear_bits_ | GL_COLOR_BUFFER_BIT) != 0 &&
3126 group_->draw_buffer() == GL_NONE) {
3127 reset_draw_buffer = true;
3128 GLenum buf = GL_BACK;
3129 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3130 buf = GL_COLOR_ATTACHMENT0;
3131 glDrawBuffersARB(1, &buf);
3132 }
[email protected]60f22d32012-12-12 00:31:583133 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423134 if (reset_draw_buffer) {
3135 GLenum buf = GL_NONE;
3136 glDrawBuffersARB(1, &buf);
3137 }
[email protected]60f22d32012-12-12 00:31:583138 backbuffer_needs_clear_bits_ = 0;
3139 RestoreClearState();
3140 }
[email protected]0d6bfdc2011-11-02 01:32:203141 return true;
3142 }
3143
[email protected]968351b2011-12-20 08:26:513144 if (framebuffer_manager()->IsComplete(framebuffer)) {
3145 return true;
3146 }
3147
[email protected]0d6bfdc2011-11-02 01:32:203148 GLenum completeness = framebuffer->IsPossiblyComplete();
3149 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513150 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433151 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273152 return false;
3153 }
[email protected]0d6bfdc2011-11-02 01:32:203154
3155 // Are all the attachments cleared?
3156 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3157 texture_manager()->HaveUnclearedMips()) {
3158 if (!framebuffer->IsCleared()) {
3159 // Can we clear them?
[email protected]73276522012-11-09 05:50:203160 if (framebuffer->GetStatus(texture_manager(), target) !=
3161 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513162 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433163 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3164 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203165 return false;
3166 }
3167 ClearUnclearedAttachments(target, framebuffer);
3168 }
3169 }
3170
[email protected]968351b2011-12-20 08:26:513171 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203172 if (framebuffer->GetStatus(texture_manager(), target) !=
3173 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513174 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433175 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3176 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513177 return false;
3178 }
3179 framebuffer_manager()->MarkAsComplete(framebuffer);
3180 }
3181
[email protected]0d6bfdc2011-11-02 01:32:203182 // NOTE: At this point we don't know if the framebuffer is complete but
3183 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273184 return true;
3185}
3186
[email protected]0d6bfdc2011-11-02 01:32:203187bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153188 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513189 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343190 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3191 func_name);
[email protected]28718a92013-04-04 12:12:513192
3193 if (valid)
3194 OnUseFramebuffer();
3195
3196 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203197 }
[email protected]9d3b2e12013-10-02 01:04:343198 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113199 GL_DRAW_FRAMEBUFFER_EXT,
3200 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343201 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113202 GL_READ_FRAMEBUFFER_EXT,
3203 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203204}
3205
[email protected]2ea5950d2014-07-09 18:20:343206bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3207 const char* func_name) {
3208 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3209 framebuffer_state_.bound_read_framebuffer.get() :
3210 framebuffer_state_.bound_draw_framebuffer.get();
3211 if (!framebuffer)
3212 return true;
3213 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3214 LOCAL_SET_GL_ERROR(
3215 GL_INVALID_OPERATION, func_name, "no color image attached");
3216 return false;
3217 }
3218 return true;
3219}
3220
zmo383512cf2014-10-14 00:11:003221bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
3222 TextureRef* texture, GLint level) {
3223 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3224 framebuffer_state_.bound_read_framebuffer.get() :
3225 framebuffer_state_.bound_draw_framebuffer.get();
3226 if (!framebuffer)
3227 return false;
3228 const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
3229 GL_COLOR_ATTACHMENT0);
3230 if (!attachment)
3231 return false;
3232 return attachment->FormsFeedbackLoop(texture, level);
3233}
3234
[email protected]8e3e0662010-08-23 18:46:303235gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353236 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453237 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203238 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353239 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203240 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263241 if (attachment) {
3242 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503243 }
[email protected]9edc6b22010-12-23 02:00:263244 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023245 } else if (offscreen_target_frame_buffer_.get()) {
3246 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353247 } else {
[email protected]f62a5ab2011-05-23 20:34:153248 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023249 }
[email protected]246a70452010-03-05 21:53:503250}
3251
[email protected]68586372013-12-11 01:27:593252GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3253 Framebuffer* framebuffer =
3254 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3255 if (framebuffer != NULL) {
3256 return framebuffer->GetColorAttachmentTextureType();
3257 } else {
3258 return GL_UNSIGNED_BYTE;
3259 }
3260}
3261
[email protected]9edc6b22010-12-23 02:00:263262GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353263 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453264 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203265 if (framebuffer != NULL) {
3266 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463267 } else if (offscreen_target_frame_buffer_.get()) {
3268 return offscreen_target_color_format_;
3269 } else {
3270 return back_buffer_color_format_;
3271 }
3272}
3273
3274GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353275 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453276 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203277 if (framebuffer != NULL) {
3278 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263279 } else if (offscreen_target_frame_buffer_.get()) {
3280 return offscreen_target_color_format_;
3281 } else {
[email protected]32fe9aa2011-01-21 23:47:133282 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263283 }
3284}
3285
[email protected]9a5afa432011-07-22 18:16:393286void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513287 if (!offscreen_saved_color_texture_info_.get())
3288 return;
3289 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3290 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3291 texture_manager()->SetLevelInfo(
3292 offscreen_saved_color_texture_info_.get(),
3293 GL_TEXTURE_2D,
3294 0, // level
3295 GL_RGBA,
3296 offscreen_size_.width(),
3297 offscreen_size_.height(),
3298 1, // depth
3299 0, // border
3300 GL_RGBA,
3301 GL_UNSIGNED_BYTE,
3302 true);
[email protected]737191ee72014-03-09 08:02:423303 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513304 "UpdateParentTextureInfo",
3305 GetErrorState(),
3306 offscreen_saved_color_texture_info_.get(),
3307 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263308 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423309 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513310 "UpdateParentTextureInfo",
3311 GetErrorState(),
3312 offscreen_saved_color_texture_info_.get(),
3313 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263314 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423315 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513316 "UpdateParentTextureInfo",
3317 GetErrorState(),
3318 offscreen_saved_color_texture_info_.get(),
3319 GL_TEXTURE_WRAP_S,
3320 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423321 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513322 "UpdateParentTextureInfo",
3323 GetErrorState(),
3324 offscreen_saved_color_texture_info_.get(),
3325 GL_TEXTURE_WRAP_T,
3326 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443327 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3328 &state_, target);
[email protected]2ad674132013-06-05 07:48:513329 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353330}
3331
[email protected]799b4b22011-08-22 17:09:593332void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073333 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523334 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003335}
3336
[email protected]1d82e822013-04-10 21:32:323337Logger* GLES2DecoderImpl::GetLogger() {
3338 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523339}
3340
[email protected]cac16542014-01-15 17:53:513341void GLES2DecoderImpl::BeginDecoding() {
3342 gpu_tracer_->BeginDecoding();
3343 gpu_trace_commands_ = gpu_tracer_->IsTracing();
vmiura1c2b1de2014-09-19 19:03:243344 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3345 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513346}
3347
3348void GLES2DecoderImpl::EndDecoding() {
3349 gpu_tracer_->EndDecoding();
3350}
3351
[email protected]d3eba342013-04-18 21:11:503352ErrorState* GLES2DecoderImpl::GetErrorState() {
3353 return state_.GetErrorState();
3354}
3355
[email protected]e3932abb2013-03-13 00:01:373356void GLES2DecoderImpl::SetShaderCacheCallback(
3357 const ShaderCacheCallback& callback) {
3358 shader_cache_callback_ = callback;
3359}
3360
[email protected]840a7e462013-02-27 01:29:513361void GLES2DecoderImpl::SetWaitSyncPointCallback(
3362 const WaitSyncPointCallback& callback) {
3363 wait_sync_point_callback_ = callback;
3364}
3365
[email protected]85a4ac22013-05-31 01:58:473366AsyncPixelTransferManager*
3367 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3368 return async_pixel_transfer_manager_.get();
3369}
3370
3371void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3372 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593373}
3374
[email protected]498b5c072013-06-04 19:30:073375void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3376 AsyncPixelTransferManager* manager) {
3377 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3378}
3379
[email protected]1318e922010-09-17 22:03:163380bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3381 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493382 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3383 if (texture_ref) {
3384 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163385 return true;
3386 }
3387 return false;
3388}
3389
[email protected]63b465922012-09-06 02:04:523390uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443391 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483392 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523393}
3394
3395base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443396 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483397 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523398}
3399
3400base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3401 return total_processing_commands_time_;
3402}
3403
[email protected]dc25dda2012-09-27 21:36:303404void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3405 total_processing_commands_time_ += time;
3406}
3407
[email protected]63c9b052012-05-17 18:27:383408void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063409 if (!initialized())
3410 return;
3411
[email protected]63c9b052012-05-17 18:27:383412 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053413
[email protected]80eb6b52012-01-19 00:14:413414 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243415 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523416 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023417 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243418 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133419 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343420 framebuffer_state_.bound_read_framebuffer = NULL;
3421 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243422 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413423
[email protected]cadac622013-06-11 16:46:363424 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513425 DCHECK(offscreen_target_color_texture_);
3426 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3427 offscreen_saved_color_texture_->id());
3428 offscreen_saved_color_texture_->Invalidate();
3429 offscreen_saved_color_texture_info_ = NULL;
3430 }
[email protected]eadc96792010-10-27 19:39:393431 if (have_context) {
[email protected]c322e882012-05-23 18:06:183432 if (copy_texture_CHROMIUM_.get()) {
3433 copy_texture_CHROMIUM_->Destroy();
3434 copy_texture_CHROMIUM_.reset();
3435 }
[email protected]43410e92012-04-20 17:06:283436
[email protected]7cd76fd2013-06-02 21:11:113437 if (state_.current_program.get()) {
3438 program_manager()->UnuseProgram(shader_manager(),
3439 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143440 }
3441
[email protected]b1122982010-05-17 23:04:243442 if (attrib_0_buffer_id_) {
3443 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3444 }
[email protected]8fbedc02010-11-18 18:43:403445 if (fixed_attrib_buffer_id_) {
3446 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3447 }
[email protected]b1122982010-05-17 23:04:243448
[email protected]4a4c18b2013-09-13 22:50:103449 if (validation_texture_) {
3450 glDeleteTextures(1, &validation_texture_);
3451 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3452 glDeleteFramebuffersEXT(1, &validation_fbo_);
3453 }
3454
[email protected]97872062010-11-03 19:07:053455 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543456 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053457 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543458 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053459 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023460 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053461 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153462 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053463 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153464 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053465 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023466 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053467 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543468 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273469 if (offscreen_resolved_frame_buffer_.get())
3470 offscreen_resolved_frame_buffer_->Destroy();
3471 if (offscreen_resolved_color_texture_.get())
3472 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053473 } else {
3474 if (offscreen_target_frame_buffer_.get())
3475 offscreen_target_frame_buffer_->Invalidate();
3476 if (offscreen_target_color_texture_.get())
3477 offscreen_target_color_texture_->Invalidate();
3478 if (offscreen_target_color_render_buffer_.get())
3479 offscreen_target_color_render_buffer_->Invalidate();
3480 if (offscreen_target_depth_render_buffer_.get())
3481 offscreen_target_depth_render_buffer_->Invalidate();
3482 if (offscreen_target_stencil_render_buffer_.get())
3483 offscreen_target_stencil_render_buffer_->Invalidate();
3484 if (offscreen_saved_frame_buffer_.get())
3485 offscreen_saved_frame_buffer_->Invalidate();
3486 if (offscreen_saved_color_texture_.get())
3487 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273488 if (offscreen_resolved_frame_buffer_.get())
3489 offscreen_resolved_frame_buffer_->Invalidate();
3490 if (offscreen_resolved_color_texture_.get())
3491 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023492 }
[email protected]83a52d032013-07-24 10:30:373493
3494 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3495 // Otherwise, we can leak objects. http://crbug.com/258772.
3496 // state_.current_program must be reset before group_ is reset because
3497 // the later deletes the ProgramManager object that referred by
3498 // state_.current_program object.
3499 state_.current_program = NULL;
3500
[email protected]43410e92012-04-20 17:06:283501 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053502
[email protected]882ba1e22012-03-08 19:02:533503 if (query_manager_.get()) {
3504 query_manager_->Destroy(have_context);
3505 query_manager_.reset();
3506 }
3507
[email protected]944b62f32012-09-27 02:20:463508 if (vertex_array_manager_ .get()) {
3509 vertex_array_manager_->Destroy(have_context);
3510 vertex_array_manager_.reset();
3511 }
3512
[email protected]d2eaf52f2014-07-31 15:01:243513 if (image_manager_.get()) {
3514 image_manager_->Destroy(have_context);
3515 image_manager_.reset();
3516 }
3517
[email protected]97872062010-11-03 19:07:053518 offscreen_target_frame_buffer_.reset();
3519 offscreen_target_color_texture_.reset();
3520 offscreen_target_color_render_buffer_.reset();
3521 offscreen_target_depth_render_buffer_.reset();
3522 offscreen_target_stencil_render_buffer_.reset();
3523 offscreen_saved_frame_buffer_.reset();
3524 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273525 offscreen_resolved_frame_buffer_.reset();
3526 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463527
[email protected]03cef9b2014-04-03 15:58:143528 // Need to release these before releasing |group_| which may own the
3529 // ShaderTranslatorCache.
3530 fragment_translator_ = NULL;
3531 vertex_translator_ = NULL;
3532
[email protected]85a4ac22013-05-31 01:58:473533 // Should destroy the transfer manager before the texture manager held
3534 // by the context group.
3535 async_pixel_transfer_manager_.reset();
3536
[email protected]7cd76fd2013-06-02 21:11:113537 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393538 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233539 group_->Destroy(this, have_context);
3540 group_ = NULL;
3541 }
3542
3543 if (context_.get()) {
3544 context_->ReleaseCurrent(NULL);
3545 context_ = NULL;
3546 }
3547
[email protected]e51bdf32011-11-23 22:21:463548#if defined(OS_MACOSX)
3549 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3550 it != texture_to_io_surface_map_.end(); ++it) {
3551 CFRelease(it->second);
3552 }
3553 texture_to_io_surface_map_.clear();
3554#endif
[email protected]96449d2c2009-11-25 00:01:323555}
3556
[email protected]63c9b052012-05-17 18:27:383557void GLES2DecoderImpl::SetSurface(
3558 const scoped_refptr<gfx::GLSurface>& surface) {
3559 DCHECK(context_->IsCurrent(NULL));
3560 DCHECK(surface_.get());
3561 surface_ = surface;
3562 RestoreCurrentFramebufferBindings();
3563}
3564
[email protected]aba551b2014-02-08 03:38:323565void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3566 if (!offscreen_saved_color_texture_.get()) {
3567 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3568 return;
3569 }
[email protected]2ad674132013-06-05 07:48:513570 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243571 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073572 offscreen_saved_color_texture_info_ = TextureRef::Create(
3573 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513574 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3575 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393576 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243577 }
[email protected]aba551b2014-02-08 03:38:323578 mailbox_manager()->ProduceTexture(
3579 GL_TEXTURE_2D, mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243580}
3581
[email protected]799b4b22011-08-22 17:09:593582bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3583 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3584 if (!is_offscreen) {
3585 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3586 << " with an onscreen framebuffer.";
3587 return false;
3588 }
3589
3590 if (offscreen_size_ == size)
3591 return true;
3592
3593 offscreen_size_ = size;
3594 int w = offscreen_size_.width();
3595 int h = offscreen_size_.height();
3596 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3597 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3598 << "to allocate storage due to excessive dimensions.";
3599 return false;
3600 }
3601
3602 // Reallocate the offscreen target buffers.
3603 DCHECK(offscreen_target_color_format_);
3604 if (IsOffscreenBufferMultisampled()) {
3605 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253606 feature_info_.get(),
3607 offscreen_size_,
3608 offscreen_target_color_format_,
3609 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593610 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3611 << "to allocate storage for offscreen target color buffer.";
3612 return false;
3613 }
3614 } else {
3615 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093616 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593617 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3618 << "to allocate storage for offscreen target color texture.";
3619 return false;
3620 }
3621 }
3622 if (offscreen_target_depth_format_ &&
3623 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253624 feature_info_.get(),
3625 offscreen_size_,
3626 offscreen_target_depth_format_,
3627 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593628 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3629 << "to allocate storage for offscreen target depth buffer.";
3630 return false;
3631 }
3632 if (offscreen_target_stencil_format_ &&
3633 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253634 feature_info_.get(),
3635 offscreen_size_,
3636 offscreen_target_stencil_format_,
3637 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593638 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3639 << "to allocate storage for offscreen target stencil buffer.";
3640 return false;
3641 }
3642
3643 // Attach the offscreen target buffers to the target frame buffer.
3644 if (IsOffscreenBufferMultisampled()) {
3645 offscreen_target_frame_buffer_->AttachRenderBuffer(
3646 GL_COLOR_ATTACHMENT0,
3647 offscreen_target_color_render_buffer_.get());
3648 } else {
3649 offscreen_target_frame_buffer_->AttachRenderTexture(
3650 offscreen_target_color_texture_.get());
3651 }
3652 if (offscreen_target_depth_format_) {
3653 offscreen_target_frame_buffer_->AttachRenderBuffer(
3654 GL_DEPTH_ATTACHMENT,
3655 offscreen_target_depth_render_buffer_.get());
3656 }
3657 const bool packed_depth_stencil =
3658 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3659 if (packed_depth_stencil) {
3660 offscreen_target_frame_buffer_->AttachRenderBuffer(
3661 GL_STENCIL_ATTACHMENT,
3662 offscreen_target_depth_render_buffer_.get());
3663 } else if (offscreen_target_stencil_format_) {
3664 offscreen_target_frame_buffer_->AttachRenderBuffer(
3665 GL_STENCIL_ATTACHMENT,
3666 offscreen_target_stencil_render_buffer_.get());
3667 }
3668
3669 if (offscreen_target_frame_buffer_->CheckStatus() !=
3670 GL_FRAMEBUFFER_COMPLETE) {
3671 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3672 << "because offscreen FBO was incomplete.";
3673 return false;
3674 }
3675
3676 // Clear the target frame buffer.
3677 {
3678 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3679 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323680 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453681 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593682 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473683 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3684 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:593685 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:453686 state_.SetDeviceDepthMask(GL_TRUE);
3687 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:593688 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3689 RestoreClearState();
3690 }
[email protected]d85ef76d2011-09-08 22:21:433691
3692 // Destroy the offscreen resolved framebuffers.
3693 if (offscreen_resolved_frame_buffer_.get())
3694 offscreen_resolved_frame_buffer_->Destroy();
3695 if (offscreen_resolved_color_texture_.get())
3696 offscreen_resolved_color_texture_->Destroy();
3697 offscreen_resolved_color_texture_.reset();
3698 offscreen_resolved_frame_buffer_.reset();
3699
[email protected]799b4b22011-08-22 17:09:593700 return true;
[email protected]6217d392010-03-25 22:08:353701}
3702
vmiuracd108592014-09-08 14:36:343703error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
3704 const void* cmd_data) {
3705 const gles2::cmds::ResizeCHROMIUM& c =
3706 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:443707 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023708 return error::kDeferCommandUntilLater;
3709
[email protected]799b4b22011-08-22 17:09:593710 GLuint width = static_cast<GLuint>(c.width);
3711 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073712 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593713 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413714
3715 width = std::max(1U, width);
3716 height = std::max(1U, height);
3717
[email protected]a0d989162011-11-22 13:15:073718#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3719 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003720 // Make sure that we are done drawing to the back buffer before resizing.
3721 glFinish();
3722#endif
[email protected]799b4b22011-08-22 17:09:593723 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3724 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493725 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3726 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3727 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593728 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493729 }
[email protected]7ff86b92010-11-25 17:50:003730 }
[email protected]799b4b22011-08-22 17:09:593731
[email protected]9d37f062011-11-22 01:24:523732 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073733 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443734 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493735 if (!context_->IsCurrent(surface_.get())) {
3736 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3737 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053738 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493739 }
[email protected]658f7562011-09-09 05:24:053740 }
[email protected]799b4b22011-08-22 17:09:593741
3742 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393743}
3744
[email protected]96449d2c2009-11-25 00:01:323745const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3746 if (command_id > kStartPoint && command_id < kNumCommands) {
3747 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3748 }
3749 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3750}
3751
vmiura8266ca72014-09-09 21:37:003752// Decode a command, and call the corresponding GL functions.
3753// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
3754// of commands at once, and is now only used for tests that need to track
3755// individual commands.
3756error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
3757 unsigned int arg_count,
3758 const void* cmd_data) {
3759 return DoCommands(1, cmd_data, arg_count + 1, 0);
3760}
3761
3762// Decode multiple commands, and call the corresponding GL functions.
3763// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
3764// changed by a (malicious) client at any time, so if validation has to happen,
3765// it should operate on a copy of them.
3766// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
3767// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:243768template <bool DebugImpl>
3769error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
3770 const void* buffer,
3771 int num_entries,
3772 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:003773 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:143774 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:003775 const CommandBufferEntry* cmd_data =
3776 static_cast<const CommandBufferEntry*>(buffer);
3777 int process_pos = 0;
3778 unsigned int command = 0;
3779
3780 while (process_pos < num_entries && result == error::kNoError &&
3781 commands_to_process_--) {
3782 const unsigned int size = cmd_data->value_header.size;
3783 command = cmd_data->value_header.command;
3784
3785 if (size == 0) {
3786 result = error::kInvalidSize;
3787 break;
3788 }
3789
3790 if (static_cast<int>(size) + process_pos > num_entries) {
3791 result = error::kOutOfBounds;
3792 break;
3793 }
3794
vmiura1c2b1de2014-09-19 19:03:243795 if (DebugImpl) {
3796 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3797 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:003798
vmiura1c2b1de2014-09-19 19:03:243799 if (log_commands()) {
3800 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
3801 << "cmd: " << GetCommandName(command);
3802 }
vmiura8266ca72014-09-09 21:37:003803 }
3804
3805 const unsigned int arg_count = size - 1;
3806 unsigned int command_index = command - kStartPoint - 1;
3807 if (command_index < arraysize(command_info)) {
3808 const CommandInfo& info = command_info[command_index];
3809 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3810 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3811 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
3812 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:243813 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:003814 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3815 doing_gpu_trace = true;
3816 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3817 }
[email protected]cac16542014-01-15 17:53:513818 }
[email protected]cac16542014-01-15 17:53:513819
vmiura8266ca72014-09-09 21:37:003820 uint32 immediate_data_size = (arg_count - info_arg_count) *
3821 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323822
vmiura8266ca72014-09-09 21:37:003823 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:513824
vmiura1c2b1de2014-09-19 19:03:243825 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:003826 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:513827
vmiura1c2b1de2014-09-19 19:03:243828 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:003829 GLenum error;
3830 while ((error = glGetError()) != GL_NO_ERROR) {
3831 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
3832 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
3833 << " : " << GetCommandName(command);
3834 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
3835 }
[email protected]b9849abf2009-11-25 19:13:193836 }
vmiura8266ca72014-09-09 21:37:003837 } else {
3838 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323839 }
3840 } else {
vmiura8266ca72014-09-09 21:37:003841 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323842 }
vmiura1c2b1de2014-09-19 19:03:243843
3844 if (DebugImpl) {
3845 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3846 GetCommandName(command));
3847 }
3848
vmiura8266ca72014-09-09 21:37:003849 if (result == error::kNoError &&
3850 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:563851 result = current_decoder_error_;
3852 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:003853 }
3854
3855 if (result != error::kDeferCommandUntilLater) {
3856 process_pos += size;
3857 cmd_data += size;
3858 }
[email protected]a3a93e7b2010-08-28 00:48:563859 }
vmiura8266ca72014-09-09 21:37:003860
3861 if (entries_processed)
3862 *entries_processed = process_pos;
3863
3864 if (error::IsError(result)) {
3865 LOG(ERROR) << "Error: " << result << " for Command "
3866 << GetCommandName(command);
3867 }
3868
[email protected]b9849abf2009-11-25 19:13:193869 return result;
[email protected]96449d2c2009-11-25 00:01:323870}
3871
vmiura1c2b1de2014-09-19 19:03:243872error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
3873 const void* buffer,
3874 int num_entries,
3875 int* entries_processed) {
3876 if (gpu_debug_commands_) {
3877 return DoCommandsImpl<true>(
3878 num_commands, buffer, num_entries, entries_processed);
3879 } else {
3880 return DoCommandsImpl<false>(
3881 num_commands, buffer, num_entries, entries_processed);
3882 }
3883}
3884
[email protected]ed9f9cd2013-02-27 21:12:353885void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3886 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503887}
3888
[email protected]ae51d192010-04-27 00:48:033889bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353890 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033891 return false;
3892 }
[email protected]96449d2c2009-11-25 00:01:323893 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033894 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353895 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323896 }
[email protected]ae51d192010-04-27 00:48:033897 return true;
[email protected]96449d2c2009-11-25 00:01:323898}
3899
[email protected]ae51d192010-04-27 00:48:033900bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353901 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033902 return false;
[email protected]96449d2c2009-11-25 00:01:323903 }
[email protected]ae51d192010-04-27 00:48:033904 GLuint service_id = glCreateShader(type);
3905 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353906 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033907 }
3908 return true;
[email protected]96449d2c2009-11-25 00:01:323909}
3910
[email protected]882ba1e22012-03-08 19:02:533911void GLES2DecoderImpl::DoFinish() {
3912 glFinish();
[email protected]5a36dc132013-07-23 23:17:553913 ProcessPendingReadPixels();
[email protected]22e3f552012-03-13 01:54:193914 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533915}
3916
3917void GLES2DecoderImpl::DoFlush() {
3918 glFlush();
[email protected]22e3f552012-03-13 01:54:193919 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533920}
3921
[email protected]3916c97e2010-02-25 03:20:503922void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453923 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023924 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513925 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533926 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503927 return;
3928 }
[email protected]e259eb412012-10-13 05:47:243929 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453930 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503931}
3932
[email protected]051b1372010-04-12 02:42:083933void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073934 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083935 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033936 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073937 buffer = GetBuffer(client_id);
3938 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353939 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:223940 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3941 "glBindBuffer",
3942 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:353943 return;
3944 }
3945
[email protected]b10492f2013-03-08 05:24:073946 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033947 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353948 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073949 buffer = GetBuffer(client_id);
[email protected]ae51d192010-04-27 00:48:033950 }
[email protected]051b1372010-04-12 02:42:083951 }
[email protected]b10492f2013-03-08 05:24:073952 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3953 if (buffer) {
3954 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513955 LOCAL_SET_GL_ERROR(
3956 GL_INVALID_OPERATION,
3957 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473958 return;
3959 }
[email protected]b10492f2013-03-08 05:24:073960 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473961 }
[email protected]96449d2c2009-11-25 00:01:323962 switch (target) {
3963 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073964 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323965 break;
3966 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073967 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323968 break;
3969 default:
[email protected]a93bb842010-02-16 23:03:473970 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323971 break;
3972 }
[email protected]051b1372010-04-12 02:42:083973 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323974}
3975
[email protected]f3b191b2013-06-19 03:43:543976bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3977 bool all_draw_buffers) {
3978 Framebuffer* framebuffer =
3979 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3980 if (!all_draw_buffers || !framebuffer) {
3981 return (GLES2Util::GetChannelsForFormat(
3982 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3983 }
3984 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:463985}
3986
3987bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353988 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453989 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203990 if (framebuffer) {
3991 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463992 }
3993 if (offscreen_target_frame_buffer_.get()) {
3994 return offscreen_target_depth_format_ != 0;
3995 }
3996 return back_buffer_has_depth_;
3997}
3998
3999bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354000 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454001 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204002 if (framebuffer) {
4003 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464004 }
4005 if (offscreen_target_frame_buffer_.get()) {
4006 return offscreen_target_stencil_format_ != 0 ||
4007 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4008 }
4009 return back_buffer_has_stencil_;
4010}
4011
4012void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444013 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454014 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4015 state_.SetDeviceColorMask(state_.color_mask_red,
4016 state_.color_mask_green,
4017 state_.color_mask_blue,
4018 state_.color_mask_alpha && have_alpha);
4019
[email protected]297ca1c2011-06-20 23:08:464020 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454021 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4022
[email protected]297ca1c2011-06-20 23:08:464023 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454024 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424025 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454026 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424027 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454028
4029 state_.SetDeviceCapabilityState(
4030 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4031 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224032 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444033 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464034 }
4035}
4036
[email protected]1868a342012-11-07 15:56:024037GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114038 return (offscreen_target_frame_buffer_.get())
4039 ? offscreen_target_frame_buffer_->id()
4040 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024041}
4042
[email protected]8875a5f2014-06-27 08:33:474043void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144044 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4045 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064046 // Restore the Framebuffer first because of bugs in Intel drivers.
4047 // Intel drivers incorrectly clip the viewport settings to
4048 // the size of the current framebuffer object.
4049 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164050 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064051}
4052
4053void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344054 GLuint service_id =
4055 framebuffer_state_.bound_draw_framebuffer.get()
4056 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4057 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064058 if (!features().chromium_framebuffer_multisample) {
4059 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4060 } else {
4061 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344062 service_id = framebuffer_state_.bound_read_framebuffer.get()
4063 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114064 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064065 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4066 }
[email protected]70d34263c2013-01-09 00:27:454067 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064068}
4069
[email protected]8875a5f2014-06-27 08:33:474070void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4071 state_.RestoreRenderbufferBindings();
4072}
4073
[email protected]29a4d902013-02-26 20:18:064074void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104075 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4076 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254077 GLenum target = texture->target();
4078 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064079 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254080 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064081 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254082 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064083 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254084 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064085 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254086 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064087 RestoreTextureUnitBindings(state_.active_texture_unit);
4088 }
[email protected]70d34263c2013-01-09 00:27:454089}
4090
[email protected]cd2ef752014-02-12 23:16:034091void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524092 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4093 // other VAOs.
4094 if (feature_info_->feature_flags().native_vertex_array_object)
4095 glBindVertexArrayOES(0);
4096
[email protected]cd2ef752014-02-12 23:16:034097 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
4098 if (i != 0) // Never disable attribute 0
4099 glDisableVertexAttribArray(i);
4100 if(features().angle_instanced_arrays)
4101 glVertexAttribDivisorANGLE(i, 0);
4102 }
4103}
4104
4105void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524106 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034107}
4108
[email protected]454157e2014-05-03 02:49:454109void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4110 state_.SetIgnoreCachedStateForTest(ignore);
4111}
4112
[email protected]70d34263c2013-01-09 00:27:454113void GLES2DecoderImpl::OnFboChanged() const {
4114 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:514115 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
4116}
4117
4118// Called after the FBO is checked for completeness.
4119void GLES2DecoderImpl::OnUseFramebuffer() const {
4120 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
4121 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:324122 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514123 glScissor(state_.scissor_x,
4124 state_.scissor_y,
4125 state_.scissor_width,
4126 state_.scissor_height);
4127
4128 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4129 // it's unclear how this bug works.
4130 glFlush();
4131 }
[email protected]b177ae22011-11-01 03:29:114132}
4133
[email protected]051b1372010-04-12 02:42:084134void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064135 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084136 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034137 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064138 framebuffer = GetFramebuffer(client_id);
4139 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354140 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224141 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4142 "glBindFramebuffer",
4143 "id not generated by glGenFramebuffers");
4144 return;
[email protected]bf5a8d132011-08-16 08:39:354145 }
4146
[email protected]4d8f0dd2013-03-09 14:37:064147 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034148 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354149 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064150 framebuffer = GetFramebuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034151 } else {
[email protected]4d8f0dd2013-03-09 14:37:064152 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084153 }
[email protected]4d8f0dd2013-03-09 14:37:064154 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084155 }
[email protected]4d8f0dd2013-03-09 14:37:064156 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304157
4158 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344159 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304160 }
[email protected]cac16542014-01-15 17:53:514161
4162 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304163 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344164 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304165 }
[email protected]6217d392010-03-25 22:08:354166
[email protected]c986af502013-08-14 01:04:444167 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464168
[email protected]b177ae22011-11-01 03:29:114169 // If we are rendering to the backbuffer get the FBO id for any simulated
4170 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064171 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114172 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464173 }
[email protected]6217d392010-03-25 22:08:354174
[email protected]051b1372010-04-12 02:42:084175 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454176 OnFboChanged();
[email protected]86093972010-03-11 00:13:564177}
4178
[email protected]051b1372010-04-12 02:42:084179void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274180 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084181 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034182 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274183 renderbuffer = GetRenderbuffer(client_id);
4184 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354185 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224186 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4187 "glBindRenderbuffer",
4188 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354189 return;
4190 }
4191
[email protected]8875a5f2014-06-27 08:33:474192 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034193 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354194 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274195 renderbuffer = GetRenderbuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034196 } else {
[email protected]ee2a79c32013-03-10 03:50:274197 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084198 }
[email protected]ee2a79c32013-03-10 03:50:274199 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084200 }
[email protected]caa13ed2014-02-17 11:29:204201 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274202 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474203 state_.bound_renderbuffer_valid = true;
4204 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564205}
4206
[email protected]051b1372010-04-12 02:42:084207void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494208 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084209 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034210 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494211 texture_ref = GetTexture(client_id);
4212 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354213 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224214 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4215 "glBindTexture",
4216 "id not generated by glGenTextures");
4217 return;
[email protected]bf5a8d132011-08-16 08:39:354218 }
4219
[email protected]02965c22013-03-09 02:40:074220 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034221 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414222 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354223 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494224 texture_ref = GetTexture(client_id);
[email protected]ae51d192010-04-27 00:48:034225 }
4226 } else {
[email protected]370eaf12013-05-18 09:19:494227 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084228 }
[email protected]ae51d192010-04-27 00:48:034229
[email protected]1958e0e2010-04-22 05:17:154230 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574231 if (texture_ref) {
4232 Texture* texture = texture_ref->texture();
4233 // Check that we are not trying to bind it to a different target.
4234 if (texture->target() != 0 && texture->target() != target) {
4235 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4236 "glBindTexture",
4237 "texture bound to more than 1 target.");
4238 return;
4239 }
4240 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4241 if (texture->target() == 0) {
4242 texture_manager()->SetTarget(texture_ref, target);
4243 }
4244 glBindTexture(target, texture->service_id());
4245 } else {
4246 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154247 }
[email protected]32145a92012-12-17 09:01:594248
[email protected]e259eb412012-10-13 05:47:244249 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504250 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474251 switch (target) {
4252 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494253 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474254 break;
4255 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494256 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474257 break;
[email protected]61eeb33f2011-07-26 15:30:314258 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494259 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314260 break;
[email protected]e51bdf32011-11-23 22:21:464261 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494262 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464263 break;
[email protected]a93bb842010-02-16 23:03:474264 default:
4265 NOTREACHED(); // Validation should prevent us getting here.
4266 break;
4267 }
4268}
4269
[email protected]07f54fcc2009-12-22 02:46:304270void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244271 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124272 if (index != 0 ||
4273 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244274 glDisableVertexAttribArray(index);
4275 }
[email protected]07f54fcc2009-12-22 02:46:304276 } else {
[email protected]ab09b612013-03-11 22:11:514277 LOCAL_SET_GL_ERROR(
4278 GL_INVALID_VALUE,
4279 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304280 }
4281}
4282
[email protected]60f22d32012-12-12 00:31:584283void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4284 GLsizei numAttachments,
4285 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:354286 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584287 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4288
4289 // Validates the attachments. If one of them fails
4290 // the whole command fails.
4291 for (GLsizei i = 0; i < numAttachments; ++i) {
4292 if ((framebuffer &&
4293 !validators_->attachment.IsValid(attachments[i])) ||
4294 (!framebuffer &&
4295 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514296 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4297 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584298 return;
4299 }
4300 }
4301
4302 // Marks each one of them as not cleared
4303 for (GLsizei i = 0; i < numAttachments; ++i) {
4304 if (framebuffer) {
4305 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4306 texture_manager(),
4307 attachments[i],
4308 false);
4309 } else {
4310 switch (attachments[i]) {
4311 case GL_COLOR_EXT:
4312 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4313 break;
4314 case GL_DEPTH_EXT:
4315 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4316 case GL_STENCIL_EXT:
4317 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4318 break;
4319 default:
4320 NOTREACHED();
4321 break;
4322 }
4323 }
4324 }
4325
[email protected]d49c5402013-09-11 15:39:024326 // If the default framebuffer is bound but we are still rendering to an
4327 // FBO, translate attachment names that refer to default framebuffer
4328 // channels to corresponding framebuffer attachments.
4329 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4330 for (GLsizei i = 0; i < numAttachments; ++i) {
4331 GLenum attachment = attachments[i];
4332 if (!framebuffer && GetBackbufferServiceId()) {
4333 switch (attachment) {
4334 case GL_COLOR_EXT:
4335 attachment = GL_COLOR_ATTACHMENT0;
4336 break;
4337 case GL_DEPTH_EXT:
4338 attachment = GL_DEPTH_ATTACHMENT;
4339 break;
4340 case GL_STENCIL_EXT:
4341 attachment = GL_STENCIL_ATTACHMENT;
4342 break;
4343 default:
4344 NOTREACHED();
4345 return;
4346 }
4347 }
4348 translated_attachments[i] = attachment;
4349 }
4350
boliu2e7d8a7a2014-10-16 20:35:204351 ScopedRenderTo do_render(framebuffer);
[email protected]d49c5402013-09-11 15:39:024352 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
[email protected]60f22d32012-12-12 00:31:584353}
4354
[email protected]07f54fcc2009-12-22 02:46:304355void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244356 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304357 glEnableVertexAttribArray(index);
4358 } else {
[email protected]ab09b612013-03-11 22:11:514359 LOCAL_SET_GL_ERROR(
4360 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304361 }
4362}
4363
[email protected]a93bb842010-02-16 23:03:474364void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444365 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4366 &state_, target);
[email protected]370eaf12013-05-18 09:19:494367 if (!texture_ref ||
4368 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514369 LOCAL_SET_GL_ERROR(
4370 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474371 return;
4372 }
[email protected]38c0a972012-05-12 00:48:024373
[email protected]12d95352012-12-14 07:23:544374 if (target == GL_TEXTURE_CUBE_MAP) {
4375 for (int i = 0; i < 6; ++i) {
4376 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494377 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514378 LOCAL_SET_GL_ERROR(
4379 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544380 return;
4381 }
4382 }
4383 } else {
[email protected]370eaf12013-05-18 09:19:494384 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514385 LOCAL_SET_GL_ERROR(
4386 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544387 return;
4388 }
[email protected]7687479c2012-05-14 23:54:044389 }
4390
[email protected]ab09b612013-03-11 22:11:514391 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194392 // Workaround for Mac driver bug. In the large scheme of things setting
4393 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564394 // hit so there's probably no need to make this conditional. The bug appears
4395 // to be that if the filtering mode is set to something that doesn't require
4396 // mipmaps for rendering, or is never set to something other than the default,
4397 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154398 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194399 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4400 }
[email protected]a93bb842010-02-16 23:03:474401 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154402 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494403 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4404 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194405 }
[email protected]ab09b612013-03-11 22:11:514406 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024407 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494408 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024409 }
[email protected]a93bb842010-02-16 23:03:474410}
4411
[email protected]b273e432010-04-12 17:23:584412bool GLES2DecoderImpl::GetHelper(
4413 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584414 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154415 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4416 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434417 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4418 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214419 // Return the GL implementation's preferred format and (see below type)
4420 // if we have the GL extension that exposes this. This allows the GPU
4421 // client to use the implementation's preferred format for glReadPixels
4422 // for optimisation.
4423 //
4424 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4425 // case when requested on integer/floating point buffers but which is
4426 // acceptable on GLES2 and with the GL_OES_read_format extension.
4427 //
4428 // Therefore if an error occurs we swallow the error and use the
4429 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434430 if (params) {
[email protected]c959a09a2014-03-27 11:44:214431 if (context_->HasExtension("GL_OES_read_format")) {
4432 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4433 GetErrorState());
4434 glGetIntegerv(pname, params);
4435 if (glGetError() == GL_NO_ERROR)
4436 return true;
4437 }
[email protected]68586372013-12-11 01:27:594438 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4439 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434440 }
4441 return true;
4442 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4443 *num_written = 1;
4444 if (params) {
[email protected]c959a09a2014-03-27 11:44:214445 if (context_->HasExtension("GL_OES_read_format")) {
4446 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4447 GetErrorState());
4448 glGetIntegerv(pname, params);
4449 if (glGetError() == GL_NO_ERROR)
4450 return true;
4451 }
[email protected]68586372013-12-11 01:27:594452 *params = GLES2Util::GetPreferredGLReadPixelsType(
4453 GetBoundReadFrameBufferInternalFormat(),
4454 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434455 }
4456 return true;
4457 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4458 *num_written = 1;
4459 if (params) {
4460 *params = group_->max_fragment_uniform_vectors();
4461 }
4462 return true;
4463 case GL_MAX_VARYING_VECTORS:
4464 *num_written = 1;
4465 if (params) {
4466 *params = group_->max_varying_vectors();
4467 }
4468 return true;
4469 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4470 *num_written = 1;
4471 if (params) {
4472 *params = group_->max_vertex_uniform_vectors();
4473 }
4474 return true;
[email protected]4e8a5b122010-05-08 22:00:104475 }
[email protected]5cb735d2011-10-13 01:37:234476 }
4477 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244478 case GL_MAX_VIEWPORT_DIMS:
4479 if (offscreen_target_frame_buffer_.get()) {
4480 *num_written = 2;
4481 if (params) {
4482 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4483 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4484 }
4485 return true;
4486 }
[email protected]5cb735d2011-10-13 01:37:234487 return false;
[email protected]84afefa2011-10-19 21:45:534488 case GL_MAX_SAMPLES:
4489 *num_written = 1;
4490 if (params) {
4491 params[0] = renderbuffer_manager()->max_samples();
4492 }
4493 return true;
4494 case GL_MAX_RENDERBUFFER_SIZE:
4495 *num_written = 1;
4496 if (params) {
4497 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4498 }
4499 return true;
[email protected]5cb735d2011-10-13 01:37:234500 case GL_MAX_TEXTURE_SIZE:
4501 *num_written = 1;
4502 if (params) {
4503 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4504 }
4505 return true;
4506 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4507 *num_written = 1;
4508 if (params) {
4509 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4510 }
4511 return true;
[email protected]2f143d482013-03-14 18:04:494512 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4513 *num_written = 1;
4514 if (params) {
4515 params[0] = group_->max_color_attachments();
4516 }
4517 return true;
4518 case GL_MAX_DRAW_BUFFERS_ARB:
4519 *num_written = 1;
4520 if (params) {
4521 params[0] = group_->max_draw_buffers();
4522 }
4523 return true;
[email protected]297ca1c2011-06-20 23:08:464524 case GL_ALPHA_BITS:
4525 *num_written = 1;
4526 if (params) {
4527 GLint v = 0;
4528 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544529 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464530 }
4531 return true;
4532 case GL_DEPTH_BITS:
4533 *num_written = 1;
4534 if (params) {
4535 GLint v = 0;
4536 glGetIntegerv(GL_DEPTH_BITS, &v);
4537 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4538 }
4539 return true;
4540 case GL_STENCIL_BITS:
4541 *num_written = 1;
4542 if (params) {
4543 GLint v = 0;
4544 glGetIntegerv(GL_STENCIL_BITS, &v);
4545 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4546 }
4547 return true;
[email protected]656dcaad2010-05-07 17:18:374548 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114549 *num_written = validators_->compressed_texture_format.GetValues().size();
4550 if (params) {
4551 for (GLint ii = 0; ii < *num_written; ++ii) {
4552 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4553 }
4554 }
[email protected]656dcaad2010-05-07 17:18:374555 return true;
[email protected]b273e432010-04-12 17:23:584556 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4557 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104558 if (params) {
[email protected]302ce6d2011-07-07 23:28:114559 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104560 }
[email protected]b273e432010-04-12 17:23:584561 return true;
4562 case GL_NUM_SHADER_BINARY_FORMATS:
4563 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104564 if (params) {
[email protected]302ce6d2011-07-07 23:28:114565 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104566 }
[email protected]b273e432010-04-12 17:23:584567 return true;
4568 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114569 *num_written = validators_->shader_binary_format.GetValues().size();
4570 if (params) {
4571 for (GLint ii = 0; ii < *num_written; ++ii) {
4572 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4573 }
4574 }
4575 return true;
[email protected]b273e432010-04-12 17:23:584576 case GL_SHADER_COMPILER:
4577 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104578 if (params) {
4579 *params = GL_TRUE;
4580 }
[email protected]b273e432010-04-12 17:23:584581 return true;
[email protected]6b8cf1a2010-05-06 16:13:584582 case GL_ARRAY_BUFFER_BINDING:
4583 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104584 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114585 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104586 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244587 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104588 &client_id);
4589 *params = client_id;
4590 } else {
4591 *params = 0;
4592 }
[email protected]6b8cf1a2010-05-06 16:13:584593 }
4594 return true;
4595 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4596 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104597 if (params) {
[email protected]e259eb412012-10-13 05:47:244598 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104599 GLuint client_id = 0;
4600 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254601 state_.vertex_attrib_manager->element_array_buffer()->
4602 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104603 *params = client_id;
4604 } else {
4605 *params = 0;
4606 }
[email protected]6b8cf1a2010-05-06 16:13:584607 }
4608 return true;
4609 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304610 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584611 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104612 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354613 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454614 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204615 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104616 GLuint client_id = 0;
4617 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204618 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304619 *params = client_id;
4620 } else {
4621 *params = 0;
4622 }
4623 }
4624 return true;
[email protected]ebfb73c2012-08-15 02:37:454625 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304626 *num_written = 1;
4627 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354628 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454629 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204630 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304631 GLuint client_id = 0;
4632 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204633 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104634 *params = client_id;
4635 } else {
4636 *params = 0;
4637 }
[email protected]6b8cf1a2010-05-06 16:13:584638 }
4639 return true;
4640 case GL_RENDERBUFFER_BINDING:
4641 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104642 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354643 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204644 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4645 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104646 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104647 } else {
4648 *params = 0;
4649 }
[email protected]6b8cf1a2010-05-06 16:13:584650 }
4651 return true;
4652 case GL_CURRENT_PROGRAM:
4653 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104654 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114655 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104656 GLuint client_id = 0;
4657 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244658 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104659 *params = client_id;
4660 } else {
4661 *params = 0;
4662 }
[email protected]6b8cf1a2010-05-06 16:13:584663 }
4664 return true;
[email protected]bf835842012-11-19 15:21:514665 case GL_VERTEX_ARRAY_BINDING_OES:
4666 *num_written = 1;
4667 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114668 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:524669 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:514670 GLuint client_id = 0;
4671 vertex_array_manager_->GetClientId(
4672 state_.vertex_attrib_manager->service_id(), &client_id);
4673 *params = client_id;
4674 } else {
4675 *params = 0;
4676 }
4677 }
4678 return true;
[email protected]4e8a5b122010-05-08 22:00:104679 case GL_TEXTURE_BINDING_2D:
4680 *num_written = 1;
4681 if (params) {
[email protected]e259eb412012-10-13 05:47:244682 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114683 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104684 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584685 } else {
4686 *params = 0;
4687 }
[email protected]6b8cf1a2010-05-06 16:13:584688 }
[email protected]4e8a5b122010-05-08 22:00:104689 return true;
4690 case GL_TEXTURE_BINDING_CUBE_MAP:
4691 *num_written = 1;
4692 if (params) {
[email protected]e259eb412012-10-13 05:47:244693 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114694 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104695 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584696 } else {
4697 *params = 0;
4698 }
[email protected]6b8cf1a2010-05-06 16:13:584699 }
[email protected]4e8a5b122010-05-08 22:00:104700 return true;
[email protected]61eeb33f2011-07-26 15:30:314701 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4702 *num_written = 1;
4703 if (params) {
[email protected]e259eb412012-10-13 05:47:244704 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114705 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104706 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314707 } else {
4708 *params = 0;
4709 }
4710 }
4711 return true;
[email protected]e51bdf32011-11-23 22:21:464712 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4713 *num_written = 1;
4714 if (params) {
[email protected]e259eb412012-10-13 05:47:244715 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114716 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104717 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464718 } else {
4719 *params = 0;
4720 }
4721 }
4722 return true;
[email protected]6c75c712012-06-19 15:43:174723 case GL_UNPACK_FLIP_Y_CHROMIUM:
4724 *num_written = 1;
4725 if (params) {
4726 params[0] = unpack_flip_y_;
4727 }
4728 return true;
4729 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4730 *num_written = 1;
4731 if (params) {
4732 params[0] = unpack_premultiply_alpha_;
4733 }
4734 return true;
4735 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4736 *num_written = 1;
4737 if (params) {
4738 params[0] = unpack_unpremultiply_alpha_;
4739 }
4740 return true;
[email protected]6eda6822014-04-03 23:00:504741 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4742 *num_written = 1;
4743 if (params) {
4744 params[0] = group_->bind_generates_resource() ? 1 : 0;
4745 }
4746 return true;
[email protected]b273e432010-04-12 17:23:584747 default:
[email protected]2f143d482013-03-14 18:04:494748 if (pname >= GL_DRAW_BUFFER0_ARB &&
4749 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4750 *num_written = 1;
4751 if (params) {
4752 Framebuffer* framebuffer =
4753 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4754 if (framebuffer) {
4755 params[0] = framebuffer->GetDrawBuffer(pname);
4756 } else { // backbuffer
4757 if (pname == GL_DRAW_BUFFER0_ARB)
4758 params[0] = group_->draw_buffer();
4759 else
4760 params[0] = GL_NONE;
4761 }
4762 }
4763 return true;
4764 }
[email protected]4e8a5b122010-05-08 22:00:104765 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534766 return false;
[email protected]b273e432010-04-12 17:23:584767 }
4768}
4769
[email protected]4e8a5b122010-05-08 22:00:104770bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4771 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264772 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534773 return true;
4774 }
[email protected]4e8a5b122010-05-08 22:00:104775 return GetHelper(pname, NULL, num_values);
4776}
4777
[email protected]7d3c36e2013-07-12 14:13:164778GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4779 if (GL_MAX_SAMPLES == pname &&
4780 features().use_img_for_multisampled_render_to_texture) {
4781 return GL_MAX_SAMPLES_IMG;
4782 }
4783 return pname;
4784}
4785
[email protected]b273e432010-04-12 17:23:584786void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4787 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104788 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534789 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554790 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264791 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534792 GetHelper(pname, values.get(), &num_written);
4793 }
[email protected]b273e432010-04-12 17:23:584794 for (GLsizei ii = 0; ii < num_written; ++ii) {
4795 params[ii] = static_cast<GLboolean>(values[ii]);
4796 }
4797 } else {
[email protected]7d3c36e2013-07-12 14:13:164798 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584799 glGetBooleanv(pname, params);
4800 }
4801}
4802
4803void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4804 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104805 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264806 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534807 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554808 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534809 GetHelper(pname, values.get(), &num_written);
4810 for (GLsizei ii = 0; ii < num_written; ++ii) {
4811 params[ii] = static_cast<GLfloat>(values[ii]);
4812 }
4813 } else {
[email protected]7d3c36e2013-07-12 14:13:164814 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534815 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584816 }
[email protected]b273e432010-04-12 17:23:584817 }
4818}
4819
4820void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4821 DCHECK(params);
4822 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264823 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534824 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164825 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584826 glGetIntegerv(pname, params);
4827 }
4828}
4829
[email protected]a0c3e972010-04-21 00:49:134830void GLES2DecoderImpl::DoGetProgramiv(
4831 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424832 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4833 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134834 return;
4835 }
[email protected]df37b9932013-03-08 05:21:424836 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134837}
4838
[email protected]17cfbe0e2013-03-07 01:26:084839void GLES2DecoderImpl::DoGetBufferParameteriv(
4840 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134841 // Just delegate it. Some validation is actually done before this.
4842 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4843 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084844}
4845
[email protected]258a3313f2011-10-18 20:13:574846void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424847 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574848 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514849 LOCAL_SET_GL_ERROR(
4850 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574851 return;
4852 }
[email protected]68dcb1f2012-04-07 00:14:564853 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514854 LOCAL_SET_GL_ERROR(
4855 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564856 return;
4857 }
4858 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514859 LOCAL_SET_GL_ERROR(
4860 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564861 return;
4862 }
[email protected]df37b9932013-03-08 05:21:424863 Program* program = GetProgramInfoNotShader(
4864 program_id, "glBindAttribLocation");
4865 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574866 return;
[email protected]558847a2010-03-24 07:02:544867 }
zmo460b593e2014-10-13 23:07:454868 // At this point, the program's shaders may not be translated yet,
4869 // therefore, we may not find the hashed attribute name.
4870 // glBindAttribLocation call with original name is useless.
4871 // So instead, we should simply cache the binding, and then call
4872 // Program::ExecuteBindAttribLocationCalls() right before link.
[email protected]df37b9932013-03-08 05:21:424873 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
zmo460b593e2014-10-13 23:07:454874 // TODO(zmo): Get rid of the following glBindAttribLocation call.
[email protected]df37b9932013-03-08 05:21:424875 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574876}
4877
[email protected]558847a2010-03-24 07:02:544878error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:344879 uint32 immediate_data_size,
4880 const void* cmd_data) {
4881 const gles2::cmds::BindAttribLocationBucket& c =
4882 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:584883 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544884 GLuint index = static_cast<GLuint>(c.index);
4885 Bucket* bucket = GetBucket(c.name_bucket_id);
4886 if (!bucket || bucket->size() == 0) {
4887 return error::kInvalidArguments;
4888 }
4889 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184890 if (!bucket->GetAsString(&name_str)) {
4891 return error::kInvalidArguments;
4892 }
[email protected]258a3313f2011-10-18 20:13:574893 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544894 return error::kNoError;
4895}
4896
[email protected]2be6abf32012-06-26 00:28:334897void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424898 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334899 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514900 LOCAL_SET_GL_ERROR(
4901 GL_INVALID_VALUE,
4902 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334903 return;
4904 }
4905 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514906 LOCAL_SET_GL_ERROR(
4907 GL_INVALID_OPERATION,
4908 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334909 return;
4910 }
4911 if (location < 0 || static_cast<uint32>(location) >=
4912 (group_->max_fragment_uniform_vectors() +
4913 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514914 LOCAL_SET_GL_ERROR(
4915 GL_INVALID_VALUE,
4916 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334917 return;
4918 }
[email protected]df37b9932013-03-08 05:21:424919 Program* program = GetProgramInfoNotShader(
4920 program_id, "glBindUniformLocationCHROMIUM");
4921 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334922 return;
4923 }
[email protected]df37b9932013-03-08 05:21:424924 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514925 LOCAL_SET_GL_ERROR(
4926 GL_INVALID_VALUE,
4927 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334928 }
4929}
4930
[email protected]2be6abf32012-06-26 00:28:334931error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4932 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:344933 const void* cmd_data) {
4934 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
4935 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
4936 cmd_data);
[email protected]2be6abf32012-06-26 00:28:334937 GLuint program = static_cast<GLuint>(c.program);
4938 GLint location = static_cast<GLint>(c.location);
4939 Bucket* bucket = GetBucket(c.name_bucket_id);
4940 if (!bucket || bucket->size() == 0) {
4941 return error::kInvalidArguments;
4942 }
4943 std::string name_str;
4944 if (!bucket->GetAsString(&name_str)) {
4945 return error::kInvalidArguments;
4946 }
4947 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4948 return error::kNoError;
4949}
4950
vmiuracd108592014-09-08 14:36:344951error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
4952 const void* cmd_data) {
4953 const gles2::cmds::DeleteShader& c =
4954 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:034955 GLuint client_id = c.shader;
4956 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424957 Shader* shader = GetShader(client_id);
4958 if (shader) {
4959 if (!shader->IsDeleted()) {
4960 glDeleteShader(shader->service_id());
4961 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144962 }
[email protected]ae51d192010-04-27 00:48:034963 } else {
[email protected]ab09b612013-03-11 22:11:514964 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034965 }
[email protected]96449d2c2009-11-25 00:01:324966 }
[email protected]f7a64ee2010-02-01 22:24:144967 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324968}
4969
vmiuracd108592014-09-08 14:36:344970error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
4971 const void* cmd_data) {
4972 const gles2::cmds::DeleteProgram& c =
4973 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:034974 GLuint client_id = c.program;
4975 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424976 Program* program = GetProgram(client_id);
4977 if (program) {
4978 if (!program->IsDeleted()) {
4979 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144980 }
[email protected]ae51d192010-04-27 00:48:034981 } else {
[email protected]ab09b612013-03-11 22:11:514982 LOCAL_SET_GL_ERROR(
4983 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034984 }
[email protected]96449d2c2009-11-25 00:01:324985 }
[email protected]f7a64ee2010-02-01 22:24:144986 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324987}
4988
[email protected]a7266a92012-06-28 02:11:084989error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444990 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204991 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:464992 ApplyDirtyState();
boliu2e7d8a7a2014-10-16 20:35:204993 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]3a03a8f2011-03-19 00:51:274994 glClear(mask);
4995 }
[email protected]a7266a92012-06-28 02:11:084996 return error::kNoError;
4997}
4998
[email protected]36cef8ce2010-03-16 07:34:454999void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5000 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035001 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065002 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5003 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515004 LOCAL_SET_GL_ERROR(
5005 GL_INVALID_OPERATION,
5006 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455007 return;
5008 }
[email protected]ae51d192010-04-27 00:48:035009 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275010 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035011 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275012 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5013 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515014 LOCAL_SET_GL_ERROR(
5015 GL_INVALID_OPERATION,
5016 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035017 return;
5018 }
[email protected]ee2a79c32013-03-10 03:50:275019 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035020 }
[email protected]ab09b612013-03-11 22:11:515021 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035022 glFramebufferRenderbufferEXT(
5023 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515024 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265025 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275026 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285027 }
[email protected]9d3b2e12013-10-02 01:04:345028 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445029 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465030 }
[email protected]81fc9d02013-03-14 23:53:325031 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285032}
5033
[email protected]3a2e7c7b2010-08-06 01:12:285034void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465035 if (SetCapabilityState(cap, false)) {
5036 glDisable(cap);
5037 }
[email protected]3a2e7c7b2010-08-06 01:12:285038}
5039
5040void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465041 if (SetCapabilityState(cap, true)) {
5042 glEnable(cap);
5043 }
[email protected]3a2e7c7b2010-08-06 01:12:285044}
5045
[email protected]88a61bf2012-10-27 13:00:425046void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5047 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5048 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5049 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285050}
5051
[email protected]b04e24c2013-01-08 18:35:255052void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425053 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5054 state_.sample_coverage_invert = (invert != 0);
5055 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285056}
5057
[email protected]0d6bfdc2011-11-02 01:32:205058// Assumes framebuffer is complete.
5059void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065060 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305061 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205062 // bind this to the DRAW point, clear then bind back to READ
5063 // TODO(gman): I don't think there is any guarantee that an FBO that
5064 // is complete on the READ attachment will be complete as a DRAW
5065 // attachment.
5066 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065067 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305068 }
[email protected]3a2e7c7b2010-08-06 01:12:285069 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425070 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465071 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205072 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465073 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065074 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5075 1.0f);
[email protected]454157e2014-05-03 02:49:455076 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285077 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535078 if (feature_info_->feature_flags().ext_draw_buffers)
5079 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285080 }
5081
[email protected]4d8f0dd2013-03-09 14:37:065082 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5083 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285084 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475085 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5086 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285087 clear_bits |= GL_STENCIL_BUFFER_BIT;
5088 }
5089
[email protected]4d8f0dd2013-03-09 14:37:065090 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5091 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285092 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455093 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285094 clear_bits |= GL_DEPTH_BUFFER_BIT;
5095 }
5096
[email protected]454157e2014-05-03 02:49:455097 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285098 glClear(clear_bits);
5099
[email protected]0e58af82014-08-08 14:02:535100 if ((clear_bits | GL_COLOR_BUFFER_BIT) != 0 &&
5101 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425102 framebuffer->RestoreDrawBuffersAfterClear();
5103
[email protected]968351b2011-12-20 08:26:515104 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065105 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285106
[email protected]c007aa02010-09-02 22:22:405107 RestoreClearState();
5108
5109 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065110 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5111 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485112 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065113 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5114 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485115 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405116 }
5117}
5118
5119void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445120 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245121 glClearColor(
5122 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5123 state_.color_clear_alpha);
5124 glClearStencil(state_.stencil_clear);
5125 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225126 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455127 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285128 }
[email protected]36cef8ce2010-03-16 07:34:455129}
5130
5131GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355132 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305133 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205134 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455135 return GL_FRAMEBUFFER_COMPLETE;
5136 }
[email protected]0d6bfdc2011-11-02 01:32:205137 GLenum completeness = framebuffer->IsPossiblyComplete();
5138 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5139 return completeness;
5140 }
[email protected]73276522012-11-09 05:50:205141 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455142}
5143
5144void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035145 GLenum target, GLenum attachment, GLenum textarget,
5146 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165147 DoFramebufferTexture2DCommon(
5148 "glFramebufferTexture2D", target, attachment,
5149 textarget, client_texture_id, level, 0);
5150}
5151
5152void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5153 GLenum target, GLenum attachment, GLenum textarget,
5154 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165155 DoFramebufferTexture2DCommon(
5156 "glFramebufferTexture2DMultisample", target, attachment,
5157 textarget, client_texture_id, level, samples);
5158}
5159
5160void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5161 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5162 GLuint client_texture_id, GLint level, GLsizei samples) {
5163 if (samples > renderbuffer_manager()->max_samples()) {
5164 LOCAL_SET_GL_ERROR(
5165 GL_INVALID_VALUE,
5166 "glFramebufferTexture2DMultisample", "samples too large");
5167 return;
5168 }
[email protected]4d8f0dd2013-03-09 14:37:065169 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5170 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515171 LOCAL_SET_GL_ERROR(
5172 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165173 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455174 return;
5175 }
[email protected]ae51d192010-04-27 00:48:035176 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495177 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035178 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495179 texture_ref = GetTexture(client_texture_id);
5180 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515181 LOCAL_SET_GL_ERROR(
5182 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165183 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035184 return;
5185 }
[email protected]370eaf12013-05-18 09:19:495186 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035187 }
[email protected]0d6bfdc2011-11-02 01:32:205188
[email protected]80eb6b52012-01-19 00:14:415189 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515190 LOCAL_SET_GL_ERROR(
5191 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165192 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205193 return;
5194 }
5195
[email protected]91c94eb2013-10-22 10:32:545196 if (texture_ref)
5197 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5198
[email protected]7d3c36e2013-07-12 14:13:165199 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5200 if (0 == samples) {
5201 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5202 } else {
5203 if (features().use_img_for_multisampled_render_to_texture) {
5204 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5205 service_id, level, samples);
5206 } else {
5207 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5208 service_id, level, samples);
5209 }
5210 }
5211 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265212 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165213 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5214 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285215 }
[email protected]9d3b2e12013-10-02 01:04:345216 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445217 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465218 }
[email protected]91c94eb2013-10-22 10:32:545219
5220 if (texture_ref)
5221 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5222
[email protected]81fc9d02013-03-14 23:53:325223 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455224}
5225
5226void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5227 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065228 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5229 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515230 LOCAL_SET_GL_ERROR(
5231 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205232 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455233 return;
5234 }
[email protected]74c1ec42010-08-12 01:55:575235 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105236 const Framebuffer::Attachment* attachment_object =
5237 framebuffer->GetAttachment(attachment);
5238 *params = attachment_object ? attachment_object->object_name() : 0;
5239 } else {
[email protected]7d3c36e2013-07-12 14:13:165240 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5241 features().use_img_for_multisampled_render_to_texture) {
5242 pname = GL_TEXTURE_SAMPLES_IMG;
5243 }
[email protected]62e65f02013-05-29 22:28:105244 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575245 }
[email protected]36cef8ce2010-03-16 07:34:455246}
5247
5248void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5249 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355250 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205251 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5252 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515253 LOCAL_SET_GL_ERROR(
5254 GL_INVALID_OPERATION,
5255 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455256 return;
5257 }
[email protected]8875a5f2014-06-27 08:33:475258
5259 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275260 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435261 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5262 *params = renderbuffer->internal_format();
5263 break;
5264 case GL_RENDERBUFFER_WIDTH:
5265 *params = renderbuffer->width();
5266 break;
5267 case GL_RENDERBUFFER_HEIGHT:
5268 *params = renderbuffer->height();
5269 break;
[email protected]7d3c36e2013-07-12 14:13:165270 case GL_RENDERBUFFER_SAMPLES_EXT:
5271 if (features().use_img_for_multisampled_render_to_texture) {
5272 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5273 params);
5274 } else {
5275 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5276 params);
5277 }
[email protected]ad84a3a2012-06-08 21:42:435278 default:
5279 glGetRenderbufferParameterivEXT(target, pname, params);
5280 break;
[email protected]b71f52c2010-06-18 22:20:205281 }
[email protected]36cef8ce2010-03-16 07:34:455282}
5283
[email protected]49cabed2013-11-13 18:15:185284void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305285 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5286 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5287 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445288 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165289
[email protected]49cabed2013-11-13 18:15:185290 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165291 return;
5292 }
5293
[email protected]454157e2014-05-03 02:49:455294 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
boliu2e7d8a7a2014-10-16 20:35:205295 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]f42f05b2013-11-15 21:46:185296 BlitFramebufferHelper(
5297 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455298 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5299 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185300}
5301
[email protected]8875a5f2014-06-27 08:33:475302void GLES2DecoderImpl::EnsureRenderbufferBound() {
5303 if (!state_.bound_renderbuffer_valid) {
5304 state_.bound_renderbuffer_valid = true;
5305 glBindRenderbufferEXT(GL_RENDERBUFFER,
5306 state_.bound_renderbuffer.get()
5307 ? state_.bound_renderbuffer->service_id()
5308 : 0);
5309 }
5310}
5311
[email protected]f42f05b2013-11-15 21:46:185312void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5313 const FeatureInfo* feature_info,
5314 GLenum target,
5315 GLsizei samples,
5316 GLenum internal_format,
5317 GLsizei width,
5318 GLsizei height) {
5319 // TODO(sievers): This could be resolved at the GL binding level, but the
5320 // binding process is currently a bit too 'brute force'.
5321 if (feature_info->feature_flags().is_angle) {
5322 glRenderbufferStorageMultisampleANGLE(
5323 target, samples, internal_format, width, height);
5324 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5325 glRenderbufferStorageMultisample(
5326 target, samples, internal_format, width, height);
5327 } else {
5328 glRenderbufferStorageMultisampleEXT(
5329 target, samples, internal_format, width, height);
5330 }
5331}
5332
5333void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5334 GLint srcY0,
5335 GLint srcX1,
5336 GLint srcY1,
5337 GLint dstX0,
5338 GLint dstY0,
5339 GLint dstX1,
5340 GLint dstY1,
5341 GLbitfield mask,
5342 GLenum filter) {
5343 // TODO(sievers): This could be resolved at the GL binding level, but the
5344 // binding process is currently a bit too 'brute force'.
5345 if (feature_info_->feature_flags().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245346 glBlitFramebufferANGLE(
5347 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185348 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5349 glBlitFramebuffer(
5350 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245351 } else {
5352 glBlitFramebufferEXT(
5353 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5354 }
[email protected]8e3e0662010-08-23 18:46:305355}
5356
[email protected]49cabed2013-11-13 18:15:185357bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5358 GLsizei samples,
5359 GLenum internalformat,
5360 GLsizei width,
5361 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535362 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515363 LOCAL_SET_GL_ERROR(
5364 GL_INVALID_VALUE,
5365 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185366 return false;
[email protected]84afefa2011-10-19 21:45:535367 }
5368
5369 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5370 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515371 LOCAL_SET_GL_ERROR(
5372 GL_INVALID_VALUE,
5373 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185374 return false;
[email protected]84afefa2011-10-19 21:45:535375 }
5376
[email protected]7989c9e2013-01-23 06:39:265377 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235378 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5379 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515380 LOCAL_SET_GL_ERROR(
5381 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205382 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185383 return false;
[email protected]8e3e0662010-08-23 18:46:305384 }
5385
[email protected]7989c9e2013-01-23 06:39:265386 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515387 LOCAL_SET_GL_ERROR(
5388 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205389 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185390 return false;
5391 }
5392
5393 return true;
5394}
5395
5396void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5397 GLenum target, GLsizei samples, GLenum internalformat,
5398 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185399 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5400 if (!renderbuffer) {
5401 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5402 "glRenderbufferStorageMultisampleCHROMIUM",
5403 "no renderbuffer bound");
5404 return;
5405 }
5406
5407 if (!ValidateRenderbufferStorageMultisample(
5408 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265409 return;
5410 }
5411
[email protected]8875a5f2014-06-27 08:33:475412 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235413 GLenum impl_format =
5414 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5415 internalformat);
[email protected]49cabed2013-11-13 18:15:185416 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5417 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185418 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:255419 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185420 GLenum error =
5421 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265422 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105423
5424 if (workarounds().validate_multisample_buffer_allocation) {
5425 if (!VerifyMultisampleRenderbufferIntegrity(
5426 renderbuffer->service_id(), impl_format)) {
5427 LOCAL_SET_GL_ERROR(
5428 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185429 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105430 return;
5431 }
5432 }
5433
[email protected]968351b2011-12-20 08:26:515434 // TODO(gman): If renderbuffers tracked which framebuffers they were
5435 // attached to we could just mark those framebuffers as not complete.
5436 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205437 renderbuffer_manager()->SetInfo(
5438 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265439 }
[email protected]8e3e0662010-08-23 18:46:305440}
5441
[email protected]49cabed2013-11-13 18:15:185442// This is the handler for multisampled_render_to_texture extensions.
5443void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5444 GLenum target, GLsizei samples, GLenum internalformat,
5445 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185446 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5447 if (!renderbuffer) {
5448 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5449 "glRenderbufferStorageMultisampleEXT",
5450 "no renderbuffer bound");
5451 return;
5452 }
5453
5454 if (!ValidateRenderbufferStorageMultisample(
5455 samples, internalformat, width, height)) {
5456 return;
5457 }
5458
[email protected]8875a5f2014-06-27 08:33:475459 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185460 GLenum impl_format =
5461 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5462 internalformat);
5463 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5464 if (features().use_img_for_multisampled_render_to_texture) {
5465 glRenderbufferStorageMultisampleIMG(
5466 target, samples, impl_format, width, height);
5467 } else {
5468 glRenderbufferStorageMultisampleEXT(
5469 target, samples, impl_format, width, height);
5470 }
5471 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5472 if (error == GL_NO_ERROR) {
5473 // TODO(gman): If renderbuffers tracked which framebuffers they were
5474 // attached to we could just mark those framebuffers as not complete.
5475 framebuffer_manager()->IncFramebufferStateChangeCount();
5476 renderbuffer_manager()->SetInfo(
5477 renderbuffer, samples, internalformat, width, height);
5478 }
5479}
5480
[email protected]4a4c18b2013-09-13 22:50:105481// This function validates the allocation of a multisampled renderbuffer
5482// by clearing it to a key color, blitting the contents to a texture, and
5483// reading back the color to ensure it matches the key.
5484bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5485 GLuint renderbuffer, GLenum format) {
5486
5487 // Only validate color buffers.
5488 // These formats have been selected because they are very common or are known
5489 // to be used by the WebGL backbuffer. If problems are observed with other
5490 // color formats they can be added here.
5491 switch(format) {
5492 case GL_RGB:
5493 case GL_RGB8:
5494 case GL_RGBA:
5495 case GL_RGBA8:
5496 break;
5497 default:
5498 return true;
5499 }
5500
5501 GLint draw_framebuffer, read_framebuffer;
5502
5503 // Cache framebuffer and texture bindings.
5504 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5505 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5506
5507 if (!validation_texture_) {
5508 GLint bound_texture;
5509 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5510
5511 // Create additional resources needed for the verification.
5512 glGenTextures(1, &validation_texture_);
5513 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5514 glGenFramebuffersEXT(1, &validation_fbo_);
5515
5516 // Texture only needs to be 1x1.
5517 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5518 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5519 GL_UNSIGNED_BYTE, NULL);
5520
5521 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5522 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5523 GL_TEXTURE_2D, validation_texture_, 0);
5524
5525 glBindTexture(GL_TEXTURE_2D, bound_texture);
5526 }
5527
5528 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5529 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5530 GL_RENDERBUFFER, renderbuffer);
5531
5532 // Cache current state and reset it to the values we require.
5533 GLboolean scissor_enabled = false;
5534 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5535 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455536 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105537
[email protected]454157e2014-05-03 02:49:455538 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105539 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455540 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105541
5542 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5543 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5544 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5545
5546 // Clear the buffer to the desired key color.
5547 glClear(GL_COLOR_BUFFER_BIT);
5548
5549 // Blit from the multisample buffer to a standard texture.
5550 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5551 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5552
[email protected]f42f05b2013-11-15 21:46:185553 BlitFramebufferHelper(
5554 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105555
5556 // Read a pixel from the buffer.
5557 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5558
5559 unsigned char pixel[3] = {0, 0, 0};
5560 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5561
5562 // Detach the renderbuffer.
5563 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5564 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5565 GL_RENDERBUFFER, 0);
5566
5567 // Restore cached state.
5568 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455569 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105570
[email protected]454157e2014-05-03 02:49:455571 state_.SetDeviceColorMask(
5572 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105573 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5574 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5575 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5576
5577 // Return true if the pixel matched the desired key color.
5578 return (pixel[0] == 0xFF &&
5579 pixel[1] == 0x00 &&
5580 pixel[2] == 0xFF);
5581}
5582
[email protected]36cef8ce2010-03-16 07:34:455583void GLES2DecoderImpl::DoRenderbufferStorage(
5584 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355585 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205586 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5587 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515588 LOCAL_SET_GL_ERROR(
5589 GL_INVALID_OPERATION,
5590 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455591 return;
5592 }
[email protected]876f6fee2010-08-02 23:10:325593
[email protected]84afefa2011-10-19 21:45:535594 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5595 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515596 LOCAL_SET_GL_ERROR(
5597 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535598 return;
5599 }
5600
[email protected]7989c9e2013-01-23 06:39:265601 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235602 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5603 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515604 LOCAL_SET_GL_ERROR(
5605 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265606 return;
5607 }
5608
5609 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515610 LOCAL_SET_GL_ERROR(
5611 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265612 return;
[email protected]b71f52c2010-06-18 22:20:205613 }
[email protected]876f6fee2010-08-02 23:10:325614
[email protected]8875a5f2014-06-27 08:33:475615 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:515616 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265617 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235618 target,
5619 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5620 internalformat),
5621 width,
5622 height);
[email protected]ab09b612013-03-11 22:11:515623 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265624 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515625 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5626 // we could just mark those framebuffers as not complete.
5627 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205628 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265629 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265630 }
[email protected]36cef8ce2010-03-16 07:34:455631}
5632
[email protected]df37b9932013-03-08 05:21:425633void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385634 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425635 Program* program = GetProgramInfoNotShader(
5636 program_id, "glLinkProgram");
5637 if (!program) {
[email protected]a93bb842010-02-16 23:03:475638 return;
5639 }
[email protected]05afda12011-01-20 00:17:345640
[email protected]df37b9932013-03-08 05:21:425641 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395642 ShaderTranslator* vertex_translator = NULL;
5643 ShaderTranslator* fragment_translator = NULL;
5644 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115645 vertex_translator = vertex_translator_.get();
5646 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395647 }
[email protected]df37b9932013-03-08 05:21:425648 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115649 vertex_translator,
5650 fragment_translator,
[email protected]008401532014-02-07 00:10:505651 workarounds().count_all_in_varyings_packing ?
5652 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115653 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425654 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185655 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425656 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185657 if (workarounds().clear_uniforms_before_first_program_use)
5658 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545659 }
5660 }
vmiura8266ca72014-09-09 21:37:005661
5662 // LinkProgram can be very slow. Exit command processing to allow for
5663 // context preemption and GPU watchdog checks.
5664 ExitCommandProcessingEarly();
[email protected]07f54fcc2009-12-22 02:46:305665};
5666
[email protected]3916c97e2010-02-25 03:20:505667void GLES2DecoderImpl::DoTexParameterf(
5668 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445669 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5670 &state_, target);
[email protected]02965c22013-03-09 02:40:075671 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515672 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245673 return;
[email protected]07f54fcc2009-12-22 02:46:305674 }
[email protected]cbb22e42011-05-12 23:36:245675
[email protected]737191ee72014-03-09 08:02:425676 texture_manager()->SetParameterf(
5677 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305678}
5679
[email protected]3916c97e2010-02-25 03:20:505680void GLES2DecoderImpl::DoTexParameteri(
5681 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445682 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5683 &state_, target);
[email protected]02965c22013-03-09 02:40:075684 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515685 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245686 return;
[email protected]3916c97e2010-02-25 03:20:505687 }
[email protected]cbb22e42011-05-12 23:36:245688
[email protected]737191ee72014-03-09 08:02:425689 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505690 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505691}
5692
5693void GLES2DecoderImpl::DoTexParameterfv(
5694 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445695 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5696 &state_, target);
[email protected]02965c22013-03-09 02:40:075697 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515698 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245699 return;
[email protected]3916c97e2010-02-25 03:20:505700 }
[email protected]cbb22e42011-05-12 23:36:245701
[email protected]737191ee72014-03-09 08:02:425702 texture_manager()->SetParameterf(
5703 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505704}
5705
5706void GLES2DecoderImpl::DoTexParameteriv(
5707 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445708 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5709 &state_, target);
[email protected]02965c22013-03-09 02:40:075710 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515711 LOCAL_SET_GL_ERROR(
5712 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245713 return;
[email protected]3916c97e2010-02-25 03:20:505714 }
[email protected]cbb22e42011-05-12 23:36:245715
[email protected]737191ee72014-03-09 08:02:425716 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505717 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505718}
5719
[email protected]939e7362010-05-13 20:49:105720bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115721 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435722 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515723 LOCAL_SET_GL_ERROR(
5724 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435725 return false;
[email protected]939e7362010-05-13 20:49:105726 }
[email protected]e259eb412012-10-13 05:47:245727 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515728 LOCAL_SET_GL_ERROR(
5729 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105730 return false;
5731 }
5732 return true;
5733}
5734
5735bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5736 GLint location, const char* function_name) {
5737 if (!CheckCurrentProgram(function_name)) {
5738 return false;
5739 }
5740 return location != -1;
5741}
5742
zmof9a81360f2014-10-17 00:06:145743bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
5744 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
5745 if (!framebuffer)
5746 return false;
5747 const Framebuffer::Attachment* attachment =
5748 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
5749 if (!attachment)
5750 return false;
5751
5752 DCHECK(state_.current_program.get());
5753 const Program::SamplerIndices& sampler_indices =
5754 state_.current_program->sampler_indices();
5755 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5756 const Program::UniformInfo* uniform_info =
5757 state_.current_program->GetUniformInfo(sampler_indices[ii]);
5758 DCHECK(uniform_info);
5759 if (uniform_info->type != GL_SAMPLER_2D)
5760 continue;
5761 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5762 GLuint texture_unit_index = uniform_info->texture_units[jj];
5763 if (texture_unit_index >= state_.texture_units.size())
5764 continue;
5765 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
5766 TextureRef* texture_ref =
5767 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
5768 if (attachment->IsTexture(texture_ref))
5769 return true;
5770 }
5771 }
5772 return false;
5773}
5774
[email protected]43c2f1f2011-03-25 18:35:365775bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:135776 GLint fake_location,
5777 const char* function_name,
5778 Program::UniformApiType api_type,
5779 GLint* real_location,
5780 GLenum* type,
5781 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365782 DCHECK(type);
5783 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125784 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525785
[email protected]1b0a6752012-02-22 03:44:125786 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105787 return false;
5788 }
[email protected]43c2f1f2011-03-25 18:35:365789 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355790 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245791 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125792 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365793 if (!info) {
[email protected]ab09b612013-03-11 22:11:515794 LOCAL_SET_GL_ERROR(
5795 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105796 return false;
5797 }
[email protected]9b1f1b52014-03-12 10:40:135798
5799 if ((api_type & info->accepts_api_type) == 0) {
[email protected]ab09b612013-03-11 22:11:515800 LOCAL_SET_GL_ERROR(
5801 GL_INVALID_OPERATION, function_name,
5802 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525803 return false;
5804 }
[email protected]43c2f1f2011-03-25 18:35:365805 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515806 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435807 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365808 return false;
5809 }
5810 *count = std::min(info->size - array_index, *count);
5811 if (*count <= 0) {
5812 return false;
5813 }
5814 *type = info->type;
[email protected]939e7362010-05-13 20:49:105815 return true;
5816}
5817
[email protected]1b0a6752012-02-22 03:44:125818void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5819 GLenum type = 0;
5820 GLsizei count = 1;
5821 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135822 if (!PrepForSetUniformByLocation(fake_location,
5823 "glUniform1i",
5824 Program::kUniform1i,
5825 &real_location,
5826 &type,
5827 &count)) {
[email protected]3916c97e2010-02-25 03:20:505828 return;
5829 }
[email protected]e259eb412012-10-13 05:47:245830 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025831 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515832 LOCAL_SET_GL_ERROR(
5833 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465834 return;
5835 }
[email protected]1b0a6752012-02-22 03:44:125836 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505837}
5838
5839void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125840 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365841 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125842 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135843 if (!PrepForSetUniformByLocation(fake_location,
5844 "glUniform1iv",
5845 Program::kUniform1i,
5846 &real_location,
5847 &type,
5848 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365849 return;
5850 }
[email protected]74727112012-06-13 21:18:085851 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5852 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245853 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025854 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515855 LOCAL_SET_GL_ERROR(
5856 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465857 return;
5858 }
[email protected]43c2f1f2011-03-25 18:35:365859 }
[email protected]1b0a6752012-02-22 03:44:125860 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505861}
5862
[email protected]939e7362010-05-13 20:49:105863void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125864 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365865 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125866 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135867 if (!PrepForSetUniformByLocation(fake_location,
5868 "glUniform1fv",
5869 Program::kUniform1f,
5870 &real_location,
5871 &type,
5872 &count)) {
[email protected]939e7362010-05-13 20:49:105873 return;
5874 }
5875 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555876 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105877 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535878 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105879 }
[email protected]1b0a6752012-02-22 03:44:125880 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105881 } else {
[email protected]1b0a6752012-02-22 03:44:125882 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105883 }
5884}
5885
5886void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125887 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365888 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125889 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135890 if (!PrepForSetUniformByLocation(fake_location,
5891 "glUniform2fv",
5892 Program::kUniform2f,
5893 &real_location,
5894 &type,
5895 &count)) {
[email protected]939e7362010-05-13 20:49:105896 return;
5897 }
5898 if (type == GL_BOOL_VEC2) {
5899 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555900 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105901 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535902 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105903 }
[email protected]1b0a6752012-02-22 03:44:125904 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105905 } else {
[email protected]1b0a6752012-02-22 03:44:125906 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105907 }
5908}
5909
5910void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125911 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365912 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125913 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135914 if (!PrepForSetUniformByLocation(fake_location,
5915 "glUniform3fv",
5916 Program::kUniform3f,
5917 &real_location,
5918 &type,
5919 &count)) {
[email protected]939e7362010-05-13 20:49:105920 return;
5921 }
5922 if (type == GL_BOOL_VEC3) {
5923 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555924 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105925 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535926 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105927 }
[email protected]1b0a6752012-02-22 03:44:125928 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105929 } else {
[email protected]1b0a6752012-02-22 03:44:125930 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105931 }
5932}
5933
5934void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125935 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365936 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125937 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135938 if (!PrepForSetUniformByLocation(fake_location,
5939 "glUniform4fv",
5940 Program::kUniform4f,
5941 &real_location,
5942 &type,
5943 &count)) {
[email protected]939e7362010-05-13 20:49:105944 return;
5945 }
5946 if (type == GL_BOOL_VEC4) {
5947 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555948 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105949 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535950 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105951 }
[email protected]1b0a6752012-02-22 03:44:125952 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105953 } else {
[email protected]1b0a6752012-02-22 03:44:125954 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105955 }
5956}
5957
[email protected]43c2f1f2011-03-25 18:35:365958void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125959 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365960 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125961 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135962 if (!PrepForSetUniformByLocation(fake_location,
5963 "glUniform2iv",
5964 Program::kUniform2i,
5965 &real_location,
5966 &type,
5967 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365968 return;
5969 }
[email protected]1b0a6752012-02-22 03:44:125970 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365971}
5972
5973void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125974 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365975 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125976 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135977 if (!PrepForSetUniformByLocation(fake_location,
5978 "glUniform3iv",
5979 Program::kUniform3i,
5980 &real_location,
5981 &type,
5982 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365983 return;
5984 }
[email protected]1b0a6752012-02-22 03:44:125985 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365986}
5987
5988void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125989 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365990 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125991 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135992 if (!PrepForSetUniformByLocation(fake_location,
5993 "glUniform4iv",
5994 Program::kUniform4i,
5995 &real_location,
5996 &type,
5997 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365998 return;
5999 }
[email protected]1b0a6752012-02-22 03:44:126000 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366001}
6002
6003void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126004 GLint fake_location, GLsizei count, GLboolean transpose,
6005 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366006 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126007 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136008 if (!PrepForSetUniformByLocation(fake_location,
6009 "glUniformMatrix2fv",
6010 Program::kUniformMatrix2f,
6011 &real_location,
6012 &type,
6013 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366014 return;
6015 }
[email protected]1b0a6752012-02-22 03:44:126016 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366017}
6018
6019void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126020 GLint fake_location, GLsizei count, GLboolean transpose,
6021 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366022 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126023 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136024 if (!PrepForSetUniformByLocation(fake_location,
6025 "glUniformMatrix3fv",
6026 Program::kUniformMatrix3f,
6027 &real_location,
6028 &type,
6029 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366030 return;
6031 }
[email protected]1b0a6752012-02-22 03:44:126032 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366033}
6034
6035void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126036 GLint fake_location, GLsizei count, GLboolean transpose,
6037 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366038 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126039 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136040 if (!PrepForSetUniformByLocation(fake_location,
6041 "glUniformMatrix4fv",
6042 Program::kUniformMatrix4f,
6043 &real_location,
6044 &type,
6045 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366046 return;
6047 }
[email protected]1b0a6752012-02-22 03:44:126048 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366049}
6050
[email protected]df37b9932013-03-08 05:21:426051void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036052 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426053 Program* program = NULL;
6054 if (program_id) {
6055 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6056 if (!program) {
[email protected]ae51d192010-04-27 00:48:036057 return;
6058 }
[email protected]df37b9932013-03-08 05:21:426059 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506060 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516061 LOCAL_SET_GL_ERROR(
6062 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506063 return;
6064 }
[email protected]df37b9932013-03-08 05:21:426065 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506066 }
[email protected]7cd76fd2013-06-02 21:11:116067 if (state_.current_program.get()) {
6068 program_manager()->UnuseProgram(shader_manager(),
6069 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146070 }
[email protected]df37b9932013-03-08 05:21:426071 state_.current_program = program;
6072 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546073 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116074 if (state_.current_program.get()) {
6075 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186076 if (workarounds().clear_uniforms_before_first_program_use)
6077 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146078 }
[email protected]3916c97e2010-02-25 03:20:506079}
6080
[email protected]ab09b612013-03-11 22:11:516081void GLES2DecoderImpl::RenderWarning(
6082 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326083 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016084}
6085
[email protected]ab09b612013-03-11 22:11:516086void GLES2DecoderImpl::PerformanceWarning(
6087 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506088 logger_.LogMessage(filename, line,
6089 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016090}
6091
[email protected]91c94eb2013-10-22 10:32:546092void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6093 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546094 // Image is already in use if texture is attached to a framebuffer.
6095 if (texture && !texture->IsAttachedToFramebuffer()) {
6096 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6097 if (image) {
6098 ScopedGLErrorSuppressor suppressor(
6099 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6100 GetErrorState());
6101 glBindTexture(textarget, texture->service_id());
6102 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026103 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546104 }
6105 }
6106}
6107
6108void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6109 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546110 // Image is still in use if texture is attached to a framebuffer.
6111 if (texture && !texture->IsAttachedToFramebuffer()) {
6112 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6113 if (image) {
6114 ScopedGLErrorSuppressor suppressor(
6115 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6116 GetErrorState());
6117 glBindTexture(textarget, texture->service_id());
6118 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026119 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546120 }
6121 }
6122}
6123
[email protected]e56131d22013-07-28 16:14:116124bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116125 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546126 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556127 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116128 return true;
[email protected]ef526492010-06-02 23:12:256129 }
[email protected]e2367b42013-05-31 03:37:216130
[email protected]ef526492010-06-02 23:12:256131 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356132 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246133 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506134 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356135 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246136 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506137 DCHECK(uniform_info);
6138 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6139 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026140 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246141 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546142 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366143 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546144 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6145 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256146 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506147 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6148 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546149 textarget,
[email protected]00f893d2010-08-24 18:55:496150 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:516151 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:016152 std::string("texture bound to texture unit ") +
6153 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:296154 " is not renderable. It maybe non-power-of-2 and have"
6155 " incompatible texture filtering or is not"
6156 " 'texture complete'");
[email protected]91c94eb2013-10-22 10:32:546157 continue;
[email protected]3916c97e2010-02-25 03:20:506158 }
[email protected]91c94eb2013-10-22 10:32:546159
[email protected]4e7b89202014-01-28 01:44:066160 if (textarget != GL_TEXTURE_CUBE_MAP) {
6161 Texture* texture = texture_ref->texture();
6162 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6163 if (image && !texture->IsAttachedToFramebuffer()) {
6164 ScopedGLErrorSuppressor suppressor(
6165 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6166 textures_set = true;
6167 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6168 image->WillUseTexImage();
6169 continue;
6170 }
[email protected]91c94eb2013-10-22 10:32:546171 }
[email protected]3916c97e2010-02-25 03:20:506172 }
6173 // else: should this be an error?
6174 }
6175 }
[email protected]e56131d22013-07-28 16:14:116176 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506177}
6178
[email protected]91c94eb2013-10-22 10:32:546179void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116180 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356181 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116182 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506183 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356184 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246185 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506186 DCHECK(uniform_info);
6187 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6188 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026189 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246190 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116191 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546192 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496193 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506194 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496195 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116196 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6197 ? texture_unit.bound_texture_2d.get()
6198 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506199 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496200 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546201 continue;
6202 }
6203
[email protected]4e7b89202014-01-28 01:44:066204 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6205 Texture* texture = texture_ref->texture();
6206 gfx::GLImage* image =
6207 texture->GetLevelImage(texture_unit.bind_target, 0);
6208 if (image && !texture->IsAttachedToFramebuffer()) {
6209 ScopedGLErrorSuppressor suppressor(
6210 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6211 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6212 image->DidUseTexImage();
6213 continue;
6214 }
[email protected]3916c97e2010-02-25 03:20:506215 }
6216 }
6217 }
6218 }
6219 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246220 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306221}
6222
[email protected]0d6bfdc2011-11-02 01:32:206223bool GLES2DecoderImpl::ClearUnclearedTextures() {
6224 // Only check if there are some uncleared textures.
6225 if (!texture_manager()->HaveUnsafeTextures()) {
6226 return true;
6227 }
6228
6229 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116230 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356231 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116232 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206233 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356234 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246235 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206236 DCHECK(uniform_info);
6237 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6238 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026239 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246240 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496241 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366242 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496243 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6244 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206245 return false;
6246 }
6247 }
6248 }
6249 }
6250 }
6251 }
6252 return true;
6253}
6254
[email protected]c6aef902012-02-14 03:31:426255bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106256 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6257 GLsizei primcount) {
6258 DCHECK(instanced || primcount == 1);
6259
[email protected]689fa1c52010-06-09 18:35:036260 // NOTE: We specifically do not check current_program->IsValid() because
6261 // it could never be invalid since glUseProgram would have failed. While
6262 // glLinkProgram could later mark the program as invalid the previous
6263 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116264 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506265 // The program does not exist.
6266 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516267 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506268 return false;
6269 }
[email protected]c6aef902012-02-14 03:31:426270
zmof9a81360f2014-10-17 00:06:146271 if (CheckDrawingFeedbackLoops()) {
6272 LOCAL_SET_GL_ERROR(
6273 GL_INVALID_OPERATION, function_name,
6274 "Source and destination textures of the draw are the same.");
6275 return false;
6276 }
6277
[email protected]7cd76fd2013-06-02 21:11:116278 return state_.vertex_attrib_manager
6279 ->ValidateBindings(function_name,
6280 this,
6281 feature_info_.get(),
6282 state_.current_program.get(),
6283 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106284 instanced,
[email protected]7cd76fd2013-06-02 21:11:116285 primcount);
[email protected]b1122982010-05-17 23:04:246286}
6287
[email protected]c13e1da62011-09-09 21:48:306288bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436289 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306290 DCHECK(simulated);
6291 *simulated = false;
6292
[email protected]876f6fee2010-08-02 23:10:326293 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306294 return true;
[email protected]876f6fee2010-08-02 23:10:326295
[email protected]ac77603c72013-03-08 13:52:066296 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356297 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246298 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246299 bool attrib_0_used =
6300 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066301 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306302 return true;
[email protected]b1122982010-05-17 23:04:246303 }
6304
[email protected]b1122982010-05-17 23:04:246305 // Make a buffer with a single repeated vec4 value enough to
6306 // simulate the constant value that is supposed to be here.
6307 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306308 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476309 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306310
6311 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476312 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306313 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516314 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306315 return false;
6316 }
6317
[email protected]ab09b612013-03-11 22:11:516318 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016319 "Attribute 0 is disabled. This has signficant performance penalty");
6320
[email protected]ab09b612013-03-11 22:11:516321 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306322 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6323
[email protected]8f0b86c2f2012-04-10 05:48:286324 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6325 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496326 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306327 GLenum error = glGetError();
6328 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516329 LOCAL_SET_GL_ERROR(
6330 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306331 return false;
6332 }
[email protected]fc753442011-02-04 19:49:496333 }
[email protected]af6380962012-11-29 23:24:136334
6335 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286336 if (new_buffer ||
6337 (attrib_0_used &&
6338 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136339 (value.v[0] != attrib_0_value_.v[0] ||
6340 value.v[1] != attrib_0_value_.v[1] ||
6341 value.v[2] != attrib_0_value_.v[2] ||
6342 value.v[3] != attrib_0_value_.v[3])))) {
6343 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496344 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6345 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136346 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246347 attrib_0_size_ = size_needed;
6348 }
6349
6350 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6351
[email protected]ac77603c72013-03-08 13:52:066352 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426353 glVertexAttribDivisorANGLE(0, 0);
6354
[email protected]c13e1da62011-09-09 21:48:306355 *simulated = true;
[email protected]b1122982010-05-17 23:04:246356 return true;
[email protected]b1122982010-05-17 23:04:246357}
6358
[email protected]3fc38e22014-05-30 00:13:236359void GLES2DecoderImpl::RestoreStateForAttrib(
6360 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066361 const VertexAttrib* attrib =
6362 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236363 if (restore_array_binding) {
6364 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6365 Buffer* buffer = attrib->buffer();
6366 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6367 glVertexAttribPointer(
6368 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6369 attrib->gl_stride(), ptr);
6370 }
[email protected]ac77603c72013-03-08 13:52:066371 if (attrib->divisor())
6372 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246373 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236374 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6375 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286376
[email protected]265f8992012-07-20 01:03:146377 // Never touch vertex attribute 0's state (in particular, never
6378 // disable it) when running on desktop GL because it will never be
6379 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066380 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146381 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066382 if (attrib->enabled()) {
6383 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146384 } else {
[email protected]ac77603c72013-03-08 13:52:066385 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146386 }
[email protected]43410e92012-04-20 17:06:286387 }
[email protected]b1122982010-05-17 23:04:246388}
[email protected]07f54fcc2009-12-22 02:46:306389
[email protected]8fbedc02010-11-18 18:43:406390bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436391 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426392 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406393 DCHECK(simulated);
6394 *simulated = false;
6395 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6396 return true;
6397
[email protected]e259eb412012-10-13 05:47:246398 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406399 return true;
6400 }
6401
[email protected]ab09b612013-03-11 22:11:516402 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016403 "GL_FIXED attributes have a signficant performance penalty");
6404
[email protected]8fbedc02010-11-18 18:43:406405 // NOTE: we could be smart and try to check if a buffer is used
6406 // twice in 2 different attribs, find the overlapping parts and therefore
6407 // duplicate the minimum amount of data but this whole code path is not meant
6408 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6409 // tests so we just add to the buffer attrib used.
6410
[email protected]c13e1da62011-09-09 21:48:306411 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066412 const VertexAttribManager::VertexAttribList& enabled_attribs =
6413 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6414 for (VertexAttribManager::VertexAttribList::const_iterator it =
6415 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6416 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356417 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066418 state_.current_program->GetAttribInfoByLocation(attrib->index());
6419 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6420 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426421 GLuint num_vertices = max_accessed + 1;
6422 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516423 LOCAL_SET_GL_ERROR(
6424 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426425 return false;
6426 }
[email protected]8fbedc02010-11-18 18:43:406427 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066428 attrib->CanAccess(max_accessed) &&
6429 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476430 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066431 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476432 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516433 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436434 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406435 return false;
6436 }
6437 }
6438 }
6439
[email protected]3aad1a32012-09-07 20:54:476440 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6441 uint32 size_needed = 0;
6442 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306443 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516444 LOCAL_SET_GL_ERROR(
6445 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406446 return false;
6447 }
6448
[email protected]ab09b612013-03-11 22:11:516449 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406450
6451 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306452 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406453 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306454 GLenum error = glGetError();
6455 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516456 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436457 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306458 return false;
6459 }
[email protected]8fbedc02010-11-18 18:43:406460 }
6461
6462 // Copy the elements and convert to float
6463 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066464 for (VertexAttribManager::VertexAttribList::const_iterator it =
6465 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6466 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356467 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066468 state_.current_program->GetAttribInfoByLocation(attrib->index());
6469 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426470 max_vertex_accessed);
6471 GLuint num_vertices = max_accessed + 1;
6472 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516473 LOCAL_SET_GL_ERROR(
6474 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426475 return false;
6476 }
[email protected]8fbedc02010-11-18 18:43:406477 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066478 attrib->CanAccess(max_accessed) &&
6479 attrib->type() == GL_FIXED) {
6480 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:406481 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:556482 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:406483 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:066484 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:406485 const int32* end = src + num_elements;
6486 float* dst = data.get();
6487 while (src != end) {
6488 *dst++ = static_cast<float>(*src++) / 65536.0f;
6489 }
6490 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6491 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066492 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406493 reinterpret_cast<GLvoid*>(offset));
6494 offset += size;
6495 }
6496 }
6497 *simulated = true;
6498 return true;
6499}
6500
6501void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6502 // There's no need to call glVertexAttribPointer because we shadow all the
6503 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246504 glBindBuffer(
6505 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116506 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6507 : 0);
[email protected]8fbedc02010-11-18 18:43:406508}
6509
[email protected]ad84a3a2012-06-08 21:42:436510error::Error GLES2DecoderImpl::DoDrawArrays(
6511 const char* function_name,
6512 bool instanced,
6513 GLenum mode,
6514 GLint first,
6515 GLsizei count,
6516 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226517 error::Error error = WillAccessBoundFramebufferForDraw();
6518 if (error != error::kNoError)
6519 return error;
[email protected]38d139d2011-07-14 00:38:436520 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516521 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436522 return error::kNoError;
6523 }
6524 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516525 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436526 return error::kNoError;
6527 }
[email protected]c6aef902012-02-14 03:31:426528 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516529 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426530 return error::kNoError;
6531 }
[email protected]ad84a3a2012-06-08 21:42:436532 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436533 return error::kNoError;
6534 }
6535 // We have to check this here because the prototype for glDrawArrays
6536 // is GLint not GLsizei.
6537 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516538 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436539 return error::kNoError;
6540 }
6541
[email protected]ac6904d62014-07-30 12:00:106542 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:516543 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436544 return error::kNoError;
6545 }
6546
6547 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:106548 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206549 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516550 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206551 return error::kNoError;
6552 }
[email protected]c13e1da62011-09-09 21:48:306553 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436554 if (!SimulateAttrib0(
6555 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306556 return error::kNoError;
6557 }
[email protected]38d139d2011-07-14 00:38:436558 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436559 if (SimulateFixedAttribs(
6560 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6561 primcount)) {
[email protected]e56131d22013-07-28 16:14:116562 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436563 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376564 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426565 if (!instanced) {
6566 glDrawArrays(mode, first, count);
6567 } else {
6568 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6569 }
[email protected]38d139d2011-07-14 00:38:436570 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546571 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436572 }
6573 if (simulated_fixed_attribs) {
6574 RestoreStateForSimulatedFixedAttribs();
6575 }
6576 }
6577 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236578 // We don't have to restore attrib 0 generic data at the end of this
6579 // function even if it is simulated. This is because we will simulate
6580 // it in each draw call, and attrib 0 generic data queries use cached
6581 // values instead of passing down to the underlying driver.
6582 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:436583 }
[email protected]38d139d2011-07-14 00:38:436584 }
6585 return error::kNoError;
6586}
6587
vmiuracd108592014-09-08 14:36:346588error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
6589 const void* cmd_data) {
6590 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436591 return DoDrawArrays("glDrawArrays",
6592 false,
[email protected]c6aef902012-02-14 03:31:426593 static_cast<GLenum>(c.mode),
6594 static_cast<GLint>(c.first),
6595 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:106596 1);
[email protected]c6aef902012-02-14 03:31:426597}
6598
6599error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:346600 uint32 immediate_data_size,
6601 const void* cmd_data) {
6602 const gles2::cmds::DrawArraysInstancedANGLE& c =
6603 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156604 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516605 LOCAL_SET_GL_ERROR(
6606 GL_INVALID_OPERATION,
6607 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426608 return error::kNoError;
6609 }
[email protected]ad84a3a2012-06-08 21:42:436610 return DoDrawArrays("glDrawArraysIntancedANGLE",
6611 true,
[email protected]c6aef902012-02-14 03:31:426612 static_cast<GLenum>(c.mode),
6613 static_cast<GLint>(c.first),
6614 static_cast<GLsizei>(c.count),
6615 static_cast<GLsizei>(c.primcount));
6616}
6617
[email protected]ad84a3a2012-06-08 21:42:436618error::Error GLES2DecoderImpl::DoDrawElements(
6619 const char* function_name,
6620 bool instanced,
6621 GLenum mode,
6622 GLsizei count,
6623 GLenum type,
6624 int32 offset,
6625 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226626 error::Error error = WillAccessBoundFramebufferForDraw();
6627 if (error != error::kNoError)
6628 return error;
[email protected]e259eb412012-10-13 05:47:246629 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516630 LOCAL_SET_GL_ERROR(
6631 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296632 return error::kNoError;
6633 }
6634
[email protected]8eee29c2010-04-29 03:38:296635 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516636 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296637 return error::kNoError;
6638 }
6639 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516640 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296641 return error::kNoError;
6642 }
[email protected]9438b012010-06-15 22:55:056643 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516644 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296645 return error::kNoError;
6646 }
[email protected]9438b012010-06-15 22:55:056647 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516648 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296649 return error::kNoError;
6650 }
[email protected]c6aef902012-02-14 03:31:426651 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516652 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426653 return error::kNoError;
6654 }
[email protected]8eee29c2010-04-29 03:38:296655
[email protected]ad84a3a2012-06-08 21:42:436656 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276657 return error::kNoError;
6658 }
6659
[email protected]ac6904d62014-07-30 12:00:106660 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:316661 return error::kNoError;
6662 }
6663
[email protected]8eee29c2010-04-29 03:38:296664 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086665 Buffer* element_array_buffer =
6666 state_.vertex_attrib_manager->element_array_buffer();
6667
6668 if (!element_array_buffer->GetMaxValueForRange(
6669 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516670 LOCAL_SET_GL_ERROR(
6671 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296672 return error::kNoError;
6673 }
6674
[email protected]ac6904d62014-07-30 12:00:106675 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206676 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516677 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206678 return error::kNoError;
6679 }
[email protected]c13e1da62011-09-09 21:48:306680 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436681 if (!SimulateAttrib0(
6682 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306683 return error::kNoError;
6684 }
[email protected]8fbedc02010-11-18 18:43:406685 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436686 if (SimulateFixedAttribs(
6687 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6688 primcount)) {
[email protected]e56131d22013-07-28 16:14:116689 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466690 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086691 // TODO(gman): Refactor to hide these details in BufferManager or
6692 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406693 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086694 bool used_client_side_array = false;
6695 if (element_array_buffer->IsClientSideArray()) {
6696 used_client_side_array = true;
6697 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6698 indices = element_array_buffer->GetRange(offset, 0);
6699 }
6700
[email protected]00c2cf92014-03-14 00:08:376701 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426702 if (!instanced) {
6703 glDrawElements(mode, count, type, indices);
6704 } else {
6705 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6706 }
[email protected]17cfbe0e2013-03-07 01:26:086707
6708 if (used_client_side_array) {
6709 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6710 element_array_buffer->service_id());
6711 }
6712
[email protected]8fbedc02010-11-18 18:43:406713 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546714 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406715 }
6716 if (simulated_fixed_attribs) {
6717 RestoreStateForSimulatedFixedAttribs();
6718 }
[email protected]ba3176a2009-12-16 18:19:466719 }
[email protected]b1122982010-05-17 23:04:246720 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236721 // We don't have to restore attrib 0 generic data at the end of this
6722 // function even if it is simulated. This is because we will simulate
6723 // it in each draw call, and attrib 0 generic data queries use cached
6724 // values instead of passing down to the underlying driver.
6725 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:246726 }
[email protected]96449d2c2009-11-25 00:01:326727 }
[email protected]f7a64ee2010-02-01 22:24:146728 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326729}
6730
vmiuracd108592014-09-08 14:36:346731error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
6732 const void* cmd_data) {
6733 const gles2::cmds::DrawElements& c =
6734 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436735 return DoDrawElements("glDrawElements",
6736 false,
[email protected]c6aef902012-02-14 03:31:426737 static_cast<GLenum>(c.mode),
6738 static_cast<GLsizei>(c.count),
6739 static_cast<GLenum>(c.type),
6740 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:106741 1);
[email protected]c6aef902012-02-14 03:31:426742}
6743
6744error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:346745 uint32 immediate_data_size,
6746 const void* cmd_data) {
6747 const gles2::cmds::DrawElementsInstancedANGLE& c =
6748 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156749 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516750 LOCAL_SET_GL_ERROR(
6751 GL_INVALID_OPERATION,
6752 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426753 return error::kNoError;
6754 }
[email protected]ad84a3a2012-06-08 21:42:436755 return DoDrawElements("glDrawElementsInstancedANGLE",
6756 true,
[email protected]c6aef902012-02-14 03:31:426757 static_cast<GLenum>(c.mode),
6758 static_cast<GLsizei>(c.count),
6759 static_cast<GLenum>(c.type),
6760 static_cast<int32>(c.index_offset),
6761 static_cast<GLsizei>(c.primcount));
6762}
6763
[email protected]269200b12010-11-18 22:53:066764GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236765 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6766 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076767 Buffer* buffer = GetBuffer(buffer_id);
6768 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036769 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516770 LOCAL_SET_GL_ERROR(
6771 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236772 } else {
[email protected]b10492f2013-03-08 05:24:076773 if (!buffer->GetMaxValueForRange(
6774 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036775 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516776 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066777 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436778 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236779 }
6780 }
6781 return max_vertex_accessed;
6782}
6783
[email protected]96449d2c2009-11-25 00:01:326784// Calls glShaderSource for the various versions of the ShaderSource command.
6785// Assumes that data / data_size points to a piece of memory that is in range
6786// of whatever context it came from (shared memory, immediate memory, bucket
6787// memory.)
[email protected]45bf5152010-02-12 00:11:316788error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036789 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576790 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426791 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6792 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316793 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326794 }
[email protected]45bf5152010-02-12 00:11:316795 // Note: We don't actually call glShaderSource here. We wait until
6796 // the call to glCompileShader.
zmo576a0492014-09-13 01:12:326797 shader->set_source(str);
[email protected]f7a64ee2010-02-01 22:24:146798 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326799}
6800
[email protected]558847a2010-03-24 07:02:546801error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
vmiuracd108592014-09-08 14:36:346802 uint32 immediate_data_size,
6803 const void* cmd_data) {
6804 const gles2::cmds::ShaderSourceBucket& c =
6805 *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data);
[email protected]558847a2010-03-24 07:02:546806 Bucket* bucket = GetBucket(c.data_bucket_id);
6807 if (!bucket || bucket->size() == 0) {
6808 return error::kInvalidArguments;
6809 }
6810 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036811 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546812 bucket->size() - 1);
6813}
6814
[email protected]ae51d192010-04-27 00:48:036815void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386816 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426817 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6818 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316819 return;
6820 }
[email protected]f57bb282010-11-12 00:51:346821 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186822 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426823 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456824 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416825 }
[email protected]de17df392010-04-23 21:09:416826
zmo576a0492014-09-13 01:12:326827 shader->DoCompile(
[email protected]b05955552014-02-06 18:41:186828 translator,
6829 feature_info_->feature_flags().angle_translated_shader_source ?
zmo576a0492014-09-13 01:12:326830 Shader::kANGLE : Shader::kGL);
vmiura8266ca72014-09-09 21:37:006831
6832 // CompileShader can be very slow. Exit command processing to allow for
6833 // context preemption and GPU watchdog checks.
6834 ExitCommandProcessingEarly();
6835}
[email protected]45bf5152010-02-12 00:11:316836
[email protected]ddd968b82010-03-02 00:44:296837void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426838 GLuint shader_id, GLenum pname, GLint* params) {
6839 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6840 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296841 return;
6842 }
[email protected]8f1ccdac2010-05-19 21:01:486843 switch (pname) {
6844 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:326845 *params = shader->source().size();
6846 if (*params)
6847 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:486848 return;
6849 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:326850 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:416851 return;
[email protected]8f1ccdac2010-05-19 21:01:486852 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:326853 *params = shader->log_info().size();
6854 if (*params)
6855 ++(*params);
[email protected]e5186162010-06-14 18:54:416856 return;
[email protected]d6a53e42011-10-05 00:09:366857 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:326858 *params = shader->translated_source().size();
6859 if (*params)
6860 ++(*params);
[email protected]d6a53e42011-10-05 00:09:366861 return;
[email protected]8f1ccdac2010-05-19 21:01:486862 default:
6863 break;
[email protected]ddd968b82010-03-02 00:44:296864 }
[email protected]df37b9932013-03-08 05:21:426865 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296866}
6867
vmiuracd108592014-09-08 14:36:346868error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
6869 const void* cmd_data) {
6870 const gles2::cmds::GetShaderSource& c =
6871 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:426872 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036873 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6874 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426875 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:326876 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:296877 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296878 return error::kNoError;
6879 }
zmo576a0492014-09-13 01:12:326880 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:036881 return error::kNoError;
6882}
6883
[email protected]d6a53e42011-10-05 00:09:366884error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6885 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:346886 const void* cmd_data) {
6887 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
6888 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
6889 cmd_data);
[email protected]df37b9932013-03-08 05:21:426890 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366891 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6892 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426893 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:206894 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:426895 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366896 bucket->SetSize(0);
6897 return error::kNoError;
6898 }
6899
zmo576a0492014-09-13 01:12:326900 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:366901 return error::kNoError;
6902}
6903
[email protected]ae51d192010-04-27 00:48:036904error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:346905 uint32 immediate_data_size,
6906 const void* cmd_data) {
6907 const gles2::cmds::GetProgramInfoLog& c =
6908 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:426909 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586910 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6911 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426912 Program* program = GetProgramInfoNotShader(
6913 program_id, "glGetProgramInfoLog");
6914 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466915 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036916 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316917 }
[email protected]df37b9932013-03-08 05:21:426918 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036919 return error::kNoError;
6920}
6921
6922error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:346923 uint32 immediate_data_size,
6924 const void* cmd_data) {
6925 const gles2::cmds::GetShaderInfoLog& c =
6926 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:426927 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586928 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6929 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426930 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:326931 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:466932 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036933 return error::kNoError;
6934 }
zmo576a0492014-09-13 01:12:326935 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:036936 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326937}
6938
[email protected]d058bca2012-11-26 10:27:266939bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6940 return state_.GetEnabled(cap);
6941}
6942
[email protected]1958e0e2010-04-22 05:17:156943bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216944 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106945 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156946}
6947
6948bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356949 const Framebuffer* framebuffer =
6950 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106951 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156952}
6953
6954bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366955 // IsProgram is true for programs as soon as they are created, until they are
6956 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356957 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106958 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156959}
6960
6961bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356962 const Renderbuffer* renderbuffer =
6963 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106964 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156965}
6966
6967bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366968 // IsShader is true for shaders as soon as they are created, until they
6969 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356970 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106971 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156972}
6973
6974bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496975 const TextureRef* texture_ref = GetTexture(client_id);
6976 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036977}
6978
6979void GLES2DecoderImpl::DoAttachShader(
6980 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426981 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586982 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426983 if (!program) {
[email protected]ae51d192010-04-27 00:48:036984 return;
[email protected]1958e0e2010-04-22 05:17:156985 }
[email protected]df37b9932013-03-08 05:21:426986 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6987 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036988 return;
6989 }
[email protected]df37b9932013-03-08 05:21:426990 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516991 LOCAL_SET_GL_ERROR(
6992 GL_INVALID_OPERATION,
6993 "glAttachShader",
6994 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316995 return;
6996 }
[email protected]df37b9932013-03-08 05:21:426997 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036998}
6999
7000void GLES2DecoderImpl::DoDetachShader(
7001 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427002 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587003 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427004 if (!program) {
[email protected]ae51d192010-04-27 00:48:037005 return;
7006 }
[email protected]df37b9932013-03-08 05:21:427007 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7008 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037009 return;
7010 }
[email protected]df37b9932013-03-08 05:21:427011 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517012 LOCAL_SET_GL_ERROR(
7013 GL_INVALID_OPERATION,
7014 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227015 return;
7016 }
[email protected]df37b9932013-03-08 05:21:427017 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037018}
7019
7020void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427021 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587022 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427023 if (!program) {
[email protected]ae51d192010-04-27 00:48:037024 return;
7025 }
[email protected]df37b9932013-03-08 05:21:427026 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157027}
7028
[email protected]ac77603c72013-03-08 13:52:067029void GLES2DecoderImpl::GetVertexAttribHelper(
7030 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247031 switch (pname) {
7032 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067033 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247034 if (buffer && !buffer->IsDeleted()) {
7035 GLuint client_id;
7036 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7037 *params = client_id;
7038 }
7039 break;
7040 }
7041 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067042 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247043 break;
7044 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067045 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247046 break;
7047 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067048 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247049 break;
7050 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067051 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247052 break;
7053 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067054 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247055 break;
[email protected]c6aef902012-02-14 03:31:427056 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067057 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427058 break;
[email protected]ac77603c72013-03-08 13:52:067059 default:
7060 NOTREACHED();
7061 break;
7062 }
7063}
7064
[email protected]4c6f5462014-03-05 00:26:567065void GLES2DecoderImpl::DoGetTexParameterfv(
7066 GLenum target, GLenum pname, GLfloat* params) {
7067 InitTextureMaxAnisotropyIfNeeded(target, pname);
7068 glGetTexParameterfv(target, pname, params);
7069}
7070
7071void GLES2DecoderImpl::DoGetTexParameteriv(
7072 GLenum target, GLenum pname, GLint* params) {
7073 InitTextureMaxAnisotropyIfNeeded(target, pname);
7074 glGetTexParameteriv(target, pname, params);
7075}
7076
7077void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7078 GLenum target, GLenum pname) {
7079 if (!workarounds().init_texture_max_anisotropy)
7080 return;
7081 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7082 !validators_->texture_parameter.IsValid(pname)) {
7083 return;
7084 }
7085
7086 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7087 &state_, target);
7088 if (!texture_ref) {
7089 LOCAL_SET_GL_ERROR(
7090 GL_INVALID_OPERATION,
7091 "glGetTexParamter{fi}v", "unknown texture for target");
7092 return;
7093 }
7094 Texture* texture = texture_ref->texture();
7095 texture->InitTextureMaxAnisotropyIfNeeded(target);
7096}
7097
[email protected]ac77603c72013-03-08 13:52:067098void GLES2DecoderImpl::DoGetVertexAttribfv(
7099 GLuint index, GLenum pname, GLfloat* params) {
7100 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7101 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517102 LOCAL_SET_GL_ERROR(
7103 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067104 return;
7105 }
7106 switch (pname) {
7107 case GL_CURRENT_VERTEX_ATTRIB: {
7108 const Vec4& value = state_.attrib_values[index];
7109 params[0] = value.v[0];
7110 params[1] = value.v[1];
7111 params[2] = value.v[2];
7112 params[3] = value.v[3];
7113 break;
7114 }
7115 default: {
7116 GLint value = 0;
7117 GetVertexAttribHelper(attrib, pname, &value);
7118 *params = static_cast<GLfloat>(value);
7119 break;
7120 }
7121 }
7122}
7123
7124void GLES2DecoderImpl::DoGetVertexAttribiv(
7125 GLuint index, GLenum pname, GLint* params) {
7126 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7127 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517128 LOCAL_SET_GL_ERROR(
7129 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067130 return;
7131 }
7132 switch (pname) {
[email protected]af6380962012-11-29 23:24:137133 case GL_CURRENT_VERTEX_ATTRIB: {
7134 const Vec4& value = state_.attrib_values[index];
7135 params[0] = static_cast<GLint>(value.v[0]);
7136 params[1] = static_cast<GLint>(value.v[1]);
7137 params[2] = static_cast<GLint>(value.v[2]);
7138 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247139 break;
[email protected]af6380962012-11-29 23:24:137140 }
[email protected]b1122982010-05-17 23:04:247141 default:
[email protected]ac77603c72013-03-08 13:52:067142 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247143 break;
7144 }
7145}
7146
[email protected]af6380962012-11-29 23:24:137147bool GLES2DecoderImpl::SetVertexAttribValue(
7148 const char* function_name, GLuint index, const GLfloat* value) {
7149 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517150 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137151 return false;
[email protected]b1122982010-05-17 23:04:247152 }
[email protected]af6380962012-11-29 23:24:137153 Vec4& v = state_.attrib_values[index];
7154 v.v[0] = value[0];
7155 v.v[1] = value[1];
7156 v.v[2] = value[2];
7157 v.v[3] = value[3];
7158 return true;
7159}
7160
7161void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7162 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7163 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7164 glVertexAttrib1f(index, v0);
7165 }
[email protected]b1122982010-05-17 23:04:247166}
7167
7168void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137169 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7170 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7171 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247172 }
[email protected]b1122982010-05-17 23:04:247173}
7174
7175void GLES2DecoderImpl::DoVertexAttrib3f(
7176 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137177 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7178 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7179 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247180 }
[email protected]b1122982010-05-17 23:04:247181}
7182
7183void GLES2DecoderImpl::DoVertexAttrib4f(
7184 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137185 GLfloat v[4] = { v0, v1, v2, v3, };
7186 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7187 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247188 }
[email protected]b1122982010-05-17 23:04:247189}
7190
7191void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137192 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7193 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7194 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247195 }
[email protected]b1122982010-05-17 23:04:247196}
7197
7198void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137199 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7200 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7201 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247202 }
[email protected]b1122982010-05-17 23:04:247203}
7204
7205void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137206 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7207 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7208 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247209 }
[email protected]b1122982010-05-17 23:04:247210}
7211
7212void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137213 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7214 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247215 }
[email protected]b1122982010-05-17 23:04:247216}
7217
[email protected]f7a64ee2010-02-01 22:24:147218error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347219 uint32 immediate_data_size,
7220 const void* cmd_data) {
7221 const gles2::cmds::VertexAttribPointer& c =
7222 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467223
[email protected]7cd76fd2013-06-02 21:11:117224 if (!state_.bound_array_buffer.get() ||
7225 state_.bound_array_buffer->IsDeleted()) {
7226 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527227 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517228 LOCAL_SET_GL_ERROR(
7229 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467230 return error::kNoError;
7231 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517232 LOCAL_SET_GL_ERROR(
7233 GL_INVALID_VALUE,
7234 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467235 return error::kNoError;
7236 }
[email protected]96449d2c2009-11-25 00:01:327237 }
[email protected]8eee29c2010-04-29 03:38:297238
7239 GLuint indx = c.indx;
7240 GLint size = c.size;
7241 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327242 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:297243 GLsizei stride = c.stride;
7244 GLsizei offset = c.offset;
7245 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057246 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517247 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297248 return error::kNoError;
7249 }
[email protected]9438b012010-06-15 22:55:057250 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517251 LOCAL_SET_GL_ERROR(
7252 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297253 return error::kNoError;
7254 }
7255 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517256 LOCAL_SET_GL_ERROR(
7257 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297258 return error::kNoError;
7259 }
7260 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517261 LOCAL_SET_GL_ERROR(
7262 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297263 return error::kNoError;
7264 }
7265 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517266 LOCAL_SET_GL_ERROR(
7267 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297268 return error::kNoError;
7269 }
7270 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517271 LOCAL_SET_GL_ERROR(
7272 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297273 return error::kNoError;
7274 }
7275 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317276 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127277 // component_size must be a power of two to use & as optimized modulo.
7278 DCHECK(GLES2Util::IsPOT(component_size));
7279 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517280 LOCAL_SET_GL_ERROR(
7281 GL_INVALID_OPERATION,
7282 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317283 return error::kNoError;
7284 }
[email protected]a07a23602014-08-05 11:36:127285 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517286 LOCAL_SET_GL_ERROR(
7287 GL_INVALID_OPERATION,
7288 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297289 return error::kNoError;
7290 }
[email protected]7cd76fd2013-06-02 21:11:117291 state_.vertex_attrib_manager
7292 ->SetAttribInfo(indx,
7293 state_.bound_array_buffer.get(),
7294 size,
7295 type,
7296 normalized,
7297 stride,
7298 stride != 0 ? stride : component_size * size,
7299 offset);
[email protected]8fbedc02010-11-18 18:43:407300 if (type != GL_FIXED) {
7301 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7302 }
[email protected]f7a64ee2010-02-01 22:24:147303 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327304}
7305
[email protected]43410e92012-04-20 17:06:287306void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7307 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247308 state_.viewport_x = x;
7309 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027310 state_.viewport_width = std::min(width, viewport_max_width_);
7311 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287312 glViewport(x, y, width, height);
7313}
7314
[email protected]c6aef902012-02-14 03:31:427315error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347316 uint32 immediate_data_size,
7317 const void* cmd_data) {
7318 const gles2::cmds::VertexAttribDivisorANGLE& c =
7319 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157320 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517321 LOCAL_SET_GL_ERROR(
7322 GL_INVALID_OPERATION,
7323 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537324 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427325 }
7326 GLuint index = c.index;
7327 GLuint divisor = c.divisor;
7328 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517329 LOCAL_SET_GL_ERROR(
7330 GL_INVALID_VALUE,
7331 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427332 return error::kNoError;
7333 }
7334
[email protected]e259eb412012-10-13 05:47:247335 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427336 index,
7337 divisor);
7338 glVertexAttribDivisorANGLE(index, divisor);
7339 return error::kNoError;
7340}
7341
[email protected]68586372013-12-11 01:27:597342template <typename pixel_data_type>
7343static void WriteAlphaData(
7344 void *pixels, uint32 row_count, uint32 channel_count,
7345 uint32 alpha_channel_index, uint32 unpadded_row_size,
7346 uint32 padded_row_size, pixel_data_type alpha_value) {
7347 DCHECK_GT(channel_count, 0U);
7348 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7349 uint32 unpadded_row_size_in_elements =
7350 unpadded_row_size / sizeof(pixel_data_type);
7351 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7352 uint32 padded_row_size_in_elements =
7353 padded_row_size / sizeof(pixel_data_type);
7354 pixel_data_type* dst =
7355 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7356 for (uint32 yy = 0; yy < row_count; ++yy) {
7357 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7358 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7359 *d = alpha_value;
7360 }
7361 dst += padded_row_size_in_elements;
7362 }
7363}
7364
[email protected]5a36dc132013-07-23 23:17:557365void GLES2DecoderImpl::FinishReadPixels(
7366 const cmds::ReadPixels& c,
7367 GLuint buffer) {
7368 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7369 GLsizei width = c.width;
7370 GLsizei height = c.height;
7371 GLenum format = c.format;
7372 GLenum type = c.type;
7373 typedef cmds::ReadPixels::Result Result;
7374 uint32 pixels_size;
7375 Result* result = NULL;
7376 if (c.result_shm_id != 0) {
7377 result = GetSharedMemoryAs<Result*>(
7378 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7379 if (!result) {
7380 if (buffer != 0) {
7381 glDeleteBuffersARB(1, &buffer);
7382 }
7383 return;
7384 }
7385 }
7386 GLES2Util::ComputeImageDataSizes(
7387 width, height, format, type, state_.pack_alignment, &pixels_size,
7388 NULL, NULL);
7389 void* pixels = GetSharedMemoryAs<void*>(
7390 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7391 if (!pixels) {
7392 if (buffer != 0) {
7393 glDeleteBuffersARB(1, &buffer);
7394 }
7395 return;
7396 }
7397
7398 if (buffer != 0) {
7399 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337400 void* data;
7401 if (features().map_buffer_range) {
7402 data = glMapBufferRange(
7403 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7404 } else {
7405 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7406 }
[email protected]5a36dc132013-07-23 23:17:557407 memcpy(pixels, data, pixels_size);
7408 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7409 // have to restore the state.
7410 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7411 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7412 glDeleteBuffersARB(1, &buffer);
7413 }
7414
7415 if (result != NULL) {
7416 *result = true;
7417 }
7418
7419 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7420 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7421 if ((channels_exist & 0x0008) == 0 &&
7422 workarounds().clear_alpha_in_readpixels) {
7423 // Set the alpha to 255 because some drivers are buggy in this regard.
7424 uint32 temp_size;
7425
7426 uint32 unpadded_row_size;
7427 uint32 padded_row_size;
7428 if (!GLES2Util::ComputeImageDataSizes(
7429 width, 2, format, type, state_.pack_alignment, &temp_size,
7430 &unpadded_row_size, &padded_row_size)) {
7431 return;
7432 }
[email protected]68586372013-12-11 01:27:597433
7434 uint32 channel_count = 0;
7435 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557436 switch (format) {
7437 case GL_RGBA:
7438 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597439 channel_count = 4;
7440 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557441 break;
[email protected]68586372013-12-11 01:27:597442 case GL_ALPHA:
7443 channel_count = 1;
7444 alpha_channel = 0;
7445 break;
7446 }
7447
7448 if (channel_count > 0) {
7449 switch (type) {
7450 case GL_UNSIGNED_BYTE:
7451 WriteAlphaData<uint8>(
7452 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7453 padded_row_size, 0xFF);
7454 break;
7455 case GL_FLOAT:
7456 WriteAlphaData<float>(
7457 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7458 padded_row_size, 1.0f);
7459 break;
7460 case GL_HALF_FLOAT:
7461 WriteAlphaData<uint16>(
7462 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7463 padded_row_size, 0x3C00);
7464 break;
[email protected]5a36dc132013-07-23 23:17:557465 }
[email protected]5a36dc132013-07-23 23:17:557466 }
7467 }
7468}
7469
vmiuracd108592014-09-08 14:36:347470error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7471 const void* cmd_data) {
7472 const gles2::cmds::ReadPixels& c =
7473 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:217474 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227475 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7476 if (fbo_error != error::kNoError)
7477 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317478 GLint x = c.x;
7479 GLint y = c.y;
7480 GLsizei width = c.width;
7481 GLsizei height = c.height;
7482 GLenum format = c.format;
7483 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327484 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:567485 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517486 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567487 return error::kNoError;
7488 }
[email protected]ed9f9cd2013-02-27 21:12:357489 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187490 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347491 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247492 width, height, format, type, state_.pack_alignment, &pixels_size,
7493 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187494 return error::kOutOfBounds;
7495 }
[email protected]612d2f82009-12-08 20:49:317496 void* pixels = GetSharedMemoryAs<void*>(
7497 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107498 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147499 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467500 }
[email protected]de43f082013-04-02 01:16:107501 Result* result = NULL;
7502 if (c.result_shm_id != 0) {
7503 result = GetSharedMemoryAs<Result*>(
7504 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7505 if (!result) {
7506 return error::kOutOfBounds;
7507 }
7508 }
[email protected]a51788e2010-02-24 21:54:257509
[email protected]9438b012010-06-15 22:55:057510 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517511 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297512 return error::kNoError;
7513 }
[email protected]68586372013-12-11 01:27:597514 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517515 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127516 return error::kNoError;
7517 }
[email protected]68586372013-12-11 01:27:597518 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7519 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7520 // format and type are acceptable enums but not guaranteed to be supported
7521 // for this framebuffer. Have to ask gl if they are valid.
7522 GLint preferred_format = 0;
7523 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7524 GLint preferred_type = 0;
7525 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7526 if (format != static_cast<GLenum>(preferred_format) ||
7527 type != static_cast<GLenum>(preferred_type)) {
7528 LOCAL_SET_GL_ERROR(
7529 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7530 "with the current read framebuffer");
7531 return error::kNoError;
7532 }
7533 }
[email protected]57f223832010-03-19 01:57:567534 if (width == 0 || height == 0) {
7535 return error::kNoError;
7536 }
7537
[email protected]57f223832010-03-19 01:57:567538 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307539 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567540
[email protected]3aad1a32012-09-07 20:54:477541 int32 max_x;
7542 int32 max_y;
7543 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517544 LOCAL_SET_GL_ERROR(
7545 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147546 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317547 }
[email protected]57f223832010-03-19 01:57:567548
[email protected]2ea5950d2014-07-09 18:20:347549 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
7550 return error::kNoError;
7551 }
7552
[email protected]0d6bfdc2011-11-02 01:32:207553 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7554 return error::kNoError;
7555 }
7556
[email protected]caa13ed2014-02-17 11:29:207557 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107558
7559 ScopedResolvedFrameBufferBinder binder(this, false, true);
7560
[email protected]d37231fa2010-04-09 21:16:027561 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567562 // The user requested an out of range area. Get the results 1 line
7563 // at a time.
7564 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347565 uint32 unpadded_row_size;
7566 uint32 padded_row_size;
7567 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247568 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347569 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517570 LOCAL_SET_GL_ERROR(
7571 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567572 return error::kNoError;
7573 }
7574
7575 GLint dest_x_offset = std::max(-x, 0);
7576 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347577 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247578 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7579 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517580 LOCAL_SET_GL_ERROR(
7581 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567582 return error::kNoError;
7583 }
7584
7585 // Copy each row into the larger dest rect.
7586 int8* dst = static_cast<int8*>(pixels);
7587 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027588 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567589 GLint read_width = read_end_x - read_x;
7590 for (GLint yy = 0; yy < height; ++yy) {
7591 GLint ry = y + yy;
7592
7593 // Clear the row.
7594 memset(dst, 0, unpadded_row_size);
7595
7596 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027597 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567598 glReadPixels(
7599 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7600 }
7601 dst += padded_row_size;
7602 }
7603 } else {
[email protected]5a36dc132013-07-23 23:17:557604 if (async && features().use_async_readpixels) {
7605 GLuint buffer;
7606 glGenBuffersARB(1, &buffer);
7607 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7608 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
7609 GLenum error = glGetError();
7610 if (error == GL_NO_ERROR) {
7611 glReadPixels(x, y, width, height, format, type, 0);
7612 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7613 new FenceCallback()));
7614 WaitForReadPixels(base::Bind(
7615 &GLES2DecoderImpl::FinishReadPixels,
7616 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7617 <GLES2DecoderImpl>(this),
7618 c, buffer));
7619 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7620 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597621 } else {
7622 // On error, unbind pack buffer and fall through to sync readpixels
7623 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
[email protected]5a36dc132013-07-23 23:17:557624 }
7625 }
[email protected]57f223832010-03-19 01:57:567626 glReadPixels(x, y, width, height, format, type, pixels);
7627 }
[email protected]ab09b612013-03-11 22:11:517628 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257629 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107630 if (result != NULL) {
7631 *result = true;
7632 }
[email protected]5a36dc132013-07-23 23:17:557633 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257634 }
[email protected]4848b9f82011-03-10 18:37:567635
[email protected]f7a64ee2010-02-01 22:24:147636 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327637}
7638
vmiuracd108592014-09-08 14:36:347639error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
7640 const void* cmd_data) {
7641 const gles2::cmds::PixelStorei& c =
7642 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:197643 GLenum pname = c.pname;
7644 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057645 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517646 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127647 return error::kNoError;
7648 }
[email protected]222471d2011-11-30 18:06:397649 switch (pname) {
7650 case GL_PACK_ALIGNMENT:
7651 case GL_UNPACK_ALIGNMENT:
7652 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517653 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207654 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397655 return error::kNoError;
7656 }
[email protected]164d6d52012-05-05 00:55:037657 break;
[email protected]0a1e9ad2012-05-04 21:13:037658 case GL_UNPACK_FLIP_Y_CHROMIUM:
7659 unpack_flip_y_ = (param != 0);
7660 return error::kNoError;
7661 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7662 unpack_premultiply_alpha_ = (param != 0);
7663 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177664 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7665 unpack_unpremultiply_alpha_ = (param != 0);
7666 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397667 default:
7668 break;
[email protected]b9849abf2009-11-25 19:13:197669 }
7670 glPixelStorei(pname, param);
7671 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437672 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247673 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437674 break;
7675 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427676 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437677 break;
7678 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247679 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437680 break;
7681 default:
7682 // Validation should have prevented us from getting here.
7683 NOTREACHED();
7684 break;
[email protected]b9849abf2009-11-25 19:13:197685 }
[email protected]f7a64ee2010-02-01 22:24:147686 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197687}
7688
[email protected]1c75a3702011-11-11 14:15:287689error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:347690 uint32 immediate_data_size,
7691 const void* cmd_data) {
7692 const gles2::cmds::PostSubBufferCHROMIUM& c =
7693 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:387694 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:277695 {
7696 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
7697 }
[email protected]b381ee32014-03-22 02:43:437698 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:517699 LOCAL_SET_GL_ERROR(
7700 GL_INVALID_OPERATION,
7701 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287702 return error::kNoError;
7703 }
[email protected]8f9b8dd2013-09-12 18:05:137704 bool is_tracing;
7705 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7706 &is_tracing);
7707 if (is_tracing) {
7708 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7709 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7710 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7711 is_offscreen ? offscreen_size_ : surface_->GetSize());
7712 }
[email protected]7794d512012-04-17 20:36:497713 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287714 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497715 } else {
7716 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287717 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497718 }
[email protected]1c75a3702011-11-11 14:15:287719}
7720
[email protected]957f0642014-04-09 16:50:017721error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
7722 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347723 const void* cmd_data) {
7724 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
7725 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:107726 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
7727 if (!ref) {
7728 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7729 "glScheduleOverlayPlaneCHROMIUM",
7730 "unknown texture");
7731 return error::kNoError;
7732 }
7733 gfx::GLImage* image =
7734 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
7735 if (!image) {
7736 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7737 "glScheduleOverlayPlaneCHROMIUM",
7738 "unsupported texture format");
7739 return error::kNoError;
7740 }
7741 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
7742 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
7743 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
7744 "glScheduleOverlayPlaneCHROMIUM",
7745 "invalid transform enum");
7746 return error::kNoError;
7747 }
7748 if (!surface_->ScheduleOverlayPlane(
7749 c.plane_z_order,
7750 transform,
7751 image,
7752 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
7753 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
7754 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
7755 "glScheduleOverlayPlaneCHROMIUM",
7756 "failed to schedule overlay");
7757 }
[email protected]957f0642014-04-09 16:50:017758 return error::kNoError;
7759}
7760
[email protected]558847a2010-03-24 07:02:547761error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7762 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7763 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577764 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517765 LOCAL_SET_GL_ERROR(
7766 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577767 return error::kNoError;
7768 }
[email protected]df37b9932013-03-08 05:21:427769 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587770 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427771 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147772 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197773 }
[email protected]df37b9932013-03-08 05:21:427774 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517775 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437776 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257777 return error::kNoError;
7778 }
[email protected]b9849abf2009-11-25 19:13:197779 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547780 location_shm_id, location_shm_offset, sizeof(GLint));
7781 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147782 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197783 }
[email protected]558847a2010-03-24 07:02:547784 // Require the client to init this incase the context is lost and we are no
7785 // longer executing commands.
7786 if (*location != -1) {
7787 return error::kGenericError;
7788 }
[email protected]df37b9932013-03-08 05:21:427789 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147790 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197791}
7792
[email protected]558847a2010-03-24 07:02:547793error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:347794 uint32 immediate_data_size,
7795 const void* cmd_data) {
7796 const gles2::cmds::GetAttribLocation& c =
7797 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:547798 Bucket* bucket = GetBucket(c.name_bucket_id);
7799 if (!bucket) {
7800 return error::kInvalidArguments;
7801 }
7802 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187803 if (!bucket->GetAsString(&name_str)) {
7804 return error::kInvalidArguments;
7805 }
[email protected]558847a2010-03-24 07:02:547806 return GetAttribLocationHelper(
7807 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7808}
7809
7810error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7811 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7812 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577813 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517814 LOCAL_SET_GL_ERROR(
7815 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577816 return error::kNoError;
7817 }
[email protected]df37b9932013-03-08 05:21:427818 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:207819 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:427820 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147821 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197822 }
[email protected]df37b9932013-03-08 05:21:427823 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517824 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437825 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257826 return error::kNoError;
7827 }
[email protected]b9849abf2009-11-25 19:13:197828 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547829 location_shm_id, location_shm_offset, sizeof(GLint));
7830 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147831 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197832 }
[email protected]558847a2010-03-24 07:02:547833 // Require the client to init this incase the context is lost an we are no
7834 // longer executing commands.
7835 if (*location != -1) {
7836 return error::kGenericError;
7837 }
[email protected]df37b9932013-03-08 05:21:427838 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147839 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197840}
7841
[email protected]f7a64ee2010-02-01 22:24:147842error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:347843 uint32 immediate_data_size,
7844 const void* cmd_data) {
7845 const gles2::cmds::GetUniformLocation& c =
7846 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:547847 Bucket* bucket = GetBucket(c.name_bucket_id);
7848 if (!bucket) {
7849 return error::kInvalidArguments;
7850 }
7851 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187852 if (!bucket->GetAsString(&name_str)) {
7853 return error::kInvalidArguments;
7854 }
[email protected]558847a2010-03-24 07:02:547855 return GetUniformLocationHelper(
7856 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197857}
7858
vmiuracd108592014-09-08 14:36:347859error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
7860 const void* cmd_data) {
7861 const gles2::cmds::GetString& c =
7862 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:297863 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057864 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517865 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297866 return error::kNoError;
7867 }
[email protected]959e9072013-09-20 16:58:387868 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:047869 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157870 switch (name) {
7871 case GL_VERSION:
7872 str = "OpenGL ES 2.0 Chromium";
7873 break;
7874 case GL_SHADING_LANGUAGE_VERSION:
7875 str = "OpenGL ES GLSL ES 1.0 Chromium";
7876 break;
[email protected]32939602012-05-09 06:25:167877 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:167878 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:387879 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
7880 // They are used by WEBGL_debug_renderer_info.
7881 if (!force_webgl_glsl_validation_)
7882 str = "Chromium";
[email protected]32939602012-05-09 06:25:167883 break;
[email protected]1958e0e2010-04-22 05:17:157884 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047885 {
[email protected]70dc60932013-06-04 03:33:497886 // For WebGL contexts, strip out the OES derivatives and
7887 // EXT frag depth extensions if they have not been enabled.
7888 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047889 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497890 if (!derivatives_explicitly_enabled_) {
7891 size_t offset = extensions.find(kOESDerivativeExtension);
7892 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097893 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:497894 std::string());
7895 }
7896 }
7897 if (!frag_depth_explicitly_enabled_) {
7898 size_t offset = extensions.find(kEXTFragDepthExtension);
7899 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097900 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:497901 std::string());
7902 }
[email protected]f0d74742011-10-03 16:31:047903 }
[email protected]aff39ac82013-06-08 04:53:137904 if (!draw_buffers_explicitly_enabled_) {
7905 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7906 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097907 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:137908 std::string());
7909 }
7910 }
[email protected]93c2fd82014-04-16 02:46:067911 if (!shader_texture_lod_explicitly_enabled_) {
7912 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
7913 if (std::string::npos != offset) {
7914 extensions.replace(offset,
7915 arraysize(kEXTShaderTextureLodExtension),
7916 std::string());
7917 }
7918 }
[email protected]f0d74742011-10-03 16:31:047919 } else {
[email protected]6f5fac9d12012-06-26 21:02:457920 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047921 }
[email protected]b381ee32014-03-22 02:43:437922 if (supports_post_sub_buffer_)
7923 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:457924 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047925 }
[email protected]1958e0e2010-04-22 05:17:157926 break;
7927 default:
[email protected]1958e0e2010-04-22 05:17:157928 break;
7929 }
[email protected]ddd968b82010-03-02 00:44:297930 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157931 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297932 return error::kNoError;
7933}
7934
vmiuracd108592014-09-08 14:36:347935error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
7936 const void* cmd_data) {
7937 const gles2::cmds::BufferData& c =
7938 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:117939 GLenum target = static_cast<GLenum>(c.target);
7940 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7941 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7942 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7943 GLenum usage = static_cast<GLenum>(c.usage);
7944 const void* data = NULL;
7945 if (data_shm_id != 0 || data_shm_offset != 0) {
7946 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7947 if (!data) {
7948 return error::kOutOfBounds;
7949 }
7950 }
[email protected]0fbba3732013-07-17 15:40:137951 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147952 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197953}
7954
[email protected]0c86dbf2010-03-05 08:14:117955void GLES2DecoderImpl::DoBufferSubData(
7956 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:137957 // Just delegate it. Some validation is actually done before this.
7958 buffer_manager()->ValidateAndDoBufferSubData(
7959 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197960}
7961
[email protected]0d6bfdc2011-11-02 01:32:207962bool GLES2DecoderImpl::ClearLevel(
7963 unsigned service_id,
7964 unsigned bind_target,
7965 unsigned target,
7966 int level,
[email protected]d8e6c9242014-02-20 16:56:257967 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:207968 unsigned format,
7969 unsigned type,
7970 int width,
[email protected]4502e6492011-12-14 19:39:157971 int height,
7972 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007973 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:007974 if (feature_info_->feature_flags().angle_depth_texture &&
7975 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:007976 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7977 // on depth formats.
7978 GLuint fb = 0;
7979 glGenFramebuffersEXT(1, &fb);
7980 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7981
7982 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7983 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7984 GL_DEPTH_ATTACHMENT;
7985
7986 glFramebufferTexture2DEXT(
7987 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7988 // ANGLE promises a depth only attachment ok.
7989 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7990 GL_FRAMEBUFFER_COMPLETE) {
7991 return false;
7992 }
7993 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:477994 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
7995 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:007996 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:457997 state_.SetDeviceDepthMask(GL_TRUE);
7998 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:007999 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8000
8001 RestoreClearState();
8002
8003 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358004 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008005 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8006 GLuint fb_service_id =
8007 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8008 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8009 return true;
8010 }
8011
[email protected]45d15a62012-04-18 14:33:178012 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8013
8014 uint32 size;
8015 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348016 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248017 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178018 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208019 return false;
8020 }
[email protected]45d15a62012-04-18 14:33:178021
[email protected]a5d3dad2012-05-26 04:34:448022 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8023
[email protected]45d15a62012-04-18 14:33:178024 int tile_height;
8025
8026 if (size > kMaxZeroSize) {
8027 if (kMaxZeroSize < padded_row_size) {
8028 // That'd be an awfully large texture.
8029 return false;
8030 }
8031 // We should never have a large total size with a zero row size.
8032 DCHECK_GT(padded_row_size, 0U);
8033 tile_height = kMaxZeroSize / padded_row_size;
8034 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248035 width, tile_height, format, type, state_.unpack_alignment, &size,
8036 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178037 return false;
8038 }
[email protected]4502e6492011-12-14 19:39:158039 } else {
[email protected]45d15a62012-04-18 14:33:178040 tile_height = height;
8041 }
8042
8043 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558044 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178045 memset(zero.get(), 0, size);
8046 glBindTexture(bind_target, service_id);
8047
8048 GLint y = 0;
8049 while (y < height) {
8050 GLint h = y + tile_height > height ? height - y : tile_height;
8051 if (is_texture_immutable || h != height) {
8052 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8053 } else {
[email protected]8f1d2aa2013-05-10 23:45:388054 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258055 target, level, internal_format, width, h, 0, format, type,
8056 zero.get());
[email protected]45d15a62012-04-18 14:33:178057 }
8058 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158059 }
[email protected]c986af502013-08-14 01:04:448060 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
8061 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:078062 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208063 return true;
8064}
8065
[email protected]ad84a3a2012-06-08 21:42:438066namespace {
8067
8068const int kS3TCBlockWidth = 4;
8069const int kS3TCBlockHeight = 4;
8070const int kS3TCDXT1BlockSize = 8;
8071const int kS3TCDXT3AndDXT5BlockSize = 16;
8072
8073bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518074 return (size == 1) ||
8075 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438076}
8077
[email protected]8aec81ec2014-04-29 01:04:518078bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128079 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518080}
8081
[email protected]ad84a3a2012-06-08 21:42:438082} // anonymous namespace.
8083
8084bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8085 const char* function_name,
8086 GLsizei width, GLsizei height, GLenum format, size_t size) {
8087 unsigned int bytes_required = 0;
8088
8089 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518090 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438091 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518092 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8093 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438094 int num_blocks_across =
8095 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8096 int num_blocks_down =
8097 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8098 int num_blocks = num_blocks_across * num_blocks_down;
8099 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8100 break;
8101 }
[email protected]8aec81ec2014-04-29 01:04:518102 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8103 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438104 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8105 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8106 int num_blocks_across =
8107 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8108 int num_blocks_down =
8109 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8110 int num_blocks = num_blocks_across * num_blocks_down;
8111 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8112 break;
8113 }
[email protected]8aec81ec2014-04-29 01:04:518114 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8115 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8116 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8117 break;
8118 }
8119 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8120 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8121 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078122 break;
8123 }
[email protected]ad84a3a2012-06-08 21:42:438124 default:
[email protected]ab09b612013-03-11 22:11:518125 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438126 return false;
8127 }
8128
8129 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518130 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438131 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8132 return false;
8133 }
8134
8135 return true;
8136}
8137
8138bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8139 const char* function_name,
8140 GLint level, GLsizei width, GLsizei height, GLenum format) {
8141 switch (format) {
8142 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8143 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8144 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8145 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8146 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518147 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438148 GL_INVALID_OPERATION, function_name,
8149 "width or height invalid for level");
8150 return false;
8151 }
8152 return true;
8153 }
[email protected]8aec81ec2014-04-29 01:04:518154 case GL_ATC_RGB_AMD:
8155 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8156 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8157 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078158 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518159 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078160 GL_INVALID_OPERATION, function_name,
8161 "width or height invalid for level");
8162 return false;
8163 }
8164 return true;
[email protected]8aec81ec2014-04-29 01:04:518165 }
8166 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8167 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8168 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8169 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8170 if (!IsValidPVRTCSize(level, width) ||
8171 !IsValidPVRTCSize(level, height)) {
8172 LOCAL_SET_GL_ERROR(
8173 GL_INVALID_OPERATION, function_name,
8174 "width or height invalid for level");
8175 return false;
8176 }
8177 return true;
8178 }
[email protected]ad84a3a2012-06-08 21:42:438179 default:
8180 return false;
8181 }
8182}
8183
8184bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8185 const char* function_name,
8186 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8187 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358188 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438189 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518190 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438191 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8192 return false;
8193 }
8194
8195 switch (format) {
8196 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8197 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8198 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8199 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8200 const int kBlockWidth = 4;
8201 const int kBlockHeight = 4;
8202 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518203 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438204 GL_INVALID_OPERATION, function_name,
8205 "xoffset or yoffset not multiple of 4");
8206 return false;
8207 }
8208 GLsizei tex_width = 0;
8209 GLsizei tex_height = 0;
8210 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8211 width - xoffset > tex_width ||
8212 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518213 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438214 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8215 return false;
8216 }
8217 return ValidateCompressedTexDimensions(
8218 function_name, level, width, height, format);
8219 }
[email protected]8aec81ec2014-04-29 01:04:518220 case GL_ATC_RGB_AMD:
8221 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8222 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8223 LOCAL_SET_GL_ERROR(
8224 GL_INVALID_OPERATION, function_name,
8225 "not supported for ATC textures");
8226 return false;
8227 }
[email protected]2d3765b2012-10-03 00:31:078228 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518229 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078230 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208231 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078232 return false;
8233 }
[email protected]8aec81ec2014-04-29 01:04:518234 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8235 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8236 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8237 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8238 if ((xoffset != 0) || (yoffset != 0)) {
8239 LOCAL_SET_GL_ERROR(
8240 GL_INVALID_OPERATION, function_name,
8241 "xoffset and yoffset must be zero");
8242 return false;
8243 }
8244 GLsizei tex_width = 0;
8245 GLsizei tex_height = 0;
8246 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8247 width != tex_width ||
8248 height != tex_height) {
8249 LOCAL_SET_GL_ERROR(
8250 GL_INVALID_OPERATION, function_name,
8251 "dimensions must match existing texture level dimensions");
8252 return false;
8253 }
8254 return ValidateCompressedTexDimensions(
8255 function_name, level, width, height, format);
8256 }
[email protected]ad84a3a2012-06-08 21:42:438257 default:
8258 return false;
8259 }
8260}
8261
[email protected]a93bb842010-02-16 23:03:478262error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8263 GLenum target,
8264 GLint level,
8265 GLenum internal_format,
8266 GLsizei width,
8267 GLsizei height,
8268 GLint border,
8269 GLsizei image_size,
8270 const void* data) {
[email protected]a93bb842010-02-16 23:03:478271 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058272 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518273 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8274 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298275 return error::kNoError;
8276 }
[email protected]9438b012010-06-15 22:55:058277 if (!validators_->compressed_texture_format.IsValid(
8278 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518279 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538280 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478281 return error::kNoError;
8282 }
[email protected]80eb6b52012-01-19 00:14:418283 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478284 border != 0) {
[email protected]ab09b612013-03-11 22:11:518285 LOCAL_SET_GL_ERROR(
8286 GL_INVALID_VALUE,
8287 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478288 return error::kNoError;
8289 }
[email protected]c986af502013-08-14 01:04:448290 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8291 &state_, target);
[email protected]370eaf12013-05-18 09:19:498292 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518293 LOCAL_SET_GL_ERROR(
8294 GL_INVALID_VALUE,
8295 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478296 return error::kNoError;
8297 }
[email protected]370eaf12013-05-18 09:19:498298 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078299 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518300 LOCAL_SET_GL_ERROR(
8301 GL_INVALID_OPERATION,
8302 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438303 return error::kNoError;
8304 }
8305
8306 if (!ValidateCompressedTexDimensions(
8307 "glCompressedTexImage2D", level, width, height, internal_format) ||
8308 !ValidateCompressedTexFuncData(
8309 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178310 return error::kNoError;
8311 }
[email protected]968351b2011-12-20 08:26:518312
[email protected]7989c9e2013-01-23 06:39:268313 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518314 LOCAL_SET_GL_ERROR(
8315 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268316 return error::kNoError;
8317 }
8318
[email protected]02965c22013-03-09 02:40:078319 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448320 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518321 }
8322
[email protected]40d90a22013-04-09 03:39:558323 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478324 if (!data) {
8325 zero.reset(new int8[image_size]);
8326 memset(zero.get(), 0, image_size);
8327 data = zero.get();
8328 }
[email protected]ab09b612013-03-11 22:11:518329 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478330 glCompressedTexImage2D(
8331 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518332 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438333 if (error == GL_NO_ERROR) {
8334 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498335 texture_ref, target, level, internal_format,
8336 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438337 }
vmiura8266ca72014-09-09 21:37:008338
8339 // This may be a slow command. Exit command processing to allow for
8340 // context preemption and GPU watchdog checks.
8341 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:478342 return error::kNoError;
8343}
8344
[email protected]f7a64ee2010-02-01 22:24:148345error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:348346 uint32 immediate_data_size,
8347 const void* cmd_data) {
8348 const gles2::cmds::CompressedTexImage2D& c =
8349 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198350 GLenum target = static_cast<GLenum>(c.target);
8351 GLint level = static_cast<GLint>(c.level);
8352 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8353 GLsizei width = static_cast<GLsizei>(c.width);
8354 GLsizei height = static_cast<GLsizei>(c.height);
8355 GLint border = static_cast<GLint>(c.border);
8356 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8357 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8358 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8359 const void* data = NULL;
8360 if (data_shm_id != 0 || data_shm_offset != 0) {
8361 data = GetSharedMemoryAs<const void*>(
8362 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468363 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148364 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198365 }
8366 }
[email protected]a93bb842010-02-16 23:03:478367 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198368 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198369}
8370
[email protected]b6140d02010-05-17 14:47:168371error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:348372 uint32 immediate_data_size,
8373 const void* cmd_data) {
8374 const gles2::cmds::CompressedTexImage2DBucket& c =
8375 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168376 GLenum target = static_cast<GLenum>(c.target);
8377 GLint level = static_cast<GLint>(c.level);
8378 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8379 GLsizei width = static_cast<GLsizei>(c.width);
8380 GLsizei height = static_cast<GLsizei>(c.height);
8381 GLint border = static_cast<GLint>(c.border);
8382 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288383 if (!bucket) {
8384 return error::kInvalidArguments;
8385 }
8386 uint32 data_size = bucket->size();
8387 GLsizei imageSize = data_size;
8388 const void* data = bucket->GetData(0, data_size);
8389 if (!data) {
8390 return error::kInvalidArguments;
8391 }
[email protected]b6140d02010-05-17 14:47:168392 return DoCompressedTexImage2D(
8393 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288394 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168395}
8396
8397error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8398 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348399 const void* cmd_data) {
8400 const gles2::cmds::CompressedTexSubImage2DBucket& c =
8401 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168402 GLenum target = static_cast<GLenum>(c.target);
8403 GLint level = static_cast<GLint>(c.level);
8404 GLint xoffset = static_cast<GLint>(c.xoffset);
8405 GLint yoffset = static_cast<GLint>(c.yoffset);
8406 GLsizei width = static_cast<GLsizei>(c.width);
8407 GLsizei height = static_cast<GLsizei>(c.height);
8408 GLenum format = static_cast<GLenum>(c.format);
8409 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288410 if (!bucket) {
8411 return error::kInvalidArguments;
8412 }
[email protected]b6140d02010-05-17 14:47:168413 uint32 data_size = bucket->size();
8414 GLsizei imageSize = data_size;
8415 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288416 if (!data) {
8417 return error::kInvalidArguments;
8418 }
[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(
[email protected]f80e6e12012-08-31 00:43:538421 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168422 return error::kNoError;
8423 }
[email protected]9438b012010-06-15 22:55:058424 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518425 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8426 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058427 return error::kNoError;
8428 }
[email protected]b6140d02010-05-17 14:47:168429 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518430 LOCAL_SET_GL_ERROR(
8431 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168432 return error::kNoError;
8433 }
8434 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518435 LOCAL_SET_GL_ERROR(
8436 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168437 return error::kNoError;
8438 }
8439 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518440 LOCAL_SET_GL_ERROR(
8441 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168442 return error::kNoError;
8443 }
[email protected]cadde4a2010-07-31 17:10:438444 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168445 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8446 return error::kNoError;
8447}
8448
vmiuracd108592014-09-08 14:36:348449error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
8450 const void* cmd_data) {
8451 const gles2::cmds::TexImage2D& c =
8452 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138453 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8454 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:448455 // Set as failed for now, but if it successed, this will be set to not failed.
8456 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198457 GLenum target = static_cast<GLenum>(c.target);
8458 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448459 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8460 // for internalformat.
8461 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198462 GLsizei width = static_cast<GLsizei>(c.width);
8463 GLsizei height = static_cast<GLsizei>(c.height);
8464 GLint border = static_cast<GLint>(c.border);
8465 GLenum format = static_cast<GLenum>(c.format);
8466 GLenum type = static_cast<GLenum>(c.type);
8467 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8468 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188469 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348470 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248471 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:348472 NULL)) {
[email protected]a76b0052010-03-05 00:33:188473 return error::kOutOfBounds;
8474 }
[email protected]b9849abf2009-11-25 19:13:198475 const void* pixels = NULL;
8476 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8477 pixels = GetSharedMemoryAs<const void*>(
8478 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468479 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148480 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198481 }
8482 }
[email protected]f598f422012-12-07 08:30:038483
[email protected]c986af502013-08-14 01:04:448484 TextureManager::DoTextImage2DArguments args = {
8485 target, level, internal_format, width, height, border, format, type,
8486 pixels, pixels_size};
8487 texture_manager()->ValidateAndDoTexImage2D(
8488 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:008489
8490 // This may be a slow command. Exit command processing to allow for
8491 // context preemption and GPU watchdog checks.
8492 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038493 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198494}
8495
[email protected]cadde4a2010-07-31 17:10:438496void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8497 GLenum target,
8498 GLint level,
8499 GLint xoffset,
8500 GLint yoffset,
8501 GLsizei width,
8502 GLsizei height,
8503 GLenum format,
8504 GLsizei image_size,
8505 const void * data) {
[email protected]c986af502013-08-14 01:04:448506 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8507 &state_, target);
[email protected]370eaf12013-05-18 09:19:498508 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518509 LOCAL_SET_GL_ERROR(
8510 GL_INVALID_OPERATION,
8511 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438512 return;
8513 }
[email protected]370eaf12013-05-18 09:19:498514 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438515 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528516 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078517 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518518 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528519 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438520 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528521 return;
8522 }
8523 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518524 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528525 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438526 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528527 return;
8528 }
[email protected]02965c22013-03-09 02:40:078529 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528530 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518531 LOCAL_SET_GL_ERROR(
8532 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438533 return;
8534 }
[email protected]ad84a3a2012-06-08 21:42:438535
8536 if (!ValidateCompressedTexFuncData(
8537 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8538 !ValidateCompressedTexSubDimensions(
8539 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078540 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438541 return;
8542 }
8543
8544
[email protected]0d6bfdc2011-11-02 01:32:208545 // Note: There is no need to deal with texture cleared tracking here
8546 // because the validation above means you can only get here if the level
8547 // is already a matching compressed format and in that case
8548 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438549 glCompressedTexSubImage2D(
8550 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:008551
8552 // This may be a slow command. Exit command processing to allow for
8553 // context preemption and GPU watchdog checks.
8554 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438555}
8556
[email protected]6e288612010-12-21 20:45:038557static void Clip(
8558 GLint start, GLint range, GLint sourceRange,
8559 GLint* out_start, GLint* out_range) {
8560 DCHECK(out_start);
8561 DCHECK(out_range);
8562 if (start < 0) {
8563 range += start;
8564 start = 0;
8565 }
8566 GLint end = start + range;
8567 if (end > sourceRange) {
8568 range -= end - sourceRange;
8569 }
8570 *out_start = start;
8571 *out_range = range;
8572}
8573
[email protected]cadde4a2010-07-31 17:10:438574void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448575 GLenum target,
8576 GLint level,
8577 GLenum internal_format,
8578 GLint x,
8579 GLint y,
8580 GLsizei width,
8581 GLsizei height,
8582 GLint border) {
[email protected]09e17272012-11-30 10:30:448583 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448584 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8585 &state_, target);
[email protected]370eaf12013-05-18 09:19:498586 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518587 LOCAL_SET_GL_ERROR(
8588 GL_INVALID_OPERATION,
8589 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438590 return;
8591 }
[email protected]370eaf12013-05-18 09:19:498592 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078593 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518594 LOCAL_SET_GL_ERROR(
8595 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:538596 return;
[email protected]97dc7cbe2011-12-06 17:26:178597 }
[email protected]80eb6b52012-01-19 00:14:418598 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188599 border != 0) {
[email protected]ab09b612013-03-11 22:11:518600 LOCAL_SET_GL_ERROR(
8601 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188602 return;
8603 }
[email protected]17a961192014-02-14 15:20:528604 if (!texture_manager()->ValidateFormatAndTypeCombination(
8605 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
8606 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:008607 return;
8608 }
[email protected]f5719fb2010-08-04 18:27:188609
[email protected]9edc6b22010-12-23 02:00:268610 // Check we have compatible formats.
8611 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8612 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8613 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8614
8615 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518616 LOCAL_SET_GL_ERROR(
8617 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268618 return;
8619 }
8620
[email protected]81375742012-06-08 00:04:008621 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518622 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008623 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268624 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8625 return;
8626 }
8627
8628 uint32 estimated_size = 0;
8629 if (!GLES2Util::ComputeImageDataSizes(
8630 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8631 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518632 LOCAL_SET_GL_ERROR(
8633 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268634 return;
8635 }
8636
8637 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518638 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008639 return;
8640 }
8641
[email protected]2ea5950d2014-07-09 18:20:348642 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
8643 return;
8644 }
8645
zmo383512cf2014-10-14 00:11:008646 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
8647 LOCAL_SET_GL_ERROR(
8648 GL_INVALID_OPERATION,
8649 "glCopyTexImage2D", "source and destination textures are the same");
8650 return;
8651 }
8652
[email protected]a0b78dc2011-11-11 10:43:108653 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8654 return;
8655 }
8656
[email protected]ab09b612013-03-11 22:11:518657 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278658 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038659 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268660
[email protected]02965c22013-03-09 02:40:078661 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448662 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:468663 }
8664
[email protected]9edc6b22010-12-23 02:00:268665 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038666 GLint copyX = 0;
8667 GLint copyY = 0;
8668 GLint copyWidth = 0;
8669 GLint copyHeight = 0;
8670 Clip(x, width, size.width(), &copyX, &copyWidth);
8671 Clip(y, height, size.height(), &copyY, &copyHeight);
8672
8673 if (copyX != x ||
8674 copyY != y ||
8675 copyWidth != width ||
8676 copyHeight != height) {
8677 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208678 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078679 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:258680 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
8681 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518682 LOCAL_SET_GL_ERROR(
8683 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038684 return;
8685 }
[email protected]6e288612010-12-21 20:45:038686 if (copyHeight > 0 && copyWidth > 0) {
8687 GLint dx = copyX - x;
8688 GLint dy = copyY - y;
8689 GLint destX = dx;
8690 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:378691 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038692 glCopyTexSubImage2D(target, level,
8693 destX, destY, copyX, copyY,
8694 copyWidth, copyHeight);
8695 }
8696 } else {
[email protected]00c2cf92014-03-14 00:08:378697 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038698 glCopyTexImage2D(target, level, internal_format,
8699 copyX, copyY, copyWidth, copyHeight, border);
8700 }
[email protected]ab09b612013-03-11 22:11:518701 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438702 if (error == GL_NO_ERROR) {
8703 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498704 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208705 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438706 }
vmiura8266ca72014-09-09 21:37:008707
8708 // This may be a slow command. Exit command processing to allow for
8709 // context preemption and GPU watchdog checks.
8710 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438711}
8712
8713void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448714 GLenum target,
8715 GLint level,
8716 GLint xoffset,
8717 GLint yoffset,
8718 GLint x,
8719 GLint y,
8720 GLsizei width,
8721 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448722 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448723 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8724 &state_, target);
[email protected]370eaf12013-05-18 09:19:498725 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518726 LOCAL_SET_GL_ERROR(
8727 GL_INVALID_OPERATION,
8728 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438729 return;
8730 }
[email protected]370eaf12013-05-18 09:19:498731 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438732 GLenum type = 0;
8733 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078734 if (!texture->GetLevelType(target, level, &type, &format) ||
8735 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528736 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518737 LOCAL_SET_GL_ERROR(
8738 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438739 return;
8740 }
[email protected]85a4ac22013-05-31 01:58:478741 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518742 LOCAL_SET_GL_ERROR(
8743 GL_INVALID_OPERATION,
8744 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598745 return;
8746 }
[email protected]9edc6b22010-12-23 02:00:268747
8748 // Check we have compatible formats.
8749 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8750 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8751 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8752
[email protected]2d3765b2012-10-03 00:31:078753 if (!channels_needed ||
8754 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518755 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438756 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268757 return;
8758 }
8759
[email protected]81375742012-06-08 00:04:008760 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518761 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008762 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438763 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008764 return;
8765 }
8766
[email protected]2ea5950d2014-07-09 18:20:348767 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
8768 return;
8769 }
8770
zmo383512cf2014-10-14 00:11:008771 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
8772 LOCAL_SET_GL_ERROR(
8773 GL_INVALID_OPERATION,
8774 "glCopyTexSubImage2D", "source and destination textures are the same");
8775 return;
8776 }
8777
[email protected]a0b78dc2011-11-11 10:43:108778 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8779 return;
8780 }
8781
[email protected]de26b3c2011-08-03 21:54:278782 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038783 gfx::Size size = GetBoundReadFrameBufferSize();
8784 GLint copyX = 0;
8785 GLint copyY = 0;
8786 GLint copyWidth = 0;
8787 GLint copyHeight = 0;
8788 Clip(x, width, size.width(), &copyX, &copyWidth);
8789 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208790
[email protected]370eaf12013-05-18 09:19:498791 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518792 LOCAL_SET_GL_ERROR(
8793 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208794 return;
8795 }
8796
[email protected]6e288612010-12-21 20:45:038797 if (copyX != x ||
8798 copyY != y ||
8799 copyWidth != width ||
8800 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208801 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038802 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348803 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248804 width, height, format, type, state_.unpack_alignment, &pixels_size,
8805 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518806 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438807 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038808 return;
8809 }
[email protected]40d90a22013-04-09 03:39:558810 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038811 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:378812 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038813 glTexSubImage2D(
8814 target, level, xoffset, yoffset, width, height,
8815 format, type, zero.get());
8816 }
[email protected]0d6bfdc2011-11-02 01:32:208817
[email protected]6e288612010-12-21 20:45:038818 if (copyHeight > 0 && copyWidth > 0) {
8819 GLint dx = copyX - x;
8820 GLint dy = copyY - y;
8821 GLint destX = xoffset + dx;
8822 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:378823 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038824 glCopyTexSubImage2D(target, level,
8825 destX, destY, copyX, copyY,
8826 copyWidth, copyHeight);
8827 }
vmiura8266ca72014-09-09 21:37:008828
8829 // This may be a slow command. Exit command processing to allow for
8830 // context preemption and GPU watchdog checks.
8831 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438832}
8833
[email protected]f598f422012-12-07 08:30:038834bool GLES2DecoderImpl::ValidateTexSubImage2D(
8835 error::Error* error,
8836 const char* function_name,
8837 GLenum target,
8838 GLint level,
8839 GLint xoffset,
8840 GLint yoffset,
8841 GLsizei width,
8842 GLsizei height,
8843 GLenum format,
8844 GLenum type,
8845 const void * data) {
8846 (*error) = error::kNoError;
8847 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518848 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038849 return false;
8850 }
8851 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518852 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038853 return false;
8854 }
8855 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518856 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038857 return false;
8858 }
[email protected]c986af502013-08-14 01:04:448859 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8860 &state_, target);
[email protected]370eaf12013-05-18 09:19:498861 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518862 LOCAL_SET_GL_ERROR(
8863 GL_INVALID_OPERATION,
8864 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038865 return false;
[email protected]cadde4a2010-07-31 17:10:438866 }
[email protected]370eaf12013-05-18 09:19:498867 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528868 GLenum current_type = 0;
8869 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078870 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518871 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038872 GL_INVALID_OPERATION, function_name, "level does not exist.");
8873 return false;
[email protected]df6cf1ad2011-01-29 01:20:528874 }
[email protected]17a961192014-02-14 15:20:528875 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
8876 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:038877 return false;
[email protected]df6cf1ad2011-01-29 01:20:528878 }
8879 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518880 LOCAL_SET_GL_ERROR(
8881 GL_INVALID_OPERATION,
8882 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038883 return false;
[email protected]df6cf1ad2011-01-29 01:20:528884 }
[email protected]85a4ac22013-05-31 01:58:478885 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518886 LOCAL_SET_GL_ERROR(
8887 GL_INVALID_OPERATION,
8888 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598889 return false;
8890 }
[email protected]02965c22013-03-09 02:40:078891 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528892 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518893 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038894 return false;
[email protected]cadde4a2010-07-31 17:10:438895 }
[email protected]81375742012-06-08 00:04:008896 if ((GLES2Util::GetChannelsForFormat(format) &
8897 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518898 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008899 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038900 function_name, "can not supply data for depth or stencil textures");
8901 return false;
[email protected]81375742012-06-08 00:04:008902 }
[email protected]f598f422012-12-07 08:30:038903 if (data == NULL) {
8904 (*error) = error::kOutOfBounds;
8905 return false;
8906 }
8907 return true;
8908}
[email protected]81375742012-06-08 00:04:008909
[email protected]f598f422012-12-07 08:30:038910error::Error GLES2DecoderImpl::DoTexSubImage2D(
8911 GLenum target,
8912 GLint level,
8913 GLint xoffset,
8914 GLint yoffset,
8915 GLsizei width,
8916 GLsizei height,
8917 GLenum format,
8918 GLenum type,
8919 const void * data) {
8920 error::Error error = error::kNoError;
8921 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8922 xoffset, yoffset, width, height, format, type, data)) {
8923 return error;
8924 }
[email protected]c986af502013-08-14 01:04:448925 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8926 &state_, target);
[email protected]370eaf12013-05-18 09:19:498927 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158928 GLsizei tex_width = 0;
8929 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078930 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158931 DCHECK(ok);
8932 if (xoffset != 0 || yoffset != 0 ||
8933 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498934 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8935 target, level)) {
[email protected]ab09b612013-03-11 22:11:518936 LOCAL_SET_GL_ERROR(
8937 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038938 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308939 }
[email protected]c986af502013-08-14 01:04:448940 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158941 glTexSubImage2D(
8942 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038943 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208944 }
[email protected]4502e6492011-12-14 19:39:158945
[email protected]345ba902013-11-14 21:39:008946 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:448947 !texture->IsImmutable()) {
8948 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:258949 GLenum internal_format;
8950 GLenum tex_type;
8951 texture->GetLevelType(target, level, &tex_type, &internal_format);
8952 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
8953 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:388954 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258955 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:158956 } else {
[email protected]c986af502013-08-14 01:04:448957 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158958 glTexSubImage2D(
8959 target, level, xoffset, yoffset, width, height, format, type, data);
8960 }
[email protected]370eaf12013-05-18 09:19:498961 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:008962
8963 // This may be a slow command. Exit command processing to allow for
8964 // context preemption and GPU watchdog checks.
8965 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038966 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438967}
8968
vmiuracd108592014-09-08 14:36:348969error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
8970 const void* cmd_data) {
8971 const gles2::cmds::TexSubImage2D& c =
8972 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138973 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
8974 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:008975 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:448976 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:008977 return error::kNoError;
8978
8979 GLenum target = static_cast<GLenum>(c.target);
8980 GLint level = static_cast<GLint>(c.level);
8981 GLint xoffset = static_cast<GLint>(c.xoffset);
8982 GLint yoffset = static_cast<GLint>(c.yoffset);
8983 GLsizei width = static_cast<GLsizei>(c.width);
8984 GLsizei height = static_cast<GLsizei>(c.height);
8985 GLenum format = static_cast<GLenum>(c.format);
8986 GLenum type = static_cast<GLenum>(c.type);
8987 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348988 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248989 width, height, format, type, state_.unpack_alignment, &data_size,
8990 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008991 return error::kOutOfBounds;
8992 }
8993 const void* pixels = GetSharedMemoryAs<const void*>(
8994 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038995 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008996 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008997}
8998
[email protected]f7a64ee2010-02-01 22:24:148999error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349000 uint32 immediate_data_size,
9001 const void* cmd_data) {
9002 const gles2::cmds::GetVertexAttribPointerv& c =
9003 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369004 GLuint index = static_cast<GLuint>(c.index);
9005 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359006 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259007 Result* result = GetSharedMemoryAs<Result*>(
9008 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369009 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149010 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369011 }
[email protected]07d0cc82010-02-17 04:51:409012 // Check that the client initialized the result.
9013 if (result->size != 0) {
9014 return error::kInvalidArguments;
9015 }
[email protected]9438b012010-06-15 22:55:059016 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519017 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9018 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149019 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369020 }
[email protected]3916c97e2010-02-25 03:20:509021 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519022 LOCAL_SET_GL_ERROR(
9023 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149024 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369025 }
[email protected]0bfd9882010-02-05 23:02:259026 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089027 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359028 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149029 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329030}
9031
[email protected]f7b85372010-02-03 01:11:379032bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:429033 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:379034 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:129035 error::Error* error, GLint* real_location,
9036 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:109037 DCHECK(error);
9038 DCHECK(service_id);
9039 DCHECK(result_pointer);
9040 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129041 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379042 *error = error::kNoError;
9043 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259044 SizedResult<GLint>* result;
9045 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9046 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9047 if (!result) {
[email protected]f7b85372010-02-03 01:11:379048 *error = error::kOutOfBounds;
9049 return false;
9050 }
[email protected]0bfd9882010-02-05 23:02:259051 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379052 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259053 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429054 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9055 if (!program) {
[email protected]ae51d192010-04-27 00:48:039056 return false;
9057 }
[email protected]df37b9932013-03-08 05:21:429058 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379059 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519060 LOCAL_SET_GL_ERROR(
9061 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379062 return false;
9063 }
[email protected]df37b9932013-03-08 05:21:429064 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369065 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359066 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429067 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129068 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369069 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379070 // No such location.
[email protected]ab09b612013-03-11 22:11:519071 LOCAL_SET_GL_ERROR(
9072 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379073 return false;
9074 }
[email protected]43c2f1f2011-03-25 18:35:369075 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509076 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379077 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519078 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379079 return false;
9080 }
[email protected]0bfd9882010-02-05 23:02:259081 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9082 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9083 if (!result) {
[email protected]f7b85372010-02-03 01:11:379084 *error = error::kOutOfBounds;
9085 return false;
9086 }
[email protected]0bfd9882010-02-05 23:02:259087 result->size = size;
[email protected]939e7362010-05-13 20:49:109088 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379089 return true;
9090}
9091
vmiuracd108592014-09-08 14:36:349092error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9093 const void* cmd_data) {
9094 const gles2::cmds::GetUniformiv& c =
9095 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379096 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339097 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379098 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109099 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:129100 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379101 Error error;
[email protected]0bfd9882010-02-05 23:02:259102 void* result;
[email protected]f7b85372010-02-03 01:11:379103 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129104 program, fake_location, c.params_shm_id, c.params_shm_offset,
9105 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:259106 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129107 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359108 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379109 }
9110 return error;
[email protected]96449d2c2009-11-25 00:01:329111}
9112
vmiuracd108592014-09-08 14:36:349113error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9114 const void* cmd_data) {
9115 const gles2::cmds::GetUniformfv& c =
9116 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379117 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339118 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379119 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129120 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379121 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359122 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109123 Result* result;
9124 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:379125 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129126 program, fake_location, c.params_shm_id, c.params_shm_offset,
9127 &error, &real_location, &service_id,
9128 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:109129 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9130 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
9131 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:559132 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129133 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109134 GLfloat* dst = result->GetData();
9135 for (GLsizei ii = 0; ii < num_values; ++ii) {
9136 dst[ii] = (temp[ii] != 0);
9137 }
9138 } else {
[email protected]1b0a6752012-02-22 03:44:129139 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109140 }
[email protected]f7b85372010-02-03 01:11:379141 }
9142 return error;
[email protected]96449d2c2009-11-25 00:01:329143}
9144
[email protected]f7a64ee2010-02-01 22:24:149145error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349146 uint32 immediate_data_size,
9147 const void* cmd_data) {
9148 const gles2::cmds::GetShaderPrecisionFormat& c =
9149 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259150 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9151 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359152 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259153 Result* result = GetSharedMemoryAs<Result*>(
9154 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9155 if (!result) {
9156 return error::kOutOfBounds;
9157 }
[email protected]07d0cc82010-02-17 04:51:409158 // Check that the client initialized the result.
9159 if (result->success != 0) {
9160 return error::kInvalidArguments;
9161 }
[email protected]9438b012010-06-15 22:55:059162 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519163 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539164 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299165 return error::kNoError;
9166 }
[email protected]9438b012010-06-15 22:55:059167 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519168 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539169 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299170 return error::kNoError;
9171 }
9172
9173 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409174
[email protected]46c86752013-05-21 05:08:399175 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409176 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219177 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409178
9179 result->min_range = range[0];
9180 result->max_range = range[1];
9181 result->precision = precision;
9182
[email protected]f7a64ee2010-02-01 22:24:149183 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329184}
9185
[email protected]f7a64ee2010-02-01 22:24:149186error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349187 uint32 immediate_data_size,
9188 const void* cmd_data) {
9189 const gles2::cmds::GetAttachedShaders& c =
9190 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259191 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429192 GLuint program_id = static_cast<GLuint>(c.program);
9193 Program* program = GetProgramInfoNotShader(
9194 program_id, "glGetAttachedShaders");
9195 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259196 return error::kNoError;
9197 }
[email protected]ed9f9cd2013-02-27 21:12:359198 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259199 uint32 max_count = Result::ComputeMaxResults(result_size);
9200 Result* result = GetSharedMemoryAs<Result*>(
9201 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9202 if (!result) {
9203 return error::kOutOfBounds;
9204 }
[email protected]07d0cc82010-02-17 04:51:409205 // Check that the client initialized the result.
9206 if (result->size != 0) {
9207 return error::kInvalidArguments;
9208 }
[email protected]0bfd9882010-02-05 23:02:259209 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039210 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429211 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259212 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039213 if (!shader_manager()->GetClientId(result->GetData()[ii],
9214 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259215 NOTREACHED();
9216 return error::kGenericError;
9217 }
9218 }
9219 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149220 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329221}
9222
[email protected]f7a64ee2010-02-01 22:24:149223error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349224 uint32 immediate_data_size,
9225 const void* cmd_data) {
9226 const gles2::cmds::GetActiveUniform& c =
9227 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429228 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259229 GLuint index = c.index;
9230 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359231 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259232 Result* result = GetSharedMemoryAs<Result*>(
9233 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9234 if (!result) {
9235 return error::kOutOfBounds;
9236 }
[email protected]07d0cc82010-02-17 04:51:409237 // Check that the client initialized the result.
9238 if (result->success != 0) {
9239 return error::kInvalidArguments;
9240 }
[email protected]df37b9932013-03-08 05:21:429241 Program* program = GetProgramInfoNotShader(
9242 program_id, "glGetActiveUniform");
9243 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259244 return error::kNoError;
9245 }
[email protected]ed9f9cd2013-02-27 21:12:359246 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429247 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:259248 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:519249 LOCAL_SET_GL_ERROR(
9250 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259251 return error::kNoError;
9252 }
9253 result->success = 1; // true.
9254 result->size = uniform_info->size;
9255 result->type = uniform_info->type;
9256 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299257 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149258 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329259}
9260
vmiuracd108592014-09-08 14:36:349261error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
9262 const void* cmd_data) {
9263 const gles2::cmds::GetActiveAttrib& c =
9264 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429265 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259266 GLuint index = c.index;
9267 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359268 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:259269 Result* result = GetSharedMemoryAs<Result*>(
9270 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9271 if (!result) {
9272 return error::kOutOfBounds;
9273 }
[email protected]07d0cc82010-02-17 04:51:409274 // Check that the client initialized the result.
9275 if (result->success != 0) {
9276 return error::kInvalidArguments;
9277 }
[email protected]df37b9932013-03-08 05:21:429278 Program* program = GetProgramInfoNotShader(
9279 program_id, "glGetActiveAttrib");
9280 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259281 return error::kNoError;
9282 }
[email protected]ed9f9cd2013-02-27 21:12:359283 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:429284 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:259285 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:519286 LOCAL_SET_GL_ERROR(
9287 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259288 return error::kNoError;
9289 }
9290 result->success = 1; // true.
9291 result->size = attrib_info->size;
9292 result->type = attrib_info->type;
9293 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299294 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149295 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329296}
9297
vmiuracd108592014-09-08 14:36:349298error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
9299 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:589300#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:519301 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:589302 return error::kNoError;
9303#else
9304 GLsizei n = static_cast<GLsizei>(c.n);
9305 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:519306 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:589307 return error::kNoError;
9308 }
9309 GLsizei length = static_cast<GLsizei>(c.length);
9310 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:519311 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:589312 return error::kNoError;
9313 }
9314 uint32 data_size;
9315 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
9316 return error::kOutOfBounds;
9317 }
9318 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
9319 c.shaders_shm_id, c.shaders_shm_offset, data_size);
9320 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
9321 const void* binary = GetSharedMemoryAs<const void*>(
9322 c.binary_shm_id, c.binary_shm_offset, length);
9323 if (shaders == NULL || binary == NULL) {
9324 return error::kOutOfBounds;
9325 }
[email protected]0782b14b2014-05-24 13:04:169326 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:589327 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:429328 Shader* shader = GetShader(shaders[ii]);
9329 if (!shader) {
[email protected]ab09b612013-03-11 22:11:519330 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:589331 return error::kNoError;
9332 }
[email protected]df37b9932013-03-08 05:21:429333 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:589334 }
9335 // TODO(gman): call glShaderBinary
9336 return error::kNoError;
9337#endif
9338}
9339
[email protected]6d792ee12013-05-15 00:40:569340void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:499341 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:089342
[email protected]64ace852011-05-19 21:49:499343 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:429344 // TRACE_EVENT for gpu tests:
9345 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:429346 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:429347 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
9348 "width", (is_offscreen ? offscreen_size_.width() :
9349 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:569350 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:499351 "offscreen", is_offscreen,
9352 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:159353 {
[email protected]a36ed4832014-04-24 16:40:279354 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:159355 }
9356
[email protected]8f9b8dd2013-09-12 18:05:139357 bool is_tracing;
9358 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
9359 &is_tracing);
9360 if (is_tracing) {
9361 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
9362 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
9363 is_offscreen ? offscreen_size_ : surface_->GetSize());
9364 }
9365
[email protected]6217d392010-03-25 22:08:359366 // If offscreen then don't actually SwapBuffers to the display. Just copy
9367 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:499368 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:319369 TRACE_EVENT2("gpu", "Offscreen",
9370 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:539371 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
9372 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9373 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9374 // fix this.
[email protected]62e155e2012-10-23 22:43:159375 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:539376 offscreen_saved_frame_buffer_->Create();
9377 glFinish();
9378 }
9379
9380 // Allocate the offscreen saved color texture.
9381 DCHECK(offscreen_saved_color_format_);
9382 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:099383 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:539384
9385 offscreen_saved_frame_buffer_->AttachRenderTexture(
9386 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:059387 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9388 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9389 GL_FRAMEBUFFER_COMPLETE) {
9390 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9391 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:569392 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9393 return;
[email protected]f0cfe752013-01-14 01:09:059394 }
[email protected]1fb8c482011-08-31 01:01:539395
[email protected]f0cfe752013-01-14 01:09:059396 // Clear the offscreen color texture.
9397 // TODO(piman): Is this still necessary?
9398 {
9399 ScopedFrameBufferBinder binder(this,
9400 offscreen_saved_frame_buffer_->id());
9401 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:459402 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9403 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:059404 glClear(GL_COLOR_BUFFER_BIT);
9405 RestoreClearState();
9406 }
[email protected]1fb8c482011-08-31 01:01:539407 }
9408
9409 UpdateParentTextureInfo();
9410 }
9411
[email protected]f0cfe752013-01-14 01:09:059412 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:569413 return;
[email protected]ab09b612013-03-11 22:11:519414 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:309415 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:359416
[email protected]34ff8b0c2010-10-01 20:06:029417 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:139418 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:279419 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:489420 } else {
[email protected]069944672012-04-25 20:52:239421 ScopedFrameBufferBinder binder(this,
9422 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:139423
[email protected]069944672012-04-25 20:52:239424 if (offscreen_target_buffer_preserved_) {
9425 // Copy the target frame buffer to the saved offscreen texture.
9426 offscreen_saved_color_texture_->Copy(
9427 offscreen_saved_color_texture_->size(),
9428 offscreen_saved_color_format_);
9429 } else {
9430 // Flip the textures in the parent context via the texture manager.
9431 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:499432 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:239433 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:569434
[email protected]069944672012-04-25 20:52:239435 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9436 offscreen_target_frame_buffer_->AttachRenderTexture(
9437 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:489438 }
[email protected]069944672012-04-25 20:52:239439
9440 // Ensure the side effects of the copy are visible to the parent
9441 // context. There is no need to do this for ANGLE because it uses a
9442 // single D3D device for all contexts.
[email protected]f42f05b2013-11-15 21:46:189443 if (!feature_info_->feature_flags().is_angle)
[email protected]069944672012-04-25 20:52:239444 glFlush();
[email protected]0c8c9d22010-06-25 17:36:399445 }
[email protected]6217d392010-03-25 22:08:359446 } else {
[email protected]f62a5ab2011-05-23 20:34:159447 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019448 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:569449 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:019450 }
[email protected]6217d392010-03-25 22:08:359451 }
vmiura8266ca72014-09-09 21:37:009452
9453 // This may be a slow command. Exit command processing to allow for
9454 // context preemption and GPU watchdog checks.
9455 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:359456}
9457
[email protected]d4239852011-08-12 04:51:229458error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:349459 uint32 immediate_data_size,
9460 const void* cmd_data) {
9461 const gles2::cmds::EnableFeatureCHROMIUM& c =
9462 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:189463 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289464 if (!bucket || bucket->size() == 0) {
9465 return error::kInvalidArguments;
9466 }
[email protected]ed9f9cd2013-02-27 21:12:359467 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189468 Result* result = GetSharedMemoryAs<Result*>(
9469 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9470 if (!result) {
9471 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109472 }
[email protected]b1d2dcb2010-05-17 19:24:189473 // Check that the client initialized the result.
9474 if (*result != 0) {
9475 return error::kInvalidArguments;
9476 }
9477 std::string feature_str;
9478 if (!bucket->GetAsString(&feature_str)) {
9479 return error::kInvalidArguments;
9480 }
9481
9482 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229483 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189484 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229485 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:409486 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9487 // TODO(gman): decide how to remove the need for this const_cast.
9488 // I could make validators_ non const but that seems bad as this is the only
9489 // place it is needed. I could make some special friend class of validators
9490 // just to allow this to set them. That seems silly. I could refactor this
9491 // code to use the extension mechanism or the initialization attributes to
9492 // turn this feature on. Given that the only real point of this is to make
9493 // the conformance tests pass and given that there is lots of real work that
9494 // needs to be done it seems like refactoring for one to one of those
9495 // methods is a very low priority.
9496 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049497 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9498 force_webgl_glsl_validation_ = true;
9499 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189500 } else {
9501 return error::kNoError;
9502 }
9503
9504 *result = 1; // true.
9505 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109506}
9507
[email protected]c2f8c8402010-12-06 18:07:249508error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9509 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:349510 const void* cmd_data) {
9511 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
9512 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
9513 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249514 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359515 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:199516 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:249517 bucket->SetFromString(info->extensions().c_str());
9518 return error::kNoError;
9519}
9520
9521error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:349522 uint32 immediate_data_size,
9523 const void* cmd_data) {
9524 const gles2::cmds::RequestExtensionCHROMIUM& c =
9525 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249526 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289527 if (!bucket || bucket->size() == 0) {
9528 return error::kInvalidArguments;
9529 }
[email protected]c2f8c8402010-12-06 18:07:249530 std::string feature_str;
9531 if (!bucket->GetAsString(&feature_str)) {
9532 return error::kInvalidArguments;
9533 }
9534
[email protected]4b7eba92013-01-08 02:23:569535 bool desire_webgl_glsl_validation =
9536 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9537 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:499538 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:139539 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:069540 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:569541 if (force_webgl_glsl_validation_) {
9542 desire_standard_derivatives =
9543 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:499544 desire_frag_depth =
9545 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:139546 desire_draw_buffers =
9547 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:069548 desire_shader_texture_lod =
9549 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049550 }
9551
[email protected]4b7eba92013-01-08 02:23:569552 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:499553 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:139554 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9555 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:499556 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9557 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9558 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:139559 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:069560 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:249561 InitializeShaderTranslator();
9562 }
9563
[email protected]302ce6d2011-07-07 23:28:119564 UpdateCapabilities();
9565
[email protected]c2f8c8402010-12-06 18:07:249566 return error::kNoError;
9567}
9568
[email protected]372e0412011-06-28 16:08:569569error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
vmiuracd108592014-09-08 14:36:349570 uint32 immediate_data_size,
9571 const void* cmd_data) {
9572 const gles2::cmds::GetMultipleIntegervCHROMIUM& c =
9573 *static_cast<const gles2::cmds::GetMultipleIntegervCHROMIUM*>(cmd_data);
[email protected]372e0412011-06-28 16:08:569574 GLuint count = c.count;
9575 uint32 pnames_size;
9576 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
9577 return error::kOutOfBounds;
9578 }
9579 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
9580 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
9581 if (pnames == NULL) {
9582 return error::kOutOfBounds;
9583 }
9584
9585 // We have to copy them since we use them twice so the client
9586 // can't change them between the time we validate them and the time we use
9587 // them.
[email protected]40d90a22013-04-09 03:39:559588 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:569589 memcpy(enums.get(), pnames, pnames_size);
9590
9591 // Count up the space needed for the result.
9592 uint32 num_results = 0;
9593 for (GLuint ii = 0; ii < count; ++ii) {
9594 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
9595 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:519596 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]caa13ed2014-02-17 11:29:209597 "glGetMultipleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:569598 return error::kNoError;
9599 }
9600 // Num will never be more than 4.
9601 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:479602 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:569603 return error::kOutOfBounds;
9604 }
9605 }
9606
9607 uint32 result_size = 0;
9608 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
9609 return error::kOutOfBounds;
9610 }
9611
9612 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:519613 LOCAL_SET_GL_ERROR(
9614 GL_INVALID_VALUE,
[email protected]caa13ed2014-02-17 11:29:209615 "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:569616 return error::kNoError;
9617 }
9618
9619 GLint* results = GetSharedMemoryAs<GLint*>(
9620 c.results_shm_id, c.results_shm_offset, result_size);
9621 if (results == NULL) {
9622 return error::kOutOfBounds;
9623 }
9624
9625 // Check the results have been cleared in case the context was lost.
9626 for (uint32 ii = 0; ii < num_results; ++ii) {
9627 if (results[ii]) {
9628 return error::kInvalidArguments;
9629 }
9630 }
9631
9632 // Get each result.
9633 GLint* start = results;
9634 for (GLuint ii = 0; ii < count; ++ii) {
9635 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:269636 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:539637 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:489638 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:569639 }
9640 results += num_written;
9641 }
9642
9643 // Just to verify. Should this be a DCHECK?
9644 if (static_cast<uint32>(results - start) != num_results) {
9645 return error::kOutOfBounds;
9646 }
9647
9648 return error::kNoError;
9649}
9650
[email protected]2318d342011-07-11 22:27:429651error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:349652 uint32 immediate_data_size,
9653 const void* cmd_data) {
9654 const gles2::cmds::GetProgramInfoCHROMIUM& c =
9655 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429656 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429657 uint32 bucket_id = c.bucket_id;
9658 Bucket* bucket = CreateBucket(bucket_id);
9659 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429660 Program* program = NULL;
9661 program = GetProgram(program_id);
9662 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469663 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429664 }
[email protected]df37b9932013-03-08 05:21:429665 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429666 return error::kNoError;
9667}
9668
[email protected]38d139d2011-07-14 00:38:439669error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9670 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439671 case GL_NO_ERROR:
9672 // TODO(kbr): improve the precision of the error code in this case.
9673 // Consider delegating to context for error code if MakeCurrent fails.
9674 return error::kUnknown;
9675 case GL_GUILTY_CONTEXT_RESET_ARB:
9676 return error::kGuilty;
9677 case GL_INNOCENT_CONTEXT_RESET_ARB:
9678 return error::kInnocent;
9679 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9680 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439681 }
9682
9683 NOTREACHED();
9684 return error::kUnknown;
9685}
9686
jbauman7a059312014-10-16 19:30:549687void GLES2DecoderImpl::MaybeExitOnContextLost() {
9688 // Some D3D drivers cannot recover from device lost in the GPU process
9689 // sandbox. Allow a new GPU process to launch.
9690 if (workarounds().exit_on_context_lost) {
9691 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
9692 << " a D3D device in the Chrome GPU process sandbox.";
9693#if defined(OS_WIN)
9694 base::win::SetShouldCrashOnProcessDetach(false);
9695#endif
9696 exit(0);
9697 }
9698}
9699
[email protected]38d139d2011-07-14 00:38:439700bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099701 if (reset_status_ != GL_NO_ERROR) {
jbauman7a059312014-10-16 19:30:549702 MaybeExitOnContextLost();
[email protected]c4485aad62012-12-17 10:19:099703 return true;
9704 }
[email protected]706b69f2012-07-27 04:59:309705 if (context_->WasAllocatedUsingRobustnessExtension()) {
9706 GLenum status = GL_NO_ERROR;
9707 if (has_robustness_extension_)
9708 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439709 if (status != GL_NO_ERROR) {
9710 // The graphics card was reset. Signal a lost context to the application.
9711 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229712 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439713 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099714 << " context lost via ARB/EXT_robustness. Reset status = "
9715 << GLES2Util::GetStringEnum(status);
jbauman7a059312014-10-16 19:30:549716 MaybeExitOnContextLost();
[email protected]38d139d2011-07-14 00:38:439717 return true;
9718 }
9719 }
9720 return false;
9721}
9722
[email protected]93a7d98f2013-07-11 00:04:229723bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9724 return WasContextLost() && reset_by_robustness_extension_;
9725}
9726
[email protected]c4485aad62012-12-17 10:19:099727void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9728 // Only loses the context once.
9729 if (reset_status_ != GL_NO_ERROR) {
9730 return;
9731 }
9732
9733 // Marks this context as lost.
9734 reset_status_ = reset_status;
9735 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099736}
9737
[email protected]b096d032013-03-08 03:08:019738error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:349739 uint32 immediate_data_size,
9740 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:019741 return error::kUnknownCommand;
9742}
9743
[email protected]840a7e462013-02-27 01:29:519744error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:349745 uint32 immediate_data_size,
9746 const void* cmd_data) {
9747 const gles2::cmds::WaitSyncPointCHROMIUM& c =
9748 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
sievers173a20d2014-10-22 18:19:329749 uint32 sync_point = c.sync_point;
[email protected]840a7e462013-02-27 01:29:519750 if (wait_sync_point_callback_.is_null())
9751 return error::kNoError;
9752
sievers173a20d2014-10-22 18:19:329753 return wait_sync_point_callback_.Run(sync_point) ?
[email protected]840a7e462013-02-27 01:29:519754 error::kNoError : error::kDeferCommandUntilLater;
9755}
9756
[email protected]5dfc457b2013-12-13 11:13:079757error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:349758 uint32 immediate_data_size,
9759 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:079760 if (surface_->DeferDraws())
9761 return error::kDeferCommandUntilLater;
9762 if (!surface_->SetBackbufferAllocation(false))
9763 return error::kLostContext;
9764 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
9765 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
9766 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
9767 return error::kNoError;
9768}
9769
[email protected]882ba1e22012-03-08 19:02:539770bool GLES2DecoderImpl::GenQueriesEXTHelper(
9771 GLsizei n, const GLuint* client_ids) {
9772 for (GLsizei ii = 0; ii < n; ++ii) {
9773 if (query_manager_->GetQuery(client_ids[ii])) {
9774 return false;
9775 }
9776 }
[email protected]4eea7e62014-04-22 21:14:439777 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:539778 return true;
9779}
9780
9781void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9782 GLsizei n, const GLuint* client_ids) {
9783 for (GLsizei ii = 0; ii < n; ++ii) {
9784 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9785 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:139786 ContextState::QueryMap::iterator it =
9787 state_.current_queries.find(query->target());
9788 if (it != state_.current_queries.end())
9789 state_.current_queries.erase(it);
9790
[email protected]c45f1972012-03-14 07:27:369791 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539792 }
[email protected]4eea7e62014-04-22 21:14:439793 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:539794 }
9795}
9796
[email protected]22e3f552012-03-13 01:54:199797bool GLES2DecoderImpl::ProcessPendingQueries() {
9798 if (query_manager_.get() == NULL) {
9799 return false;
9800 }
[email protected]c45f1972012-03-14 07:27:369801 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199802 current_decoder_error_ = error::kOutOfBounds;
9803 }
9804 return query_manager_->HavePendingQueries();
9805}
9806
[email protected]5a36dc132013-07-23 23:17:559807// Note that if there are no pending readpixels right now,
9808// this function will call the callback immediately.
9809void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9810 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9811 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9812 } else {
9813 callback.Run();
9814 }
9815}
9816
9817void GLES2DecoderImpl::ProcessPendingReadPixels() {
9818 while (!pending_readpixel_fences_.empty() &&
9819 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9820 std::vector<base::Closure> callbacks =
9821 pending_readpixel_fences_.front()->callbacks;
9822 pending_readpixel_fences_.pop();
9823 for (size_t i = 0; i < callbacks.size(); i++) {
9824 callbacks[i].Run();
9825 }
9826 }
9827}
9828
[email protected]2b1767cf2013-03-16 09:25:059829bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559830 return !pending_readpixel_fences_.empty() ||
9831 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059832}
9833
9834void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559835 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:489836 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059837 return;
[email protected]b68b100752013-06-05 08:34:489838 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059839 ProcessFinishedAsyncTransfers();
9840}
9841
vmiuracd108592014-09-08 14:36:349842error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
9843 const void* cmd_data) {
9844 const gles2::cmds::BeginQueryEXT& c =
9845 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:539846 GLenum target = static_cast<GLenum>(c.target);
9847 GLuint client_id = static_cast<GLuint>(c.id);
9848 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9849 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9850
[email protected]c45f1972012-03-14 07:27:369851 switch (target) {
9852 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559853 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:319854 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
9855 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009856 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369857 break;
[email protected]6a25ae422014-04-17 23:48:279858 case GL_COMMANDS_COMPLETED_CHROMIUM:
9859 if (!features().chromium_sync_query) {
9860 LOCAL_SET_GL_ERROR(
9861 GL_INVALID_OPERATION, "glBeginQueryEXT",
9862 "not enabled for commands completed queries");
9863 return error::kNoError;
9864 }
9865 break;
[email protected]c45f1972012-03-14 07:27:369866 default:
[email protected]62e155e2012-10-23 22:43:159867 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519868 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009869 GL_INVALID_OPERATION, "glBeginQueryEXT",
9870 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369871 return error::kNoError;
9872 }
9873 break;
[email protected]882ba1e22012-03-08 19:02:539874 }
9875
[email protected]8ebd46c2014-01-08 12:06:139876 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519877 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439878 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539879 return error::kNoError;
9880 }
9881
9882 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519883 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539884 return error::kNoError;
9885 }
9886
9887 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9888 if (!query) {
[email protected]4eea7e62014-04-22 21:14:439889 if (!query_manager_->IsValidQuery(client_id)) {
9890 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9891 "glBeginQueryEXT",
9892 "id not made by glGenQueriesEXT");
9893 return error::kNoError;
9894 }
[email protected]c45f1972012-03-14 07:27:369895 query = query_manager_->CreateQuery(
9896 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539897 }
9898
[email protected]c45f1972012-03-14 07:27:369899 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519900 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439901 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539902 return error::kNoError;
9903 } else if (query->shm_id() != sync_shm_id ||
9904 query->shm_offset() != sync_shm_offset) {
9905 DLOG(ERROR) << "Shared memory used by query not the same as before";
9906 return error::kInvalidArguments;
9907 }
9908
[email protected]c45f1972012-03-14 07:27:369909 if (!query_manager_->BeginQuery(query)) {
9910 return error::kOutOfBounds;
9911 }
[email protected]882ba1e22012-03-08 19:02:539912
[email protected]8ebd46c2014-01-08 12:06:139913 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:539914 return error::kNoError;
9915}
9916
vmiuracd108592014-09-08 14:36:349917error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
9918 const void* cmd_data) {
9919 const gles2::cmds::EndQueryEXT& c =
9920 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:539921 GLenum target = static_cast<GLenum>(c.target);
9922 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:139923 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:539924
[email protected]8ebd46c2014-01-08 12:06:139925 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519926 LOCAL_SET_GL_ERROR(
9927 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539928 return error::kNoError;
9929 }
[email protected]882ba1e22012-03-08 19:02:539930
[email protected]8ebd46c2014-01-08 12:06:139931 QueryManager::Query* query = it->second.get();
9932 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369933 return error::kOutOfBounds;
9934 }
9935
[email protected]fe8d73c2013-02-16 22:37:329936 query_manager_->ProcessPendingTransferQueries();
9937
[email protected]8ebd46c2014-01-08 12:06:139938 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:539939 return error::kNoError;
9940}
9941
[email protected]944b62f32012-09-27 02:20:469942bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9943 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469944 for (GLsizei ii = 0; ii < n; ++ii) {
9945 if (GetVertexAttribManager(client_ids[ii])) {
9946 return false;
9947 }
9948 }
[email protected]ab4fd7282012-10-12 16:25:579949
[email protected]62e155e2012-10-23 22:43:159950 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579951 // Emulated VAO
9952 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:489953 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:579954 }
9955 } else {
[email protected]40d90a22013-04-09 03:39:559956 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579957
9958 glGenVertexArraysOES(n, service_ids.get());
9959 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:489960 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:579961 }
[email protected]944b62f32012-09-27 02:20:469962 }
[email protected]ab4fd7282012-10-12 16:25:579963
[email protected]944b62f32012-09-27 02:20:469964 return true;
9965}
9966
9967void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9968 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469969 for (GLsizei ii = 0; ii < n; ++ii) {
9970 VertexAttribManager* vao =
9971 GetVertexAttribManager(client_ids[ii]);
9972 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119973 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:119974 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:469975 }
9976 RemoveVertexAttribManager(client_ids[ii]);
9977 }
9978 }
9979}
9980
9981void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469982 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:469983 if (client_id != 0) {
9984 vao = GetVertexAttribManager(client_id);
9985 if (!vao) {
9986 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9987 // only allows names that have been previously generated. As such, we do
9988 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519989 LOCAL_SET_GL_ERROR(
9990 GL_INVALID_OPERATION,
9991 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469992 current_decoder_error_ = error::kNoError;
9993 return;
[email protected]944b62f32012-09-27 02:20:469994 }
[email protected]944b62f32012-09-27 02:20:469995 } else {
[email protected]81f20a622014-04-18 01:54:529996 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:469997 }
9998
[email protected]ab4fd7282012-10-12 16:25:579999 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110000 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2410001 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1510002 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710003 EmulateVertexArrayState();
10004 } else {
[email protected]da364812014-05-09 21:39:4810005 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5710006 glBindVertexArrayOES(service_id);
10007 }
10008 }
10009}
10010
10011// Used when OES_vertex_array_object isn't natively supported
10012void GLES2DecoderImpl::EmulateVertexArrayState() {
10013 // Setup the Vertex attribute state
10014 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2310015 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5710016 }
10017
10018 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2110019 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2410020 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5710021 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
10022 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4610023}
10024
10025bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610026 const VertexAttribManager* vao =
10027 GetVertexAttribManager(client_id);
10028 return vao && vao->IsValid() && !vao->IsDeleted();
10029}
10030
[email protected]e51bdf32011-11-23 22:21:4610031#if defined(OS_MACOSX)
10032void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
10033 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
10034 texture_id);
10035 if (it != texture_to_io_surface_map_.end()) {
10036 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5310037 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4610038 CFRelease(surface);
10039 texture_to_io_surface_map_.erase(it);
10040 }
10041}
10042#endif
10043
10044void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
10045 GLenum target, GLsizei width, GLsizei height,
10046 GLuint io_surface_id, GLuint plane) {
10047#if defined(OS_MACOSX)
10048 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5110049 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310050 GL_INVALID_OPERATION,
10051 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4610052 return;
10053 }
10054
[email protected]e51bdf32011-11-23 22:21:4610055 if (target != GL_TEXTURE_RECTANGLE_ARB) {
10056 // This might be supported in the future, and if we could require
10057 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
10058 // could delete a lot of code. For now, perform strict validation so we
10059 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5110060 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610061 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310062 "glTexImageIOSurface2DCHROMIUM",
10063 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4610064 return;
10065 }
10066
[email protected]09d50362012-10-18 20:54:3710067 // Default target might be conceptually valid, but disallow it to avoid
10068 // accidents.
[email protected]c986af502013-08-14 01:04:4410069 TextureRef* texture_ref =
10070 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910071 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110072 LOCAL_SET_GL_ERROR(
10073 GL_INVALID_OPERATION,
10074 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4610075 return;
10076 }
[email protected]e51bdf32011-11-23 22:21:4610077
10078 // Look up the new IOSurface. Note that because of asynchrony
10079 // between processes this might fail; during live resizing the
10080 // plugin process might allocate and release an IOSurface before
10081 // this process gets a chance to look it up. Hold on to any old
10082 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5310083 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4610084 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5110085 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310086 GL_INVALID_OPERATION,
10087 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4610088 return;
10089 }
10090
10091 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4910092 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4610093
10094 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
10095 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4910096 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4610097
10098 CGLContextObj context =
10099 static_cast<CGLContextObj>(context_->GetHandle());
10100
[email protected]c3a6b4a2014-06-04 09:25:5310101 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4610102 context,
10103 target,
10104 GL_RGBA,
10105 width,
10106 height,
10107 GL_BGRA,
10108 GL_UNSIGNED_INT_8_8_8_8_REV,
10109 surface,
10110 plane);
10111
10112 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5110113 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610114 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310115 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4610116 return;
10117 }
10118
10119 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910120 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4610121 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
10122
10123#else
[email protected]ab09b612013-03-11 22:11:5110124 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310125 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4610126#endif
10127}
10128
[email protected]97dc7cbe2011-12-06 17:26:1710129static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
10130 switch (internalformat) {
10131 case GL_RGB565:
10132 return GL_RGB;
10133 case GL_RGBA4:
10134 return GL_RGBA;
10135 case GL_RGB5_A1:
10136 return GL_RGBA;
10137 case GL_RGB8_OES:
10138 return GL_RGB;
10139 case GL_RGBA8_OES:
10140 return GL_RGBA;
10141 case GL_LUMINANCE8_ALPHA8_EXT:
10142 return GL_LUMINANCE_ALPHA;
10143 case GL_LUMINANCE8_EXT:
10144 return GL_LUMINANCE;
10145 case GL_ALPHA8_EXT:
10146 return GL_ALPHA;
10147 case GL_RGBA32F_EXT:
10148 return GL_RGBA;
10149 case GL_RGB32F_EXT:
10150 return GL_RGB;
10151 case GL_ALPHA32F_EXT:
10152 return GL_ALPHA;
10153 case GL_LUMINANCE32F_EXT:
10154 return GL_LUMINANCE;
10155 case GL_LUMINANCE_ALPHA32F_EXT:
10156 return GL_LUMINANCE_ALPHA;
10157 case GL_RGBA16F_EXT:
10158 return GL_RGBA;
10159 case GL_RGB16F_EXT:
10160 return GL_RGB;
10161 case GL_ALPHA16F_EXT:
10162 return GL_ALPHA;
10163 case GL_LUMINANCE16F_EXT:
10164 return GL_LUMINANCE;
10165 case GL_LUMINANCE_ALPHA16F_EXT:
10166 return GL_LUMINANCE_ALPHA;
10167 case GL_BGRA8_EXT:
10168 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5910169 case GL_SRGB8_ALPHA8_EXT:
10170 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1710171 default:
10172 return GL_NONE;
10173 }
10174}
10175
[email protected]43410e92012-04-20 17:06:2810176void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:0310177 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:5410178 GLenum internal_format, GLenum dest_type) {
[email protected]1e24dc7f2014-04-14 02:40:0810179 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
10180
[email protected]370eaf12013-05-18 09:19:4910181 TextureRef* dest_texture_ref = GetTexture(dest_id);
10182 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:2810183
[email protected]370eaf12013-05-18 09:19:4910184 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110185 LOCAL_SET_GL_ERROR(
10186 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:2810187 return;
10188 }
10189
10190 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110191 LOCAL_SET_GL_ERROR(
10192 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:2810193 return;
10194 }
10195
[email protected]370eaf12013-05-18 09:19:4910196 Texture* source_texture = source_texture_ref->texture();
10197 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710198 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2510199 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3410200 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
10201 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:0010202 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10203 "glCopyTextureCHROMIUM",
10204 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:0310205 return;
10206 }
10207
[email protected]43410e92012-04-20 17:06:2810208 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:2810209
[email protected]3e0dfd72014-02-21 06:28:4110210 gfx::GLImage* image =
10211 source_texture->GetLevelImage(source_texture->target(), 0);
10212 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5510213 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5610214 source_width = size.width();
10215 source_height = size.height();
10216 if (source_width <= 0 || source_height <= 0) {
10217 LOCAL_SET_GL_ERROR(
10218 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5510219 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5610220 return;
10221 }
[email protected]3ecc1052013-09-26 08:59:0010222 } else {
10223 if (!source_texture->GetLevelSize(
10224 source_texture->target(), 0, &source_width, &source_height)) {
10225 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10226 "glCopyTextureChromium",
10227 "source texture has no level 0");
10228 return;
10229 }
10230
10231 // Check that this type of texture is allowed.
10232 if (!texture_manager()->ValidForTarget(
10233 source_texture->target(), level, source_width, source_height, 1)) {
10234 LOCAL_SET_GL_ERROR(
10235 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
10236 return;
10237 }
[email protected]377976552013-05-14 23:32:5610238 }
10239
[email protected]04b5b37d2014-02-07 02:11:5110240 // Clear the source texture if necessary.
10241 if (!texture_manager()->ClearTextureLevel(
10242 this, source_texture_ref, source_texture->target(), 0)) {
10243 LOCAL_SET_GL_ERROR(
10244 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
10245 return;
10246 }
10247
[email protected]a6e3d282014-08-22 22:20:4410248 GLenum source_type = 0;
10249 GLenum source_internal_format = 0;
10250 source_texture->GetLevelType(
10251 source_texture->target(), 0, &source_type, &source_internal_format);
10252
10253 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
10254 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
10255 // renderable on some platforms.
reveman6b0fbe42014-09-04 00:55:0310256 bool valid_dest_format = internal_format == GL_RGB ||
10257 internal_format == GL_RGBA ||
10258 internal_format == GL_BGRA_EXT;
[email protected]a6e3d282014-08-22 22:20:4410259 bool valid_source_format = source_internal_format == GL_ALPHA ||
10260 source_internal_format == GL_RGB ||
10261 source_internal_format == GL_RGBA ||
10262 source_internal_format == GL_LUMINANCE ||
10263 source_internal_format == GL_LUMINANCE_ALPHA ||
10264 source_internal_format == GL_BGRA_EXT;
10265 if (!valid_source_format || !valid_dest_format) {
10266 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10267 "glCopyTextureCHROMIUM",
10268 "invalid internal format");
10269 return;
10270 }
10271
[email protected]cf6b8f62012-05-25 21:43:3710272 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
10273 // needed because it takes 10s of milliseconds to initialize.
10274 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5110275 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3710276 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2710277 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3710278 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5110279 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3710280 return;
10281 }
10282
[email protected]efc87712014-07-09 00:22:4710283 GLenum dest_type_previous = dest_type;
10284 GLenum dest_internal_format = internal_format;
[email protected]02965c22013-03-09 02:40:0710285 bool dest_level_defined = dest_texture->GetLevelSize(
10286 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2810287
[email protected]0a1e9ad2012-05-04 21:13:0310288 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:5410289 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0710290 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0310291 }
10292
10293 // Resize the destination texture to the dimensions of the source texture.
10294 if (!dest_level_defined || dest_width != source_width ||
10295 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5410296 dest_internal_format != internal_format ||
10297 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2810298 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5110299 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0710300 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:3810301 glTexImage2D(
[email protected]43410e92012-04-20 17:06:2810302 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:0310303 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5110304 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0310305 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0210306 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2810307 return;
[email protected]0a1e9ad2012-05-04 21:13:0310308 }
[email protected]43410e92012-04-20 17:06:2810309
10310 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910311 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0310312 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2510313 } else {
[email protected]02965c22013-03-09 02:40:0710314 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:4910315 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:2810316 }
10317
[email protected]00c2cf92014-03-14 00:08:3710318 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5410319
revemance8fbe82014-09-05 02:19:5210320 // Try using GLImage::CopyTexImage when possible.
10321 bool unpack_premultiply_alpha_change =
10322 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
10323 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
10324 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
10325 if (image->CopyTexImage(GL_TEXTURE_2D))
10326 return;
10327 }
10328
10329 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
10330
[email protected]5394a4102013-04-18 05:41:3710331 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
10332 // before presenting.
10333 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
10334 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
10335 // instead of using default matrix crbug.com/226218.
10336 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
10337 0.0f, 1.0f, 0.0f, 0.0f,
10338 0.0f, 0.0f, 1.0f, 0.0f,
10339 0.0f, 0.0f, 0.0f, 1.0f};
10340 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
10341 this,
10342 source_texture->target(),
[email protected]5394a4102013-04-18 05:41:3710343 source_texture->service_id(),
[email protected]90f7d30d2014-08-13 02:51:5710344 dest_texture->service_id(),
10345 level,
10346 source_width,
10347 source_height,
[email protected]5394a4102013-04-18 05:41:3710348 unpack_flip_y_,
10349 unpack_premultiply_alpha_,
10350 unpack_unpremultiply_alpha_,
10351 default_matrix);
10352 } else {
[email protected]90f7d30d2014-08-13 02:51:5710353 copy_texture_CHROMIUM_->DoCopyTexture(this,
10354 source_texture->target(),
10355 source_texture->service_id(),
10356 source_internal_format,
10357 dest_texture->service_id(),
10358 level,
10359 internal_format,
10360 source_width,
10361 source_height,
10362 unpack_flip_y_,
10363 unpack_premultiply_alpha_,
10364 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3710365 }
[email protected]91c94eb2013-10-22 10:32:5410366
10367 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2810368}
10369
[email protected]97dc7cbe2011-12-06 17:26:1710370static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
10371 switch (internalformat) {
10372 case GL_RGB565:
10373 return GL_UNSIGNED_SHORT_5_6_5;
10374 case GL_RGBA4:
10375 return GL_UNSIGNED_SHORT_4_4_4_4;
10376 case GL_RGB5_A1:
10377 return GL_UNSIGNED_SHORT_5_5_5_1;
10378 case GL_RGB8_OES:
10379 return GL_UNSIGNED_BYTE;
10380 case GL_RGBA8_OES:
10381 return GL_UNSIGNED_BYTE;
10382 case GL_LUMINANCE8_ALPHA8_EXT:
10383 return GL_UNSIGNED_BYTE;
10384 case GL_LUMINANCE8_EXT:
10385 return GL_UNSIGNED_BYTE;
10386 case GL_ALPHA8_EXT:
10387 return GL_UNSIGNED_BYTE;
10388 case GL_RGBA32F_EXT:
10389 return GL_FLOAT;
10390 case GL_RGB32F_EXT:
10391 return GL_FLOAT;
10392 case GL_ALPHA32F_EXT:
10393 return GL_FLOAT;
10394 case GL_LUMINANCE32F_EXT:
10395 return GL_FLOAT;
10396 case GL_LUMINANCE_ALPHA32F_EXT:
10397 return GL_FLOAT;
10398 case GL_RGBA16F_EXT:
10399 return GL_HALF_FLOAT_OES;
10400 case GL_RGB16F_EXT:
10401 return GL_HALF_FLOAT_OES;
10402 case GL_ALPHA16F_EXT:
10403 return GL_HALF_FLOAT_OES;
10404 case GL_LUMINANCE16F_EXT:
10405 return GL_HALF_FLOAT_OES;
10406 case GL_LUMINANCE_ALPHA16F_EXT:
10407 return GL_HALF_FLOAT_OES;
10408 case GL_BGRA8_EXT:
10409 return GL_UNSIGNED_BYTE;
10410 default:
10411 return GL_NONE;
10412 }
10413}
10414
10415void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4410416 GLenum target,
10417 GLint levels,
10418 GLenum internal_format,
10419 GLsizei width,
10420 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1310421 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
10422 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4110423 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0010424 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5110425 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310426 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1710427 return;
10428 }
[email protected]c986af502013-08-14 01:04:4410429 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10430 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910431 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110432 LOCAL_SET_GL_ERROR(
10433 GL_INVALID_OPERATION,
10434 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1710435 return;
10436 }
[email protected]370eaf12013-05-18 09:19:4910437 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710438 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4410439 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1710440 }
[email protected]02965c22013-03-09 02:40:0710441 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5110442 LOCAL_SET_GL_ERROR(
10443 GL_INVALID_OPERATION,
10444 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1710445 return;
10446 }
[email protected]7989c9e2013-01-23 06:39:2610447
10448 GLenum format = ExtractFormatFromStorageFormat(internal_format);
10449 GLenum type = ExtractTypeFromStorageFormat(internal_format);
10450
10451 {
10452 GLsizei level_width = width;
10453 GLsizei level_height = height;
10454 uint32 estimated_size = 0;
10455 for (int ii = 0; ii < levels; ++ii) {
10456 uint32 level_size = 0;
10457 if (!GLES2Util::ComputeImageDataSizes(
10458 level_width, level_height, format, type, state_.unpack_alignment,
10459 &estimated_size, NULL, NULL) ||
10460 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110461 LOCAL_SET_GL_ERROR(
10462 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2610463 return;
10464 }
10465 level_width = std::max(1, level_width >> 1);
10466 level_height = std::max(1, level_height >> 1);
10467 }
10468 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110469 LOCAL_SET_GL_ERROR(
10470 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610471 return;
10472 }
10473 }
10474
[email protected]ab09b612013-03-11 22:11:5110475 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3810476 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5110477 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1710478 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1510479 GLsizei level_width = width;
10480 GLsizei level_height = height;
10481 for (int ii = 0; ii < levels; ++ii) {
10482 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910483 texture_ref, target, ii, format,
10484 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1510485 level_width = std::max(1, level_width >> 1);
10486 level_height = std::max(1, level_height >> 1);
10487 }
[email protected]02965c22013-03-09 02:40:0710488 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1710489 }
[email protected]97dc7cbe2011-12-06 17:26:1710490}
[email protected]e51bdf32011-11-23 22:21:4610491
[email protected]78b514b2012-05-01 21:50:5910492error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3410493 uint32 immediate_data_size,
10494 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3510495 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5910496}
10497
10498void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710499 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210500 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210501 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710502 "mailbox[0]", static_cast<unsigned char>(data[0]));
10503
[email protected]43f253da2014-06-10 17:51:2210504 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10505 &state_, target);
10506 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
10507}
10508
10509void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
10510 GLenum target, const GLbyte* data) {
10511 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
10512 "context", logger_.GetLogPrefix(),
10513 "mailbox[0]", static_cast<unsigned char>(data[0]));
10514
10515 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
10516 target, data);
10517}
10518
10519void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
10520 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3710521 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2210522 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3710523 "mailbox that was not generated by "
10524 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210525
[email protected]370eaf12013-05-18 09:19:4910526 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110527 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210528 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910529 return;
10530 }
10531
[email protected]62e65f02013-05-29 22:28:1010532 Texture* produced = texture_manager()->Produce(texture_ref);
10533 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5110534 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210535 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
10536 return;
10537 }
10538
10539 if (produced->target() != target) {
10540 LOCAL_SET_GL_ERROR(
10541 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5910542 return;
10543 }
10544
[email protected]64ba52f2014-02-15 14:22:3710545 group_->mailbox_manager()->ProduceTexture(target, mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5910546}
10547
10548void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710549 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210550 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210551 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710552 "mailbox[0]", static_cast<unsigned char>(data[0]));
10553 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10554 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
10555 "mailbox that was not generated by "
10556 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210557
[email protected]62e65f02013-05-29 22:28:1010558 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4410559 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1110560 if (!texture_ref.get()) {
10561 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10562 "glConsumeTextureCHROMIUM",
10563 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910564 return;
10565 }
[email protected]62e65f02013-05-29 22:28:1010566 GLuint client_id = texture_ref->client_id();
10567 if (!client_id) {
10568 LOCAL_SET_GL_ERROR(
10569 GL_INVALID_OPERATION,
10570 "glConsumeTextureCHROMIUM", "unknown texture for target");
10571 return;
10572 }
[email protected]64ba52f2014-02-15 14:22:3710573 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
[email protected]62e65f02013-05-29 22:28:1010574 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110575 LOCAL_SET_GL_ERROR(
10576 GL_INVALID_OPERATION,
10577 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910578 return;
10579 }
[email protected]62e65f02013-05-29 22:28:1010580 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110581 LOCAL_SET_GL_ERROR(
10582 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1010583 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5910584 return;
10585 }
[email protected]62e65f02013-05-29 22:28:1010586
10587 DeleteTexturesHelper(1, &client_id);
10588 texture_ref = texture_manager()->Consume(client_id, texture);
10589 glBindTexture(target, texture_ref->service_id());
10590
10591 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10592 unit.bind_target = target;
10593 switch (target) {
10594 case GL_TEXTURE_2D:
10595 unit.bound_texture_2d = texture_ref;
10596 break;
10597 case GL_TEXTURE_CUBE_MAP:
10598 unit.bound_texture_cube_map = texture_ref;
10599 break;
10600 case GL_TEXTURE_EXTERNAL_OES:
10601 unit.bound_texture_external_oes = texture_ref;
10602 break;
10603 case GL_TEXTURE_RECTANGLE_ARB:
10604 unit.bound_texture_rectangle_arb = texture_ref;
10605 break;
10606 default:
10607 NOTREACHED(); // Validation should prevent us getting here.
10608 break;
10609 }
[email protected]78b514b2012-05-01 21:50:5910610}
10611
[email protected]43f253da2014-06-10 17:51:2210612error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
10613 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3410614 const void* cmd_data) {
10615 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
10616 *static_cast<
10617 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
10618 cmd_data);
[email protected]43f253da2014-06-10 17:51:2210619 GLenum target = static_cast<GLenum>(c.target);
10620 uint32_t data_size;
10621 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
10622 return error::kOutOfBounds;
10623 }
10624 if (data_size > immediate_data_size) {
10625 return error::kOutOfBounds;
10626 }
10627 const GLbyte* mailbox =
10628 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
10629 if (!validators_->texture_bind_target.IsValid(target)) {
10630 LOCAL_SET_GL_ERROR_INVALID_ENUM(
10631 "glCreateAndConsumeTextureCHROMIUM", target, "target");
10632 return error::kNoError;
10633 }
10634 if (mailbox == NULL) {
10635 return error::kOutOfBounds;
10636 }
10637 uint32_t client_id = c.client_id;
10638 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
10639 return error::kNoError;
10640}
10641
10642void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
10643 const GLbyte* data, GLuint client_id) {
10644 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
10645 "context", logger_.GetLogPrefix(),
10646 "mailbox[0]", static_cast<unsigned char>(data[0]));
10647 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10648 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
10649 "passed a mailbox that was not "
10650 "generated by GenMailboxCHROMIUM.";
10651
10652 TextureRef* texture_ref = GetTexture(client_id);
10653 if (texture_ref) {
10654 LOCAL_SET_GL_ERROR(
10655 GL_INVALID_OPERATION,
10656 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
10657 return;
10658 }
10659 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
10660 if (!texture) {
10661 LOCAL_SET_GL_ERROR(
10662 GL_INVALID_OPERATION,
10663 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
10664 return;
10665 }
10666 if (texture->target() != target) {
10667 LOCAL_SET_GL_ERROR(
10668 GL_INVALID_OPERATION,
10669 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
10670 return;
10671 }
10672
[email protected]43f253da2014-06-10 17:51:2210673 texture_ref = texture_manager()->Consume(client_id, texture);
10674}
10675
[email protected]d2a0e1a2012-08-12 02:25:0110676void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10677 GLsizei length, const GLchar* marker) {
10678 if (!marker) {
10679 marker = "";
10680 }
10681 debug_marker_manager_.SetMarker(
10682 length ? std::string(marker, length) : std::string(marker));
10683}
10684
10685void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10686 GLsizei length, const GLchar* marker) {
10687 if (!marker) {
10688 marker = "";
10689 }
[email protected]cac16542014-01-15 17:53:5110690 std::string name = length ? std::string(marker, length) : std::string(marker);
10691 debug_marker_manager_.PushGroup(name);
10692 gpu_tracer_->Begin(name, kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110693}
10694
10695void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10696 debug_marker_manager_.PopGroup();
[email protected]cac16542014-01-15 17:53:5110697 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110698}
10699
[email protected]09d50362012-10-18 20:54:3710700void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10701 GLenum target, GLint image_id) {
10702 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710703
[email protected]bc26e8d2014-01-29 00:40:3010704 if (target == GL_TEXTURE_CUBE_MAP) {
10705 LOCAL_SET_GL_ERROR(
10706 GL_INVALID_ENUM,
10707 "glBindTexImage2DCHROMIUM", "invalid target");
10708 return;
10709 }
10710
[email protected]09d50362012-10-18 20:54:3710711 // Default target might be conceptually valid, but disallow it to avoid
10712 // accidents.
[email protected]c986af502013-08-14 01:04:4410713 TextureRef* texture_ref =
10714 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910715 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110716 LOCAL_SET_GL_ERROR(
10717 GL_INVALID_OPERATION,
10718 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710719 return;
10720 }
10721
10722 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10723 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110724 LOCAL_SET_GL_ERROR(
10725 GL_INVALID_OPERATION,
10726 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710727 return;
10728 }
10729
[email protected]b8160812013-04-09 00:41:0410730 {
10731 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010732 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610733 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0410734 LOCAL_SET_GL_ERROR(
10735 GL_INVALID_OPERATION,
10736 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10737 return;
10738 }
[email protected]09d50362012-10-18 20:54:3710739 }
10740
10741 gfx::Size size = gl_image->GetSize();
10742 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910743 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710744 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910745 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710746}
10747
10748void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10749 GLenum target, GLint image_id) {
10750 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710751
10752 // Default target might be conceptually valid, but disallow it to avoid
10753 // accidents.
[email protected]c986af502013-08-14 01:04:4410754 TextureRef* texture_ref =
10755 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910756 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110757 LOCAL_SET_GL_ERROR(
10758 GL_INVALID_OPERATION,
10759 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710760 return;
10761 }
10762
10763 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10764 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110765 LOCAL_SET_GL_ERROR(
10766 GL_INVALID_OPERATION,
10767 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710768 return;
10769 }
10770
10771 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910772 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710773 return;
10774
[email protected]b8160812013-04-09 00:41:0410775 {
10776 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010777 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610778 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0410779 }
[email protected]09d50362012-10-18 20:54:3710780
10781 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910782 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710783 GL_RGBA, GL_UNSIGNED_BYTE, false);
10784}
[email protected]d2a0e1a2012-08-12 02:25:0110785
[email protected]94307712012-11-16 23:26:1110786error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3410787 uint32 immediate_data_size,
10788 const void* cmd_data) {
10789 const gles2::cmds::TraceBeginCHROMIUM& c =
10790 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
[email protected]94307712012-11-16 23:26:1110791 Bucket* bucket = GetBucket(c.bucket_id);
10792 if (!bucket || bucket->size() == 0) {
10793 return error::kInvalidArguments;
10794 }
10795 std::string command_name;
10796 if (!bucket->GetAsString(&command_name)) {
10797 return error::kInvalidArguments;
10798 }
[email protected]fb97b662013-02-20 23:02:1410799 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
[email protected]cac16542014-01-15 17:53:5110800 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5110801 LOCAL_SET_GL_ERROR(
10802 GL_INVALID_OPERATION,
10803 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410804 return error::kNoError;
10805 }
[email protected]94307712012-11-16 23:26:1110806 return error::kNoError;
10807}
10808
10809void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410810 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110811 LOCAL_SET_GL_ERROR(
10812 GL_INVALID_OPERATION,
10813 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110814 return;
10815 }
[email protected]fb97b662013-02-20 23:02:1410816 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
[email protected]cac16542014-01-15 17:53:5110817 gpu_tracer_->End(kTraceCHROMIUM);
[email protected]94307712012-11-16 23:26:1110818}
10819
[email protected]2f143d482013-03-14 18:04:4910820void GLES2DecoderImpl::DoDrawBuffersEXT(
10821 GLsizei count, const GLenum* bufs) {
10822 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10823 LOCAL_SET_GL_ERROR(
10824 GL_INVALID_VALUE,
10825 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10826 return;
10827 }
10828
10829 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10830 if (framebuffer) {
10831 for (GLsizei i = 0; i < count; ++i) {
10832 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10833 bufs[i] != GL_NONE) {
10834 LOCAL_SET_GL_ERROR(
10835 GL_INVALID_OPERATION,
10836 "glDrawBuffersEXT",
10837 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10838 return;
10839 }
10840 }
10841 glDrawBuffersARB(count, bufs);
10842 framebuffer->SetDrawBuffers(count, bufs);
10843 } else { // backbuffer
10844 if (count > 1 ||
10845 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10846 LOCAL_SET_GL_ERROR(
10847 GL_INVALID_OPERATION,
10848 "glDrawBuffersEXT",
10849 "more than one buffer or bufs not GL_NONE or GL_BACK");
10850 return;
10851 }
10852 GLenum mapped_buf = bufs[0];
10853 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10854 bufs[0] == GL_BACK) {
10855 mapped_buf = GL_COLOR_ATTACHMENT0;
10856 }
10857 glDrawBuffersARB(count, &mapped_buf);
10858 group_->set_draw_buffer(bufs[0]);
10859 }
10860}
10861
[email protected]a6a09f852014-05-23 13:05:0310862void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
10863 group_->LoseContexts(other);
10864 reset_status_ = current;
10865 current_decoder_error_ = error::kLostContext;
10866}
10867
kkinnunen337d59632014-08-26 10:19:5710868void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
10869 const GLfloat* matrix) {
10870 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
10871 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
10872 if (!features().chromium_path_rendering) {
10873 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10874 "glMatrixLoadfCHROMIUM",
10875 "function not available");
10876 return;
10877 }
10878
10879 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
10880 ? state_.projection_matrix
10881 : state_.modelview_matrix;
10882 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
10883 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
10884 // since the values of the _NV and _CHROMIUM tokens match.
10885 glMatrixLoadfEXT(matrix_mode, matrix);
10886}
10887
10888void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
10889 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
10890 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
10891
10892 if (!features().chromium_path_rendering) {
10893 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10894 "glMatrixLoadIdentityCHROMIUM",
10895 "function not available");
10896 return;
10897 }
10898
10899 static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
10900 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
10901 0.0f, 0.0f, 0.0f, 1.0f};
10902
10903 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
10904 ? state_.projection_matrix
10905 : state_.modelview_matrix;
10906 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
10907 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
10908 // since the values of the _NV and _CHROMIUM tokens match.
10909 glMatrixLoadIdentityEXT(matrix_mode);
10910}
10911
[email protected]32145a92012-12-17 09:01:5910912bool GLES2DecoderImpl::ValidateAsyncTransfer(
10913 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710914 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910915 GLenum target,
10916 GLint level,
10917 const void * data) {
10918 // We only support async uploads to 2D textures for now.
10919 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110920 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910921 return false;
10922 }
10923 // We only support uploads to level zero for now.
10924 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110925 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910926 return false;
10927 }
10928 // A transfer buffer must be bound, even for asyncTexImage2D.
10929 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110930 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910931 return false;
10932 }
10933 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710934 if (!texture_ref ||
10935 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110936 LOCAL_SET_GL_ERROR(
10937 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910938 function_name, "transfer already in progress");
10939 return false;
10940 }
10941 return true;
10942}
10943
[email protected]e3c4a9ab2014-03-31 09:07:0210944base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
10945 uint32 async_upload_token,
10946 uint32 sync_data_shm_id,
10947 uint32 sync_data_shm_offset) {
10948 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2510949 if (!buffer.get() ||
10950 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0210951 return base::Closure();
10952
10953 AsyncMemoryParams mem_params(buffer,
10954 sync_data_shm_offset,
10955 sizeof(AsyncUploadSync));
10956
10957 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
10958 new AsyncUploadTokenCompletionObserver(async_upload_token));
10959
10960 return base::Bind(
10961 &AsyncPixelTransferManager::AsyncNotifyCompletion,
10962 base::Unretained(GetAsyncPixelTransferManager()),
10963 mem_params,
10964 observer);
10965}
10966
[email protected]69023942012-11-30 19:57:1610967error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3410968 uint32 immediate_data_size,
10969 const void* cmd_data) {
10970 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
10971 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1610972 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610973 GLenum target = static_cast<GLenum>(c.target);
10974 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4410975 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1610976 GLsizei width = static_cast<GLsizei>(c.width);
10977 GLsizei height = static_cast<GLsizei>(c.height);
10978 GLint border = static_cast<GLint>(c.border);
10979 GLenum format = static_cast<GLenum>(c.format);
10980 GLenum type = static_cast<GLenum>(c.type);
10981 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10982 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10983 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0210984 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
10985 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
10986 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10987
10988 base::ScopedClosureRunner scoped_completion_callback;
10989 if (async_upload_token) {
10990 base::Closure completion_closure =
10991 AsyncUploadTokenCompletionClosure(async_upload_token,
10992 sync_data_shm_id,
10993 sync_data_shm_offset);
10994 if (completion_closure.is_null())
10995 return error::kInvalidArguments;
10996
10997 scoped_completion_callback.Reset(completion_closure);
10998 }
[email protected]32145a92012-12-17 09:01:5910999
11000 // TODO(epenner): Move this and copies of this memory validation
11001 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1611002 if (!GLES2Util::ComputeImageDataSizes(
11003 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
11004 NULL)) {
11005 return error::kOutOfBounds;
11006 }
11007 const void* pixels = NULL;
11008 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
11009 pixels = GetSharedMemoryAs<const void*>(
11010 pixels_shm_id, pixels_shm_offset, pixels_size);
11011 if (!pixels) {
11012 return error::kOutOfBounds;
11013 }
11014 }
11015
[email protected]c986af502013-08-14 01:04:4411016 TextureManager::DoTextImage2DArguments args = {
11017 target, level, internal_format, width, height, border, format, type,
11018 pixels, pixels_size};
11019 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5911020 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4411021 if (!texture_manager()->ValidateTexImage2D(
11022 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5911023 return error::kNoError;
11024 }
11025
11026 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4911027 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911028 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711029 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911030 return error::kNoError;
11031
11032 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0711033 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5111034 LOCAL_SET_GL_ERROR(
11035 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911036 "glAsyncTexImage2DCHROMIUM", "already defined");
11037 return error::kNoError;
11038 }
11039
[email protected]7989c9e2013-01-23 06:39:2611040 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5111041 LOCAL_SET_GL_ERROR(
11042 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611043 return error::kNoError;
11044 }
11045
[email protected]5b3a8e02013-03-13 05:36:4411046 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3811047 AsyncTexImage2DParams tex_params = {
11048 target, level, static_cast<GLenum>(internal_format),
11049 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1211050 AsyncMemoryParams mem_params(
11051 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5911052
[email protected]5b3a8e02013-03-13 05:36:4411053 // Set up the async state if needed, and make the texture
11054 // immutable so the async state stays valid. The level info
11055 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1811056 AsyncPixelTransferDelegate* delegate =
11057 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
11058 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4411059 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5911060
[email protected]896425e2013-06-12 17:27:1811061 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4411062 tex_params,
11063 mem_params,
11064 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4911065 // The callback is only invoked if the transfer delegate still
11066 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4411067 // ownership that both of these pointers are valid.
11068 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4911069 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4411070 tex_params));
[email protected]f598f422012-12-07 08:30:0311071 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611072}
11073
11074error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411075 uint32 immediate_data_size,
11076 const void* cmd_data) {
11077 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
11078 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611079 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611080 GLenum target = static_cast<GLenum>(c.target);
11081 GLint level = static_cast<GLint>(c.level);
11082 GLint xoffset = static_cast<GLint>(c.xoffset);
11083 GLint yoffset = static_cast<GLint>(c.yoffset);
11084 GLsizei width = static_cast<GLsizei>(c.width);
11085 GLsizei height = static_cast<GLsizei>(c.height);
11086 GLenum format = static_cast<GLenum>(c.format);
11087 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0211088 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11089 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11090 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11091
11092 base::ScopedClosureRunner scoped_completion_callback;
11093 if (async_upload_token) {
11094 base::Closure completion_closure =
11095 AsyncUploadTokenCompletionClosure(async_upload_token,
11096 sync_data_shm_id,
11097 sync_data_shm_offset);
11098 if (completion_closure.is_null())
11099 return error::kInvalidArguments;
11100
11101 scoped_completion_callback.Reset(completion_closure);
11102 }
[email protected]32145a92012-12-17 09:01:5911103
11104 // TODO(epenner): Move this and copies of this memory validation
11105 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1611106 uint32 data_size;
11107 if (!GLES2Util::ComputeImageDataSizes(
11108 width, height, format, type, state_.unpack_alignment, &data_size,
11109 NULL, NULL)) {
11110 return error::kOutOfBounds;
11111 }
11112 const void* pixels = GetSharedMemoryAs<const void*>(
11113 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5911114
11115 // All the normal glTexSubImage2D validation.
11116 error::Error error = error::kNoError;
11117 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
11118 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
11119 return error;
[email protected]69023942012-11-30 19:57:1611120 }
11121
[email protected]32145a92012-12-17 09:01:5911122 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4411123 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11124 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911125 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911126 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711127 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911128 return error::kNoError;
11129
11130 // Guarantee async textures are always 'cleared' as follows:
11131 // - AsyncTexImage2D can not redefine an existing texture
11132 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
11133 // - AsyncTexSubImage2D clears synchronously if not already cleared.
11134 // - Textures become immutable after an async call.
11135 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0711136 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4911137 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
11138 target, level)) {
[email protected]ab09b612013-03-11 22:11:5111139 LOCAL_SET_GL_ERROR(
11140 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2511141 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5911142 return error::kNoError;
11143 }
11144 }
11145
[email protected]5b3a8e02013-03-13 05:36:4411146 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0311147 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5911148 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1211149 AsyncMemoryParams mem_params(
11150 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1811151 AsyncPixelTransferDelegate* delegate =
11152 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11153 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4411154 // TODO(epenner): We may want to enforce exclusive use
11155 // of async APIs in which case this should become an error,
11156 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0311157 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4411158 0, 0, 0, 0, 0, 0};
11159 texture->GetLevelSize(target, level, &define_params.width,
11160 &define_params.height);
11161 texture->GetLevelType(target, level, &define_params.type,
11162 &define_params.internal_format);
11163 // Set up the async state if needed, and make the texture
11164 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1811165 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4711166 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4411167 texture->SetImmutable(true);
11168 }
11169
[email protected]896425e2013-06-12 17:27:1811170 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5911171 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611172}
11173
[email protected]a00c1f742013-03-05 17:02:1611174error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411175 uint32 immediate_data_size,
11176 const void* cmd_data) {
11177 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
11178 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1611179 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11180 GLenum target = static_cast<GLenum>(c.target);
11181
11182 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111183 LOCAL_SET_GL_ERROR(
11184 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1611185 return error::kNoError;
11186 }
[email protected]c986af502013-08-14 01:04:4411187 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11188 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911189 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111190 LOCAL_SET_GL_ERROR(
11191 GL_INVALID_OPERATION,
11192 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1611193 return error::kNoError;
11194 }
[email protected]896425e2013-06-12 17:27:1811195 AsyncPixelTransferDelegate* delegate =
11196 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11197 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4911198 LOCAL_SET_GL_ERROR(
11199 GL_INVALID_OPERATION,
11200 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
11201 return error::kNoError;
11202 }
[email protected]896425e2013-06-12 17:27:1811203 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0911204 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1611205 return error::kNoError;
11206}
11207
[email protected]e3c4a9ab2014-03-31 09:07:0211208error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411209 uint32 immediate_data_size,
11210 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0211211 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11212
11213 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
11214 ProcessFinishedAsyncTransfers();
11215 return error::kNoError;
11216}
11217
[email protected]91c94eb2013-10-22 10:32:5411218void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
11219 TextureRef* texture_ref) {
11220 Texture* texture = texture_ref->texture();
11221 DoDidUseTexImageIfNeeded(texture, texture->target());
11222}
11223
[email protected]828a3932014-04-02 14:43:1311224void GLES2DecoderImpl::OnOutOfMemoryError() {
11225 if (lose_context_when_out_of_memory_) {
11226 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
11227 LoseContext(GL_GUILTY_CONTEXT_RESET_ARB);
11228 }
11229}
11230
[email protected]96449d2c2009-11-25 00:01:3211231// Include the auto-generated part of this file. We split this because it means
11232// we can easily edit the non-auto generated parts right here in this file
11233// instead of having to edit some template or the code generator.
11234#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
11235
11236} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2511237} // namespace gpu