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

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: fix windows approach and video_capture_utils. 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 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 public: 494 public:
495 explicit ScopedFramebufferRestorer(WebGLRenderingContextBase* context) 495 explicit ScopedFramebufferRestorer(WebGLRenderingContextBase* context)
496 : m_context(context) {} 496 : m_context(context) {}
497 497
498 ~ScopedFramebufferRestorer() { m_context->restoreCurrentFramebuffer(); } 498 ~ScopedFramebufferRestorer() { m_context->restoreCurrentFramebuffer(); }
499 499
500 private: 500 private:
501 Member<WebGLRenderingContextBase> m_context; 501 Member<WebGLRenderingContextBase> m_context;
502 }; 502 };
503 503
504 class ScopedUnpackParametersResetRestore {
505 STACK_ALLOCATED();
506
507 public:
508 explicit ScopedUnpackParametersResetRestore(
509 WebGLRenderingContextBase* context,
510 bool enabled = true)
511 : m_context(context), m_enabled(enabled) {
512 if (enabled)
513 m_context->resetUnpackParameters();
514 }
515
516 ~ScopedUnpackParametersResetRestore() {
517 if (m_enabled)
518 m_context->restoreUnpackParameters();
519 }
520
521 private:
522 Member<WebGLRenderingContextBase> m_context;
523 bool m_enabled;
524 };
525
504 static void formatWebGLStatusString(const StringView& glInfo, 526 static void formatWebGLStatusString(const StringView& glInfo,
505 const StringView& infoString, 527 const StringView& infoString,
506 StringBuilder& builder) { 528 StringBuilder& builder) {
507 if (infoString.isEmpty()) 529 if (infoString.isEmpty())
508 return; 530 return;
509 builder.append(", "); 531 builder.append(", ");
510 builder.append(glInfo); 532 builder.append(glInfo);
511 builder.append(" = "); 533 builder.append(" = ");
512 builder.append(infoString); 534 builder.append(infoString);
513 } 535 }
(...skipping 3823 matching lines...) Expand 10 before | Expand all | Expand 10 after
4337 if (!WebGLImageConversion::packImageData( 4359 if (!WebGLImageConversion::packImageData(
4338 image, imagePixelData, format, type, flipY, alphaOp, 4360 image, imagePixelData, format, type, flipY, alphaOp,
4339 sourceDataFormat, imageExtractor.imageWidth(), 4361 sourceDataFormat, imageExtractor.imageWidth(),
4340 imageExtractor.imageHeight(), 4362 imageExtractor.imageHeight(),
4341 imageExtractor.imageSourceUnpackAlignment(), data)) { 4363 imageExtractor.imageSourceUnpackAlignment(), data)) {
4342 synthesizeGLError(GL_INVALID_VALUE, funcName, "packImage error"); 4364 synthesizeGLError(GL_INVALID_VALUE, funcName, "packImage error");
4343 return; 4365 return;
4344 } 4366 }
4345 } 4367 }
4346 4368
4347 resetUnpackParameters(); 4369 ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
4348 if (functionID == TexImage2D) { 4370 if (functionID == TexImage2D) {
4349 texImage2DBase(target, level, internalformat, imageExtractor.imageWidth(), 4371 texImage2DBase(target, level, internalformat, imageExtractor.imageWidth(),
4350 imageExtractor.imageHeight(), 0, format, type, 4372 imageExtractor.imageHeight(), 0, format, type,
4351 needConversion ? data.data() : imagePixelData); 4373 needConversion ? data.data() : imagePixelData);
4352 } else if (functionID == TexSubImage2D) { 4374 } else if (functionID == TexSubImage2D) {
4353 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, 4375 contextGL()->TexSubImage2D(target, level, xoffset, yoffset,
4354 imageExtractor.imageWidth(), 4376 imageExtractor.imageWidth(),
4355 imageExtractor.imageHeight(), format, type, 4377 imageExtractor.imageHeight(), format, type,
4356 needConversion ? data.data() : imagePixelData); 4378 needConversion ? data.data() : imagePixelData);
4357 } else { 4379 } else {
4358 DCHECK_EQ(functionID, TexSubImage3D); 4380 DCHECK_EQ(functionID, TexSubImage3D);
4359 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, 4381 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset,
4360 imageExtractor.imageWidth(), 4382 imageExtractor.imageWidth(),
4361 imageExtractor.imageHeight(), 1, format, type, 4383 imageExtractor.imageHeight(), 1, format, type,
4362 needConversion ? data.data() : imagePixelData); 4384 needConversion ? data.data() : imagePixelData);
4363 } 4385 }
4364 restoreUnpackParameters();
4365 } 4386 }
4366 4387
4367 bool WebGLRenderingContextBase::validateTexFunc( 4388 bool WebGLRenderingContextBase::validateTexFunc(
4368 const char* functionName, 4389 const char* functionName,
4369 TexImageFunctionType functionType, 4390 TexImageFunctionType functionType,
4370 TexFuncValidationSourceType sourceType, 4391 TexFuncValidationSourceType sourceType,
4371 GLenum target, 4392 GLenum target,
4372 GLint level, 4393 GLint level,
4373 GLenum internalformat, 4394 GLenum internalformat,
4374 GLsizei width, 4395 GLsizei width,
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
4540 convertTexInternalFormat(internalformat, type), 4561 convertTexInternalFormat(internalformat, type),
4541 width, height, depth, border, format, type, data); 4562 width, height, depth, border, format, type, data);
4542 return; 4563 return;
4543 } 4564 }
4544 if (functionID == TexSubImage3D) { 4565 if (functionID == TexSubImage3D) {
4545 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, 4566 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
4546 height, depth, format, type, data); 4567 height, depth, format, type, data);
4547 return; 4568 return;
4548 } 4569 }
4549 4570
4550 if (changeUnpackAlignment) 4571 ScopedUnpackParametersResetRestore temporaryResetUnpack(
4551 resetUnpackParameters(); 4572 this, changeUnpackAlignment);
4552 if (functionID == TexImage2D) 4573 if (functionID == TexImage2D)
4553 texImage2DBase(target, level, internalformat, width, height, border, format, 4574 texImage2DBase(target, level, internalformat, width, height, border, format,
4554 type, data); 4575 type, data);
4555 else if (functionID == TexSubImage2D) 4576 else if (functionID == TexSubImage2D)
4556 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, height, 4577 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, height,
4557 format, type, data); 4578 format, type, data);
4558 if (changeUnpackAlignment)
4559 restoreUnpackParameters();
4560 } 4579 }
4561 4580
4562 void WebGLRenderingContextBase::texImage2D(GLenum target, 4581 void WebGLRenderingContextBase::texImage2D(GLenum target,
4563 GLint level, 4582 GLint level,
4564 GLint internalformat, 4583 GLint internalformat,
4565 GLsizei width, 4584 GLsizei width,
4566 GLsizei height, 4585 GLsizei height,
4567 GLint border, 4586 GLint border,
4568 GLenum format, 4587 GLenum format,
4569 GLenum type, 4588 GLenum type,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4623 type = GL_FLOAT; 4642 type = GL_FLOAT;
4624 } 4643 }
4625 if (!WebGLImageConversion::extractImageData( 4644 if (!WebGLImageConversion::extractImageData(
4626 pixels->data()->data(), 4645 pixels->data()->data(),
4627 WebGLImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), 4646 WebGLImageConversion::DataFormat::DataFormatRGBA8, pixels->size(),
4628 format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { 4647 format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
4629 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); 4648 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
4630 return; 4649 return;
4631 } 4650 }
4632 } 4651 }
4633 resetUnpackParameters(); 4652 ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
4634 if (functionID == TexImage2D) { 4653 if (functionID == TexImage2D) {
4635 texImage2DBase(target, level, internalformat, pixels->width(), 4654 texImage2DBase(target, level, internalformat, pixels->width(),
4636 pixels->height(), border, format, type, 4655 pixels->height(), border, format, type,
4637 needConversion ? data.data() : pixels->data()->data()); 4656 needConversion ? data.data() : pixels->data()->data());
4638 } else if (functionID == TexSubImage2D) { 4657 } else if (functionID == TexSubImage2D) {
4639 contextGL()->TexSubImage2D( 4658 contextGL()->TexSubImage2D(
4640 target, level, xoffset, yoffset, pixels->width(), pixels->height(), 4659 target, level, xoffset, yoffset, pixels->width(), pixels->height(),
4641 format, type, needConversion ? data.data() : pixels->data()->data()); 4660 format, type, needConversion ? data.data() : pixels->data()->data());
4642 } else { 4661 } else {
4643 DCHECK_EQ(functionID, TexSubImage3D); 4662 DCHECK_EQ(functionID, TexSubImage3D);
4644 contextGL()->TexSubImage3D( 4663 contextGL()->TexSubImage3D(
4645 target, level, xoffset, yoffset, zoffset, pixels->width(), 4664 target, level, xoffset, yoffset, zoffset, pixels->width(),
4646 pixels->height(), depth, format, type, 4665 pixels->height(), depth, format, type,
4647 needConversion ? data.data() : pixels->data()->data()); 4666 needConversion ? data.data() : pixels->data()->data());
4648 } 4667 }
4649 restoreUnpackParameters();
4650 } 4668 }
4651 4669
4652 void WebGLRenderingContextBase::texImage2D(GLenum target, 4670 void WebGLRenderingContextBase::texImage2D(GLenum target,
4653 GLint level, 4671 GLint level,
4654 GLint internalformat, 4672 GLint internalformat,
4655 GLenum format, 4673 GLenum format,
4656 GLenum type, 4674 GLenum type,
4657 ImageData* pixels) { 4675 ImageData* pixels) {
4658 texImageHelperImageData(TexImage2D, target, level, internalformat, 0, format, 4676 texImageHelperImageData(TexImage2D, target, level, internalformat, 0, format,
4659 type, 1, 0, 0, 0, pixels); 4677 type, 1, 0, 0, 0, pixels);
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
4950 if (functionID == TexImage2D) 4968 if (functionID == TexImage2D)
4951 functionType = TexImage; 4969 functionType = TexImage;
4952 else 4970 else
4953 functionType = TexSubImage; 4971 functionType = TexSubImage;
4954 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, 4972 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target,
4955 level, internalformat, video->videoWidth(), 4973 level, internalformat, video->videoWidth(),
4956 video->videoHeight(), 1, 0, format, type, xoffset, 4974 video->videoHeight(), 1, 0, format, type, xoffset,
4957 yoffset, zoffset)) 4975 yoffset, zoffset))
4958 return; 4976 return;
4959 4977
4960 if (functionID == TexImage2D) { 4978 const bool useCopyTextureChromium =
4979 functionID == TexImage2D && GL_TEXTURE_2D == target &&
4980 Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type,
4981 level);
4982 if (useCopyTextureChromium) {
4961 // Go through the fast path doing a GPU-GPU textures copy without a readback 4983 // Go through the fast path doing a GPU-GPU textures copy without a readback
4962 // to system memory if possible. Otherwise, it will fall back to the normal 4984 // to system memory if possible.
4963 // SW path. 4985 // Otherwise, it will fall back to the normal SW path.
4964 if (GL_TEXTURE_2D == target) { 4986 if (video->copyVideoTextureToPlatformTexture(
4965 if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, 4987 contextGL(), texture->object(), internalformat, type,
4966 type, level) && 4988 m_unpackPremultiplyAlpha, m_unpackFlipY)) {
4967 video->copyVideoTextureToPlatformTexture( 4989 return;
4968 contextGL(), texture->object(), internalformat, type, 4990 }
4969 m_unpackPremultiplyAlpha, m_unpackFlipY)) { 4991 }
4970 return;
4971 }
4972 4992
4973 // Try using an accelerated image buffer, this allows YUV conversion to be 4993 {
4974 // done on the GPU. 4994 // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It
4975 std::unique_ptr<ImageBufferSurface> surface = 4995 // leaves early for other formats or if frame is stored on GPU.
4976 wrapUnique(new AcceleratedImageBufferSurface( 4996 ScopedUnpackParametersResetRestore(
4977 IntSize(video->videoWidth(), video->videoHeight()))); 4997 this, m_unpackFlipY || m_unpackPremultiplyAlpha);
4978 if (surface->isValid()) { 4998 if (video->texImageImpl(getTexImageFunctionName(functionID), target,
4979 std::unique_ptr<ImageBuffer> imageBuffer( 4999 contextGL(), level, internalformat, format, type,
4980 ImageBuffer::create(std::move(surface))); 5000 xoffset, yoffset, zoffset, m_unpackFlipY,
4981 if (imageBuffer) { 5001 m_unpackPremultiplyAlpha &&
4982 // The video element paints an RGBA frame into our surface here. By 5002 m_unpackColorspaceConversion == GL_NONE))
4983 // using an AcceleratedImageBufferSurface, we enable the 5003 return;
4984 // WebMediaPlayer implementation to do any necessary color space 5004 }
4985 // conversion on the GPU (though it
4986 // may still do a CPU conversion and upload the results).
4987 video->paintCurrentFrame(
4988 imageBuffer->canvas(),
4989 IntRect(0, 0, video->videoWidth(), video->videoHeight()),
4990 nullptr);
4991 5005
4992 // This is a straight GPU-GPU copy, any necessary color space 5006 if (useCopyTextureChromium) {
4993 // conversion was handled in the paintCurrentFrameInContext() call. 5007 // Try using an accelerated image buffer, this allows YUV conversion to be
4994 if (imageBuffer->copyToPlatformTexture( 5008 // done on the GPU.
4995 contextGL(), texture->object(), internalformat, type, level, 5009 std::unique_ptr<ImageBufferSurface> surface =
4996 m_unpackPremultiplyAlpha, m_unpackFlipY)) { 5010 wrapUnique(new AcceleratedImageBufferSurface(
4997 return; 5011 IntSize(video->videoWidth(), video->videoHeight())));
4998 } 5012 if (surface->isValid()) {
5013 std::unique_ptr<ImageBuffer> imageBuffer(
5014 ImageBuffer::create(std::move(surface)));
5015 if (imageBuffer) {
5016 // The video element paints an RGBA frame into our surface here. By
5017 // using an AcceleratedImageBufferSurface, we enable the WebMediaPlayer
5018 // implementation to do any necessary color space conversion on the GPU
5019 // (though it may still do a CPU conversion and upload the results).
5020 video->paintCurrentFrame(
5021 imageBuffer->canvas(),
5022 IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr);
5023
5024 // This is a straight GPU-GPU copy, any necessary color space conversion
5025 // was handled in the paintCurrentFrameInContext() call.
5026 if (imageBuffer->copyToPlatformTexture(
5027 contextGL(), texture->object(), internalformat, type, level,
5028 m_unpackPremultiplyAlpha, m_unpackFlipY)) {
5029 return;
4999 } 5030 }
5000 } 5031 }
5001 } 5032 }
5002 } 5033 }
5003 5034
5004 RefPtr<Image> image = videoFrameToImage(video); 5035 RefPtr<Image> image = videoFrameToImage(video);
5005 if (!image) 5036 if (!image)
5006 return; 5037 return;
5007 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, 5038 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset,
5008 zoffset, format, type, image.get(), 5039 zoffset, format, type, image.get(),
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
5113 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, 5144 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8,
5114 bitmap->size(), format, type, false, false, data)) || 5145 bitmap->size(), format, type, false, false, data)) ||
5115 (isPixelDataRGBA && 5146 (isPixelDataRGBA &&
5116 !WebGLImageConversion::extractImageData( 5147 !WebGLImageConversion::extractImageData(
5117 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, 5148 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8,
5118 bitmap->size(), format, type, false, false, data))) { 5149 bitmap->size(), format, type, false, false, data))) {
5119 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); 5150 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
5120 return; 5151 return;
5121 } 5152 }
5122 } 5153 }
5123 resetUnpackParameters(); 5154 ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
5124 if (functionID == TexImage2D) { 5155 if (functionID == TexImage2D) {
5125 texImage2DBase(target, level, internalformat, bitmap->width(), 5156 texImage2DBase(target, level, internalformat, bitmap->width(),
5126 bitmap->height(), 0, format, type, 5157 bitmap->height(), 0, format, type,
5127 needConversion ? data.data() : pixelDataPtr); 5158 needConversion ? data.data() : pixelDataPtr);
5128 } else if (functionID == TexSubImage2D) { 5159 } else if (functionID == TexSubImage2D) {
5129 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(), 5160 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(),
5130 bitmap->height(), format, type, 5161 bitmap->height(), format, type,
5131 needConversion ? data.data() : pixelDataPtr); 5162 needConversion ? data.data() : pixelDataPtr);
5132 } else { 5163 } else {
5133 DCHECK_EQ(functionID, TexSubImage3D); 5164 DCHECK_EQ(functionID, TexSubImage3D);
5134 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, 5165 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset,
5135 bitmap->width(), bitmap->height(), 1, format, 5166 bitmap->width(), bitmap->height(), 1, format,
5136 type, 5167 type,
5137 needConversion ? data.data() : pixelDataPtr); 5168 needConversion ? data.data() : pixelDataPtr);
5138 } 5169 }
5139 restoreUnpackParameters();
5140 } 5170 }
5141 5171
5142 void WebGLRenderingContextBase::texImage2D(GLenum target, 5172 void WebGLRenderingContextBase::texImage2D(GLenum target,
5143 GLint level, 5173 GLint level,
5144 GLint internalformat, 5174 GLint internalformat,
5145 GLenum format, 5175 GLenum format,
5146 GLenum type, 5176 GLenum type,
5147 ImageBitmap* bitmap, 5177 ImageBitmap* bitmap,
5148 ExceptionState& exceptionState) { 5178 ExceptionState& exceptionState) {
5149 texImageHelperImageBitmap(TexImage2D, target, level, internalformat, format, 5179 texImageHelperImageBitmap(TexImage2D, target, level, internalformat, format,
(...skipping 2370 matching lines...) Expand 10 before | Expand all | Expand 10 after
7520 7550
7521 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( 7551 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas(
7522 HTMLCanvasElementOrOffscreenCanvas& result) const { 7552 HTMLCanvasElementOrOffscreenCanvas& result) const {
7523 if (canvas()) 7553 if (canvas())
7524 result.setHTMLCanvasElement(canvas()); 7554 result.setHTMLCanvasElement(canvas());
7525 else 7555 else
7526 result.setOffscreenCanvas(getOffscreenCanvas()); 7556 result.setOffscreenCanvas(getOffscreenCanvas());
7527 } 7557 }
7528 7558
7529 } // namespace blink 7559 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698