Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp

Issue 2026803002: Avoid GPU readback in tex(Sub)Image2D(ImageBitmap) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: staticbitmapimage does not keep provider anymore Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 4236 matching lines...) Expand 10 before | Expand all | Expand 10 after
4247 4247
4248 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m _unpackFlipY, m_unpackPremultiplyAlpha); 4248 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m _unpackFlipY, m_unpackPremultiplyAlpha);
4249 } 4249 }
4250 4250
4251 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4251 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4252 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState) 4252 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState)
4253 { 4253 {
4254 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, image, exceptionState); 4254 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, image, exceptionState);
4255 } 4255 }
4256 4256
4257 bool WebGLRenderingContextBase::canUseTexImageCanvasByGPU(GLint internalformat, GLenum type) 4257 bool WebGLRenderingContextBase::canUseTexImageByGPU(GLint internalformat, GLenum type)
4258 { 4258 {
4259 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat)) 4259 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat))
4260 return false; 4260 return false;
4261 return true; 4261 return true;
4262 } 4262 }
4263 4263
4264 void WebGLRenderingContextBase::texImageCanvasByGPU(TexImageByGPUType functionTy pe, WebGLTexture* texture, GLenum target, 4264 void WebGLRenderingContextBase::texImageCanvasByGPU(HTMLCanvasElement* canvas, G Luint targetTexture, GLenum targetInternalformat, GLenum targetType, GLint targe tLevel)
4265 GLint level, GLint internalformat, GLenum type, GLint xoffset, GLint yoffset , GLint zoffset, HTMLCanvasElement* canvas)
4266 { 4265 {
4266 if (!canvas->is3D()) {
4267 ImageBuffer* buffer = canvas->buffer();
4268 if (!buffer->copyToPlatformTexture(contextGL(), targetTexture, targetInt ernalformat, targetType,
4269 targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
4270 NOTREACHED();
4271 }
4272 } else {
4273 WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->rend eringContext());
4274 ScopedTexture2DRestorer restorer(gl);
4275 if (!gl->drawingBuffer()->copyToPlatformTexture(contextGL(), targetTextu re, targetInternalformat, targetType,
4276 targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, BackBuffer)) {
4277 NOTREACHED();
4278 }
4279 }
4280 }
4281
4282 void WebGLRenderingContextBase::texImageByGPU(TexImageByGPUType functionType, We bGLTexture* texture, GLenum target,
4283 GLint level, GLint internalformat, GLenum type, GLint xoffset, GLint yoffset , GLint zoffset, HTMLCanvasElement* canvas, ImageBitmap* bitmap)
Justin Novosad 2016/06/14 19:30:53 Instead of having these two arguments (canvas + bi
xidachen 2016/06/15 12:18:47 I do agree that it is a better design to use the b
4284 {
4285 DCHECK((!canvas || !bitmap) && (canvas || bitmap));
4286 int width;
4287 int height;
4288 if (canvas) {
4289 width = canvas->width();
4290 height = canvas->height();
4291 } else {
4292 width = bitmap->width();
4293 height = bitmap->height();
4294 }
4267 ScopedTexture2DRestorer restorer(this); 4295 ScopedTexture2DRestorer restorer(this);
4268 4296
4269 GLuint targetTexture = texture->object(); 4297 GLuint targetTexture = texture->object();
4270 GLenum targetType = type; 4298 GLenum targetType = type;
4271 GLenum targetInternalformat = internalformat; 4299 GLenum targetInternalformat = internalformat;
4272 GLint targetLevel = level; 4300 GLint targetLevel = level;
4273 bool possibleDirectCopy = false; 4301 bool possibleDirectCopy = false;
4302 // TODO: Make this function support more cases in texSubImage calls.
4274 if (functionType == TexImage2DByGPU) { 4303 if (functionType == TexImage2DByGPU) {
4275 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level); 4304 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level);
4276 } 4305 }
4277 4306
4278 // if direct copy is not possible, create a temporary texture and then copy from canvas to temporary texture to target texture. 4307 // if direct copy is not possible, create a temporary texture and then copy from canvas to temporary texture to target texture.
4279 if (!possibleDirectCopy) { 4308 if (!possibleDirectCopy) {
4280 targetLevel = 0; 4309 targetLevel = 0;
4281 targetInternalformat = GL_RGBA; 4310 targetInternalformat = GL_RGBA;
4282 targetType = GL_UNSIGNED_BYTE; 4311 targetType = GL_UNSIGNED_BYTE;
4283 contextGL()->GenTextures(1, &targetTexture); 4312 contextGL()->GenTextures(1, &targetTexture);
4284 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); 4313 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture);
4285 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAR EST); 4314 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAR EST);
4286 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAR EST); 4315 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAR EST);
4287 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO _EDGE); 4316 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO _EDGE);
4288 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO _EDGE); 4317 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO _EDGE);
4289 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, canvas-> width(), 4318 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, width, h eight, 0, GL_RGBA, targetType, 0);
4290 canvas->height(), 0, GL_RGBA, targetType, 0);
4291 } 4319 }
4292 4320
4293 if (!canvas->is3D()) { 4321 if (canvas)
4294 ImageBuffer* buffer = canvas->buffer(); 4322 texImageCanvasByGPU(canvas, targetTexture, targetInternalformat, targetT ype, targetLevel);
4295 if (!buffer->copyToPlatformTexture(contextGL(), targetTexture, targetInt ernalformat, targetType, 4323 else
4296 targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) { 4324 texImageBitmapByGPU(bitmap, targetTexture, targetInternalformat, targetT ype, targetLevel);
4297 ASSERT_NOT_REACHED();
4298 }
4299 } else {
4300 WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->rend eringContext());
4301 ScopedTexture2DRestorer restorer(gl);
4302 if (!gl->drawingBuffer()->copyToPlatformTexture(contextGL(), targetTextu re, targetInternalformat, targetType,
4303 targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, BackBuffer)) {
4304 ASSERT_NOT_REACHED();
4305 }
4306 }
4307 4325
4308 if (!possibleDirectCopy) { 4326 if (!possibleDirectCopy) {
4309 GLuint tmpFBO; 4327 GLuint tmpFBO;
4310 contextGL()->GenFramebuffers(1, &tmpFBO); 4328 contextGL()->GenFramebuffers(1, &tmpFBO);
4311 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); 4329 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO);
4312 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0); 4330 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0);
4313 contextGL()->BindTexture(texture->getTarget(), texture->object()); 4331 contextGL()->BindTexture(texture->getTarget(), texture->object());
4314 if (functionType == TexImage2DByGPU) { 4332 if (functionType == TexImage2DByGPU) {
4315 contextGL()->CopyTexSubImage2D(target, level, 0, 0, 0, 0, canvas->wi dth(), canvas->height()); 4333 contextGL()->CopyTexSubImage2D(target, level, 0, 0, 0, 0, width, hei ght);
4316 } else if (functionType == TexSubImage2DByGPU) { 4334 } else if (functionType == TexSubImage2DByGPU) {
4317 contextGL()->CopyTexSubImage2D(target, level, xoffset, yoffset, 0, 0 , canvas->width(), canvas->height()); 4335 contextGL()->CopyTexSubImage2D(target, level, xoffset, yoffset, 0, 0 , width, height);
4318 } else if (functionType == TexSubImage3DByGPU) { 4336 } else if (functionType == TexSubImage3DByGPU) {
4319 contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoff set, 0, 0, canvas->width(), canvas->height()); 4337 contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoff set, 0, 0, width, height);
4320 } 4338 }
4321 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 4339 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
4322 restoreCurrentFramebuffer(); 4340 restoreCurrentFramebuffer();
4323 contextGL()->DeleteFramebuffers(1, &tmpFBO); 4341 contextGL()->DeleteFramebuffers(1, &tmpFBO);
4324 contextGL()->DeleteTextures(1, &targetTexture); 4342 contextGL()->DeleteTextures(1, &targetTexture);
4325 } 4343 }
4326 } 4344 }
4327 4345
4328 void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(TexImageFunction ID functionID, 4346 void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(TexImageFunction ID functionID,
4329 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset, 4347 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4330 GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exc eptionState) 4348 GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exc eptionState)
4331 { 4349 {
4332 const char* funcName = getTexImageFunctionName(functionID); 4350 const char* funcName = getTexImageFunctionName(functionID);
4333 if (isContextLost()) 4351 if (isContextLost())
4334 return; 4352 return;
4335 if (!validateHTMLCanvasElement(funcName, canvas, exceptionState)) 4353 if (!validateHTMLCanvasElement(funcName, canvas, exceptionState))
4336 return; 4354 return;
4337 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target ); 4355 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target );
4338 if (!texture) 4356 if (!texture)
4339 return; 4357 return;
4340 TexImageFunctionType functionType; 4358 TexImageFunctionType functionType;
4341 if (functionID == TexImage2D) 4359 if (functionID == TexImage2D)
4342 functionType = TexImage; 4360 functionType = TexImage;
4343 else 4361 else
4344 functionType = TexSubImage; 4362 functionType = TexSubImage;
4345 if (!validateTexFunc(funcName, functionType, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset)) 4363 if (!validateTexFunc(funcName, functionType, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset))
4346 return; 4364 return;
4347 if (functionID == TexImage2D) { 4365 if (functionID == TexImage2D) {
4348 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format. 4366 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support flo at/integer/sRGB internal format.
4349 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats. 4367 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats.
4350 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || !canUseTexImageCanvasByGPU(internalformat, type)) { 4368 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || !canUseTexImageByGPU(internalformat, type)) {
4351 // 2D canvas has only FrontBuffer. 4369 // 2D canvas has only FrontBuffer.
4352 texImageImpl(TexImage2D, target, level, internalformat, xoffset, yof fset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration ).get(), 4370 texImageImpl(TexImage2D, target, level, internalformat, xoffset, yof fset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration ).get(),
4353 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha); 4371 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha);
4354 return; 4372 return;
4355 } 4373 }
4356 4374
4357 texImage2DBase(target, level, internalformat, canvas->width(), canvas->h eight(), 0, format, type, 0); 4375 texImage2DBase(target, level, internalformat, canvas->width(), canvas->h eight(), 0, format, type, 0);
4358 texImageCanvasByGPU(TexImage2DByGPU, texture, target, level, internalfor mat, type, 0, 0, 0, canvas); 4376 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, t ype, 0, 0, 0, canvas, nullptr);
4359 } else if (functionID == TexSubImage2D) { 4377 } else if (functionID == TexSubImage2D) {
4360 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal format s. 4378 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal format s.
4361 bool useReadBackPath = isWebGL2OrHigher() 4379 bool useReadBackPath = isWebGL2OrHigher()
4362 || extensionEnabled(OESTextureFloatName) 4380 || extensionEnabled(OESTextureFloatName)
4363 || extensionEnabled(OESTextureHalfFloatName) 4381 || extensionEnabled(OESTextureHalfFloatName)
4364 || extensionEnabled(EXTsRGBName); 4382 || extensionEnabled(EXTsRGBName);
4365 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format. 4383 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format.
4366 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats. 4384 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats.
4367 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || useReadBackPath) { 4385 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || useReadBackPath) {
4368 // 2D canvas has only FrontBuffer. 4386 // 2D canvas has only FrontBuffer.
4369 texImageImpl(TexSubImage2D, target, level, 0, xoffset, yoffset, 0, f ormat, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), 4387 texImageImpl(TexSubImage2D, target, level, 0, xoffset, yoffset, 0, f ormat, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4370 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha); 4388 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha);
4371 return; 4389 return;
4372 } 4390 }
4373 4391
4374 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, canvas); 4392 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, canvas, nullptr);
4375 } else { 4393 } else {
4376 DCHECK_EQ(functionID, TexSubImage3D); 4394 DCHECK_EQ(functionID, TexSubImage3D);
4377 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269). 4395 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269).
4378 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), 4396 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4379 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); 4397 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha);
4380 } 4398 }
4381 } 4399 }
4382 4400
4383 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4401 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4384 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) 4402 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
4447 } 4465 }
4448 } 4466 }
4449 } 4467 }
4450 4468
4451 RefPtr<Image> image = videoFrameToImage(video); 4469 RefPtr<Image> image = videoFrameToImage(video);
4452 if (!image) 4470 if (!image)
4453 return; 4471 return;
4454 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFl ipY, m_unpackPremultiplyAlpha); 4472 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFl ipY, m_unpackPremultiplyAlpha);
4455 } 4473 }
4456 4474
4475 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, GLuint targetTexture, GLenum targetInternalformat, GLenum targetType, GLint targetLevel )
4476 {
4477 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(drawin gBuffer()->contextProvider());
4478 bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(), tar getTexture, targetInternalformat, targetType);
Justin Novosad 2016/06/14 19:30:53 I think this is where your bug is. When copying a
4479 }
4480
4457 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4481 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4458 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) 4482 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState)
4459 { 4483 {
4460 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, video, exceptionState); 4484 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, video, exceptionState);
4461 } 4485 }
4462 4486
4463 void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionID fun ctionID, 4487 void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionID fun ctionID,
4464 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset, 4488 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4465 GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exception State) 4489 GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exception State)
4466 { 4490 {
4467 const char* funcName = getTexImageFunctionName(functionID); 4491 const char* funcName = getTexImageFunctionName(functionID);
4468 if (isContextLost()) 4492 if (isContextLost())
4469 return; 4493 return;
4470 if (!validateImageBitmap(funcName, bitmap, exceptionState)) 4494 if (!validateImageBitmap(funcName, bitmap, exceptionState))
4471 return; 4495 return;
4472 if (!validateTexImageBinding(funcName, functionID, target)) 4496 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target );
4497 if (!texture)
4473 return; 4498 return;
4474 TexImageFunctionType functionType; 4499 TexImageFunctionType functionType;
4475 if (functionID == TexImage2D) 4500 if (functionID == TexImage2D)
4476 functionType = TexImage; 4501 functionType = TexImage;
4477 else 4502 else
4478 functionType = TexSubImage; 4503 functionType = TexSubImage;
4479 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffse t, yoffset, zoffset)) 4504 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffse t, yoffset, zoffset))
4480 return; 4505 return;
4481 ASSERT(bitmap->bitmapImage()); 4506 ASSERT(bitmap->bitmapImage());
4507 if (bitmap->isTextureBacked() && canUseTexImageByGPU(internalformat, type)) {
4508 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, 0);
4509 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, t ype, 0, 0, 0, nullptr, bitmap);
4510 return;
4511 }
4482 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); 4512 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
4483 SkPixmap pixmap; 4513 SkPixmap pixmap;
4484 OwnPtr<uint8_t[]> pixelData; 4514 OwnPtr<uint8_t[]> pixelData;
4485 uint8_t* pixelDataPtr = nullptr; 4515 uint8_t* pixelDataPtr = nullptr;
4486 // TODO(crbug.com/613411): peekPixels fails if the SkImage is texture-backed 4516 // In the case where an ImageBitmap is not texture backed, peekPixels() alwa ys succeed.
4487 // Use texture mailbox in that case. 4517 // However, when it is texture backed and !canUseTexImageByGPU, we do a GPU read back.
4488 bool peekSucceed = skImage->peekPixels(&pixmap); 4518 bool peekSucceed = skImage->peekPixels(&pixmap);
4489 if (peekSucceed) { 4519 if (peekSucceed) {
4490 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); 4520 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
4491 } else if (skImage->isTextureBacked()) { 4521 } else {
4492 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha); 4522 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha);
4493 pixelDataPtr = pixelData.get(); 4523 pixelDataPtr = pixelData.get();
4494 } 4524 }
4495 Vector<uint8_t> data; 4525 Vector<uint8_t> data;
4496 bool needConversion = true; 4526 bool needConversion = true;
4497 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType); 4527 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType);
4498 bool isPixelDataRBGA = (havePeekableRGBA || !peekSucceed); 4528 bool isPixelDataRGBA = (havePeekableRGBA || !peekSucceed);
4499 if (isPixelDataRBGA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { 4529 if (isPixelDataRGBA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
4500 needConversion = false; 4530 needConversion = false;
4501 } else { 4531 } else {
4502 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4532 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4503 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. 4533 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed.
4504 type = GL_FLOAT; 4534 type = GL_FLOAT;
4505 } 4535 }
4506 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha. 4536 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha.
4507 bool isPixelDataBGRA = (peekSucceed && pixmap.colorType() == SkColorType ::kBGRA_8888_SkColorType); 4537 bool isPixelDataBGRA = pixmap.colorType() == SkColorType::kBGRA_8888_SkC olorType;
4508 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data)) 4538 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data))
4509 || (isPixelDataRBGA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) { 4539 || (isPixelDataRGBA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) {
4510 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); 4540 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
4511 return; 4541 return;
4512 } 4542 }
4513 } 4543 }
4514 resetUnpackParameters(); 4544 resetUnpackParameters();
4515 if (functionID == TexImage2D) { 4545 if (functionID == TexImage2D) {
4516 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, needConversion ? data.data() : pixelDataPtr); 4546 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, needConversion ? data.data() : pixelDataPtr);
4517 } else if (functionID == TexSubImage2D) { 4547 } else if (functionID == TexSubImage2D) {
4518 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->widt h(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr ); 4548 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->widt h(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr );
4519 } else { 4549 } else {
(...skipping 1905 matching lines...) Expand 10 before | Expand all | Expand 10 after
6425 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1); 6455 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
6426 } 6456 }
6427 6457
6428 void WebGLRenderingContextBase::restoreUnpackParameters() 6458 void WebGLRenderingContextBase::restoreUnpackParameters()
6429 { 6459 {
6430 if (m_unpackAlignment != 1) 6460 if (m_unpackAlignment != 1)
6431 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); 6461 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
6432 } 6462 }
6433 6463
6434 } // namespace blink 6464 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698