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

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 kbr@'s comments 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 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 // TODO(crbug.com/622958): Implement GPU-to-GPU path for WebGL 2 and more in ternal formats.
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;
4278 if (functionType == TexImage2DByGPU) { 4303 if (functionType == TexImage2DByGPU) {
4279 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level); 4304 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level);
4280 } 4305 }
4281 4306
4282 // 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.
4283 if (!possibleDirectCopy) { 4308 if (!possibleDirectCopy) {
4284 targetLevel = 0; 4309 targetLevel = 0;
4285 targetInternalformat = GL_RGBA; 4310 targetInternalformat = GL_RGBA;
4286 targetType = GL_UNSIGNED_BYTE; 4311 targetType = GL_UNSIGNED_BYTE;
4287 contextGL()->GenTextures(1, &targetTexture); 4312 contextGL()->GenTextures(1, &targetTexture);
4288 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); 4313 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture);
4289 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);
4290 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);
4291 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);
4292 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);
4293 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);
4294 canvas->height(), 0, GL_RGBA, targetType, 0);
4295 } 4319 }
4296 4320
4297 if (!canvas->is3D()) { 4321 if (image->isCanvasElement())
4298 ImageBuffer* buffer = canvas->buffer(); 4322 texImageCanvasByGPU(static_cast<HTMLCanvasElement*>(image), targetTextur e, targetInternalformat, targetType, targetLevel);
4299 if (!buffer->copyToPlatformTexture(contextGL(), targetTexture, targetInt ernalformat, targetType, 4323 else
4300 targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) { 4324 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 4325
4312 if (!possibleDirectCopy) { 4326 if (!possibleDirectCopy) {
4313 GLuint tmpFBO; 4327 GLuint tmpFBO;
4314 contextGL()->GenFramebuffers(1, &tmpFBO); 4328 contextGL()->GenFramebuffers(1, &tmpFBO);
4315 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); 4329 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO);
4316 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);
4317 contextGL()->BindTexture(texture->getTarget(), texture->object()); 4331 contextGL()->BindTexture(texture->getTarget(), texture->object());
4318 if (functionType == TexImage2DByGPU) { 4332 if (functionType == TexImage2DByGPU) {
4319 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);
4320 } else if (functionType == TexSubImage2DByGPU) { 4334 } else if (functionType == TexSubImage2DByGPU) {
4321 contextGL()->CopyTexSubImage2D(target, level, xoffset, yoffset, 0, 0 , canvas->width(), canvas->height()); 4335 contextGL()->CopyTexSubImage2D(target, level, xoffset, yoffset, 0, 0 , width, height);
4322 } else if (functionType == TexSubImage3DByGPU) { 4336 } else if (functionType == TexSubImage3DByGPU) {
4323 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);
4324 } 4338 }
4325 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);
4326 restoreCurrentFramebuffer(); 4340 restoreCurrentFramebuffer();
4327 contextGL()->DeleteFramebuffers(1, &tmpFBO); 4341 contextGL()->DeleteFramebuffers(1, &tmpFBO);
4328 contextGL()->DeleteTextures(1, &targetTexture); 4342 contextGL()->DeleteTextures(1, &targetTexture);
4329 } 4343 }
4330 } 4344 }
4331 4345
4332 void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(TexImageFunction ID functionID, 4346 void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(TexImageFunction ID functionID,
4333 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,
4334 GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exc eptionState) 4348 GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exc eptionState)
4335 { 4349 {
4336 const char* funcName = getTexImageFunctionName(functionID); 4350 const char* funcName = getTexImageFunctionName(functionID);
4337 if (isContextLost()) 4351 if (isContextLost())
4338 return; 4352 return;
4339 if (!validateHTMLCanvasElement(funcName, canvas, exceptionState)) 4353 if (!validateHTMLCanvasElement(funcName, canvas, exceptionState))
4340 return; 4354 return;
4341 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target ); 4355 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target );
4342 if (!texture) 4356 if (!texture)
4343 return; 4357 return;
4344 TexImageFunctionType functionType; 4358 TexImageFunctionType functionType;
4345 if (functionID == TexImage2D) 4359 if (functionID == TexImage2D)
4346 functionType = TexImage; 4360 functionType = TexImage;
4347 else 4361 else
4348 functionType = TexSubImage; 4362 functionType = TexSubImage;
4349 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))
4350 return; 4364 return;
4365 // TODO(xidachen): merge TexImage2D and TexSubImage2D because they have simi lar code path
4351 if (functionID == TexImage2D) { 4366 if (functionID == TexImage2D) {
4352 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format. 4367 // 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. 4368 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats.
4354 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || !canUseTexImageCanvasByGPU(internalformat, type)) { 4369 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || !canUseTexImageByGPU(functionID, internalformat, type)) {
4355 // 2D canvas has only FrontBuffer. 4370 // 2D canvas has only FrontBuffer.
4356 texImageImpl(TexImage2D, target, level, internalformat, xoffset, yof fset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration ).get(), 4371 texImageImpl(TexImage2D, target, level, internalformat, xoffset, yof fset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration ).get(),
4357 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha); 4372 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha);
4358 return; 4373 return;
4359 } 4374 }
4360 4375
4361 texImage2DBase(target, level, internalformat, canvas->width(), canvas->h eight(), 0, format, type, 0); 4376 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); 4377 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, t ype, 0, 0, 0, canvas);
4363 } else if (functionID == TexSubImage2D) { 4378 } 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. 4379 // 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. 4380 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats.
4371 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || useReadBackPath) { 4381 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || !canUseTexImageByGPU(functionID, internalformat, type)) {
4372 // 2D canvas has only FrontBuffer. 4382 // 2D canvas has only FrontBuffer.
4373 texImageImpl(TexSubImage2D, target, level, 0, xoffset, yoffset, 0, f ormat, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), 4383 texImageImpl(TexSubImage2D, target, level, 0, xoffset, yoffset, 0, f ormat, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4374 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha); 4384 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha);
4375 return; 4385 return;
4376 } 4386 }
4377 4387
4378 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, canvas); 4388 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, canvas);
4379 } else { 4389 } else {
4380 DCHECK_EQ(functionID, TexSubImage3D); 4390 DCHECK_EQ(functionID, TexSubImage3D);
4381 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269). 4391 // 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(), 4392 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4383 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); 4393 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha);
4384 } 4394 }
4385 } 4395 }
4386 4396
4387 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4397 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4388 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) 4398 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
4451 } 4461 }
4452 } 4462 }
4453 } 4463 }
4454 4464
4455 RefPtr<Image> image = videoFrameToImage(video); 4465 RefPtr<Image> image = videoFrameToImage(video);
4456 if (!image) 4466 if (!image)
4457 return; 4467 return;
4458 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFl ipY, m_unpackPremultiplyAlpha); 4468 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFl ipY, m_unpackPremultiplyAlpha);
4459 } 4469 }
4460 4470
4471 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, GLuint targetTexture, GLenum targetInternalformat, GLenum targetType, GLint targetLevel , bool flipY)
4472 {
4473 bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(), tar getTexture, targetInternalformat, targetType, flipY);
4474 }
4475
4461 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4476 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4462 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) 4477 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState)
4463 { 4478 {
4464 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, video, exceptionState); 4479 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, video, exceptionState);
4465 } 4480 }
4466 4481
4467 void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionID fun ctionID, 4482 void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionID fun ctionID,
4468 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset, 4483 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4469 GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exception State) 4484 GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exception State)
4470 { 4485 {
4471 const char* funcName = getTexImageFunctionName(functionID); 4486 const char* funcName = getTexImageFunctionName(functionID);
4472 if (isContextLost()) 4487 if (isContextLost())
4473 return; 4488 return;
4474 if (!validateImageBitmap(funcName, bitmap, exceptionState)) 4489 if (!validateImageBitmap(funcName, bitmap, exceptionState))
4475 return; 4490 return;
4476 if (!validateTexImageBinding(funcName, functionID, target)) 4491 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target );
4492 if (!texture)
4477 return; 4493 return;
4478 TexImageFunctionType functionType; 4494 TexImageFunctionType functionType;
4479 if (functionID == TexImage2D) 4495 if (functionID == TexImage2D)
4480 functionType = TexImage; 4496 functionType = TexImage;
4481 else 4497 else
4482 functionType = TexSubImage; 4498 functionType = TexSubImage;
4483 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffse t, yoffset, zoffset)) 4499 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffse t, yoffset, zoffset))
4484 return; 4500 return;
4485 ASSERT(bitmap->bitmapImage()); 4501 ASSERT(bitmap->bitmapImage());
4502 // TODO(xidachen): find out why GPU-GPU copy fails on r8_red, rg8_rg, rgb8_r gb, rgba8_rgba only.
4503 if (functionID != TexSubImage3D && bitmap->isTextureBacked() && canUseTexIma geByGPU(functionID, internalformat, type)
4504 && internalformat != GL_R8 && internalformat != GL_RG8 && internalformat != GL_RGB8 && internalformat != GL_RGBA8) {
4505 if (functionID == TexImage2D) {
4506 texImage2DBase(target, level, internalformat, bitmap->width(), bitma p->height(), 0, format, type, 0);
4507 texImageByGPU(TexImage2DByGPU, texture, target, level, internalforma t, type, 0, 0, 0, bitmap);
4508 } else if (functionID == TexSubImage2D) {
4509 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, t ype, xoffset, yoffset, 0, bitmap);
4510 }
4511 return;
4512 }
4486 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); 4513 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
4487 SkPixmap pixmap; 4514 SkPixmap pixmap;
4488 std::unique_ptr<uint8_t[]> pixelData; 4515 std::unique_ptr<uint8_t[]> pixelData;
4489 uint8_t* pixelDataPtr = nullptr; 4516 uint8_t* pixelDataPtr = nullptr;
4490 // TODO(crbug.com/613411): peekPixels fails if the SkImage is texture-backed 4517 // In the case where an ImageBitmap is not texture backed, peekPixels() alwa ys succeed.
4491 // Use texture mailbox in that case. 4518 // However, when it is texture backed and !canUseTexImageByGPU, we do a GPU read back.
4492 bool peekSucceed = skImage->peekPixels(&pixmap); 4519 bool peekSucceed = skImage->peekPixels(&pixmap);
4493 if (peekSucceed) { 4520 if (peekSucceed) {
4494 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); 4521 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
4495 } else if (skImage->isTextureBacked()) { 4522 } else {
4496 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha); 4523 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha);
4497 pixelDataPtr = pixelData.get(); 4524 pixelDataPtr = pixelData.get();
4498 } 4525 }
4499 Vector<uint8_t> data; 4526 Vector<uint8_t> data;
4500 bool needConversion = true; 4527 bool needConversion = true;
4501 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType); 4528 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType);
4502 bool isPixelDataRBGA = (havePeekableRGBA || !peekSucceed); 4529 bool isPixelDataRGBA = (havePeekableRGBA || !peekSucceed);
4503 if (isPixelDataRBGA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { 4530 if (isPixelDataRGBA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
4504 needConversion = false; 4531 needConversion = false;
4505 } else { 4532 } else {
4506 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4533 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4507 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. 4534 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed.
4508 type = GL_FLOAT; 4535 type = GL_FLOAT;
4509 } 4536 }
4510 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha. 4537 // 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); 4538 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)) 4539 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))) { 4540 || (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"); 4541 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
4515 return; 4542 return;
4516 } 4543 }
4517 } 4544 }
4518 resetUnpackParameters(); 4545 resetUnpackParameters();
4519 if (functionID == TexImage2D) { 4546 if (functionID == TexImage2D) {
4520 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, needConversion ? data.data() : pixelDataPtr); 4547 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, needConversion ? data.data() : pixelDataPtr);
4521 } else if (functionID == TexSubImage2D) { 4548 } else if (functionID == TexSubImage2D) {
4522 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->widt h(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr ); 4549 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->widt h(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr );
4523 } else { 4550 } else {
(...skipping 1900 matching lines...) Expand 10 before | Expand all | Expand 10 after
6424 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1); 6451 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
6425 } 6452 }
6426 6453
6427 void WebGLRenderingContextBase::restoreUnpackParameters() 6454 void WebGLRenderingContextBase::restoreUnpackParameters()
6428 { 6455 {
6429 if (m_unpackAlignment != 1) 6456 if (m_unpackAlignment != 1)
6430 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); 6457 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
6431 } 6458 }
6432 6459
6433 } // namespace blink 6460 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698