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

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

Issue 2428263004: 16 bpp video stream capture, render and createImageBitmap(video) using (CPU) shared memory buffers (Closed)
Patch Set: fixes 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
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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 public: 493 public:
494 explicit ScopedFramebufferRestorer(WebGLRenderingContextBase* context) 494 explicit ScopedFramebufferRestorer(WebGLRenderingContextBase* context)
495 : m_context(context) {} 495 : m_context(context) {}
496 496
497 ~ScopedFramebufferRestorer() { m_context->restoreCurrentFramebuffer(); } 497 ~ScopedFramebufferRestorer() { m_context->restoreCurrentFramebuffer(); }
498 498
499 private: 499 private:
500 Member<WebGLRenderingContextBase> m_context; 500 Member<WebGLRenderingContextBase> m_context;
501 }; 501 };
502 502
503 class ScopedUnpackParametersResetRestore {
504 STACK_ALLOCATED();
505
506 public:
507 explicit ScopedUnpackParametersResetRestore(
508 WebGLRenderingContextBase* context,
509 bool enabled = true)
510 : m_context(context), m_enabled(enabled) {
511 if (enabled)
512 m_context->resetUnpackParameters();
513 }
514
515 ~ScopedUnpackParametersResetRestore() {
516 if (m_enabled)
517 m_context->restoreUnpackParameters();
518 }
519
520 private:
521 Member<WebGLRenderingContextBase> m_context;
522 bool m_enabled;
523 };
524
503 static void formatWebGLStatusString(const StringView& glInfo, 525 static void formatWebGLStatusString(const StringView& glInfo,
504 const StringView& infoString, 526 const StringView& infoString,
505 StringBuilder& builder) { 527 StringBuilder& builder) {
506 if (infoString.isEmpty()) 528 if (infoString.isEmpty())
507 return; 529 return;
508 builder.append(", "); 530 builder.append(", ");
509 builder.append(glInfo); 531 builder.append(glInfo);
510 builder.append(" = "); 532 builder.append(" = ");
511 builder.append(infoString); 533 builder.append(infoString);
512 } 534 }
(...skipping 3884 matching lines...) Expand 10 before | Expand all | Expand 10 after
4397 if (!WebGLImageConversion::packImageData( 4419 if (!WebGLImageConversion::packImageData(
4398 image, imagePixelData, format, type, flipY, alphaOp, 4420 image, imagePixelData, format, type, flipY, alphaOp,
4399 sourceDataFormat, imageExtractor.imageWidth(), 4421 sourceDataFormat, imageExtractor.imageWidth(),
4400 imageExtractor.imageHeight(), 4422 imageExtractor.imageHeight(),
4401 imageExtractor.imageSourceUnpackAlignment(), data)) { 4423 imageExtractor.imageSourceUnpackAlignment(), data)) {
4402 synthesizeGLError(GL_INVALID_VALUE, funcName, "packImage error"); 4424 synthesizeGLError(GL_INVALID_VALUE, funcName, "packImage error");
4403 return; 4425 return;
4404 } 4426 }
4405 } 4427 }
4406 4428
4407 resetUnpackParameters(); 4429 ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
4408 if (functionID == TexImage2D) { 4430 if (functionID == TexImage2D) {
4409 texImage2DBase(target, level, internalformat, imageExtractor.imageWidth(), 4431 texImage2DBase(target, level, internalformat, imageExtractor.imageWidth(),
4410 imageExtractor.imageHeight(), 0, format, type, 4432 imageExtractor.imageHeight(), 0, format, type,
4411 needConversion ? data.data() : imagePixelData); 4433 needConversion ? data.data() : imagePixelData);
4412 } else if (functionID == TexSubImage2D) { 4434 } else if (functionID == TexSubImage2D) {
4413 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, 4435 contextGL()->TexSubImage2D(target, level, xoffset, yoffset,
4414 imageExtractor.imageWidth(), 4436 imageExtractor.imageWidth(),
4415 imageExtractor.imageHeight(), format, type, 4437 imageExtractor.imageHeight(), format, type,
4416 needConversion ? data.data() : imagePixelData); 4438 needConversion ? data.data() : imagePixelData);
4417 } else { 4439 } else {
4418 DCHECK_EQ(functionID, TexSubImage3D); 4440 DCHECK_EQ(functionID, TexSubImage3D);
4419 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, 4441 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset,
4420 imageExtractor.imageWidth(), 4442 imageExtractor.imageWidth(),
4421 imageExtractor.imageHeight(), 1, format, type, 4443 imageExtractor.imageHeight(), 1, format, type,
4422 needConversion ? data.data() : imagePixelData); 4444 needConversion ? data.data() : imagePixelData);
4423 } 4445 }
4424 restoreUnpackParameters();
4425 } 4446 }
4426 4447
4427 bool WebGLRenderingContextBase::validateTexFunc( 4448 bool WebGLRenderingContextBase::validateTexFunc(
4428 const char* functionName, 4449 const char* functionName,
4429 TexImageFunctionType functionType, 4450 TexImageFunctionType functionType,
4430 TexFuncValidationSourceType sourceType, 4451 TexFuncValidationSourceType sourceType,
4431 GLenum target, 4452 GLenum target,
4432 GLint level, 4453 GLint level,
4433 GLenum internalformat, 4454 GLenum internalformat,
4434 GLsizei width, 4455 GLsizei width,
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
4600 convertTexInternalFormat(internalformat, type), 4621 convertTexInternalFormat(internalformat, type),
4601 width, height, depth, border, format, type, data); 4622 width, height, depth, border, format, type, data);
4602 return; 4623 return;
4603 } 4624 }
4604 if (functionID == TexSubImage3D) { 4625 if (functionID == TexSubImage3D) {
4605 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, 4626 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
4606 height, depth, format, type, data); 4627 height, depth, format, type, data);
4607 return; 4628 return;
4608 } 4629 }
4609 4630
4610 if (changeUnpackAlignment) 4631 ScopedUnpackParametersResetRestore temporaryResetUnpack(
4611 resetUnpackParameters(); 4632 this, changeUnpackAlignment);
4612 if (functionID == TexImage2D) 4633 if (functionID == TexImage2D)
4613 texImage2DBase(target, level, internalformat, width, height, border, format, 4634 texImage2DBase(target, level, internalformat, width, height, border, format,
4614 type, data); 4635 type, data);
4615 else if (functionID == TexSubImage2D) 4636 else if (functionID == TexSubImage2D)
4616 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, height, 4637 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, height,
4617 format, type, data); 4638 format, type, data);
4618 if (changeUnpackAlignment)
4619 restoreUnpackParameters();
4620 } 4639 }
4621 4640
4622 void WebGLRenderingContextBase::texImage2D(GLenum target, 4641 void WebGLRenderingContextBase::texImage2D(GLenum target,
4623 GLint level, 4642 GLint level,
4624 GLint internalformat, 4643 GLint internalformat,
4625 GLsizei width, 4644 GLsizei width,
4626 GLsizei height, 4645 GLsizei height,
4627 GLint border, 4646 GLint border,
4628 GLenum format, 4647 GLenum format,
4629 GLenum type, 4648 GLenum type,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4683 type = GL_FLOAT; 4702 type = GL_FLOAT;
4684 } 4703 }
4685 if (!WebGLImageConversion::extractImageData( 4704 if (!WebGLImageConversion::extractImageData(
4686 pixels->data()->data(), 4705 pixels->data()->data(),
4687 WebGLImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), 4706 WebGLImageConversion::DataFormat::DataFormatRGBA8, pixels->size(),
4688 format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { 4707 format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
4689 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); 4708 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
4690 return; 4709 return;
4691 } 4710 }
4692 } 4711 }
4693 resetUnpackParameters(); 4712 ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
4694 if (functionID == TexImage2D) { 4713 if (functionID == TexImage2D) {
4695 texImage2DBase(target, level, internalformat, pixels->width(), 4714 texImage2DBase(target, level, internalformat, pixels->width(),
4696 pixels->height(), border, format, type, 4715 pixels->height(), border, format, type,
4697 needConversion ? data.data() : pixels->data()->data()); 4716 needConversion ? data.data() : pixels->data()->data());
4698 } else if (functionID == TexSubImage2D) { 4717 } else if (functionID == TexSubImage2D) {
4699 contextGL()->TexSubImage2D( 4718 contextGL()->TexSubImage2D(
4700 target, level, xoffset, yoffset, pixels->width(), pixels->height(), 4719 target, level, xoffset, yoffset, pixels->width(), pixels->height(),
4701 format, type, needConversion ? data.data() : pixels->data()->data()); 4720 format, type, needConversion ? data.data() : pixels->data()->data());
4702 } else { 4721 } else {
4703 DCHECK_EQ(functionID, TexSubImage3D); 4722 DCHECK_EQ(functionID, TexSubImage3D);
4704 contextGL()->TexSubImage3D( 4723 contextGL()->TexSubImage3D(
4705 target, level, xoffset, yoffset, zoffset, pixels->width(), 4724 target, level, xoffset, yoffset, zoffset, pixels->width(),
4706 pixels->height(), depth, format, type, 4725 pixels->height(), depth, format, type,
4707 needConversion ? data.data() : pixels->data()->data()); 4726 needConversion ? data.data() : pixels->data()->data());
4708 } 4727 }
4709 restoreUnpackParameters();
4710 } 4728 }
4711 4729
4712 void WebGLRenderingContextBase::texImage2D(GLenum target, 4730 void WebGLRenderingContextBase::texImage2D(GLenum target,
4713 GLint level, 4731 GLint level,
4714 GLint internalformat, 4732 GLint internalformat,
4715 GLenum format, 4733 GLenum format,
4716 GLenum type, 4734 GLenum type,
4717 ImageData* pixels) { 4735 ImageData* pixels) {
4718 texImageHelperImageData(TexImage2D, target, level, internalformat, 0, format, 4736 texImageHelperImageData(TexImage2D, target, level, internalformat, 0, format,
4719 type, 1, 0, 0, 0, pixels); 4737 type, 1, 0, 0, 0, pixels);
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
5010 if (functionID == TexImage2D) 5028 if (functionID == TexImage2D)
5011 functionType = TexImage; 5029 functionType = TexImage;
5012 else 5030 else
5013 functionType = TexSubImage; 5031 functionType = TexSubImage;
5014 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, 5032 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target,
5015 level, internalformat, video->videoWidth(), 5033 level, internalformat, video->videoWidth(),
5016 video->videoHeight(), 1, 0, format, type, xoffset, 5034 video->videoHeight(), 1, 0, format, type, xoffset,
5017 yoffset, zoffset)) 5035 yoffset, zoffset))
5018 return; 5036 return;
5019 5037
5020 if (functionID == TexImage2D) { 5038 const bool useCopyTextureChromium =
5039 functionID == TexImage2D && GL_TEXTURE_2D == target &&
5040 Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type,
5041 level);
5042 if (useCopyTextureChromium) {
5021 // Go through the fast path doing a GPU-GPU textures copy without a readback 5043 // Go through the fast path doing a GPU-GPU textures copy without a readback
5022 // to system memory if possible. Otherwise, it will fall back to the normal 5044 // to system memory if possible.
5023 // SW path. 5045 // Otherwise, it will fall back to the normal SW path.
5024 if (GL_TEXTURE_2D == target) { 5046 if (video->copyVideoTextureToPlatformTexture(
5025 if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, 5047 contextGL(), texture->object(), internalformat, type,
5026 type, level) && 5048 m_unpackPremultiplyAlpha, m_unpackFlipY)) {
5027 video->copyVideoTextureToPlatformTexture( 5049 return;
5028 contextGL(), texture->object(), internalformat, type, 5050 }
5029 m_unpackPremultiplyAlpha, m_unpackFlipY)) { 5051 }
5030 return;
5031 }
5032 5052
5033 // Try using an accelerated image buffer, this allows YUV conversion to be 5053 {
5034 // done on the GPU. 5054 // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It
5035 std::unique_ptr<ImageBufferSurface> surface = 5055 // leaves early for other formats or if frame is stored on GPU.
5036 wrapUnique(new AcceleratedImageBufferSurface( 5056 ScopedUnpackParametersResetRestore(
5037 IntSize(video->videoWidth(), video->videoHeight()))); 5057 this, m_unpackFlipY || m_unpackPremultiplyAlpha);
5038 if (surface->isValid()) { 5058 if (video->texImageImpl(getTexImageFunctionName(functionID), target,
5039 std::unique_ptr<ImageBuffer> imageBuffer( 5059 contextGL(), level, internalformat, format, type,
5040 ImageBuffer::create(std::move(surface))); 5060 xoffset, yoffset, zoffset, m_unpackFlipY,
5041 if (imageBuffer) { 5061 m_unpackPremultiplyAlpha &&
5042 // The video element paints an RGBA frame into our surface here. By 5062 m_unpackColorspaceConversion == GL_NONE))
5043 // using an AcceleratedImageBufferSurface, we enable the 5063 return;
5044 // WebMediaPlayer implementation to do any necessary color space 5064 }
5045 // conversion on the GPU (though it
5046 // may still do a CPU conversion and upload the results).
5047 video->paintCurrentFrame(
5048 imageBuffer->canvas(),
5049 IntRect(0, 0, video->videoWidth(), video->videoHeight()),
5050 nullptr);
5051 5065
5052 // This is a straight GPU-GPU copy, any necessary color space 5066 if (useCopyTextureChromium) {
5053 // conversion was handled in the paintCurrentFrameInContext() call. 5067 // Try using an accelerated image buffer, this allows YUV conversion to be
5054 if (imageBuffer->copyToPlatformTexture( 5068 // done on the GPU.
5055 contextGL(), texture->object(), internalformat, type, level, 5069 std::unique_ptr<ImageBufferSurface> surface =
5056 m_unpackPremultiplyAlpha, m_unpackFlipY)) { 5070 wrapUnique(new AcceleratedImageBufferSurface(
5057 return; 5071 IntSize(video->videoWidth(), video->videoHeight())));
5058 } 5072 if (surface->isValid()) {
5073 std::unique_ptr<ImageBuffer> imageBuffer(
5074 ImageBuffer::create(std::move(surface)));
5075 if (imageBuffer) {
5076 // The video element paints an RGBA frame into our surface here. By
5077 // using an AcceleratedImageBufferSurface, we enable the WebMediaPlayer
5078 // implementation to do any necessary color space conversion on the GPU
5079 // (though it may still do a CPU conversion and upload the results).
5080 video->paintCurrentFrame(
5081 imageBuffer->canvas(),
5082 IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr);
5083
5084 // This is a straight GPU-GPU copy, any necessary color space conversion
5085 // was handled in the paintCurrentFrameInContext() call.
5086 if (imageBuffer->copyToPlatformTexture(
5087 contextGL(), texture->object(), internalformat, type, level,
5088 m_unpackPremultiplyAlpha, m_unpackFlipY)) {
5089 return;
5059 } 5090 }
5060 } 5091 }
5061 } 5092 }
5062 } 5093 }
5063 5094
5064 RefPtr<Image> image = videoFrameToImage(video); 5095 RefPtr<Image> image = videoFrameToImage(video);
5065 if (!image) 5096 if (!image)
5066 return; 5097 return;
5067 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, 5098 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset,
5068 zoffset, format, type, image.get(), 5099 zoffset, format, type, image.get(),
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
5173 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, 5204 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8,
5174 bitmap->size(), format, type, false, false, data)) || 5205 bitmap->size(), format, type, false, false, data)) ||
5175 (isPixelDataRGBA && 5206 (isPixelDataRGBA &&
5176 !WebGLImageConversion::extractImageData( 5207 !WebGLImageConversion::extractImageData(
5177 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, 5208 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8,
5178 bitmap->size(), format, type, false, false, data))) { 5209 bitmap->size(), format, type, false, false, data))) {
5179 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); 5210 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
5180 return; 5211 return;
5181 } 5212 }
5182 } 5213 }
5183 resetUnpackParameters(); 5214 ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
5184 if (functionID == TexImage2D) { 5215 if (functionID == TexImage2D) {
5185 texImage2DBase(target, level, internalformat, bitmap->width(), 5216 texImage2DBase(target, level, internalformat, bitmap->width(),
5186 bitmap->height(), 0, format, type, 5217 bitmap->height(), 0, format, type,
5187 needConversion ? data.data() : pixelDataPtr); 5218 needConversion ? data.data() : pixelDataPtr);
5188 } else if (functionID == TexSubImage2D) { 5219 } else if (functionID == TexSubImage2D) {
5189 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(), 5220 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(),
5190 bitmap->height(), format, type, 5221 bitmap->height(), format, type,
5191 needConversion ? data.data() : pixelDataPtr); 5222 needConversion ? data.data() : pixelDataPtr);
5192 } else { 5223 } else {
5193 DCHECK_EQ(functionID, TexSubImage3D); 5224 DCHECK_EQ(functionID, TexSubImage3D);
5194 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, 5225 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset,
5195 bitmap->width(), bitmap->height(), 1, format, 5226 bitmap->width(), bitmap->height(), 1, format,
5196 type, 5227 type,
5197 needConversion ? data.data() : pixelDataPtr); 5228 needConversion ? data.data() : pixelDataPtr);
5198 } 5229 }
5199 restoreUnpackParameters();
5200 } 5230 }
5201 5231
5202 void WebGLRenderingContextBase::texImage2D(GLenum target, 5232 void WebGLRenderingContextBase::texImage2D(GLenum target,
5203 GLint level, 5233 GLint level,
5204 GLint internalformat, 5234 GLint internalformat,
5205 GLenum format, 5235 GLenum format,
5206 GLenum type, 5236 GLenum type,
5207 ImageBitmap* bitmap, 5237 ImageBitmap* bitmap,
5208 ExceptionState& exceptionState) { 5238 ExceptionState& exceptionState) {
5209 texImageHelperImageBitmap(TexImage2D, target, level, internalformat, format, 5239 texImageHelperImageBitmap(TexImage2D, target, level, internalformat, format,
(...skipping 2321 matching lines...) Expand 10 before | Expand all | Expand 10 after
7531 7561
7532 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( 7562 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas(
7533 HTMLCanvasElementOrOffscreenCanvas& result) const { 7563 HTMLCanvasElementOrOffscreenCanvas& result) const {
7534 if (canvas()) 7564 if (canvas())
7535 result.setHTMLCanvasElement(canvas()); 7565 result.setHTMLCanvasElement(canvas());
7536 else 7566 else
7537 result.setOffscreenCanvas(getOffscreenCanvas()); 7567 result.setOffscreenCanvas(getOffscreenCanvas());
7538 } 7568 }
7539 7569
7540 } // namespace blink 7570 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698