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

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: should work 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) 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)
Ken Russell (switch to Gerrit) 2016/06/01 22:55:09 Please add DCHECK(!canvas || !bitmap) and DCHECK(c
xidachen 2016/06/02 13:52:52 Done.
4153 { 4171 {
4154 ScopedTexture2DRestorer restorer(this); 4172 ScopedTexture2DRestorer restorer(this);
4155 4173
4156 GLuint targetTexture = texture->object(); 4174 GLuint targetTexture = texture->object();
4157 GLenum targetType = type; 4175 GLenum targetType = type;
4158 GLenum targetInternalformat = internalformat; 4176 GLenum targetInternalformat = internalformat;
4159 GLint targetLevel = level; 4177 GLint targetLevel = level;
4160 bool possibleDirectCopy = false; 4178 bool possibleDirectCopy = false;
4161 if (functionType == TexImage2DByGPU) { 4179 if (functionType == TexImage2DByGPU) {
4162 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level); 4180 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level);
Ken Russell (switch to Gerrit) 2016/06/01 22:55:09 At some point this function should be expanded to
xidachen 2016/06/02 13:52:52 Done.
4163 } 4181 }
4164 4182
4165 // if direct copy is not possible, create a temporary texture and then copy from canvas to temporary texture to target texture. 4183 // if direct copy is not possible, create a temporary texture and then copy from canvas to temporary texture to target texture.
4166 if (!possibleDirectCopy) { 4184 if (!possibleDirectCopy) {
4167 targetLevel = 0; 4185 targetLevel = 0;
4168 targetInternalformat = GL_RGBA; 4186 targetInternalformat = GL_RGBA;
4169 targetType = GL_UNSIGNED_BYTE; 4187 targetType = GL_UNSIGNED_BYTE;
4170 contextGL()->GenTextures(1, &targetTexture); 4188 contextGL()->GenTextures(1, &targetTexture);
4171 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); 4189 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture);
4172 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAR EST); 4190 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); 4191 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); 4192 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); 4193 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO _EDGE);
4176 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, canvas-> width(), 4194 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, canvas-> width(),
4177 canvas->height(), 0, GL_RGBA, targetType, 0); 4195 canvas->height(), 0, GL_RGBA, targetType, 0);
4178 } 4196 }
4179 4197
4180 if (!canvas->is3D()) { 4198 if (canvas)
4181 ImageBuffer* buffer = canvas->buffer(); 4199 texImageCanvasByGPU(canvas, targetTexture, targetInternalformat, targetT ype, targetLevel);
4182 if (!buffer->copyToPlatformTexture(contextGL(), targetTexture, targetInt ernalformat, targetType, 4200 else
4183 targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) { 4201 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 4202
4195 if (!possibleDirectCopy) { 4203 if (!possibleDirectCopy) {
4196 GLuint tmpFBO; 4204 GLuint tmpFBO;
4197 contextGL()->GenFramebuffers(1, &tmpFBO); 4205 contextGL()->GenFramebuffers(1, &tmpFBO);
4198 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); 4206 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO);
4199 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0); 4207 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0);
4200 contextGL()->BindTexture(texture->getTarget(), texture->object()); 4208 contextGL()->BindTexture(texture->getTarget(), texture->object());
4201 if (functionType == TexImage2DByGPU) { 4209 if (functionType == TexImage2DByGPU) {
4202 contextGL()->CopyTexSubImage2D(target, level, 0, 0, 0, 0, canvas->wi dth(), canvas->height()); 4210 contextGL()->CopyTexSubImage2D(target, level, 0, 0, 0, 0, canvas->wi dth(), canvas->height());
4203 } else if (functionType == TexSubImage2DByGPU) { 4211 } else if (functionType == TexSubImage2DByGPU) {
(...skipping 14 matching lines...) Expand all
4218 if (isContextLost()) 4226 if (isContextLost())
4219 return; 4227 return;
4220 if (!validateHTMLCanvasElement("texImage2D", canvas, exceptionState)) 4228 if (!validateHTMLCanvasElement("texImage2D", canvas, exceptionState))
4221 return; 4229 return;
4222 WebGLTexture* texture = validateTexture2DBinding("texImage2D", target); 4230 WebGLTexture* texture = validateTexture2DBinding("texImage2D", target);
4223 if (!texture) 4231 if (!texture)
4224 return; 4232 return;
4225 if (!validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, 0, 0, 0)) 4233 if (!validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, 0, 0, 0))
4226 return; 4234 return;
4227 4235
4228 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support f loat/integer/sRGB internal format. 4236 // 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. 4237 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats.
4230 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || !canUseTexImageCanvasByGPU(internalformat, type)) { 4238 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || !canUseTexImageByGPU(internalformat, type)) {
4231 // 2D canvas has only FrontBuffer. 4239 // 2D canvas has only FrontBuffer.
4232 texImage2DImpl(target, level, internalformat, format, type, canvas->copi edImage(FrontBuffer, PreferAcceleration).get(), 4240 texImage2DImpl(target, level, internalformat, format, type, canvas->copi edImage(FrontBuffer, PreferAcceleration).get(),
4233 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); 4241 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha);
4234 return; 4242 return;
4235 } 4243 }
4236 4244
4237 texImage2DBase(target, level, internalformat, canvas->width(), canvas->heigh t(), 0, format, type, 0); 4245 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); 4246 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, type, 0, 0, 0, canvas, nullptr);
4239 } 4247 }
4240 4248
4241 PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video) 4249 PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video)
4242 { 4250 {
4243 IntSize size(video->videoWidth(), video->videoHeight()); 4251 IntSize size(video->videoWidth(), video->videoHeight());
4244 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size); 4252 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
4245 if (!buf) { 4253 if (!buf) {
4246 synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory"); 4254 synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
4247 return nullptr; 4255 return nullptr;
4248 } 4256 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
4291 } 4299 }
4292 } 4300 }
4293 4301
4294 // Normal pure SW path. 4302 // Normal pure SW path.
4295 RefPtr<Image> image = videoFrameToImage(video); 4303 RefPtr<Image> image = videoFrameToImage(video);
4296 if (!image) 4304 if (!image)
4297 return; 4305 return;
4298 texImage2DImpl(target, level, internalformat, format, type, image.get(), Web GLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha); 4306 texImage2DImpl(target, level, internalformat, format, type, image.get(), Web GLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
4299 } 4307 }
4300 4308
4309 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, GLuint targetTexture, GLenum targetInternalformat, GLenum targetType, GLint targetLevel )
4310 {
4311 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(drawin gBuffer()->contextProvider());
4312 bitmap->bitmapImage()->copyTexture(drawingBuffer()->contextProvider(), targe tTexture, targetInternalformat, targetType);
4313 }
4314
4301 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4315 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4302 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate) 4316 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate)
4303 { 4317 {
4304 if (isContextLost()) 4318 if (isContextLost())
4305 return; 4319 return;
4306 if (!validateImageBitmap("texImage2D", bitmap, exceptionState)) 4320 if (!validateImageBitmap("texImage2D", bitmap, exceptionState))
4307 return; 4321 return;
4308 if (!validateTexture2DBinding("texImage2D", target)) 4322 WebGLTexture* texture = validateTexture2DBinding("texImage2D", target);
4323 if (!texture)
4309 return; 4324 return;
4310 if (!validateTexFunc("texImage2D", TexImage, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0)) 4325 if (!validateTexFunc("texImage2D", TexImage, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0))
4311 return; 4326 return;
4312 ASSERT(bitmap->bitmapImage()); 4327 ASSERT(bitmap->bitmapImage());
4328 if (bitmap->isTextureBacked() && canUseTexImageByGPU(internalformat, type)) {
4329 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, 0);
4330 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, t ype, 0, 0, 0, nullptr, bitmap);
4331 return;
4332 }
4313 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); 4333 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
4314 SkPixmap pixmap; 4334 SkPixmap pixmap;
4315 OwnPtr<uint8_t[]> pixelData; 4335 OwnPtr<uint8_t[]> pixelData;
4316 uint8_t* pixelDataPtr = nullptr; 4336 uint8_t* pixelDataPtr = nullptr;
4317 // TODO(crbug.com/613411): peekPixels fails if the SkImage is texture-backed 4337 // In the case where we cannot use texImageByGPU, peekPixels() fails.
Ken Russell (switch to Gerrit) 2016/06/01 22:55:09 This comment seems to indicate that peekPixels() w
xidachen 2016/06/02 13:52:52 The comment is bad, it doesn't convey what I want
4318 // Use texture mailbox in that case.
4319 bool peekSucceed = skImage->peekPixels(&pixmap); 4338 bool peekSucceed = skImage->peekPixels(&pixmap);
4320 if (peekSucceed) { 4339 if (peekSucceed) {
4321 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); 4340 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
4322 } else if (skImage->isTextureBacked()) { 4341 } else {
4323 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha); 4342 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha);
4324 pixelDataPtr = pixelData.get(); 4343 pixelDataPtr = pixelData.get();
4325 } 4344 }
4326 Vector<uint8_t> data; 4345 Vector<uint8_t> data;
4327 bool needConversion = true; 4346 bool needConversion = true;
4328 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType); 4347 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType);
4329 bool isPixelDataRBGA = (havePeekableRGBA || !peekSucceed); 4348 bool isPixelDataRGBA = (havePeekableRGBA || !peekSucceed);
4330 if (isPixelDataRBGA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { 4349 if (isPixelDataRGBA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
4331 needConversion = false; 4350 needConversion = false;
4332 } else { 4351 } else {
4333 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4352 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4334 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. 4353 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed.
4335 type = GL_FLOAT; 4354 type = GL_FLOAT;
4336 } 4355 }
4337 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha. 4356 // 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); 4357 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)) 4358 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))) { 4359 || (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"); 4360 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
4342 return; 4361 return;
4343 } 4362 }
4344 } 4363 }
4345 resetUnpackParameters(); 4364 resetUnpackParameters();
4346 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->heigh t(), 0, format, type, needConversion ? data.data() : pixelDataPtr); 4365 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->heigh t(), 0, format, type, needConversion ? data.data() : pixelDataPtr);
4347 restoreUnpackParameters(); 4366 restoreUnpackParameters();
4348 } 4367 }
4349 4368
4350 void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloa t paramf, GLint parami, bool isFloat) 4369 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) 4562 if (!texture)
4544 return; 4563 return;
4545 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, 0, canvas->width(), canvas->height(), 1, 0, format, type, xoffset , yoffset, 0)) 4564 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, 0, canvas->width(), canvas->height(), 1, 0, format, type, xoffset , yoffset, 0))
4546 return; 4565 return;
4547 4566
4548 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal formats. 4567 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal formats.
4549 bool useReadBackPath = isWebGL2OrHigher() 4568 bool useReadBackPath = isWebGL2OrHigher()
4550 || extensionEnabled(OESTextureFloatName) 4569 || extensionEnabled(OESTextureFloatName)
4551 || extensionEnabled(OESTextureHalfFloatName) 4570 || extensionEnabled(OESTextureHalfFloatName)
4552 || extensionEnabled(EXTsRGBName); 4571 || extensionEnabled(EXTsRGBName);
4553 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support f loat/integer/sRGB internal format. 4572 // 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. 4573 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats.
4555 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || useReadBackPath) { 4574 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || useReadBackPath) {
4556 // 2D canvas has only FrontBuffer. 4575 // 2D canvas has only FrontBuffer.
4557 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas- >copiedImage(FrontBuffer, PreferAcceleration).get(), 4576 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas- >copiedImage(FrontBuffer, PreferAcceleration).get(),
4558 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); 4577 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha);
4559 return; 4578 return;
4560 } 4579 }
4561 4580
4562 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, typ e, xoffset, yoffset, 0, canvas); 4581 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xof fset, yoffset, 0, canvas, nullptr);
4563 } 4582 }
4564 4583
4565 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4584 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4566 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) 4585 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState)
4567 { 4586 {
4568 if (isContextLost()) 4587 if (isContextLost())
4569 return; 4588 return;
4570 if (!validateHTMLVideoElement("texSubImage2D", video, exceptionState)) 4589 if (!validateHTMLVideoElement("texSubImage2D", video, exceptionState))
4571 return; 4590 return;
4572 if (!validateTexture2DBinding("texSubImage2D", target)) 4591 if (!validateTexture2DBinding("texSubImage2D", target))
4573 return; 4592 return;
4574 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, t arget, level, 0, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, 0)) 4593 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, t arget, level, 0, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, 0))
4575 return; 4594 return;
4576 4595
4577 RefPtr<Image> image = videoFrameToImage(video); 4596 RefPtr<Image> image = videoFrameToImage(video);
4578 if (!image) 4597 if (!image)
4579 return; 4598 return;
4580 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get() , WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha); 4599 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get() , WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
4581 } 4600 }
4582 4601
4583 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4602 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4584 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate) 4603 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate)
4585 { 4604 {
4586 if (isContextLost()) 4605 if (isContextLost())
4587 return; 4606 return;
4588 if (!validateImageBitmap("texSubImage2D", bitmap, exceptionState)) 4607 if (!validateImageBitmap("texSubImage2D", bitmap, exceptionState))
4589 return; 4608 return;
4590 if (!validateTexture2DBinding("texSubImage2D", target)) 4609 WebGLTexture* texture = validateTexture2DBinding("texSubImage2D", target);
4610 if (!texture)
4591 return; 4611 return;
4592 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageBitmap, target , level, 0, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0)) 4612 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageBitmap, target , level, 0, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffset, yoff set, 0))
4593 return; 4613 return;
4594 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4614 bool useReadBackPath = isWebGL2OrHigher()
4595 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. 4615 || extensionEnabled(OESTextureFloatName)
4596 type = GL_FLOAT; 4616 || extensionEnabled(OESTextureHalfFloatName)
4617 || extensionEnabled(EXTsRGBName);
Ken Russell (switch to Gerrit) 2016/06/01 22:55:09 This looks wrong. Whether the readback path is use
xidachen 2016/06/02 13:52:52 This part of code is actually copied from line 454
4618 if (bitmap->isTextureBacked() && !useReadBackPath) {
4619 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, nullptr, bitmap);
4620 return;
4597 } 4621 }
4598 ASSERT(bitmap->bitmapImage());
4599 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); 4622 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
4600 SkPixmap pixmap; 4623 SkPixmap pixmap;
4601 OwnPtr<uint8_t[]> pixelData; 4624 OwnPtr<uint8_t[]> pixelData;
4602 uint8_t* pixelDataPtr = nullptr; 4625 uint8_t* pixelDataPtr = nullptr;
4626 // In the case where we cannot use texImageByGPU, peekPixels() fails.
Ken Russell (switch to Gerrit) 2016/06/01 22:55:09 Same comment as above here.
xidachen 2016/06/02 13:52:52 Done.
4603 bool peekSucceed = skImage->peekPixels(&pixmap); 4627 bool peekSucceed = skImage->peekPixels(&pixmap);
4604 if (peekSucceed) { 4628 if (peekSucceed) {
4605 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); 4629 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
4606 } else if (skImage->isTextureBacked()) { 4630 } else {
4607 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha); 4631 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha);
4608 pixelDataPtr = pixelData.get(); 4632 pixelDataPtr = pixelData.get();
4609 } 4633 }
4610 Vector<uint8_t> data; 4634 Vector<uint8_t> data;
4611 bool needConversion = true; 4635 bool needConversion = true;
4612 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType); 4636 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType);
4613 bool isPixelDataRBGA = (havePeekableRGBA || !peekSucceed); 4637 bool isPixelDataRGBA = (havePeekableRGBA || !peekSucceed);
4614 if (isPixelDataRBGA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { 4638 if (isPixelDataRGBA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
4615 needConversion = false; 4639 needConversion = false;
4616 } else { 4640 } else {
4641 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4642 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed.
4643 type = GL_FLOAT;
4644 }
4617 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha. 4645 // 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); 4646 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)) 4647 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))) { 4648 || (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 "); 4649 synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data ");
4622 return; 4650 return;
4623 } 4651 }
4624 } 4652 }
4625 resetUnpackParameters(); 4653 resetUnpackParameters();
4626 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr); 4654 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr);
4627 restoreUnpackParameters(); 4655 restoreUnpackParameters();
4628 } 4656 }
4629 4657
4630 void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x) 4658 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); 6452 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
6425 } 6453 }
6426 6454
6427 void WebGLRenderingContextBase::restoreUnpackParameters() 6455 void WebGLRenderingContextBase::restoreUnpackParameters()
6428 { 6456 {
6429 if (m_unpackAlignment != 1) 6457 if (m_unpackAlignment != 1)
6430 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); 6458 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
6431 } 6459 }
6432 6460
6433 } // namespace blink 6461 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698