OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "gpu/command_buffer/service/gl_utils.h" | 10 #include "gpu/command_buffer/service/gl_utils.h" |
(...skipping 14 matching lines...) Expand all Loading... | |
25 "#define TextureLookup texture2DRect\n" SHADER(src) | 25 "#define TextureLookup texture2DRect\n" SHADER(src) |
26 #define SHADER_EXTERNAL_OES(src) \ | 26 #define SHADER_EXTERNAL_OES(src) \ |
27 "#extension GL_OES_EGL_image_external : require\n" \ | 27 "#extension GL_OES_EGL_image_external : require\n" \ |
28 "#define SamplerType samplerExternalOES\n" \ | 28 "#define SamplerType samplerExternalOES\n" \ |
29 "#define TextureLookup texture2D\n" SHADER(src) | 29 "#define TextureLookup texture2D\n" SHADER(src) |
30 #define FRAGMENT_SHADERS(src) \ | 30 #define FRAGMENT_SHADERS(src) \ |
31 SHADER_2D(src), SHADER_RECTANGLE_ARB(src), SHADER_EXTERNAL_OES(src) | 31 SHADER_2D(src), SHADER_RECTANGLE_ARB(src), SHADER_EXTERNAL_OES(src) |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, | |
36 0.0f, 1.0f, 0.0f, 0.0f, | |
37 0.0f, 0.0f, 1.0f, 0.0f, | |
38 0.0f, 0.0f, 0.0f, 1.0f}; | |
39 | |
35 enum VertexShaderId { | 40 enum VertexShaderId { |
36 VERTEX_SHADER_COPY_TEXTURE, | 41 VERTEX_SHADER_COPY_TEXTURE, |
37 VERTEX_SHADER_COPY_TEXTURE_FLIP_Y, | 42 VERTEX_SHADER_COPY_TEXTURE_FLIP_Y, |
38 NUM_VERTEX_SHADERS, | 43 NUM_VERTEX_SHADERS, |
39 }; | 44 }; |
40 | 45 |
41 enum FragmentShaderId { | 46 enum FragmentShaderId { |
42 FRAGMENT_SHADER_COPY_TEXTURE_2D, | 47 FRAGMENT_SHADER_COPY_TEXTURE_2D, |
43 FRAGMENT_SHADER_COPY_TEXTURE_RECTANGLE_ARB, | 48 FRAGMENT_SHADER_COPY_TEXTURE_RECTANGLE_ARB, |
44 FRAGMENT_SHADER_COPY_TEXTURE_EXTERNAL_OES, | 49 FRAGMENT_SHADER_COPY_TEXTURE_EXTERNAL_OES, |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 #endif | 186 #endif |
182 } | 187 } |
183 | 188 |
184 void DeleteShader(GLuint shader) { | 189 void DeleteShader(GLuint shader) { |
185 if (shader) | 190 if (shader) |
186 glDeleteShader(shader); | 191 glDeleteShader(shader); |
187 } | 192 } |
188 | 193 |
189 bool BindFramebufferTexture2D(GLenum target, | 194 bool BindFramebufferTexture2D(GLenum target, |
190 GLuint texture_id, | 195 GLuint texture_id, |
191 GLint level, | |
192 GLuint framebuffer) { | 196 GLuint framebuffer) { |
193 DCHECK(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB); | 197 DCHECK(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB); |
194 glActiveTexture(GL_TEXTURE0); | 198 glActiveTexture(GL_TEXTURE0); |
195 glBindTexture(target, texture_id); | 199 glBindTexture(target, texture_id); |
196 // NVidia drivers require texture settings to be a certain way | 200 // NVidia drivers require texture settings to be a certain way |
197 // or they won't report FRAMEBUFFER_COMPLETE. | 201 // or they won't report FRAMEBUFFER_COMPLETE. |
198 glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 202 glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
199 glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 203 glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
200 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 204 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
201 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 205 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
202 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer); | 206 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer); |
203 glFramebufferTexture2DEXT( | 207 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, |
204 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, texture_id, level); | 208 texture_id, 0); |
205 | 209 |
206 #ifndef NDEBUG | 210 #ifndef NDEBUG |
207 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | 211 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
208 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { | 212 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { |
209 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; | 213 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; |
210 return false; | 214 return false; |
211 } | 215 } |
212 #endif | 216 #endif |
213 return true; | 217 return true; |
214 } | 218 } |
215 | 219 |
216 void DoCopyTexImage2D(const gpu::gles2::GLES2Decoder* decoder, | 220 void DoCopyTexImage2D(const gpu::gles2::GLES2Decoder* decoder, |
217 GLenum source_target, | 221 GLenum source_target, |
218 GLuint source_id, | 222 GLuint source_id, |
219 GLuint dest_id, | 223 GLuint dest_id, |
220 GLint dest_level, | |
221 GLenum dest_internal_format, | 224 GLenum dest_internal_format, |
222 GLsizei width, | 225 GLsizei width, |
223 GLsizei height, | 226 GLsizei height, |
224 GLuint framebuffer) { | 227 GLuint framebuffer) { |
225 DCHECK(source_target == GL_TEXTURE_2D || | 228 DCHECK(source_target == GL_TEXTURE_2D || |
226 source_target == GL_TEXTURE_RECTANGLE_ARB); | 229 source_target == GL_TEXTURE_RECTANGLE_ARB); |
227 if (BindFramebufferTexture2D( | 230 if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) { |
228 source_target, source_id, 0 /* level */, framebuffer)) { | |
229 glBindTexture(GL_TEXTURE_2D, dest_id); | 231 glBindTexture(GL_TEXTURE_2D, dest_id); |
230 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 232 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
231 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 233 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 234 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 235 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
234 glCopyTexImage2D(GL_TEXTURE_2D, | 236 glCopyTexImage2D(GL_TEXTURE_2D, 0 /* level */, dest_internal_format, |
235 dest_level, | 237 0 /* x */, 0 /* y */, width, height, 0 /* border */); |
236 dest_internal_format, | |
237 0 /* x */, | |
238 0 /* y */, | |
239 width, | |
240 height, | |
241 0 /* border */); | |
242 } | 238 } |
243 | 239 |
244 decoder->RestoreTextureState(source_id); | 240 decoder->RestoreTextureState(source_id); |
245 decoder->RestoreTextureState(dest_id); | 241 decoder->RestoreTextureState(dest_id); |
246 decoder->RestoreTextureUnitBindings(0); | 242 decoder->RestoreTextureUnitBindings(0); |
247 decoder->RestoreActiveTexture(); | 243 decoder->RestoreActiveTexture(); |
248 decoder->RestoreFramebufferBindings(); | 244 decoder->RestoreFramebufferBindings(); |
249 } | 245 } |
250 | 246 |
247 void DoCopyTexSubImage2D(const gpu::gles2::GLES2Decoder* decoder, | |
248 GLenum source_target, | |
249 GLuint source_id, | |
250 GLuint dest_id, | |
251 GLint xoffset, | |
252 GLint yoffset, | |
253 GLsizei source_width, | |
254 GLsizei source_height, | |
255 GLuint framebuffer) { | |
256 DCHECK(source_target == GL_TEXTURE_2D || | |
257 source_target == GL_TEXTURE_RECTANGLE_ARB); | |
258 if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) { | |
259 glBindTexture(GL_TEXTURE_2D, dest_id); | |
260 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
261 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
264 glCopyTexSubImage2D(GL_TEXTURE_2D, 0 /* level */, xoffset, yoffset, | |
265 0 /* x */, 0 /* y */, source_width, source_height); | |
266 } | |
267 | |
268 decoder->RestoreTextureState(source_id); | |
269 decoder->RestoreTextureState(dest_id); | |
270 decoder->RestoreTextureUnitBindings(0); | |
271 decoder->RestoreActiveTexture(); | |
272 decoder->RestoreFramebufferBindings(); | |
273 } | |
274 | |
275 // Copy from SkMatrix44::preTranslate | |
276 void PreTranslate(GLfloat* matrix, GLfloat dx, GLfloat dy, GLfloat dz) { | |
277 if (!dx && !dy && !dz) | |
278 return; | |
279 | |
280 for (int i = 0; i < 4; ++i) { | |
281 matrix[(3 * 4) + i] = matrix[(0 * 4) + i] * dx + matrix[(1 * 4) + i] * dy + | |
282 matrix[(2 * 4) + i] * dz + matrix[(3 * 4) + i]; | |
283 } | |
284 } | |
285 | |
251 } // namespace | 286 } // namespace |
252 | 287 |
253 namespace gpu { | 288 namespace gpu { |
254 | 289 |
255 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() | 290 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() |
256 : initialized_(false), | 291 : initialized_(false), |
257 vertex_shaders_(NUM_VERTEX_SHADERS, 0u), | 292 vertex_shaders_(NUM_VERTEX_SHADERS, 0u), |
258 fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u), | 293 fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u), |
259 buffer_id_(0u), | 294 buffer_id_(0u), |
260 framebuffer_(0u) {} | 295 framebuffer_(0u) {} |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 glDeleteBuffersARB(1, &buffer_id_); | 346 glDeleteBuffersARB(1, &buffer_id_); |
312 buffer_id_ = 0; | 347 buffer_id_ = 0; |
313 } | 348 } |
314 | 349 |
315 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( | 350 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( |
316 const gles2::GLES2Decoder* decoder, | 351 const gles2::GLES2Decoder* decoder, |
317 GLenum source_target, | 352 GLenum source_target, |
318 GLuint source_id, | 353 GLuint source_id, |
319 GLenum source_internal_format, | 354 GLenum source_internal_format, |
320 GLuint dest_id, | 355 GLuint dest_id, |
321 GLint dest_level, | |
322 GLenum dest_internal_format, | 356 GLenum dest_internal_format, |
323 GLsizei width, | 357 GLsizei width, |
324 GLsizei height, | 358 GLsizei height, |
325 bool flip_y, | 359 bool flip_y, |
326 bool premultiply_alpha, | 360 bool premultiply_alpha, |
327 bool unpremultiply_alpha) { | 361 bool unpremultiply_alpha) { |
328 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; | 362 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; |
329 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's | 363 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's |
330 // format does not contain a superset of the components required by the base | 364 // format does not contain a superset of the components required by the base |
331 // format of internalformat. | 365 // format of internalformat. |
332 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml | 366 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml |
333 bool source_format_contain_superset_of_dest_format = | 367 bool source_format_contain_superset_of_dest_format = |
334 (source_internal_format == dest_internal_format && | 368 (source_internal_format == dest_internal_format && |
335 source_internal_format != GL_BGRA_EXT) || | 369 source_internal_format != GL_BGRA_EXT) || |
336 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); | 370 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); |
337 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, | 371 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, |
338 // so restrict this to GL_TEXTURE_2D. | 372 // so restrict this to GL_TEXTURE_2D. |
339 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && | 373 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && |
340 source_format_contain_superset_of_dest_format) { | 374 source_format_contain_superset_of_dest_format) { |
341 DoCopyTexImage2D(decoder, | 375 DoCopyTexImage2D(decoder, |
342 source_target, | 376 source_target, |
343 source_id, | 377 source_id, |
344 dest_id, | 378 dest_id, |
345 dest_level, | |
346 dest_internal_format, | 379 dest_internal_format, |
347 width, | 380 width, |
348 height, | 381 height, |
349 framebuffer_); | 382 framebuffer_); |
350 return; | 383 return; |
351 } | 384 } |
352 | 385 |
353 // Use default transform matrix if no transform passed in. | 386 // Use kIdentityMatrix if no transform passed in. |
354 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, | 387 DoCopyTextureWithTransform(decoder, source_target, source_id, dest_id, width, |
355 0.0f, 1.0f, 0.0f, 0.0f, | 388 height, flip_y, premultiply_alpha, |
356 0.0f, 0.0f, 1.0f, 0.0f, | 389 unpremultiply_alpha, kIdentityMatrix); |
357 0.0f, 0.0f, 0.0f, 1.0f}; | 390 } |
358 DoCopyTextureWithTransform(decoder, | 391 |
359 source_target, | 392 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( |
360 source_id, | 393 const gles2::GLES2Decoder* decoder, |
361 dest_id, | 394 GLenum source_target, |
362 dest_level, | 395 GLuint source_id, |
363 width, | 396 GLenum source_internal_format, |
364 height, | 397 GLuint dest_id, |
365 flip_y, | 398 GLenum dest_internal_format, |
366 premultiply_alpha, | 399 GLint xoffset, |
367 unpremultiply_alpha, | 400 GLint yoffset, |
368 default_matrix); | 401 GLsizei dest_width, |
402 GLsizei dest_height, | |
403 GLsizei source_width, | |
404 GLsizei source_height, | |
405 bool flip_y, | |
406 bool premultiply_alpha, | |
407 bool unpremultiply_alpha) { | |
408 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; | |
409 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's | |
410 // format does not contain a superset of the components required by the base | |
411 // format of internalformat. | |
412 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml | |
413 bool source_format_contain_superset_of_dest_format = | |
414 (source_internal_format == dest_internal_format && | |
415 source_internal_format != GL_BGRA_EXT) || | |
416 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); | |
417 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, | |
418 // so restrict this to GL_TEXTURE_2D. | |
419 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && | |
420 source_format_contain_superset_of_dest_format) { | |
421 DoCopyTexSubImage2D(decoder, source_target, source_id, dest_id, xoffset, | |
422 yoffset, source_width, source_height, framebuffer_); | |
423 return; | |
424 } | |
425 | |
426 // Use kIdentityMatrix if no transform passed in. | |
427 DoCopySubTextureWithTransform( | |
428 decoder, source_target, source_id, dest_id, xoffset, yoffset, dest_width, | |
429 dest_height, source_width, source_height, flip_y, premultiply_alpha, | |
430 unpremultiply_alpha, kIdentityMatrix); | |
369 } | 431 } |
370 | 432 |
371 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( | 433 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( |
372 const gles2::GLES2Decoder* decoder, | 434 const gles2::GLES2Decoder* decoder, |
373 GLenum source_target, | 435 GLenum source_target, |
374 GLuint source_id, | 436 GLuint source_id, |
375 GLuint dest_id, | 437 GLuint dest_id, |
376 GLint dest_level, | |
377 GLsizei width, | 438 GLsizei width, |
378 GLsizei height, | 439 GLsizei height, |
379 bool flip_y, | 440 bool flip_y, |
380 bool premultiply_alpha, | 441 bool premultiply_alpha, |
381 bool unpremultiply_alpha, | 442 bool unpremultiply_alpha, |
382 const GLfloat transform_matrix[16]) { | 443 const GLfloat transform_matrix[16]) { |
444 GLsizei dest_width = width; | |
445 GLsizei dest_height = height; | |
446 DoCopyTextureInternal(decoder, source_target, source_id, dest_id, 0, 0, | |
447 dest_width, dest_height, width, height, flip_y, | |
448 premultiply_alpha, unpremultiply_alpha, | |
449 transform_matrix); | |
450 } | |
451 | |
452 void CopyTextureCHROMIUMResourceManager::DoCopySubTextureWithTransform( | |
453 const gles2::GLES2Decoder* decoder, | |
454 GLenum source_target, | |
455 GLuint source_id, | |
456 GLuint dest_id, | |
457 GLint xoffset, | |
458 GLint yoffset, | |
459 GLsizei dest_width, | |
460 GLsizei dest_height, | |
461 GLsizei source_width, | |
462 GLsizei source_height, | |
463 bool flip_y, | |
464 bool premultiply_alpha, | |
465 bool unpremultiply_alpha, | |
466 const GLfloat transform_matrix[16]) { | |
467 DoCopyTextureInternal(decoder, source_target, source_id, dest_id, xoffset, | |
468 yoffset, dest_width, dest_height, source_width, | |
469 source_height, flip_y, premultiply_alpha, | |
470 unpremultiply_alpha, transform_matrix); | |
471 } | |
472 | |
473 void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( | |
474 const gles2::GLES2Decoder* decoder, | |
475 GLenum source_target, | |
476 GLuint source_id, | |
477 GLuint dest_id, | |
478 GLint xoffset, | |
479 GLint yoffset, | |
480 GLsizei dest_width, | |
481 GLsizei dest_height, | |
482 GLsizei source_width, | |
483 GLsizei source_height, | |
484 bool flip_y, | |
485 bool premultiply_alpha, | |
486 bool unpremultiply_alpha, | |
487 const GLfloat transform_matrix[16]) { | |
383 DCHECK(source_target == GL_TEXTURE_2D || | 488 DCHECK(source_target == GL_TEXTURE_2D || |
384 source_target == GL_TEXTURE_RECTANGLE_ARB || | 489 source_target == GL_TEXTURE_RECTANGLE_ARB || |
385 source_target == GL_TEXTURE_EXTERNAL_OES); | 490 source_target == GL_TEXTURE_EXTERNAL_OES); |
491 DCHECK(xoffset >= 0 && xoffset + source_width <= dest_width); | |
492 DCHECK(yoffset >= 0 && yoffset + source_height <= dest_height); | |
piman
2015/02/26 19:52:31
Where is this validated in the calling code? I did
| |
386 if (!initialized_) { | 493 if (!initialized_) { |
387 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; | 494 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; |
388 return; | 495 return; |
389 } | 496 } |
390 | 497 |
391 VertexShaderId vertex_shader_id = GetVertexShaderId(flip_y); | 498 VertexShaderId vertex_shader_id = GetVertexShaderId(flip_y); |
392 DCHECK_LT(static_cast<size_t>(vertex_shader_id), vertex_shaders_.size()); | 499 DCHECK_LT(static_cast<size_t>(vertex_shader_id), vertex_shaders_.size()); |
393 FragmentShaderId fragment_shader_id = GetFragmentShaderId( | 500 FragmentShaderId fragment_shader_id = GetFragmentShaderId( |
394 premultiply_alpha, unpremultiply_alpha, source_target); | 501 premultiply_alpha, unpremultiply_alpha, source_target); |
395 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size()); | 502 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 #ifndef NDEBUG | 536 #ifndef NDEBUG |
430 glValidateProgram(info->program); | 537 glValidateProgram(info->program); |
431 GLint validation_status; | 538 GLint validation_status; |
432 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); | 539 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); |
433 if (GL_TRUE != validation_status) { | 540 if (GL_TRUE != validation_status) { |
434 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; | 541 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; |
435 return; | 542 return; |
436 } | 543 } |
437 #endif | 544 #endif |
438 | 545 |
439 glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix); | 546 if (!xoffset && !yoffset) { |
547 glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix); | |
548 } else { | |
549 // transform offsets from ([0, dest_width], [0, dest_height]) coord. | |
550 // to ([-1, 1], [-1, 1]) coord. | |
551 GLfloat xoffset_on_vertex = ((2.f * xoffset) / dest_width); | |
552 GLfloat yoffset_on_vertex = ((2.f * yoffset) / dest_height); | |
553 | |
554 // Pass view_matrix * offset_matrix to the program. | |
555 GLfloat view_transform[16]; | |
556 memcpy(view_transform, transform_matrix, 16 * sizeof(GLfloat)); | |
557 PreTranslate(view_transform, xoffset_on_vertex, yoffset_on_vertex, 0); | |
558 glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, view_transform); | |
559 } | |
440 if (source_target == GL_TEXTURE_RECTANGLE_ARB) | 560 if (source_target == GL_TEXTURE_RECTANGLE_ARB) |
441 glUniform2f(info->half_size_handle, width / 2.0f, height / 2.0f); | 561 glUniform2f(info->half_size_handle, source_width / 2.0f, |
562 source_height / 2.0f); | |
442 else | 563 else |
443 glUniform2f(info->half_size_handle, 0.5f, 0.5f); | 564 glUniform2f(info->half_size_handle, 0.5f, 0.5f); |
444 | 565 |
445 if (BindFramebufferTexture2D( | 566 if (BindFramebufferTexture2D(GL_TEXTURE_2D, dest_id, framebuffer_)) { |
446 GL_TEXTURE_2D, dest_id, dest_level, framebuffer_)) { | |
447 decoder->ClearAllAttributes(); | 567 decoder->ClearAllAttributes(); |
448 glEnableVertexAttribArray(kVertexPositionAttrib); | 568 glEnableVertexAttribArray(kVertexPositionAttrib); |
449 | 569 |
450 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); | 570 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); |
451 glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); | 571 glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); |
452 | 572 |
453 glUniform1i(info->sampler_handle, 0); | 573 glUniform1i(info->sampler_handle, 0); |
454 | 574 |
455 glBindTexture(source_target, source_id); | 575 glBindTexture(source_target, source_id); |
456 glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 576 glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
457 glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 577 glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
458 glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 578 glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
459 glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 579 glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
460 | 580 |
461 glDisable(GL_DEPTH_TEST); | 581 glDisable(GL_DEPTH_TEST); |
462 glDisable(GL_SCISSOR_TEST); | 582 glDisable(GL_SCISSOR_TEST); |
463 glDisable(GL_STENCIL_TEST); | 583 glDisable(GL_STENCIL_TEST); |
464 glDisable(GL_CULL_FACE); | 584 glDisable(GL_CULL_FACE); |
465 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | 585 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
466 glDepthMask(GL_FALSE); | 586 glDepthMask(GL_FALSE); |
467 glDisable(GL_BLEND); | 587 glDisable(GL_BLEND); |
468 | 588 |
469 glViewport(0, 0, width, height); | 589 glViewport(0, 0, dest_width, dest_height); |
470 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | 590 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
471 } | 591 } |
472 | 592 |
473 decoder->RestoreAllAttributes(); | 593 decoder->RestoreAllAttributes(); |
474 decoder->RestoreTextureState(source_id); | 594 decoder->RestoreTextureState(source_id); |
475 decoder->RestoreTextureState(dest_id); | 595 decoder->RestoreTextureState(dest_id); |
476 decoder->RestoreTextureUnitBindings(0); | 596 decoder->RestoreTextureUnitBindings(0); |
477 decoder->RestoreActiveTexture(); | 597 decoder->RestoreActiveTexture(); |
478 decoder->RestoreProgramBindings(); | 598 decoder->RestoreProgramBindings(); |
479 decoder->RestoreBufferBindings(); | 599 decoder->RestoreBufferBindings(); |
480 decoder->RestoreFramebufferBindings(); | 600 decoder->RestoreFramebufferBindings(); |
481 decoder->RestoreGlobalState(); | 601 decoder->RestoreGlobalState(); |
482 } | 602 } |
483 | 603 |
484 } // namespace gpu | 604 } // namespace gpu |
OLD | NEW |