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

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

Issue 2482793005: Implement tex{Sub}Image3D taking sub-rectangles of HTMLImageElements. (Closed)
Patch Set: Early out in case of error. Roll WebGL conformance tests too. Created 4 years, 1 month 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
« no previous file with comments | « third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 4329 matching lines...) Expand 10 before | Expand all | Expand 10 after
4340 GLint internalformat, 4340 GLint internalformat,
4341 GLint xoffset, 4341 GLint xoffset,
4342 GLint yoffset, 4342 GLint yoffset,
4343 GLint zoffset, 4343 GLint zoffset,
4344 GLenum format, 4344 GLenum format,
4345 GLenum type, 4345 GLenum type,
4346 Image* image, 4346 Image* image,
4347 WebGLImageConversion::ImageHtmlDomSource domSource, 4347 WebGLImageConversion::ImageHtmlDomSource domSource,
4348 bool flipY, 4348 bool flipY,
4349 bool premultiplyAlpha, 4349 bool premultiplyAlpha,
4350 const IntRect& sourceImageRect) { 4350 const IntRect& sourceImageRect,
4351 GLsizei depth,
4352 GLint unpackImageHeight) {
4351 const char* funcName = getTexImageFunctionName(functionID); 4353 const char* funcName = getTexImageFunctionName(functionID);
4352 // All calling functions check isContextLost, so a duplicate check is not 4354 // All calling functions check isContextLost, so a duplicate check is not
4353 // needed here. 4355 // needed here.
4354 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4356 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4355 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. 4357 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
4356 type = GL_FLOAT; 4358 type = GL_FLOAT;
4357 } 4359 }
4358 Vector<uint8_t> data; 4360 Vector<uint8_t> data;
4359 4361
4360 IntRect subRect = sourceImageRect; 4362 IntRect subRect = sourceImageRect;
(...skipping 19 matching lines...) Expand all
4380 4382
4381 if (subRect.x() < 0 || subRect.y() < 0 || subRect.maxX() > image->width() || 4383 if (subRect.x() < 0 || subRect.y() < 0 || subRect.maxX() > image->width() ||
4382 subRect.maxY() > image->height() || subRect.width() < 0 || 4384 subRect.maxY() > image->height() || subRect.width() < 0 ||
4383 subRect.height() < 0) { 4385 subRect.height() < 0) {
4384 synthesizeGLError(GL_INVALID_OPERATION, funcName, 4386 synthesizeGLError(GL_INVALID_OPERATION, funcName,
4385 "source sub-rectangle specified via pixel unpack " 4387 "source sub-rectangle specified via pixel unpack "
4386 "parameters is invalid"); 4388 "parameters is invalid");
4387 return; 4389 return;
4388 } 4390 }
4389 4391
4392 if (functionID == TexImage3D || functionID == TexSubImage3D) {
4393 DCHECK_GE(unpackImageHeight, 0);
4394
4395 // Verify that the image data can cover the required depth.
4396 CheckedNumeric<GLint> maxDepthSupported = 1;
4397 if (unpackImageHeight) {
4398 maxDepthSupported = subRect.height();
4399 maxDepthSupported /= unpackImageHeight;
4400 }
4401
4402 if (!maxDepthSupported.IsValid() ||
4403 maxDepthSupported.ValueOrDie() < depth) {
4404 synthesizeGLError(
4405 GL_INVALID_OPERATION, funcName,
4406 "Not enough data supplied to upload to a 3D texture with depth > 1");
4407 return;
4408 }
4409 } else {
4410 DCHECK_EQ(depth, 1);
4411 DCHECK_EQ(unpackImageHeight, 0);
4412 }
4413
4390 // Adjust the source image rectangle if doing a y-flip. 4414 // Adjust the source image rectangle if doing a y-flip.
4391 IntRect adjustedSourceImageRect = subRect; 4415 IntRect adjustedSourceImageRect = subRect;
4392 if (flipY) { 4416 if (flipY) {
4393 adjustedSourceImageRect.setY(image->height() - 4417 adjustedSourceImageRect.setY(image->height() -
4394 adjustedSourceImageRect.maxY()); 4418 adjustedSourceImageRect.maxY());
4395 } 4419 }
4396 4420
4397 WebGLImageConversion::ImageExtractor imageExtractor( 4421 WebGLImageConversion::ImageExtractor imageExtractor(
4398 image, domSource, premultiplyAlpha, 4422 image, domSource, premultiplyAlpha,
4399 m_unpackColorspaceConversion == GL_NONE); 4423 m_unpackColorspaceConversion == GL_NONE);
(...skipping 29 matching lines...) Expand all
4429 texImage2DBase(target, level, internalformat, 4453 texImage2DBase(target, level, internalformat,
4430 adjustedSourceImageRect.width(), 4454 adjustedSourceImageRect.width(),
4431 adjustedSourceImageRect.height(), 0, format, type, 4455 adjustedSourceImageRect.height(), 0, format, type,
4432 needConversion ? data.data() : imagePixelData); 4456 needConversion ? data.data() : imagePixelData);
4433 } else if (functionID == TexSubImage2D) { 4457 } else if (functionID == TexSubImage2D) {
4434 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, 4458 contextGL()->TexSubImage2D(target, level, xoffset, yoffset,
4435 adjustedSourceImageRect.width(), 4459 adjustedSourceImageRect.width(),
4436 adjustedSourceImageRect.height(), format, type, 4460 adjustedSourceImageRect.height(), format, type,
4437 needConversion ? data.data() : imagePixelData); 4461 needConversion ? data.data() : imagePixelData);
4438 } else { 4462 } else {
4439 DCHECK_EQ(functionID, TexSubImage3D); 4463 // 3D functions.
4440 contextGL()->TexSubImage3D( 4464 GLint uploadHeight = adjustedSourceImageRect.height();
4441 target, level, xoffset, yoffset, zoffset, 4465 if (unpackImageHeight) {
4442 adjustedSourceImageRect.width(), adjustedSourceImageRect.height(), 1, 4466 // GL_UNPACK_IMAGE_HEIGHT overrides the passed-in height.
4443 format, type, needConversion ? data.data() : imagePixelData); 4467 uploadHeight = unpackImageHeight;
4468 }
4469 if (functionID == TexImage3D) {
4470 contextGL()->TexImage3D(target, level, internalformat,
4471 adjustedSourceImageRect.width(), uploadHeight,
4472 depth, 0, format, type,
4473 needConversion ? data.data() : imagePixelData);
4474 } else {
4475 DCHECK_EQ(functionID, TexSubImage3D);
4476 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset,
4477 adjustedSourceImageRect.width(), uploadHeight,
4478 depth, format, type,
4479 needConversion ? data.data() : imagePixelData);
4480 }
4444 } 4481 }
4445 restoreUnpackParameters(); 4482 restoreUnpackParameters();
4446 } 4483 }
4447 4484
4448 bool WebGLRenderingContextBase::validateTexFunc( 4485 bool WebGLRenderingContextBase::validateTexFunc(
4449 const char* functionName, 4486 const char* functionName,
4450 TexImageFunctionType functionType, 4487 TexImageFunctionType functionType,
4451 TexFuncValidationSourceType sourceType, 4488 TexFuncValidationSourceType sourceType,
4452 GLenum target, 4489 GLenum target,
4453 GLint level, 4490 GLint level,
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
4757 GLenum target, 4794 GLenum target,
4758 GLint level, 4795 GLint level,
4759 GLint internalformat, 4796 GLint internalformat,
4760 GLenum format, 4797 GLenum format,
4761 GLenum type, 4798 GLenum type,
4762 GLint xoffset, 4799 GLint xoffset,
4763 GLint yoffset, 4800 GLint yoffset,
4764 GLint zoffset, 4801 GLint zoffset,
4765 HTMLImageElement* image, 4802 HTMLImageElement* image,
4766 const IntRect& sourceImageRect, 4803 const IntRect& sourceImageRect,
4804 GLsizei depth,
4805 GLint unpackImageHeight,
4767 ExceptionState& exceptionState) { 4806 ExceptionState& exceptionState) {
4768 const char* funcName = getTexImageFunctionName(functionID); 4807 const char* funcName = getTexImageFunctionName(functionID);
4769 if (isContextLost()) 4808 if (isContextLost())
4770 return; 4809 return;
4771 if (!validateHTMLImageElement(funcName, image, exceptionState)) 4810 if (!validateHTMLImageElement(funcName, image, exceptionState))
4772 return; 4811 return;
4773 if (!validateTexImageBinding(funcName, functionID, target)) 4812 if (!validateTexImageBinding(funcName, functionID, target))
4774 return; 4813 return;
4775 4814
4776 RefPtr<Image> imageForRender = image->cachedImage()->getImage(); 4815 RefPtr<Image> imageForRender = image->cachedImage()->getImage();
4777 if (imageForRender && imageForRender->isSVGImage()) 4816 if (imageForRender && imageForRender->isSVGImage())
4778 imageForRender = drawImageIntoBuffer( 4817 imageForRender = drawImageIntoBuffer(
4779 imageForRender.release(), image->width(), image->height(), funcName); 4818 imageForRender.release(), image->width(), image->height(), funcName);
4780 4819
4781 TexImageFunctionType functionType; 4820 TexImageFunctionType functionType;
4782 if (functionID == TexImage2D) 4821 if (functionID == TexImage2D)
4783 functionType = TexImage; 4822 functionType = TexImage;
4784 else 4823 else
4785 functionType = TexSubImage; 4824 functionType = TexSubImage;
4786 if (!imageForRender || 4825 if (!imageForRender ||
4787 !validateTexFunc(funcName, functionType, SourceHTMLImageElement, target, 4826 !validateTexFunc(funcName, functionType, SourceHTMLImageElement, target,
4788 level, internalformat, imageForRender->width(), 4827 level, internalformat, imageForRender->width(),
4789 imageForRender->height(), 1, 0, format, type, xoffset, 4828 imageForRender->height(), depth, 0, format, type,
4790 yoffset, zoffset)) 4829 xoffset, yoffset, zoffset))
4791 return; 4830 return;
4792 4831
4793 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, 4832 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset,
4794 zoffset, format, type, imageForRender.get(), 4833 zoffset, format, type, imageForRender.get(),
4795 WebGLImageConversion::HtmlDomImage, m_unpackFlipY, 4834 WebGLImageConversion::HtmlDomImage, m_unpackFlipY,
4796 m_unpackPremultiplyAlpha, sourceImageRect); 4835 m_unpackPremultiplyAlpha, sourceImageRect, depth,
4836 unpackImageHeight);
4797 } 4837 }
4798 4838
4799 void WebGLRenderingContextBase::texImage2D(GLenum target, 4839 void WebGLRenderingContextBase::texImage2D(GLenum target,
4800 GLint level, 4840 GLint level,
4801 GLint internalformat, 4841 GLint internalformat,
4802 GLenum format, 4842 GLenum format,
4803 GLenum type, 4843 GLenum type,
4804 HTMLImageElement* image, 4844 HTMLImageElement* image,
4805 ExceptionState& exceptionState) { 4845 ExceptionState& exceptionState) {
4806 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, 4846 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat,
4807 format, type, 0, 0, 0, image, 4847 format, type, 0, 0, 0, image,
4808 sentinelEmptyRect(), exceptionState); 4848 sentinelEmptyRect(), 1, 0, exceptionState);
4809 } 4849 }
4810 4850
4811 bool WebGLRenderingContextBase::canUseTexImageByGPU( 4851 bool WebGLRenderingContextBase::canUseTexImageByGPU(
4812 TexImageFunctionID functionID, 4852 TexImageFunctionID functionID,
4813 GLint internalformat, 4853 GLint internalformat,
4814 GLenum type) { 4854 GLenum type) {
4815 if (functionID == TexImage2D && 4855 if (functionID == TexImage2D &&
4816 (isFloatType(type) || isIntegerFormat(internalformat) || 4856 (isFloatType(type) || isIntegerFormat(internalformat) ||
4817 isSRGBFormat(internalformat))) 4857 isSRGBFormat(internalformat)))
4818 return false; 4858 return false;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
4966 // upgraded to handle more formats. 5006 // upgraded to handle more formats.
4967 if (!canvas->renderingContext() || 5007 if (!canvas->renderingContext() ||
4968 !canvas->renderingContext()->isAccelerated() || 5008 !canvas->renderingContext()->isAccelerated() ||
4969 !canUseTexImageByGPU(functionID, internalformat, type)) { 5009 !canUseTexImageByGPU(functionID, internalformat, type)) {
4970 // 2D canvas has only FrontBuffer. 5010 // 2D canvas has only FrontBuffer.
4971 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, 5011 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset,
4972 zoffset, format, type, 5012 zoffset, format, type,
4973 canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), 5013 canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4974 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, 5014 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY,
4975 m_unpackPremultiplyAlpha, 5015 m_unpackPremultiplyAlpha,
4976 IntRect(0, 0, canvas->width(), canvas->height())); 5016 IntRect(0, 0, canvas->width(), canvas->height()), 1, 0);
4977 return; 5017 return;
4978 } 5018 }
4979 5019
4980 if (functionID == TexImage2D) { 5020 if (functionID == TexImage2D) {
4981 texImage2DBase(target, level, internalformat, canvas->width(), 5021 texImage2DBase(target, level, internalformat, canvas->width(),
4982 canvas->height(), 0, format, type, 0); 5022 canvas->height(), 0, format, type, 0);
4983 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, 5023 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat,
4984 type, 0, 0, 0, canvas); 5024 type, 0, 0, 0, canvas);
4985 } else { 5025 } else {
4986 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, 5026 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type,
4987 xoffset, yoffset, 0, canvas); 5027 xoffset, yoffset, 0, canvas);
4988 } 5028 }
4989 } else { 5029 } else {
4990 DCHECK_EQ(functionID, TexSubImage3D); 5030 DCHECK_EQ(functionID, TexSubImage3D);
4991 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269). 5031 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269).
4992 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, 5032 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset,
4993 format, type, 5033 format, type,
4994 canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), 5034 canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4995 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, 5035 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY,
4996 m_unpackPremultiplyAlpha, 5036 m_unpackPremultiplyAlpha,
4997 IntRect(0, 0, canvas->width(), canvas->height())); 5037 IntRect(0, 0, canvas->width(), canvas->height()), 1, 0);
4998 } 5038 }
4999 } 5039 }
5000 5040
5001 void WebGLRenderingContextBase::texImage2D(GLenum target, 5041 void WebGLRenderingContextBase::texImage2D(GLenum target,
5002 GLint level, 5042 GLint level,
5003 GLint internalformat, 5043 GLint internalformat,
5004 GLenum format, 5044 GLenum format,
5005 GLenum type, 5045 GLenum type,
5006 HTMLCanvasElement* canvas, 5046 HTMLCanvasElement* canvas,
5007 ExceptionState& exceptionState) { 5047 ExceptionState& exceptionState) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
5098 } 5138 }
5099 } 5139 }
5100 5140
5101 RefPtr<Image> image = videoFrameToImage(video); 5141 RefPtr<Image> image = videoFrameToImage(video);
5102 if (!image) 5142 if (!image)
5103 return; 5143 return;
5104 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, 5144 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset,
5105 zoffset, format, type, image.get(), 5145 zoffset, format, type, image.get(),
5106 WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, 5146 WebGLImageConversion::HtmlDomVideo, m_unpackFlipY,
5107 m_unpackPremultiplyAlpha, 5147 m_unpackPremultiplyAlpha,
5108 IntRect(0, 0, video->videoWidth(), video->videoHeight())); 5148 IntRect(0, 0, video->videoWidth(), video->videoHeight()), 1, 0);
5109 } 5149 }
5110 5150
5111 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, 5151 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap,
5112 GLuint targetTexture, 5152 GLuint targetTexture,
5113 GLenum targetInternalformat, 5153 GLenum targetInternalformat,
5114 GLenum targetType, 5154 GLenum targetType,
5115 GLint targetLevel, 5155 GLint targetLevel,
5116 bool flipY) { 5156 bool flipY) {
5117 bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(), 5157 bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(),
5118 targetTexture, targetInternalformat, 5158 targetTexture, targetInternalformat,
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
5350 void WebGLRenderingContextBase::texSubImage2D(GLenum target, 5390 void WebGLRenderingContextBase::texSubImage2D(GLenum target,
5351 GLint level, 5391 GLint level,
5352 GLint xoffset, 5392 GLint xoffset,
5353 GLint yoffset, 5393 GLint yoffset,
5354 GLenum format, 5394 GLenum format,
5355 GLenum type, 5395 GLenum type,
5356 HTMLImageElement* image, 5396 HTMLImageElement* image,
5357 ExceptionState& exceptionState) { 5397 ExceptionState& exceptionState) {
5358 texImageHelperHTMLImageElement(TexSubImage2D, target, level, 0, format, type, 5398 texImageHelperHTMLImageElement(TexSubImage2D, target, level, 0, format, type,
5359 xoffset, yoffset, 0, image, 5399 xoffset, yoffset, 0, image,
5360 sentinelEmptyRect(), exceptionState); 5400 sentinelEmptyRect(), 1, 0, exceptionState);
5361 } 5401 }
5362 5402
5363 void WebGLRenderingContextBase::texSubImage2D(GLenum target, 5403 void WebGLRenderingContextBase::texSubImage2D(GLenum target,
5364 GLint level, 5404 GLint level,
5365 GLint xoffset, 5405 GLint xoffset,
5366 GLint yoffset, 5406 GLint yoffset,
5367 GLenum format, 5407 GLenum format,
5368 GLenum type, 5408 GLenum type,
5369 HTMLCanvasElement* canvas, 5409 HTMLCanvasElement* canvas,
5370 ExceptionState& exceptionState) { 5410 ExceptionState& exceptionState) {
(...skipping 2248 matching lines...) Expand 10 before | Expand all | Expand 10 after
7619 7659
7620 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( 7660 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas(
7621 HTMLCanvasElementOrOffscreenCanvas& result) const { 7661 HTMLCanvasElementOrOffscreenCanvas& result) const {
7622 if (canvas()) 7662 if (canvas())
7623 result.setHTMLCanvasElement(canvas()); 7663 result.setHTMLCanvasElement(canvas());
7624 else 7664 else
7625 result.setOffscreenCanvas(getOffscreenCanvas()); 7665 result.setOffscreenCanvas(getOffscreenCanvas());
7626 } 7666 }
7627 7667
7628 } // namespace blink 7668 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698