OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "platform/graphics/gpu/WebGLImageConversion.h" | 5 #include "platform/graphics/gpu/WebGLImageConversion.h" |
6 | 6 |
7 #include "platform/CheckedInt.h" | 7 #include "platform/CheckedInt.h" |
8 #include "platform/graphics/ImageObserver.h" | 8 #include "platform/graphics/ImageObserver.h" |
9 #include "platform/graphics/cpu/arm/WebGLImageConversionNEON.h" | 9 #include "platform/graphics/cpu/arm/WebGLImageConversionNEON.h" |
10 #include "platform/graphics/cpu/x86/WebGLImageConversionSSE.h" | 10 #include "platform/graphics/cpu/x86/WebGLImageConversionSSE.h" |
(...skipping 1905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1916 unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermType*>(m_unpac
kedIntermediateSrcData.get()), m_width); | 1916 unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermType*>(m_unpac
kedIntermediateSrcData.get()), m_width); |
1917 pack<DstFormat, alphaOp>(reinterpret_cast<IntermType*>(m_unpackedInt
ermediateSrcData.get()), dstRowStart, m_width); | 1917 pack<DstFormat, alphaOp>(reinterpret_cast<IntermType*>(m_unpackedInt
ermediateSrcData.get()), dstRowStart, m_width); |
1918 srcRowStart += srcStrideInElements; | 1918 srcRowStart += srcStrideInElements; |
1919 dstRowStart += dstStrideInElements; | 1919 dstRowStart += dstStrideInElements; |
1920 } | 1920 } |
1921 } | 1921 } |
1922 m_success = true; | 1922 m_success = true; |
1923 return; | 1923 return; |
1924 } | 1924 } |
1925 | 1925 |
| 1926 bool frameIsValid(const SkBitmap& frameBitmap) |
| 1927 { |
| 1928 return !frameBitmap.isNull() |
| 1929 && !frameBitmap.empty() |
| 1930 && frameBitmap.isImmutable() |
| 1931 && frameBitmap.colorType() == kN32_SkColorType; |
| 1932 } |
| 1933 |
1926 } // anonymous namespace | 1934 } // anonymous namespace |
1927 | 1935 |
| 1936 WebGLImageConversion::PixelStoreParams::PixelStoreParams() |
| 1937 : alignment(4) |
| 1938 , rowLength(0) |
| 1939 , imageHeight(0) |
| 1940 , skipPixels(0) |
| 1941 , skipRows(0) |
| 1942 , skipImages(0) |
| 1943 { |
| 1944 } |
| 1945 |
1928 bool WebGLImageConversion::computeFormatAndTypeParameters(GLenum format, GLenum
type, unsigned* componentsPerPixel, unsigned* bytesPerComponent) | 1946 bool WebGLImageConversion::computeFormatAndTypeParameters(GLenum format, GLenum
type, unsigned* componentsPerPixel, unsigned* bytesPerComponent) |
1929 { | 1947 { |
1930 switch (format) { | 1948 switch (format) { |
1931 case GL_ALPHA: | 1949 case GL_ALPHA: |
1932 case GL_LUMINANCE: | 1950 case GL_LUMINANCE: |
1933 case GL_RED: | 1951 case GL_RED: |
1934 case GL_RED_INTEGER: | 1952 case GL_RED_INTEGER: |
1935 case GL_DEPTH_COMPONENT: | 1953 case GL_DEPTH_COMPONENT: |
1936 case GL_DEPTH_STENCIL: // Treat it as one component. | 1954 case GL_DEPTH_STENCIL: // Treat it as one component. |
1937 *componentsPerPixel = 1; | 1955 *componentsPerPixel = 1; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1993 case GL_HALF_FLOAT: | 2011 case GL_HALF_FLOAT: |
1994 case GL_HALF_FLOAT_OES: // OES_texture_half_float | 2012 case GL_HALF_FLOAT_OES: // OES_texture_half_float |
1995 *bytesPerComponent = sizeof(GLushort); | 2013 *bytesPerComponent = sizeof(GLushort); |
1996 break; | 2014 break; |
1997 default: | 2015 default: |
1998 return false; | 2016 return false; |
1999 } | 2017 } |
2000 return true; | 2018 return true; |
2001 } | 2019 } |
2002 | 2020 |
2003 GLenum WebGLImageConversion::computeImageSizeInBytes(GLenum format, GLenum type,
GLsizei width, GLsizei height, GLsizei depth, GLint alignment, unsigned* imageS
izeInBytes, unsigned* paddingInBytes) | 2021 GLenum WebGLImageConversion::computeImageSizeInBytes(GLenum format, GLenum type,
GLsizei width, GLsizei height, GLsizei depth, const PixelStoreParams& params, u
nsigned* imageSizeInBytes, unsigned* paddingInBytes, unsigned* skipSizeInBytes) |
2004 { | 2022 { |
2005 ASSERT(imageSizeInBytes); | 2023 ASSERT(imageSizeInBytes); |
2006 ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8)
; | 2024 ASSERT(params.alignment == 1 || params.alignment == 2 || params.alignment ==
4 || params.alignment == 8); |
| 2025 ASSERT(params.rowLength >= 0 && params.imageHeight >= 0); |
| 2026 ASSERT(params.skipPixels >= 0 && params.skipRows >= 0 && params.skipImages >
= 0); |
2007 if (width < 0 || height < 0 || depth < 0) | 2027 if (width < 0 || height < 0 || depth < 0) |
2008 return GL_INVALID_VALUE; | 2028 return GL_INVALID_VALUE; |
2009 unsigned bytesPerComponent, componentsPerPixel; | |
2010 if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &compo
nentsPerPixel)) | |
2011 return GL_INVALID_ENUM; | |
2012 if (!width || !height || !depth) { | 2029 if (!width || !height || !depth) { |
2013 *imageSizeInBytes = 0; | 2030 *imageSizeInBytes = 0; |
2014 if (paddingInBytes) | 2031 if (paddingInBytes) |
2015 *paddingInBytes = 0; | 2032 *paddingInBytes = 0; |
| 2033 if (skipSizeInBytes) |
| 2034 *skipSizeInBytes = 0; |
2016 return GL_NO_ERROR; | 2035 return GL_NO_ERROR; |
2017 } | 2036 } |
2018 CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel); | 2037 |
2019 checkedValue *= width; | 2038 int rowLength = params.rowLength > 0 ? params.rowLength : width; |
| 2039 int imageHeight = params.imageHeight > 0 ? params.imageHeight : height; |
| 2040 |
| 2041 unsigned bytesPerComponent, componentsPerPixel; |
| 2042 if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &compo
nentsPerPixel)) |
| 2043 return GL_INVALID_ENUM; |
| 2044 unsigned bytesPerGroup = bytesPerComponent * componentsPerPixel; |
| 2045 CheckedInt<uint32_t> checkedValue = static_cast<uint32_t>(rowLength); |
| 2046 checkedValue *= bytesPerGroup; |
2020 if (!checkedValue.isValid()) | 2047 if (!checkedValue.isValid()) |
2021 return GL_INVALID_VALUE; | 2048 return GL_INVALID_VALUE; |
2022 unsigned validRowSize = checkedValue.value(); | 2049 |
| 2050 unsigned lastRowSize; |
| 2051 if (params.rowLength > 0 && params.rowLength != width) { |
| 2052 CheckedInt<uint32_t> tmp = width; |
| 2053 tmp *= bytesPerGroup; |
| 2054 if (!tmp.isValid()) |
| 2055 return GL_INVALID_VALUE; |
| 2056 lastRowSize = tmp.value(); |
| 2057 } else { |
| 2058 lastRowSize = checkedValue.value(); |
| 2059 } |
| 2060 |
2023 unsigned padding = 0; | 2061 unsigned padding = 0; |
2024 unsigned residual = validRowSize % alignment; | 2062 unsigned residual = checkedValue.value() % params.alignment; |
2025 if (residual) { | 2063 if (residual) { |
2026 padding = alignment - residual; | 2064 padding = params.alignment - residual; |
2027 checkedValue += padding; | 2065 checkedValue += padding; |
2028 } | 2066 } |
2029 // Last row needs no padding. | 2067 if (!checkedValue.isValid()) |
2030 checkedValue *= (height * depth - 1); | 2068 return GL_INVALID_VALUE; |
2031 checkedValue += validRowSize; | 2069 unsigned paddedRowSize = checkedValue.value(); |
| 2070 |
| 2071 CheckedInt<uint32_t> rows = imageHeight; |
| 2072 rows *= (depth - 1); |
| 2073 // Last image is not affected by IMAGE_HEIGHT parameter. |
| 2074 rows += height; |
| 2075 if (!rows.isValid()) |
| 2076 return GL_INVALID_VALUE; |
| 2077 checkedValue *= (rows.value() - 1); |
| 2078 // Last row is not affected by ROW_LENGTH parameter. |
| 2079 checkedValue += lastRowSize; |
2032 if (!checkedValue.isValid()) | 2080 if (!checkedValue.isValid()) |
2033 return GL_INVALID_VALUE; | 2081 return GL_INVALID_VALUE; |
2034 *imageSizeInBytes = checkedValue.value(); | 2082 *imageSizeInBytes = checkedValue.value(); |
2035 if (paddingInBytes) | 2083 if (paddingInBytes) |
2036 *paddingInBytes = padding; | 2084 *paddingInBytes = padding; |
| 2085 |
| 2086 CheckedInt<uint32_t> skipSize = 0; |
| 2087 if (params.skipImages > 0) { |
| 2088 CheckedInt<uint32_t> tmp = paddedRowSize; |
| 2089 tmp *= imageHeight; |
| 2090 tmp *= params.skipImages; |
| 2091 if (!tmp.isValid()) |
| 2092 return GL_INVALID_VALUE; |
| 2093 skipSize += tmp.value(); |
| 2094 } |
| 2095 if (params.skipRows > 0) { |
| 2096 CheckedInt<uint32_t> tmp = paddedRowSize; |
| 2097 tmp *= params.skipRows; |
| 2098 if (!tmp.isValid()) |
| 2099 return GL_INVALID_VALUE; |
| 2100 skipSize += tmp.value(); |
| 2101 } |
| 2102 if (params.skipPixels > 0) { |
| 2103 CheckedInt<uint32_t> tmp = bytesPerGroup; |
| 2104 tmp *= params.skipPixels; |
| 2105 if (!tmp.isValid()) |
| 2106 return GL_INVALID_VALUE; |
| 2107 skipSize += tmp.value(); |
| 2108 } |
| 2109 if (!skipSize.isValid()) |
| 2110 return GL_INVALID_VALUE; |
| 2111 if (skipSizeInBytes) |
| 2112 *skipSizeInBytes = skipSize.value(); |
| 2113 |
| 2114 checkedValue += skipSize.value(); |
| 2115 if (!checkedValue.isValid()) |
| 2116 return GL_INVALID_VALUE; |
2037 return GL_NO_ERROR; | 2117 return GL_NO_ERROR; |
2038 } | 2118 } |
2039 | 2119 |
2040 WebGLImageConversion::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomS
ource imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile
) | 2120 WebGLImageConversion::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomS
ource imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile
) |
2041 { | 2121 { |
2042 m_image = image; | 2122 m_image = image; |
2043 m_imageHtmlDomSource = imageHtmlDomSource; | 2123 m_imageHtmlDomSource = imageHtmlDomSource; |
2044 extractImage(premultiplyAlpha, ignoreGammaAndColorProfile); | 2124 extractImage(premultiplyAlpha, ignoreGammaAndColorProfile); |
2045 } | 2125 } |
2046 | 2126 |
2047 namespace { | |
2048 | |
2049 bool frameIsValid(const SkBitmap& frameBitmap) | |
2050 { | |
2051 return !frameBitmap.isNull() | |
2052 && !frameBitmap.empty() | |
2053 && frameBitmap.isImmutable() | |
2054 && frameBitmap.colorType() == kN32_SkColorType; | |
2055 } | |
2056 | |
2057 } // anonymous namespace | |
2058 | |
2059 void WebGLImageConversion::ImageExtractor::extractImage(bool premultiplyAlpha, b
ool ignoreGammaAndColorProfile) | 2127 void WebGLImageConversion::ImageExtractor::extractImage(bool premultiplyAlpha, b
ool ignoreGammaAndColorProfile) |
2060 { | 2128 { |
2061 ASSERT(!m_imagePixelLocker); | 2129 ASSERT(!m_imagePixelLocker); |
2062 | 2130 |
2063 if (!m_image) | 2131 if (!m_image) |
2064 return; | 2132 return; |
2065 | 2133 |
2066 RefPtr<SkImage> skiaImage = m_image->imageForCurrentFrame(); | 2134 RefPtr<SkImage> skiaImage = m_image->imageForCurrentFrame(); |
2067 SkImageInfo info = skiaImage | 2135 SkImageInfo info = skiaImage |
2068 ? SkImageInfo::MakeN32Premul(m_image->width(), m_image->height()) | 2136 ? SkImageInfo::MakeN32Premul(m_image->width(), m_image->height()) |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2223 unsigned width, | 2291 unsigned width, |
2224 unsigned height, | 2292 unsigned height, |
2225 unsigned sourceUnpackAlignment, | 2293 unsigned sourceUnpackAlignment, |
2226 Vector<uint8_t>& data) | 2294 Vector<uint8_t>& data) |
2227 { | 2295 { |
2228 if (!pixels) | 2296 if (!pixels) |
2229 return false; | 2297 return false; |
2230 | 2298 |
2231 unsigned packedSize; | 2299 unsigned packedSize; |
2232 // Output data is tightly packed (alignment == 1). | 2300 // Output data is tightly packed (alignment == 1). |
2233 if (computeImageSizeInBytes(format, type, width, height, 1, 1, &packedSize,
0) != GL_NO_ERROR) | 2301 PixelStoreParams params; |
| 2302 params.alignment = 1; |
| 2303 if (computeImageSizeInBytes(format, type, width, height, 1, params, &packedS
ize, 0, 0) != GL_NO_ERROR) |
2234 return false; | 2304 return false; |
2235 data.resize(packedSize); | 2305 data.resize(packedSize); |
2236 | 2306 |
2237 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, widt
h, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY)) | 2307 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, widt
h, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY)) |
2238 return false; | 2308 return false; |
2239 if (ImageObserver *observer = image->imageObserver()) | 2309 if (ImageObserver *observer = image->imageObserver()) |
2240 observer->didDraw(image); | 2310 observer->didDraw(image); |
2241 return true; | 2311 return true; |
2242 } | 2312 } |
2243 | 2313 |
2244 bool WebGLImageConversion::extractImageData( | 2314 bool WebGLImageConversion::extractImageData( |
2245 const uint8_t* imageData, | 2315 const uint8_t* imageData, |
2246 const IntSize& imageDataSize, | 2316 const IntSize& imageDataSize, |
2247 GLenum format, | 2317 GLenum format, |
2248 GLenum type, | 2318 GLenum type, |
2249 bool flipY, | 2319 bool flipY, |
2250 bool premultiplyAlpha, | 2320 bool premultiplyAlpha, |
2251 Vector<uint8_t>& data) | 2321 Vector<uint8_t>& data) |
2252 { | 2322 { |
2253 if (!imageData) | 2323 if (!imageData) |
2254 return false; | 2324 return false; |
2255 int width = imageDataSize.width(); | 2325 int width = imageDataSize.width(); |
2256 int height = imageDataSize.height(); | 2326 int height = imageDataSize.height(); |
2257 | 2327 |
2258 unsigned packedSize; | 2328 unsigned packedSize; |
2259 // Output data is tightly packed (alignment == 1). | 2329 // Output data is tightly packed (alignment == 1). |
2260 if (computeImageSizeInBytes(format, type, width, height, 1, 1, &packedSize,
0) != GL_NO_ERROR) | 2330 PixelStoreParams params; |
| 2331 params.alignment = 1; |
| 2332 if (computeImageSizeInBytes(format, type, width, height, 1, params, &packedS
ize, 0, 0) != GL_NO_ERROR) |
2261 return false; | 2333 return false; |
2262 data.resize(packedSize); | 2334 data.resize(packedSize); |
2263 | 2335 |
2264 if (!packPixels(imageData, DataFormatRGBA8, width, height, 0, format, type,
premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data(), flipY)) | 2336 if (!packPixels(imageData, DataFormatRGBA8, width, height, 0, format, type,
premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data(), flipY)) |
2265 return false; | 2337 return false; |
2266 | 2338 |
2267 return true; | 2339 return true; |
2268 } | 2340 } |
2269 | 2341 |
2270 bool WebGLImageConversion::extractTextureData( | 2342 bool WebGLImageConversion::extractTextureData( |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2331 } | 2403 } |
2332 | 2404 |
2333 FormatConverter converter(width, height, sourceData, destinationData, srcStr
ide, dstStride); | 2405 FormatConverter converter(width, height, sourceData, destinationData, srcStr
ide, dstStride); |
2334 converter.convert(sourceDataFormat, dstDataFormat, alphaOp); | 2406 converter.convert(sourceDataFormat, dstDataFormat, alphaOp); |
2335 if (!converter.Success()) | 2407 if (!converter.Success()) |
2336 return false; | 2408 return false; |
2337 return true; | 2409 return true; |
2338 } | 2410 } |
2339 | 2411 |
2340 } // namespace blink | 2412 } // namespace blink |
OLD | NEW |