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

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: address junov@'s comments Created 4 years, 5 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 4240 matching lines...) Expand 10 before | Expand all | Expand 10 after
4251 4251
4252 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m _unpackFlipY, m_unpackPremultiplyAlpha); 4252 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m _unpackFlipY, m_unpackPremultiplyAlpha);
4253 } 4253 }
4254 4254
4255 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4255 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4256 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState) 4256 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState)
4257 { 4257 {
4258 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, image, exceptionState); 4258 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, image, exceptionState);
4259 } 4259 }
4260 4260
4261 bool WebGLRenderingContextBase::canUseTexImageCanvasByGPU(GLint internalformat, GLenum type) 4261 bool WebGLRenderingContextBase::canUseTexImageByGPU(TexImageFunctionID functionI D, GLint internalformat, GLenum type)
4262 { 4262 {
4263 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat)) 4263 if (functionID == TexImage2D && (isFloatType(type) || isIntegerFormat(intern alformat) || isSRGBFormat(internalformat)))
4264 return false;
4265 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal formats.
Ken Russell (switch to Gerrit) 2016/06/24 01:25:10 TODO(xidachen). Also, please reference a bug ID fo
xidachen 2016/06/24 14:36:07 Bug filed here: https://bugs.chromium.org/p/chromi
4266 if (functionID == TexSubImage2D && (isWebGL2OrHigher() || extensionEnabled(O ESTextureFloatName) || extensionEnabled(OESTextureHalfFloatName) || extensionEna bled(EXTsRGBName)))
4264 return false; 4267 return false;
4265 return true; 4268 return true;
4266 } 4269 }
4267 4270
4268 void WebGLRenderingContextBase::texImageCanvasByGPU(TexImageByGPUType functionTy pe, WebGLTexture* texture, GLenum target, 4271 void WebGLRenderingContextBase::texImageCanvasByGPU(HTMLCanvasElement* canvas, G Luint targetTexture, GLenum targetInternalformat, GLenum targetType, GLint targe tLevel)
4269 GLint level, GLint internalformat, GLenum type, GLint xoffset, GLint yoffset , GLint zoffset, HTMLCanvasElement* canvas)
4270 { 4272 {
4273 if (!canvas->is3D()) {
4274 ImageBuffer* buffer = canvas->buffer();
4275 if (!buffer->copyToPlatformTexture(contextGL(), targetTexture, targetInt ernalformat, targetType,
4276 targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
4277 NOTREACHED();
4278 }
4279 } else {
4280 WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->rend eringContext());
4281 ScopedTexture2DRestorer restorer(gl);
4282 if (!gl->drawingBuffer()->copyToPlatformTexture(contextGL(), targetTextu re, targetInternalformat, targetType,
4283 targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, BackBuffer)) {
4284 NOTREACHED();
4285 }
4286 }
4287 }
4288
4289 void WebGLRenderingContextBase::texImageByGPU(TexImageByGPUType functionType, We bGLTexture* texture, GLenum target,
4290 GLint level, GLint internalformat, GLenum type, GLint xoffset, GLint yoffset , GLint zoffset, CanvasImageSource* image)
4291 {
4292 DCHECK(image->isCanvasElement() || image->isImageBitmap());
4293 int width = image->sourceWidth();
4294 int height = image->sourceHeight();
4295
4271 ScopedTexture2DRestorer restorer(this); 4296 ScopedTexture2DRestorer restorer(this);
4272 4297
4273 GLuint targetTexture = texture->object(); 4298 GLuint targetTexture = texture->object();
4274 GLenum targetType = type; 4299 GLenum targetType = type;
4275 GLenum targetInternalformat = internalformat; 4300 GLenum targetInternalformat = internalformat;
4276 GLint targetLevel = level; 4301 GLint targetLevel = level;
4277 bool possibleDirectCopy = false; 4302 bool possibleDirectCopy = false;
4303 // TODO: Make this function support more cases in texSubImage calls.
Ken Russell (switch to Gerrit) 2016/06/24 01:25:10 TODO(xidachen)
xidachen 2016/06/24 14:36:07 This comment is duplicate of the above one which s
4278 if (functionType == TexImage2DByGPU) { 4304 if (functionType == TexImage2DByGPU) {
4279 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level); 4305 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level);
4280 } 4306 }
4281 4307
4282 // if direct copy is not possible, create a temporary texture and then copy from canvas to temporary texture to target texture. 4308 // if direct copy is not possible, create a temporary texture and then copy from canvas to temporary texture to target texture.
4283 if (!possibleDirectCopy) { 4309 if (!possibleDirectCopy) {
4284 targetLevel = 0; 4310 targetLevel = 0;
4285 targetInternalformat = GL_RGBA; 4311 targetInternalformat = GL_RGBA;
4286 targetType = GL_UNSIGNED_BYTE; 4312 targetType = GL_UNSIGNED_BYTE;
4287 contextGL()->GenTextures(1, &targetTexture); 4313 contextGL()->GenTextures(1, &targetTexture);
4288 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); 4314 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture);
4289 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAR EST); 4315 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAR EST);
4290 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAR EST); 4316 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAR EST);
4291 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO _EDGE); 4317 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO _EDGE);
4292 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO _EDGE); 4318 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO _EDGE);
4293 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, canvas-> width(), 4319 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, width, h eight, 0, GL_RGBA, targetType, 0);
4294 canvas->height(), 0, GL_RGBA, targetType, 0);
4295 } 4320 }
4296 4321
4297 if (!canvas->is3D()) { 4322 if (image->isCanvasElement())
4298 ImageBuffer* buffer = canvas->buffer(); 4323 texImageCanvasByGPU(static_cast<HTMLCanvasElement*>(image), targetTextur e, targetInternalformat, targetType, targetLevel);
4299 if (!buffer->copyToPlatformTexture(contextGL(), targetTexture, targetInt ernalformat, targetType, 4324 else
4300 targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) { 4325 texImageBitmapByGPU(static_cast<ImageBitmap*>(image), targetTexture, tar getInternalformat, targetType, targetLevel, !m_unpackFlipY);
4301 ASSERT_NOT_REACHED();
4302 }
4303 } else {
4304 WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->rend eringContext());
4305 ScopedTexture2DRestorer restorer(gl);
4306 if (!gl->drawingBuffer()->copyToPlatformTexture(contextGL(), targetTextu re, targetInternalformat, targetType,
4307 targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, BackBuffer)) {
4308 ASSERT_NOT_REACHED();
4309 }
4310 }
4311 4326
4312 if (!possibleDirectCopy) { 4327 if (!possibleDirectCopy) {
4313 GLuint tmpFBO; 4328 GLuint tmpFBO;
4314 contextGL()->GenFramebuffers(1, &tmpFBO); 4329 contextGL()->GenFramebuffers(1, &tmpFBO);
4315 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); 4330 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO);
4316 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0); 4331 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0);
4317 contextGL()->BindTexture(texture->getTarget(), texture->object()); 4332 contextGL()->BindTexture(texture->getTarget(), texture->object());
4318 if (functionType == TexImage2DByGPU) { 4333 if (functionType == TexImage2DByGPU) {
4319 contextGL()->CopyTexSubImage2D(target, level, 0, 0, 0, 0, canvas->wi dth(), canvas->height()); 4334 contextGL()->CopyTexSubImage2D(target, level, 0, 0, 0, 0, width, hei ght);
4320 } else if (functionType == TexSubImage2DByGPU) { 4335 } else if (functionType == TexSubImage2DByGPU) {
4321 contextGL()->CopyTexSubImage2D(target, level, xoffset, yoffset, 0, 0 , canvas->width(), canvas->height()); 4336 contextGL()->CopyTexSubImage2D(target, level, xoffset, yoffset, 0, 0 , width, height);
4322 } else if (functionType == TexSubImage3DByGPU) { 4337 } else if (functionType == TexSubImage3DByGPU) {
4323 contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoff set, 0, 0, canvas->width(), canvas->height()); 4338 contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoff set, 0, 0, width, height);
4324 } 4339 }
4325 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 4340 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
4326 restoreCurrentFramebuffer(); 4341 restoreCurrentFramebuffer();
4327 contextGL()->DeleteFramebuffers(1, &tmpFBO); 4342 contextGL()->DeleteFramebuffers(1, &tmpFBO);
4328 contextGL()->DeleteTextures(1, &targetTexture); 4343 contextGL()->DeleteTextures(1, &targetTexture);
4329 } 4344 }
4330 } 4345 }
4331 4346
4332 void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(TexImageFunction ID functionID, 4347 void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(TexImageFunction ID functionID,
4333 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset, 4348 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4334 GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exc eptionState) 4349 GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exc eptionState)
4335 { 4350 {
4336 const char* funcName = getTexImageFunctionName(functionID); 4351 const char* funcName = getTexImageFunctionName(functionID);
4337 if (isContextLost()) 4352 if (isContextLost())
4338 return; 4353 return;
4339 if (!validateHTMLCanvasElement(funcName, canvas, exceptionState)) 4354 if (!validateHTMLCanvasElement(funcName, canvas, exceptionState))
4340 return; 4355 return;
4341 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target ); 4356 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target );
4342 if (!texture) 4357 if (!texture)
4343 return; 4358 return;
4344 TexImageFunctionType functionType; 4359 TexImageFunctionType functionType;
4345 if (functionID == TexImage2D) 4360 if (functionID == TexImage2D)
4346 functionType = TexImage; 4361 functionType = TexImage;
4347 else 4362 else
4348 functionType = TexSubImage; 4363 functionType = TexSubImage;
4349 if (!validateTexFunc(funcName, functionType, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset)) 4364 if (!validateTexFunc(funcName, functionType, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset))
4350 return; 4365 return;
4366 // TODO(xidachen): merge TexImage2D and TexSubImage2D because they have simi lar code path
4351 if (functionID == TexImage2D) { 4367 if (functionID == TexImage2D) {
4352 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format. 4368 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support flo at/integer/sRGB internal format.
4353 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats. 4369 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats.
4354 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || !canUseTexImageCanvasByGPU(internalformat, type)) { 4370 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || !canUseTexImageByGPU(functionID, internalformat, type)) {
4355 // 2D canvas has only FrontBuffer. 4371 // 2D canvas has only FrontBuffer.
4356 texImageImpl(TexImage2D, target, level, internalformat, xoffset, yof fset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration ).get(), 4372 texImageImpl(TexImage2D, target, level, internalformat, xoffset, yof fset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration ).get(),
4357 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha); 4373 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha);
4358 return; 4374 return;
4359 } 4375 }
4360 4376
4361 texImage2DBase(target, level, internalformat, canvas->width(), canvas->h eight(), 0, format, type, 0); 4377 texImage2DBase(target, level, internalformat, canvas->width(), canvas->h eight(), 0, format, type, 0);
4362 texImageCanvasByGPU(TexImage2DByGPU, texture, target, level, internalfor mat, type, 0, 0, 0, canvas); 4378 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, t ype, 0, 0, 0, canvas);
4363 } else if (functionID == TexSubImage2D) { 4379 } else if (functionID == TexSubImage2D) {
4364 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal format s.
4365 bool useReadBackPath = isWebGL2OrHigher()
4366 || extensionEnabled(OESTextureFloatName)
4367 || extensionEnabled(OESTextureHalfFloatName)
4368 || extensionEnabled(EXTsRGBName);
4369 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format. 4380 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format.
4370 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats. 4381 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats.
4371 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || useReadBackPath) { 4382 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || !canUseTexImageByGPU(functionID, internalformat, type)) {
4372 // 2D canvas has only FrontBuffer. 4383 // 2D canvas has only FrontBuffer.
4373 texImageImpl(TexSubImage2D, target, level, 0, xoffset, yoffset, 0, f ormat, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), 4384 texImageImpl(TexSubImage2D, target, level, 0, xoffset, yoffset, 0, f ormat, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4374 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha); 4385 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha);
4375 return; 4386 return;
4376 } 4387 }
4377 4388
4378 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, canvas); 4389 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, canvas);
4379 } else { 4390 } else {
4380 DCHECK_EQ(functionID, TexSubImage3D); 4391 DCHECK_EQ(functionID, TexSubImage3D);
4381 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269). 4392 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269).
4382 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), 4393 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4383 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); 4394 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha);
4384 } 4395 }
4385 } 4396 }
4386 4397
4387 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4398 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4388 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) 4399 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
4451 } 4462 }
4452 } 4463 }
4453 } 4464 }
4454 4465
4455 RefPtr<Image> image = videoFrameToImage(video); 4466 RefPtr<Image> image = videoFrameToImage(video);
4456 if (!image) 4467 if (!image)
4457 return; 4468 return;
4458 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFl ipY, m_unpackPremultiplyAlpha); 4469 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFl ipY, m_unpackPremultiplyAlpha);
4459 } 4470 }
4460 4471
4472 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, GLuint targetTexture, GLenum targetInternalformat, GLenum targetType, GLint targetLevel , bool flipY)
4473 {
4474 GLuint textureId = bitmap->bitmapImage()->textureIdForWebGL(drawingBuffer()- >contextProvider());
4475 bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(), tex tureId, targetTexture, targetInternalformat, targetType, flipY);
Ken Russell (switch to Gerrit) 2016/06/24 01:25:10 It seems a little strange that this work is split
xidachen 2016/06/24 14:36:07 There is no need to split the function calls indee
4476 }
4477
4461 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4478 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4462 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) 4479 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState)
4463 { 4480 {
4464 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, video, exceptionState); 4481 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, video, exceptionState);
4465 } 4482 }
4466 4483
4467 void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionID fun ctionID, 4484 void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionID fun ctionID,
4468 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset, 4485 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4469 GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exception State) 4486 GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exception State)
4470 { 4487 {
4471 const char* funcName = getTexImageFunctionName(functionID); 4488 const char* funcName = getTexImageFunctionName(functionID);
4472 if (isContextLost()) 4489 if (isContextLost())
4473 return; 4490 return;
4474 if (!validateImageBitmap(funcName, bitmap, exceptionState)) 4491 if (!validateImageBitmap(funcName, bitmap, exceptionState))
4475 return; 4492 return;
4476 if (!validateTexImageBinding(funcName, functionID, target)) 4493 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target );
4494 if (!texture)
4477 return; 4495 return;
4478 TexImageFunctionType functionType; 4496 TexImageFunctionType functionType;
4479 if (functionID == TexImage2D) 4497 if (functionID == TexImage2D)
4480 functionType = TexImage; 4498 functionType = TexImage;
4481 else 4499 else
4482 functionType = TexSubImage; 4500 functionType = TexSubImage;
4483 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffse t, yoffset, zoffset)) 4501 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffse t, yoffset, zoffset))
4484 return; 4502 return;
4485 ASSERT(bitmap->bitmapImage()); 4503 ASSERT(bitmap->bitmapImage());
4504 // TODO(xidachen): find out why GPU-GPU copy fails on r8_red, rg8_rg, rgb8_r gb, rgba8_rgba only.
4505 if (functionID != TexSubImage3D && bitmap->isTextureBacked() && canUseTexIma geByGPU(functionID, internalformat, type)
4506 && internalformat != GL_R8 && internalformat != GL_RG8 && internalformat != GL_RGB8 && internalformat != GL_RGBA8) {
Ken Russell (switch to Gerrit) 2016/06/24 01:25:10 That is very strange -- at least that a copy of a
xidachen 2016/06/24 14:36:07 I have not yet debug deeply. But it is strange tha
4507 if (functionID == TexImage2D) {
4508 texImage2DBase(target, level, internalformat, bitmap->width(), bitma p->height(), 0, format, type, 0);
4509 texImageByGPU(TexImage2DByGPU, texture, target, level, internalforma t, type, 0, 0, 0, bitmap);
4510 } else if (functionID == TexSubImage2D) {
4511 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, t ype, xoffset, yoffset, 0, bitmap);
4512 }
4513 return;
4514 }
4486 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); 4515 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
4487 SkPixmap pixmap; 4516 SkPixmap pixmap;
4488 std::unique_ptr<uint8_t[]> pixelData; 4517 std::unique_ptr<uint8_t[]> pixelData;
4489 uint8_t* pixelDataPtr = nullptr; 4518 uint8_t* pixelDataPtr = nullptr;
4490 // TODO(crbug.com/613411): peekPixels fails if the SkImage is texture-backed 4519 // In the case where an ImageBitmap is not texture backed, peekPixels() alwa ys succeed.
4491 // Use texture mailbox in that case. 4520 // However, when it is texture backed and !canUseTexImageByGPU, we do a GPU read back.
4492 bool peekSucceed = skImage->peekPixels(&pixmap); 4521 bool peekSucceed = skImage->peekPixels(&pixmap);
4493 if (peekSucceed) { 4522 if (peekSucceed) {
4494 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); 4523 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
4495 } else if (skImage->isTextureBacked()) { 4524 } else {
4496 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha); 4525 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha);
4497 pixelDataPtr = pixelData.get(); 4526 pixelDataPtr = pixelData.get();
4498 } 4527 }
4499 Vector<uint8_t> data; 4528 Vector<uint8_t> data;
4500 bool needConversion = true; 4529 bool needConversion = true;
4501 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType); 4530 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType);
4502 bool isPixelDataRBGA = (havePeekableRGBA || !peekSucceed); 4531 bool isPixelDataRGBA = (havePeekableRGBA || !peekSucceed);
4503 if (isPixelDataRBGA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { 4532 if (isPixelDataRGBA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
4504 needConversion = false; 4533 needConversion = false;
4505 } else { 4534 } else {
4506 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4535 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4507 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. 4536 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed.
4508 type = GL_FLOAT; 4537 type = GL_FLOAT;
4509 } 4538 }
4510 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha. 4539 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha.
4511 bool isPixelDataBGRA = (peekSucceed && pixmap.colorType() == SkColorType ::kBGRA_8888_SkColorType); 4540 bool isPixelDataBGRA = pixmap.colorType() == SkColorType::kBGRA_8888_SkC olorType;
4512 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data)) 4541 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data))
4513 || (isPixelDataRBGA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) { 4542 || (isPixelDataRGBA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) {
4514 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); 4543 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
4515 return; 4544 return;
4516 } 4545 }
4517 } 4546 }
4518 resetUnpackParameters(); 4547 resetUnpackParameters();
4519 if (functionID == TexImage2D) { 4548 if (functionID == TexImage2D) {
4520 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, needConversion ? data.data() : pixelDataPtr); 4549 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, needConversion ? data.data() : pixelDataPtr);
4521 } else if (functionID == TexSubImage2D) { 4550 } else if (functionID == TexSubImage2D) {
4522 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->widt h(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr ); 4551 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->widt h(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr );
4523 } else { 4552 } else {
(...skipping 1900 matching lines...) Expand 10 before | Expand all | Expand 10 after
6424 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1); 6453 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
6425 } 6454 }
6426 6455
6427 void WebGLRenderingContextBase::restoreUnpackParameters() 6456 void WebGLRenderingContextBase::restoreUnpackParameters()
6428 { 6457 {
6429 if (m_unpackAlignment != 1) 6458 if (m_unpackAlignment != 1)
6430 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); 6459 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
6431 } 6460 }
6432 6461
6433 } // namespace blink 6462 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698