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

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: layout test timeout in a strange way 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 4246 matching lines...) Expand 10 before | Expand all | Expand 10 after
4257 4257
4258 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m _unpackFlipY, m_unpackPremultiplyAlpha); 4258 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m _unpackFlipY, m_unpackPremultiplyAlpha);
4259 } 4259 }
4260 4260
4261 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4261 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4262 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState) 4262 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState)
4263 { 4263 {
4264 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, image, exceptionState); 4264 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, image, exceptionState);
4265 } 4265 }
4266 4266
4267 bool WebGLRenderingContextBase::canUseTexImageCanvasByGPU(GLint internalformat, GLenum type) 4267 bool WebGLRenderingContextBase::canUseTexImageByGPU(GLint internalformat, GLenum type)
4268 { 4268 {
4269 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat)) 4269 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat))
4270 return false; 4270 return false;
4271 return true; 4271 return true;
4272 } 4272 }
4273 4273
4274 void WebGLRenderingContextBase::texImageCanvasByGPU(TexImageByGPUType functionTy pe, WebGLTexture* texture, GLenum target, 4274 void WebGLRenderingContextBase::texImageCanvasByGPU(HTMLCanvasElement* canvas, G Luint targetTexture, GLenum targetInternalformat, GLenum targetType, GLint targe tLevel)
4275 GLint level, GLint internalformat, GLenum type, GLint xoffset, GLint yoffset , GLint zoffset, HTMLCanvasElement* canvas)
4276 { 4275 {
4276 if (!canvas->is3D()) {
4277 ImageBuffer* buffer = canvas->buffer();
4278 if (!buffer->copyToPlatformTexture(contextGL(), targetTexture, targetInt ernalformat, targetType,
4279 targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
4280 NOTREACHED();
4281 }
4282 } else {
4283 WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->rend eringContext());
4284 ScopedTexture2DRestorer restorer(gl);
4285 if (!gl->drawingBuffer()->copyToPlatformTexture(contextGL(), targetTextu re, targetInternalformat, targetType,
4286 targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, BackBuffer)) {
4287 NOTREACHED();
4288 }
4289 }
4290 }
4291
4292 void WebGLRenderingContextBase::texImageByGPU(TexImageByGPUType functionType, We bGLTexture* texture, GLenum target,
4293 GLint level, GLint internalformat, GLenum type, GLint xoffset, GLint yoffset , GLint zoffset, HTMLCanvasElement* canvas, ImageBitmap* bitmap)
4294 {
4295 DCHECK((!canvas || !bitmap) && (canvas || bitmap));
4296 int width;
4297 int height;
4298 if (canvas) {
4299 width = canvas->width();
4300 height = canvas->height();
4301 } else {
4302 width = bitmap->width();
4303 height = bitmap->height();
4304 }
4277 ScopedTexture2DRestorer restorer(this); 4305 ScopedTexture2DRestorer restorer(this);
4278 4306
4279 GLuint targetTexture = texture->object(); 4307 GLuint targetTexture = texture->object();
4280 GLenum targetType = type; 4308 GLenum targetType = type;
4281 GLenum targetInternalformat = internalformat; 4309 GLenum targetInternalformat = internalformat;
4282 GLint targetLevel = level; 4310 GLint targetLevel = level;
4283 bool possibleDirectCopy = false; 4311 bool possibleDirectCopy = false;
4312 // TODO: Make this function support more cases in texSubImage calls.
4284 if (functionType == TexImage2DByGPU) { 4313 if (functionType == TexImage2DByGPU) {
4285 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level); 4314 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level);
4286 } 4315 }
4287 4316
4288 // if direct copy is not possible, create a temporary texture and then copy from canvas to temporary texture to target texture. 4317 // if direct copy is not possible, create a temporary texture and then copy from canvas to temporary texture to target texture.
4289 if (!possibleDirectCopy) { 4318 if (!possibleDirectCopy) {
4290 targetLevel = 0; 4319 targetLevel = 0;
4291 targetInternalformat = GL_RGBA; 4320 targetInternalformat = GL_RGBA;
4292 targetType = GL_UNSIGNED_BYTE; 4321 targetType = GL_UNSIGNED_BYTE;
4293 contextGL()->GenTextures(1, &targetTexture); 4322 contextGL()->GenTextures(1, &targetTexture);
4294 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); 4323 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture);
4295 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAR EST); 4324 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAR EST);
4296 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAR EST); 4325 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAR EST);
4297 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO _EDGE); 4326 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO _EDGE);
4298 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO _EDGE); 4327 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO _EDGE);
4299 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, canvas-> width(), 4328 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, width, h eight, 0, GL_RGBA, targetType, 0);
4300 canvas->height(), 0, GL_RGBA, targetType, 0);
4301 } 4329 }
4302 4330
4303 if (!canvas->is3D()) { 4331 if (canvas)
4304 ImageBuffer* buffer = canvas->buffer(); 4332 texImageCanvasByGPU(canvas, targetTexture, targetInternalformat, targetT ype, targetLevel);
4305 if (!buffer->copyToPlatformTexture(contextGL(), targetTexture, targetInt ernalformat, targetType, 4333 else
4306 targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) { 4334 texImageBitmapByGPU(bitmap, targetTexture, targetInternalformat, targetT ype, targetLevel, !m_unpackFlipY);
4307 ASSERT_NOT_REACHED();
4308 }
4309 } else {
4310 WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->rend eringContext());
4311 ScopedTexture2DRestorer restorer(gl);
4312 if (!gl->drawingBuffer()->copyToPlatformTexture(contextGL(), targetTextu re, targetInternalformat, targetType,
4313 targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, BackBuffer)) {
4314 ASSERT_NOT_REACHED();
4315 }
4316 }
4317 4335
4318 if (!possibleDirectCopy) { 4336 if (!possibleDirectCopy) {
4319 GLuint tmpFBO; 4337 GLuint tmpFBO;
4320 contextGL()->GenFramebuffers(1, &tmpFBO); 4338 contextGL()->GenFramebuffers(1, &tmpFBO);
4321 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); 4339 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO);
4322 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0); 4340 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0);
4323 contextGL()->BindTexture(texture->getTarget(), texture->object()); 4341 contextGL()->BindTexture(texture->getTarget(), texture->object());
4324 if (functionType == TexImage2DByGPU) { 4342 if (functionType == TexImage2DByGPU) {
4325 contextGL()->CopyTexSubImage2D(target, level, 0, 0, 0, 0, canvas->wi dth(), canvas->height()); 4343 contextGL()->CopyTexSubImage2D(target, level, 0, 0, 0, 0, width, hei ght);
4326 } else if (functionType == TexSubImage2DByGPU) { 4344 } else if (functionType == TexSubImage2DByGPU) {
4327 contextGL()->CopyTexSubImage2D(target, level, xoffset, yoffset, 0, 0 , canvas->width(), canvas->height()); 4345 contextGL()->CopyTexSubImage2D(target, level, xoffset, yoffset, 0, 0 , width, height);
4328 } else if (functionType == TexSubImage3DByGPU) { 4346 } else if (functionType == TexSubImage3DByGPU) {
4329 contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoff set, 0, 0, canvas->width(), canvas->height()); 4347 contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoff set, 0, 0, width, height);
4330 } 4348 }
4331 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 4349 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
4332 restoreCurrentFramebuffer(); 4350 restoreCurrentFramebuffer();
4333 contextGL()->DeleteFramebuffers(1, &tmpFBO); 4351 contextGL()->DeleteFramebuffers(1, &tmpFBO);
4334 contextGL()->DeleteTextures(1, &targetTexture); 4352 contextGL()->DeleteTextures(1, &targetTexture);
4335 } 4353 }
4336 } 4354 }
4337 4355
4338 void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(TexImageFunction ID functionID, 4356 void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(TexImageFunction ID functionID,
4339 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset, 4357 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4340 GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exc eptionState) 4358 GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exc eptionState)
4341 { 4359 {
4342 const char* funcName = getTexImageFunctionName(functionID); 4360 const char* funcName = getTexImageFunctionName(functionID);
4343 if (isContextLost()) 4361 if (isContextLost())
4344 return; 4362 return;
4345 if (!validateHTMLCanvasElement(funcName, canvas, exceptionState)) 4363 if (!validateHTMLCanvasElement(funcName, canvas, exceptionState))
4346 return; 4364 return;
4347 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target ); 4365 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target );
4348 if (!texture) 4366 if (!texture)
4349 return; 4367 return;
4350 TexImageFunctionType functionType; 4368 TexImageFunctionType functionType;
4351 if (functionID == TexImage2D) 4369 if (functionID == TexImage2D)
4352 functionType = TexImage; 4370 functionType = TexImage;
4353 else 4371 else
4354 functionType = TexSubImage; 4372 functionType = TexSubImage;
4355 if (!validateTexFunc(funcName, functionType, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset)) 4373 if (!validateTexFunc(funcName, functionType, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset))
4356 return; 4374 return;
4357 if (functionID == TexImage2D) { 4375 if (functionID == TexImage2D) {
4358 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format. 4376 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support flo at/integer/sRGB internal format.
4359 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats. 4377 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats.
4360 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || !canUseTexImageCanvasByGPU(internalformat, type)) { 4378 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || !canUseTexImageByGPU(internalformat, type)) {
4361 // 2D canvas has only FrontBuffer. 4379 // 2D canvas has only FrontBuffer.
4362 texImageImpl(TexImage2D, target, level, internalformat, xoffset, yof fset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration ).get(), 4380 texImageImpl(TexImage2D, target, level, internalformat, xoffset, yof fset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration ).get(),
4363 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha); 4381 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha);
4364 return; 4382 return;
4365 } 4383 }
4366 4384
4367 texImage2DBase(target, level, internalformat, canvas->width(), canvas->h eight(), 0, format, type, 0); 4385 texImage2DBase(target, level, internalformat, canvas->width(), canvas->h eight(), 0, format, type, 0);
4368 texImageCanvasByGPU(TexImage2DByGPU, texture, target, level, internalfor mat, type, 0, 0, 0, canvas); 4386 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, t ype, 0, 0, 0, canvas, nullptr);
4369 } else if (functionID == TexSubImage2D) { 4387 } else if (functionID == TexSubImage2D) {
4370 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal format s. 4388 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal format s.
4371 bool useReadBackPath = isWebGL2OrHigher() 4389 bool useReadBackPath = isWebGL2OrHigher()
4372 || extensionEnabled(OESTextureFloatName) 4390 || extensionEnabled(OESTextureFloatName)
4373 || extensionEnabled(OESTextureHalfFloatName) 4391 || extensionEnabled(OESTextureHalfFloatName)
4374 || extensionEnabled(EXTsRGBName); 4392 || extensionEnabled(EXTsRGBName);
4375 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format. 4393 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format.
4376 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats. 4394 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats.
4377 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || useReadBackPath) { 4395 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || useReadBackPath) {
4378 // 2D canvas has only FrontBuffer. 4396 // 2D canvas has only FrontBuffer.
4379 texImageImpl(TexSubImage2D, target, level, 0, xoffset, yoffset, 0, f ormat, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), 4397 texImageImpl(TexSubImage2D, target, level, 0, xoffset, yoffset, 0, f ormat, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4380 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha); 4398 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha);
4381 return; 4399 return;
4382 } 4400 }
4383 4401
4384 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, canvas); 4402 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, canvas, nullptr);
4385 } else { 4403 } else {
4386 DCHECK_EQ(functionID, TexSubImage3D); 4404 DCHECK_EQ(functionID, TexSubImage3D);
4387 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269). 4405 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269).
4388 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), 4406 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4389 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); 4407 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha);
4390 } 4408 }
4391 } 4409 }
4392 4410
4393 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4411 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4394 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) 4412 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
4457 } 4475 }
4458 } 4476 }
4459 } 4477 }
4460 4478
4461 RefPtr<Image> image = videoFrameToImage(video); 4479 RefPtr<Image> image = videoFrameToImage(video);
4462 if (!image) 4480 if (!image)
4463 return; 4481 return;
4464 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFl ipY, m_unpackPremultiplyAlpha); 4482 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFl ipY, m_unpackPremultiplyAlpha);
4465 } 4483 }
4466 4484
4485 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, GLuint targetTexture, GLenum targetInternalformat, GLenum targetType, GLint targetLevel , bool flipY)
4486 {
4487 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(drawin gBuffer()->contextProvider());
4488 bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(), tar getTexture, targetInternalformat, targetType, flipY);
4489 }
4490
4467 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4491 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4468 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) 4492 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState)
4469 { 4493 {
4470 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, video, exceptionState); 4494 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, video, exceptionState);
4471 } 4495 }
4472 4496
4473 void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionID fun ctionID, 4497 void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionID fun ctionID,
4474 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset, 4498 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4475 GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exception State) 4499 GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exception State)
4476 { 4500 {
4477 const char* funcName = getTexImageFunctionName(functionID); 4501 const char* funcName = getTexImageFunctionName(functionID);
4478 if (isContextLost()) 4502 if (isContextLost())
4479 return; 4503 return;
4480 if (!validateImageBitmap(funcName, bitmap, exceptionState)) 4504 if (!validateImageBitmap(funcName, bitmap, exceptionState))
4481 return; 4505 return;
4482 if (!validateTexImageBinding(funcName, functionID, target)) 4506 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target );
4507 if (!texture)
4483 return; 4508 return;
4484 TexImageFunctionType functionType; 4509 TexImageFunctionType functionType;
4485 if (functionID == TexImage2D) 4510 if (functionID == TexImage2D)
4486 functionType = TexImage; 4511 functionType = TexImage;
4487 else 4512 else
4488 functionType = TexSubImage; 4513 functionType = TexSubImage;
4489 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffse t, yoffset, zoffset)) 4514 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffse t, yoffset, zoffset))
4490 return; 4515 return;
4491 ASSERT(bitmap->bitmapImage()); 4516 ASSERT(bitmap->bitmapImage());
4517 if (bitmap->isTextureBacked() && canUseTexImageByGPU(internalformat, type)) {
4518 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, 0);
4519 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, t ype, 0, 0, 0, nullptr, bitmap);
4520 return;
4521 }
4492 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); 4522 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
4493 SkPixmap pixmap; 4523 SkPixmap pixmap;
4494 OwnPtr<uint8_t[]> pixelData; 4524 OwnPtr<uint8_t[]> pixelData;
4495 uint8_t* pixelDataPtr = nullptr; 4525 uint8_t* pixelDataPtr = nullptr;
4496 // TODO(crbug.com/613411): peekPixels fails if the SkImage is texture-backed 4526 // In the case where an ImageBitmap is not texture backed, peekPixels() alwa ys succeed.
4497 // Use texture mailbox in that case. 4527 // However, when it is texture backed and !canUseTexImageByGPU, we do a GPU read back.
4498 bool peekSucceed = skImage->peekPixels(&pixmap); 4528 bool peekSucceed = skImage->peekPixels(&pixmap);
4499 if (peekSucceed) { 4529 if (peekSucceed) {
4500 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); 4530 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
4501 } else if (skImage->isTextureBacked()) { 4531 } else {
4502 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha); 4532 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha);
4503 pixelDataPtr = pixelData.get(); 4533 pixelDataPtr = pixelData.get();
4504 } 4534 }
4505 Vector<uint8_t> data; 4535 Vector<uint8_t> data;
4506 bool needConversion = true; 4536 bool needConversion = true;
4507 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType); 4537 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType);
4508 bool isPixelDataRBGA = (havePeekableRGBA || !peekSucceed); 4538 bool isPixelDataRGBA = (havePeekableRGBA || !peekSucceed);
4509 if (isPixelDataRBGA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { 4539 if (isPixelDataRGBA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
4510 needConversion = false; 4540 needConversion = false;
4511 } else { 4541 } else {
4512 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4542 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4513 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. 4543 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed.
4514 type = GL_FLOAT; 4544 type = GL_FLOAT;
4515 } 4545 }
4516 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha. 4546 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha.
4517 bool isPixelDataBGRA = (peekSucceed && pixmap.colorType() == SkColorType ::kBGRA_8888_SkColorType); 4547 bool isPixelDataBGRA = pixmap.colorType() == SkColorType::kBGRA_8888_SkC olorType;
4518 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data)) 4548 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data))
4519 || (isPixelDataRBGA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) { 4549 || (isPixelDataRGBA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) {
4520 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); 4550 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
4521 return; 4551 return;
4522 } 4552 }
4523 } 4553 }
4524 resetUnpackParameters(); 4554 resetUnpackParameters();
4525 if (functionID == TexImage2D) { 4555 if (functionID == TexImage2D) {
4526 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, needConversion ? data.data() : pixelDataPtr); 4556 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, needConversion ? data.data() : pixelDataPtr);
4527 } else if (functionID == TexSubImage2D) { 4557 } else if (functionID == TexSubImage2D) {
4528 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->widt h(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr ); 4558 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->widt h(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr );
4529 } else { 4559 } else {
(...skipping 1905 matching lines...) Expand 10 before | Expand all | Expand 10 after
6435 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1); 6465 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
6436 } 6466 }
6437 6467
6438 void WebGLRenderingContextBase::restoreUnpackParameters() 6468 void WebGLRenderingContextBase::restoreUnpackParameters()
6439 { 6469 {
6440 if (m_unpackAlignment != 1) 6470 if (m_unpackAlignment != 1)
6441 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); 6471 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
6442 } 6472 }
6443 6473
6444 } // namespace blink 6474 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698