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

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 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 4123 matching lines...) Expand 10 before | Expand all | Expand 10 after
4134 if (!imageForRender || !validateTexFunc("texImage2D", TexImage, SourceHTMLIm ageElement, target, level, internalformat, imageForRender->width(), imageForRend er->height(), 1, 0, format, type, 0, 0, 0)) 4134 if (!imageForRender || !validateTexFunc("texImage2D", TexImage, SourceHTMLIm ageElement, target, level, internalformat, imageForRender->width(), imageForRend er->height(), 1, 0, format, type, 0, 0, 0))
4135 return; 4135 return;
4136 4136
4137 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4137 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4138 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. 4138 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
4139 type = GL_FLOAT; 4139 type = GL_FLOAT;
4140 } 4140 }
4141 texImage2DImpl(target, level, internalformat, format, type, imageForRender.g et(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlph a); 4141 texImage2DImpl(target, level, internalformat, format, type, imageForRender.g et(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlph a);
4142 } 4142 }
4143 4143
4144 bool WebGLRenderingContextBase::canUseTexImageCanvasByGPU(GLint internalformat, GLenum type) 4144 bool WebGLRenderingContextBase::canUseTexImageByGPU(GLint internalformat, GLenum type)
4145 { 4145 {
4146 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat)) 4146 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat))
4147 return false; 4147 return false;
4148 return true; 4148 return true;
4149 } 4149 }
4150 4150
4151 void WebGLRenderingContextBase::texImageCanvasByGPU(TexImageByGPUType functionTy pe, WebGLTexture* texture, GLenum target, 4151 void WebGLRenderingContextBase::texImageCanvasByGPU(HTMLCanvasElement* canvas, G Luint targetTexture, GLenum targetInternalformat, GLenum targetType, GLint targe tLevel)
4152 GLint level, GLint internalformat, GLenum type, GLint xoffset, GLint yoffset , GLint zoffset, HTMLCanvasElement* canvas)
4153 { 4152 {
4153 if (!canvas->is3D()) {
4154 ImageBuffer* buffer = canvas->buffer();
4155 if (!buffer->copyToPlatformTexture(contextGL(), targetTexture, targetInt ernalformat, targetType,
4156 targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
4157 NOTREACHED();
4158 }
4159 } else {
4160 WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->rend eringContext());
4161 ScopedTexture2DRestorer restorer(gl);
4162 if (!gl->drawingBuffer()->copyToPlatformTexture(contextGL(), targetTextu re, targetInternalformat, targetType,
4163 targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, BackBuffer)) {
4164 NOTREACHED();
4165 }
4166 }
4167 }
4168
4169 void WebGLRenderingContextBase::texImageByGPU(TexImageByGPUType functionType, We bGLTexture* texture, GLenum target,
4170 GLint level, GLint internalformat, GLenum type, GLint xoffset, GLint yoffset , GLint zoffset, HTMLCanvasElement* canvas, ImageBitmap* bitmap)
4171 {
4172 DCHECK((!canvas || !bitmap) && (canvas || bitmap));
4154 ScopedTexture2DRestorer restorer(this); 4173 ScopedTexture2DRestorer restorer(this);
4155 4174
4156 GLuint targetTexture = texture->object(); 4175 GLuint targetTexture = texture->object();
4157 GLenum targetType = type; 4176 GLenum targetType = type;
4158 GLenum targetInternalformat = internalformat; 4177 GLenum targetInternalformat = internalformat;
4159 GLint targetLevel = level; 4178 GLint targetLevel = level;
4160 bool possibleDirectCopy = false; 4179 bool possibleDirectCopy = false;
4180 // TODO: Make this function support more cases in texSubImage calls.
4161 if (functionType == TexImage2DByGPU) { 4181 if (functionType == TexImage2DByGPU) {
4162 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level); 4182 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level);
4163 } 4183 }
4164 4184
4165 // if direct copy is not possible, create a temporary texture and then copy from canvas to temporary texture to target texture. 4185 // if direct copy is not possible, create a temporary texture and then copy from canvas to temporary texture to target texture.
4166 if (!possibleDirectCopy) { 4186 if (!possibleDirectCopy) {
4167 targetLevel = 0; 4187 targetLevel = 0;
4168 targetInternalformat = GL_RGBA; 4188 targetInternalformat = GL_RGBA;
4169 targetType = GL_UNSIGNED_BYTE; 4189 targetType = GL_UNSIGNED_BYTE;
4170 contextGL()->GenTextures(1, &targetTexture); 4190 contextGL()->GenTextures(1, &targetTexture);
4171 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); 4191 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture);
4172 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAR EST); 4192 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAR EST);
4173 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAR EST); 4193 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAR EST);
4174 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO _EDGE); 4194 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO _EDGE);
4175 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO _EDGE); 4195 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO _EDGE);
4176 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, canvas-> width(), 4196 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, canvas-> width(),
4177 canvas->height(), 0, GL_RGBA, targetType, 0); 4197 canvas->height(), 0, GL_RGBA, targetType, 0);
4178 } 4198 }
4179 4199
4180 if (!canvas->is3D()) { 4200 if (canvas)
4181 ImageBuffer* buffer = canvas->buffer(); 4201 texImageCanvasByGPU(canvas, targetTexture, targetInternalformat, targetT ype, targetLevel);
4182 if (!buffer->copyToPlatformTexture(contextGL(), targetTexture, targetInt ernalformat, targetType, 4202 else
4183 targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) { 4203 texImageBitmapByGPU(bitmap, targetTexture, targetInternalformat, targetT ype, targetLevel);
4184 ASSERT_NOT_REACHED();
4185 }
4186 } else {
4187 WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->rend eringContext());
4188 ScopedTexture2DRestorer restorer(gl);
4189 if (!gl->drawingBuffer()->copyToPlatformTexture(contextGL(), targetTextu re, targetInternalformat, targetType,
4190 targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, BackBuffer)) {
4191 ASSERT_NOT_REACHED();
4192 }
4193 }
4194 4204
4195 if (!possibleDirectCopy) { 4205 if (!possibleDirectCopy) {
4196 GLuint tmpFBO; 4206 GLuint tmpFBO;
4197 contextGL()->GenFramebuffers(1, &tmpFBO); 4207 contextGL()->GenFramebuffers(1, &tmpFBO);
4198 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); 4208 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO);
4199 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0); 4209 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0);
4200 contextGL()->BindTexture(texture->getTarget(), texture->object()); 4210 contextGL()->BindTexture(texture->getTarget(), texture->object());
4201 if (functionType == TexImage2DByGPU) { 4211 if (functionType == TexImage2DByGPU) {
4202 contextGL()->CopyTexSubImage2D(target, level, 0, 0, 0, 0, canvas->wi dth(), canvas->height()); 4212 contextGL()->CopyTexSubImage2D(target, level, 0, 0, 0, 0, canvas->wi dth(), canvas->height());
4203 } else if (functionType == TexSubImage2DByGPU) { 4213 } else if (functionType == TexSubImage2DByGPU) {
(...skipping 14 matching lines...) Expand all
4218 if (isContextLost()) 4228 if (isContextLost())
4219 return; 4229 return;
4220 if (!validateHTMLCanvasElement("texImage2D", canvas, exceptionState)) 4230 if (!validateHTMLCanvasElement("texImage2D", canvas, exceptionState))
4221 return; 4231 return;
4222 WebGLTexture* texture = validateTexture2DBinding("texImage2D", target); 4232 WebGLTexture* texture = validateTexture2DBinding("texImage2D", target);
4223 if (!texture) 4233 if (!texture)
4224 return; 4234 return;
4225 if (!validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, 0, 0, 0)) 4235 if (!validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, 0, 0, 0))
4226 return; 4236 return;
4227 4237
4228 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support f loat/integer/sRGB internal format. 4238 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support float/i nteger/sRGB internal format.
4229 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats. 4239 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats.
4230 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || !canUseTexImageCanvasByGPU(internalformat, type)) { 4240 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || !canUseTexImageByGPU(internalformat, type)) {
4231 // 2D canvas has only FrontBuffer. 4241 // 2D canvas has only FrontBuffer.
4232 texImage2DImpl(target, level, internalformat, format, type, canvas->copi edImage(FrontBuffer, PreferAcceleration).get(), 4242 texImage2DImpl(target, level, internalformat, format, type, canvas->copi edImage(FrontBuffer, PreferAcceleration).get(),
4233 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); 4243 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha);
4234 return; 4244 return;
4235 } 4245 }
4236 4246
4237 texImage2DBase(target, level, internalformat, canvas->width(), canvas->heigh t(), 0, format, type, 0); 4247 texImage2DBase(target, level, internalformat, canvas->width(), canvas->heigh t(), 0, format, type, 0);
4238 texImageCanvasByGPU(TexImage2DByGPU, texture, target, level, internalformat, type, 0, 0, 0, canvas); 4248 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, type, 0, 0, 0, canvas, nullptr);
4239 } 4249 }
4240 4250
4241 PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video) 4251 PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video)
4242 { 4252 {
4243 IntSize size(video->videoWidth(), video->videoHeight()); 4253 IntSize size(video->videoWidth(), video->videoHeight());
4244 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size); 4254 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
4245 if (!buf) { 4255 if (!buf) {
4246 synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory"); 4256 synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
4247 return nullptr; 4257 return nullptr;
4248 } 4258 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
4291 } 4301 }
4292 } 4302 }
4293 4303
4294 // Normal pure SW path. 4304 // Normal pure SW path.
4295 RefPtr<Image> image = videoFrameToImage(video); 4305 RefPtr<Image> image = videoFrameToImage(video);
4296 if (!image) 4306 if (!image)
4297 return; 4307 return;
4298 texImage2DImpl(target, level, internalformat, format, type, image.get(), Web GLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha); 4308 texImage2DImpl(target, level, internalformat, format, type, image.get(), Web GLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
4299 } 4309 }
4300 4310
4311 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, GLuint targetTexture, GLenum targetInternalformat, GLenum targetType, GLint targetLevel )
4312 {
4313 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(drawin gBuffer()->contextProvider());
4314 bitmap->bitmapImage()->copyTexture(drawingBuffer()->contextProvider(), targe tTexture, targetInternalformat, targetType);
4315 }
4316
4301 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4317 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4302 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate) 4318 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate)
4303 { 4319 {
4304 if (isContextLost()) 4320 if (isContextLost())
4305 return; 4321 return;
4306 if (!validateImageBitmap("texImage2D", bitmap, exceptionState)) 4322 if (!validateImageBitmap("texImage2D", bitmap, exceptionState))
4307 return; 4323 return;
4308 if (!validateTexture2DBinding("texImage2D", target)) 4324 WebGLTexture* texture = validateTexture2DBinding("texImage2D", target);
4325 if (!texture)
4309 return; 4326 return;
4310 if (!validateTexFunc("texImage2D", TexImage, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0)) 4327 if (!validateTexFunc("texImage2D", TexImage, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0))
4311 return; 4328 return;
4312 ASSERT(bitmap->bitmapImage()); 4329 ASSERT(bitmap->bitmapImage());
4330 if (bitmap->isTextureBacked() && canUseTexImageByGPU(internalformat, type)) {
4331 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, 0);
4332 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, t ype, 0, 0, 0, nullptr, bitmap);
4333 return;
4334 }
4313 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); 4335 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
4314 SkPixmap pixmap; 4336 SkPixmap pixmap;
4315 OwnPtr<uint8_t[]> pixelData; 4337 OwnPtr<uint8_t[]> pixelData;
4316 uint8_t* pixelDataPtr = nullptr; 4338 uint8_t* pixelDataPtr = nullptr;
4317 // TODO(crbug.com/613411): peekPixels fails if the SkImage is texture-backed 4339 // In the case where an ImageBitmap is not texture backed, peekPixels() alwa ys succeed.
Stephen White 2016/06/03 17:59:13 Is the mailbox case now handled by the copyTexture
4318 // Use texture mailbox in that case. 4340 // However, when it is texture backed and !canUseTexImageByGPU, we do a GPU read back.
4319 bool peekSucceed = skImage->peekPixels(&pixmap); 4341 bool peekSucceed = skImage->peekPixels(&pixmap);
4320 if (peekSucceed) { 4342 if (peekSucceed) {
4321 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); 4343 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
4322 } else if (skImage->isTextureBacked()) { 4344 } else {
4323 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha); 4345 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha);
4324 pixelDataPtr = pixelData.get(); 4346 pixelDataPtr = pixelData.get();
4325 } 4347 }
4326 Vector<uint8_t> data; 4348 Vector<uint8_t> data;
4327 bool needConversion = true; 4349 bool needConversion = true;
4328 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType); 4350 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType);
4329 bool isPixelDataRBGA = (havePeekableRGBA || !peekSucceed); 4351 bool isPixelDataRGBA = (havePeekableRGBA || !peekSucceed);
4330 if (isPixelDataRBGA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { 4352 if (isPixelDataRGBA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
4331 needConversion = false; 4353 needConversion = false;
4332 } else { 4354 } else {
4333 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4355 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4334 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. 4356 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed.
4335 type = GL_FLOAT; 4357 type = GL_FLOAT;
4336 } 4358 }
4337 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha. 4359 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha.
4338 bool isPixelDataBGRA = (peekSucceed && pixmap.colorType() == SkColorType ::kBGRA_8888_SkColorType); 4360 bool isPixelDataBGRA = pixmap.colorType() == SkColorType::kBGRA_8888_SkC olorType;
4339 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data)) 4361 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data))
4340 || (isPixelDataRBGA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) { 4362 || (isPixelDataRGBA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) {
4341 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data"); 4363 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
4342 return; 4364 return;
4343 } 4365 }
4344 } 4366 }
4345 resetUnpackParameters(); 4367 resetUnpackParameters();
4346 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->heigh t(), 0, format, type, needConversion ? data.data() : pixelDataPtr); 4368 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->heigh t(), 0, format, type, needConversion ? data.data() : pixelDataPtr);
4347 restoreUnpackParameters(); 4369 restoreUnpackParameters();
4348 } 4370 }
4349 4371
4350 void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloa t paramf, GLint parami, bool isFloat) 4372 void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloa t paramf, GLint parami, bool isFloat)
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
4543 if (!texture) 4565 if (!texture)
4544 return; 4566 return;
4545 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, 0, canvas->width(), canvas->height(), 1, 0, format, type, xoffset , yoffset, 0)) 4567 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, 0, canvas->width(), canvas->height(), 1, 0, format, type, xoffset , yoffset, 0))
4546 return; 4568 return;
4547 4569
4548 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal formats. 4570 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal formats.
4549 bool useReadBackPath = isWebGL2OrHigher() 4571 bool useReadBackPath = isWebGL2OrHigher()
4550 || extensionEnabled(OESTextureFloatName) 4572 || extensionEnabled(OESTextureFloatName)
4551 || extensionEnabled(OESTextureHalfFloatName) 4573 || extensionEnabled(OESTextureHalfFloatName)
4552 || extensionEnabled(EXTsRGBName); 4574 || extensionEnabled(EXTsRGBName);
4553 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support f loat/integer/sRGB internal format. 4575 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support float/i nteger/sRGB internal format.
4554 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats. 4576 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats.
4555 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || useReadBackPath) { 4577 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || useReadBackPath) {
4556 // 2D canvas has only FrontBuffer. 4578 // 2D canvas has only FrontBuffer.
4557 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas- >copiedImage(FrontBuffer, PreferAcceleration).get(), 4579 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas- >copiedImage(FrontBuffer, PreferAcceleration).get(),
4558 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); 4580 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha);
4559 return; 4581 return;
4560 } 4582 }
4561 4583
4562 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, typ e, xoffset, yoffset, 0, canvas); 4584 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xof fset, yoffset, 0, canvas, nullptr);
4563 } 4585 }
4564 4586
4565 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4587 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4566 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) 4588 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState)
4567 { 4589 {
4568 if (isContextLost()) 4590 if (isContextLost())
4569 return; 4591 return;
4570 if (!validateHTMLVideoElement("texSubImage2D", video, exceptionState)) 4592 if (!validateHTMLVideoElement("texSubImage2D", video, exceptionState))
4571 return; 4593 return;
4572 if (!validateTexture2DBinding("texSubImage2D", target)) 4594 if (!validateTexture2DBinding("texSubImage2D", target))
4573 return; 4595 return;
4574 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, t arget, level, 0, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, 0)) 4596 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, t arget, level, 0, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, 0))
4575 return; 4597 return;
4576 4598
4577 RefPtr<Image> image = videoFrameToImage(video); 4599 RefPtr<Image> image = videoFrameToImage(video);
4578 if (!image) 4600 if (!image)
4579 return; 4601 return;
4580 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get() , WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha); 4602 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get() , WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
4581 } 4603 }
4582 4604
4583 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4605 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4584 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate) 4606 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate)
4585 { 4607 {
4586 if (isContextLost()) 4608 if (isContextLost())
4587 return; 4609 return;
4588 if (!validateImageBitmap("texSubImage2D", bitmap, exceptionState)) 4610 if (!validateImageBitmap("texSubImage2D", bitmap, exceptionState))
4589 return; 4611 return;
4590 if (!validateTexture2DBinding("texSubImage2D", target)) 4612 WebGLTexture* texture = validateTexture2DBinding("texSubImage2D", target);
4613 if (!texture)
4591 return; 4614 return;
4592 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageBitmap, target , level, 0, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0)) 4615 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageBitmap, target , level, 0, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffset, yoff set, 0))
4593 return; 4616 return;
4594 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4617 bool useReadBackPath = isWebGL2OrHigher()
Stephen White 2016/06/03 17:59:13 Seems to be copied from line 4570. Could you refac
4595 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. 4618 || extensionEnabled(OESTextureFloatName)
4596 type = GL_FLOAT; 4619 || extensionEnabled(OESTextureHalfFloatName)
4620 || extensionEnabled(EXTsRGBName);
4621 if (bitmap->isTextureBacked() && !useReadBackPath) {
Stephen White 2016/06/03 17:59:13 Are there tests which cover all these possible con
4622 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, nullptr, bitmap);
4623 return;
4597 } 4624 }
4598 ASSERT(bitmap->bitmapImage());
4599 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); 4625 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
4600 SkPixmap pixmap; 4626 SkPixmap pixmap;
4601 OwnPtr<uint8_t[]> pixelData; 4627 OwnPtr<uint8_t[]> pixelData;
4602 uint8_t* pixelDataPtr = nullptr; 4628 uint8_t* pixelDataPtr = nullptr;
4629 // In the case where an ImageBitmap is not texture backed, peekPixels() alwa ys succeed.
4630 // However, when it is texture backed and !canUseTexImageByGPU, we do a GPU read back.
4603 bool peekSucceed = skImage->peekPixels(&pixmap); 4631 bool peekSucceed = skImage->peekPixels(&pixmap);
4604 if (peekSucceed) { 4632 if (peekSucceed) {
4605 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); 4633 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
4606 } else if (skImage->isTextureBacked()) { 4634 } else {
4607 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha); 4635 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha);
4608 pixelDataPtr = pixelData.get(); 4636 pixelDataPtr = pixelData.get();
4609 } 4637 }
4610 Vector<uint8_t> data; 4638 Vector<uint8_t> data;
4611 bool needConversion = true; 4639 bool needConversion = true;
4612 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType); 4640 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType);
4613 bool isPixelDataRBGA = (havePeekableRGBA || !peekSucceed); 4641 bool isPixelDataRGBA = (havePeekableRGBA || !peekSucceed);
4614 if (isPixelDataRBGA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { 4642 if (isPixelDataRGBA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
4615 needConversion = false; 4643 needConversion = false;
4616 } else { 4644 } else {
4645 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
Stephen White 2016/06/03 17:59:13 Is there a 10_11_11 test somewhere?
4646 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed.
4647 type = GL_FLOAT;
4648 }
4617 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha. 4649 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha.
4618 bool isPixelDataBGRA = (peekSucceed && pixmap.colorType() == SkColorType ::kBGRA_8888_SkColorType); 4650 bool isPixelDataBGRA = pixmap.colorType() == SkColorType::kBGRA_8888_SkC olorType;
4619 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data)) 4651 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data))
4620 || (isPixelDataRBGA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) { 4652 || (isPixelDataRGBA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) {
4621 synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data "); 4653 synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data ");
4622 return; 4654 return;
4623 } 4655 }
4624 } 4656 }
4625 resetUnpackParameters(); 4657 resetUnpackParameters();
4626 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr); 4658 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr);
4627 restoreUnpackParameters(); 4659 restoreUnpackParameters();
4628 } 4660 }
4629 4661
4630 void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x) 4662 void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x)
(...skipping 1793 matching lines...) Expand 10 before | Expand all | Expand 10 after
6424 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1); 6456 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
6425 } 6457 }
6426 6458
6427 void WebGLRenderingContextBase::restoreUnpackParameters() 6459 void WebGLRenderingContextBase::restoreUnpackParameters()
6428 { 6460 {
6429 if (m_unpackAlignment != 1) 6461 if (m_unpackAlignment != 1)
6430 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); 6462 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
6431 } 6463 }
6432 6464
6433 } // namespace blink 6465 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698