| 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/graphics/ImageObserver.h" | 7 #include "platform/graphics/ImageObserver.h" |
| 8 #include "platform/graphics/cpu/arm/WebGLImageConversionNEON.h" | 8 #include "platform/graphics/cpu/arm/WebGLImageConversionNEON.h" |
| 9 #include "platform/graphics/cpu/mips/WebGLImageConversionMSA.h" | 9 #include "platform/graphics/cpu/mips/WebGLImageConversionMSA.h" |
| 10 #include "platform/graphics/cpu/x86/WebGLImageConversionSSE.h" | 10 #include "platform/graphics/cpu/x86/WebGLImageConversionSSE.h" |
| (...skipping 2215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2226 } | 2226 } |
| 2227 } | 2227 } |
| 2228 | 2228 |
| 2229 /* END CODE SHARED WITH MOZILLA FIREFOX */ | 2229 /* END CODE SHARED WITH MOZILLA FIREFOX */ |
| 2230 | 2230 |
| 2231 class FormatConverter { | 2231 class FormatConverter { |
| 2232 STACK_ALLOCATED(); | 2232 STACK_ALLOCATED(); |
| 2233 | 2233 |
| 2234 public: | 2234 public: |
| 2235 FormatConverter(const IntRect& sourceDataSubRectangle, | 2235 FormatConverter(const IntRect& sourceDataSubRectangle, |
| 2236 int depth, |
| 2237 int unpackImageHeight, |
| 2236 const void* srcStart, | 2238 const void* srcStart, |
| 2237 void* dstStart, | 2239 void* dstStart, |
| 2238 int srcStride, | 2240 int srcStride, |
| 2239 int srcRowOffset, | 2241 int srcRowOffset, |
| 2240 int dstStride) | 2242 int dstStride) |
| 2241 : m_srcSubRectangle(sourceDataSubRectangle), | 2243 : m_srcSubRectangle(sourceDataSubRectangle), |
| 2244 m_depth(depth), |
| 2245 m_unpackImageHeight(unpackImageHeight), |
| 2242 m_srcStart(srcStart), | 2246 m_srcStart(srcStart), |
| 2243 m_dstStart(dstStart), | 2247 m_dstStart(dstStart), |
| 2244 m_srcStride(srcStride), | 2248 m_srcStride(srcStride), |
| 2245 m_srcRowOffset(srcRowOffset), | 2249 m_srcRowOffset(srcRowOffset), |
| 2246 m_dstStride(dstStride), | 2250 m_dstStride(dstStride), |
| 2247 m_success(false) { | 2251 m_success(false) { |
| 2248 const unsigned MaxNumberOfComponents = 4; | 2252 const unsigned MaxNumberOfComponents = 4; |
| 2249 const unsigned MaxBytesPerComponent = 4; | 2253 const unsigned MaxBytesPerComponent = 4; |
| 2250 m_unpackedIntermediateSrcData = wrapArrayUnique( | 2254 m_unpackedIntermediateSrcData = wrapArrayUnique( |
| 2251 new uint8_t[m_srcSubRectangle.width() * MaxNumberOfComponents * | 2255 new uint8_t[m_srcSubRectangle.width() * MaxNumberOfComponents * |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2266 template <WebGLImageConversion::DataFormat SrcFormat, | 2270 template <WebGLImageConversion::DataFormat SrcFormat, |
| 2267 WebGLImageConversion::DataFormat DstFormat> | 2271 WebGLImageConversion::DataFormat DstFormat> |
| 2268 void convert(WebGLImageConversion::AlphaOp); | 2272 void convert(WebGLImageConversion::AlphaOp); |
| 2269 | 2273 |
| 2270 template <WebGLImageConversion::DataFormat SrcFormat, | 2274 template <WebGLImageConversion::DataFormat SrcFormat, |
| 2271 WebGLImageConversion::DataFormat DstFormat, | 2275 WebGLImageConversion::DataFormat DstFormat, |
| 2272 WebGLImageConversion::AlphaOp alphaOp> | 2276 WebGLImageConversion::AlphaOp alphaOp> |
| 2273 void convert(); | 2277 void convert(); |
| 2274 | 2278 |
| 2275 const IntRect& m_srcSubRectangle; | 2279 const IntRect& m_srcSubRectangle; |
| 2280 const int m_depth; |
| 2281 const int m_unpackImageHeight; |
| 2276 const void* const m_srcStart; | 2282 const void* const m_srcStart; |
| 2277 void* const m_dstStart; | 2283 void* const m_dstStart; |
| 2278 const int m_srcStride, m_srcRowOffset, m_dstStride; | 2284 const int m_srcStride, m_srcRowOffset, m_dstStride; |
| 2279 bool m_success; | 2285 bool m_success; |
| 2280 std::unique_ptr<uint8_t[]> m_unpackedIntermediateSrcData; | 2286 std::unique_ptr<uint8_t[]> m_unpackedIntermediateSrcData; |
| 2281 }; | 2287 }; |
| 2282 | 2288 |
| 2283 void FormatConverter::convert(WebGLImageConversion::DataFormat srcFormat, | 2289 void FormatConverter::convert(WebGLImageConversion::DataFormat srcFormat, |
| 2284 WebGLImageConversion::DataFormat dstFormat, | 2290 WebGLImageConversion::DataFormat dstFormat, |
| 2285 WebGLImageConversion::AlphaOp alphaOp) { | 2291 WebGLImageConversion::AlphaOp alphaOp) { |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2450 const ptrdiff_t dstStrideInElements = m_dstStride / sizeof(DstType); | 2456 const ptrdiff_t dstStrideInElements = m_dstStride / sizeof(DstType); |
| 2451 const bool trivialUnpack = SrcFormat == IntermFormat; | 2457 const bool trivialUnpack = SrcFormat == IntermFormat; |
| 2452 const bool trivialPack = DstFormat == IntermFormat && | 2458 const bool trivialPack = DstFormat == IntermFormat && |
| 2453 alphaOp == WebGLImageConversion::AlphaDoNothing; | 2459 alphaOp == WebGLImageConversion::AlphaDoNothing; |
| 2454 ASSERT(!trivialUnpack || !trivialPack); | 2460 ASSERT(!trivialUnpack || !trivialPack); |
| 2455 | 2461 |
| 2456 const SrcType* srcRowStart = | 2462 const SrcType* srcRowStart = |
| 2457 static_cast<const SrcType*>(static_cast<const void*>( | 2463 static_cast<const SrcType*>(static_cast<const void*>( |
| 2458 static_cast<const uint8_t*>(m_srcStart) + | 2464 static_cast<const uint8_t*>(m_srcStart) + |
| 2459 ((m_srcStride * m_srcSubRectangle.y()) + m_srcRowOffset))); | 2465 ((m_srcStride * m_srcSubRectangle.y()) + m_srcRowOffset))); |
| 2466 |
| 2467 // If packing multiple images into a 3D texture, and flipY is true, |
| 2468 // then the sub-rectangle is pointing at the start of the |
| 2469 // "bottommost" of those images. Since the source pointer strides in |
| 2470 // the positive direction, we need to back it up to point at the |
| 2471 // last, or "topmost", of these images. |
| 2472 if (m_dstStride < 0 && m_depth > 1) { |
| 2473 srcRowStart -= (m_depth - 1) * srcStrideInElements * m_unpackImageHeight; |
| 2474 } |
| 2475 |
| 2460 DstType* dstRowStart = static_cast<DstType*>(m_dstStart); | 2476 DstType* dstRowStart = static_cast<DstType*>(m_dstStart); |
| 2461 if (trivialUnpack) { | 2477 if (trivialUnpack) { |
| 2462 for (int i = 0; i < m_srcSubRectangle.height(); ++i) { | 2478 for (int d = 0; d < m_depth; ++d) { |
| 2463 pack<DstFormat, alphaOp>(srcRowStart, dstRowStart, | 2479 for (int i = 0; i < m_srcSubRectangle.height(); ++i) { |
| 2464 m_srcSubRectangle.width()); | 2480 pack<DstFormat, alphaOp>(srcRowStart, dstRowStart, |
| 2465 srcRowStart += srcStrideInElements; | 2481 m_srcSubRectangle.width()); |
| 2466 dstRowStart += dstStrideInElements; | 2482 srcRowStart += srcStrideInElements; |
| 2483 dstRowStart += dstStrideInElements; |
| 2484 } |
| 2485 srcRowStart += srcStrideInElements * |
| 2486 (m_unpackImageHeight - m_srcSubRectangle.height()); |
| 2467 } | 2487 } |
| 2468 } else if (trivialPack) { | 2488 } else if (trivialPack) { |
| 2469 for (int i = 0; i < m_srcSubRectangle.height(); ++i) { | 2489 for (int d = 0; d < m_depth; ++d) { |
| 2470 unpack<SrcFormat>(srcRowStart, dstRowStart, m_srcSubRectangle.width()); | 2490 for (int i = 0; i < m_srcSubRectangle.height(); ++i) { |
| 2471 srcRowStart += srcStrideInElements; | 2491 unpack<SrcFormat>(srcRowStart, dstRowStart, m_srcSubRectangle.width()); |
| 2472 dstRowStart += dstStrideInElements; | 2492 srcRowStart += srcStrideInElements; |
| 2493 dstRowStart += dstStrideInElements; |
| 2494 } |
| 2495 srcRowStart += srcStrideInElements * |
| 2496 (m_unpackImageHeight - m_srcSubRectangle.height()); |
| 2473 } | 2497 } |
| 2474 } else { | 2498 } else { |
| 2475 for (int i = 0; i < m_srcSubRectangle.height(); ++i) { | 2499 for (int d = 0; d < m_depth; ++d) { |
| 2476 unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermType*>( | 2500 for (int i = 0; i < m_srcSubRectangle.height(); ++i) { |
| 2477 m_unpackedIntermediateSrcData.get()), | 2501 unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermType*>( |
| 2478 m_srcSubRectangle.width()); | 2502 m_unpackedIntermediateSrcData.get()), |
| 2479 pack<DstFormat, alphaOp>( | 2503 m_srcSubRectangle.width()); |
| 2480 reinterpret_cast<IntermType*>(m_unpackedIntermediateSrcData.get()), | 2504 pack<DstFormat, alphaOp>( |
| 2481 dstRowStart, m_srcSubRectangle.width()); | 2505 reinterpret_cast<IntermType*>(m_unpackedIntermediateSrcData.get()), |
| 2482 srcRowStart += srcStrideInElements; | 2506 dstRowStart, m_srcSubRectangle.width()); |
| 2483 dstRowStart += dstStrideInElements; | 2507 srcRowStart += srcStrideInElements; |
| 2508 dstRowStart += dstStrideInElements; |
| 2509 } |
| 2510 srcRowStart += srcStrideInElements * |
| 2511 (m_unpackImageHeight - m_srcSubRectangle.height()); |
| 2484 } | 2512 } |
| 2485 } | 2513 } |
| 2486 m_success = true; | 2514 m_success = true; |
| 2487 return; | 2515 return; |
| 2488 } | 2516 } |
| 2489 | 2517 |
| 2490 bool frameIsValid(const SkBitmap& frameBitmap) { | 2518 bool frameIsValid(const SkBitmap& frameBitmap) { |
| 2491 return !frameBitmap.isNull() && !frameBitmap.empty() && | 2519 return !frameBitmap.isNull() && !frameBitmap.empty() && |
| 2492 frameBitmap.colorType() == kN32_SkColorType; | 2520 frameBitmap.colorType() == kN32_SkColorType; |
| 2493 } | 2521 } |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2862 bool WebGLImageConversion::packImageData(Image* image, | 2890 bool WebGLImageConversion::packImageData(Image* image, |
| 2863 const void* pixels, | 2891 const void* pixels, |
| 2864 GLenum format, | 2892 GLenum format, |
| 2865 GLenum type, | 2893 GLenum type, |
| 2866 bool flipY, | 2894 bool flipY, |
| 2867 AlphaOp alphaOp, | 2895 AlphaOp alphaOp, |
| 2868 DataFormat sourceFormat, | 2896 DataFormat sourceFormat, |
| 2869 unsigned sourceImageWidth, | 2897 unsigned sourceImageWidth, |
| 2870 unsigned sourceImageHeight, | 2898 unsigned sourceImageHeight, |
| 2871 const IntRect& sourceImageSubRectangle, | 2899 const IntRect& sourceImageSubRectangle, |
| 2900 int depth, |
| 2872 unsigned sourceUnpackAlignment, | 2901 unsigned sourceUnpackAlignment, |
| 2902 int unpackImageHeight, |
| 2873 Vector<uint8_t>& data) { | 2903 Vector<uint8_t>& data) { |
| 2874 if (!pixels) | 2904 if (!pixels) |
| 2875 return false; | 2905 return false; |
| 2876 | 2906 |
| 2877 unsigned packedSize; | 2907 unsigned packedSize; |
| 2878 // Output data is tightly packed (alignment == 1). | 2908 // Output data is tightly packed (alignment == 1). |
| 2879 PixelStoreParams params; | 2909 PixelStoreParams params; |
| 2880 params.alignment = 1; | 2910 params.alignment = 1; |
| 2881 if (computeImageSizeInBytes(format, type, sourceImageSubRectangle.width(), | 2911 if (computeImageSizeInBytes(format, type, sourceImageSubRectangle.width(), |
| 2882 sourceImageSubRectangle.height(), 1, params, | 2912 sourceImageSubRectangle.height(), depth, params, |
| 2883 &packedSize, 0, 0) != GL_NO_ERROR) | 2913 &packedSize, 0, 0) != GL_NO_ERROR) |
| 2884 return false; | 2914 return false; |
| 2885 data.resize(packedSize); | 2915 data.resize(packedSize); |
| 2886 | 2916 |
| 2887 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, | 2917 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, |
| 2888 sourceImageWidth, sourceImageHeight, sourceImageSubRectangle, | 2918 sourceImageWidth, sourceImageHeight, sourceImageSubRectangle, |
| 2889 sourceUnpackAlignment, format, type, alphaOp, data.data(), | 2919 depth, sourceUnpackAlignment, unpackImageHeight, format, type, |
| 2890 flipY)) | 2920 alphaOp, data.data(), flipY)) |
| 2891 return false; | 2921 return false; |
| 2892 if (ImageObserver* observer = image->getImageObserver()) | 2922 if (ImageObserver* observer = image->getImageObserver()) |
| 2893 observer->didDraw(image); | 2923 observer->didDraw(image); |
| 2894 return true; | 2924 return true; |
| 2895 } | 2925 } |
| 2896 | 2926 |
| 2897 bool WebGLImageConversion::extractImageData(const uint8_t* imageData, | 2927 bool WebGLImageConversion::extractImageData( |
| 2898 DataFormat sourceDataFormat, | 2928 const uint8_t* imageData, |
| 2899 const IntSize& imageDataSize, | 2929 DataFormat sourceDataFormat, |
| 2900 const IntRect& sourceImageSubRect, | 2930 const IntSize& imageDataSize, |
| 2901 GLenum format, | 2931 const IntRect& sourceImageSubRectangle, |
| 2902 GLenum type, | 2932 int depth, |
| 2903 bool flipY, | 2933 int unpackImageHeight, |
| 2904 bool premultiplyAlpha, | 2934 GLenum format, |
| 2905 Vector<uint8_t>& data) { | 2935 GLenum type, |
| 2936 bool flipY, |
| 2937 bool premultiplyAlpha, |
| 2938 Vector<uint8_t>& data) { |
| 2906 if (!imageData) | 2939 if (!imageData) |
| 2907 return false; | 2940 return false; |
| 2908 int width = imageDataSize.width(); | 2941 int width = imageDataSize.width(); |
| 2909 int height = imageDataSize.height(); | 2942 int height = imageDataSize.height(); |
| 2910 | 2943 |
| 2911 unsigned packedSize; | 2944 unsigned packedSize; |
| 2912 // Output data is tightly packed (alignment == 1). | 2945 // Output data is tightly packed (alignment == 1). |
| 2913 PixelStoreParams params; | 2946 PixelStoreParams params; |
| 2914 params.alignment = 1; | 2947 params.alignment = 1; |
| 2915 if (computeImageSizeInBytes(format, type, sourceImageSubRect.width(), | 2948 if (computeImageSizeInBytes(format, type, sourceImageSubRectangle.width(), |
| 2916 sourceImageSubRect.height(), 1, params, | 2949 sourceImageSubRectangle.height(), depth, params, |
| 2917 &packedSize, 0, 0) != GL_NO_ERROR) | 2950 &packedSize, 0, 0) != GL_NO_ERROR) |
| 2918 return false; | 2951 return false; |
| 2919 data.resize(packedSize); | 2952 data.resize(packedSize); |
| 2920 | 2953 |
| 2921 if (!packPixels(imageData, sourceDataFormat, width, height, | 2954 if (!packPixels(imageData, sourceDataFormat, width, height, |
| 2922 sourceImageSubRect, 0, format, type, | 2955 sourceImageSubRectangle, depth, 0, unpackImageHeight, format, |
| 2923 premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, | 2956 type, premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, |
| 2924 data.data(), flipY)) | 2957 data.data(), flipY)) |
| 2925 return false; | 2958 return false; |
| 2926 | 2959 |
| 2927 return true; | 2960 return true; |
| 2928 } | 2961 } |
| 2929 | 2962 |
| 2930 bool WebGLImageConversion::extractTextureData(unsigned width, | 2963 bool WebGLImageConversion::extractTextureData(unsigned width, |
| 2931 unsigned height, | 2964 unsigned height, |
| 2932 GLenum format, | 2965 GLenum format, |
| 2933 GLenum type, | 2966 GLenum type, |
| 2934 unsigned unpackAlignment, | 2967 unsigned unpackAlignment, |
| 2935 bool flipY, | 2968 bool flipY, |
| 2936 bool premultiplyAlpha, | 2969 bool premultiplyAlpha, |
| 2937 const void* pixels, | 2970 const void* pixels, |
| 2938 Vector<uint8_t>& data) { | 2971 Vector<uint8_t>& data) { |
| 2939 // Assumes format, type, etc. have already been validated. | 2972 // Assumes format, type, etc. have already been validated. |
| 2940 DataFormat sourceDataFormat = getDataFormat(format, type); | 2973 DataFormat sourceDataFormat = getDataFormat(format, type); |
| 2941 | 2974 |
| 2942 // Resize the output buffer. | 2975 // Resize the output buffer. |
| 2943 unsigned int componentsPerPixel, bytesPerComponent; | 2976 unsigned int componentsPerPixel, bytesPerComponent; |
| 2944 if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, | 2977 if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, |
| 2945 &bytesPerComponent)) | 2978 &bytesPerComponent)) |
| 2946 return false; | 2979 return false; |
| 2947 unsigned bytesPerPixel = componentsPerPixel * bytesPerComponent; | 2980 unsigned bytesPerPixel = componentsPerPixel * bytesPerComponent; |
| 2948 data.resize(width * height * bytesPerPixel); | 2981 data.resize(width * height * bytesPerPixel); |
| 2949 | 2982 |
| 2950 if (!packPixels(static_cast<const uint8_t*>(pixels), sourceDataFormat, width, | 2983 if (!packPixels(static_cast<const uint8_t*>(pixels), sourceDataFormat, width, |
| 2951 height, IntRect(0, 0, width, height), unpackAlignment, format, | 2984 height, IntRect(0, 0, width, height), 1, unpackAlignment, 0, |
| 2952 type, | 2985 format, type, |
| 2953 (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing), | 2986 (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing), |
| 2954 data.data(), flipY)) | 2987 data.data(), flipY)) |
| 2955 return false; | 2988 return false; |
| 2956 | 2989 |
| 2957 return true; | 2990 return true; |
| 2958 } | 2991 } |
| 2959 | 2992 |
| 2960 bool WebGLImageConversion::packPixels(const uint8_t* sourceData, | 2993 bool WebGLImageConversion::packPixels(const uint8_t* sourceData, |
| 2961 DataFormat sourceDataFormat, | 2994 DataFormat sourceDataFormat, |
| 2962 unsigned sourceDataWidth, | 2995 unsigned sourceDataWidth, |
| 2963 unsigned sourceDataHeight, | 2996 unsigned sourceDataHeight, |
| 2964 const IntRect& sourceDataSubRectangle, | 2997 const IntRect& sourceDataSubRectangle, |
| 2998 int depth, |
| 2965 unsigned sourceUnpackAlignment, | 2999 unsigned sourceUnpackAlignment, |
| 3000 int unpackImageHeight, |
| 2966 unsigned destinationFormat, | 3001 unsigned destinationFormat, |
| 2967 unsigned destinationType, | 3002 unsigned destinationType, |
| 2968 AlphaOp alphaOp, | 3003 AlphaOp alphaOp, |
| 2969 void* destinationData, | 3004 void* destinationData, |
| 2970 bool flipY) { | 3005 bool flipY) { |
| 3006 DCHECK_GE(depth, 1); |
| 3007 if (unpackImageHeight == 0) { |
| 3008 unpackImageHeight = sourceDataSubRectangle.height(); |
| 3009 } |
| 2971 int validSrc = sourceDataWidth * TexelBytesForFormat(sourceDataFormat); | 3010 int validSrc = sourceDataWidth * TexelBytesForFormat(sourceDataFormat); |
| 2972 int remainder = | 3011 int remainder = |
| 2973 sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0; | 3012 sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0; |
| 2974 int srcStride = | 3013 int srcStride = |
| 2975 remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc; | 3014 remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc; |
| 2976 int srcRowOffset = | 3015 int srcRowOffset = |
| 2977 sourceDataSubRectangle.x() * TexelBytesForFormat(sourceDataFormat); | 3016 sourceDataSubRectangle.x() * TexelBytesForFormat(sourceDataFormat); |
| 2978 | 3017 |
| 2979 DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType); | 3018 DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType); |
| 2980 int dstStride = | 3019 int dstStride = |
| 2981 sourceDataSubRectangle.width() * TexelBytesForFormat(dstDataFormat); | 3020 sourceDataSubRectangle.width() * TexelBytesForFormat(dstDataFormat); |
| 2982 if (flipY) { | 3021 if (flipY) { |
| 2983 destinationData = static_cast<uint8_t*>(destinationData) + | 3022 destinationData = |
| 2984 dstStride * (sourceDataSubRectangle.height() - 1); | 3023 static_cast<uint8_t*>(destinationData) + |
| 3024 dstStride * ((depth * sourceDataSubRectangle.height()) - 1); |
| 2985 dstStride = -dstStride; | 3025 dstStride = -dstStride; |
| 2986 } | 3026 } |
| 2987 if (!HasAlpha(sourceDataFormat) || !HasColor(sourceDataFormat) || | 3027 if (!HasAlpha(sourceDataFormat) || !HasColor(sourceDataFormat) || |
| 2988 !HasColor(dstDataFormat)) | 3028 !HasColor(dstDataFormat)) |
| 2989 alphaOp = AlphaDoNothing; | 3029 alphaOp = AlphaDoNothing; |
| 2990 | 3030 |
| 2991 if (sourceDataFormat == dstDataFormat && alphaOp == AlphaDoNothing) { | 3031 if (sourceDataFormat == dstDataFormat && alphaOp == AlphaDoNothing) { |
| 2992 const uint8_t* ptr = sourceData + srcStride * sourceDataSubRectangle.y(); | 3032 const uint8_t* basePtr = |
| 2993 const uint8_t* ptrEnd = | 3033 sourceData + srcStride * sourceDataSubRectangle.y(); |
| 3034 const uint8_t* baseEnd = |
| 2994 sourceData + srcStride * sourceDataSubRectangle.maxY(); | 3035 sourceData + srcStride * sourceDataSubRectangle.maxY(); |
| 3036 |
| 3037 // If packing multiple images into a 3D texture, and flipY is true, |
| 3038 // then the sub-rectangle is pointing at the start of the |
| 3039 // "bottommost" of those images. Since the source pointer strides in |
| 3040 // the positive direction, we need to back it up to point at the |
| 3041 // last, or "topmost", of these images. |
| 3042 if (flipY && depth > 1) { |
| 3043 const ptrdiff_t distanceToTopImage = |
| 3044 (depth - 1) * srcStride * unpackImageHeight; |
| 3045 basePtr -= distanceToTopImage; |
| 3046 baseEnd -= distanceToTopImage; |
| 3047 } |
| 3048 |
| 2995 unsigned rowSize = (dstStride > 0) ? dstStride : -dstStride; | 3049 unsigned rowSize = (dstStride > 0) ? dstStride : -dstStride; |
| 2996 uint8_t* dst = static_cast<uint8_t*>(destinationData); | 3050 uint8_t* dst = static_cast<uint8_t*>(destinationData); |
| 2997 while (ptr < ptrEnd) { | 3051 |
| 2998 memcpy(dst, ptr + srcRowOffset, rowSize); | 3052 for (int i = 0; i < depth; ++i) { |
| 2999 ptr += srcStride; | 3053 const uint8_t* ptr = basePtr; |
| 3000 dst += dstStride; | 3054 const uint8_t* ptrEnd = baseEnd; |
| 3055 while (ptr < ptrEnd) { |
| 3056 memcpy(dst, ptr + srcRowOffset, rowSize); |
| 3057 ptr += srcStride; |
| 3058 dst += dstStride; |
| 3059 } |
| 3060 basePtr += unpackImageHeight * srcStride; |
| 3061 baseEnd += unpackImageHeight * srcStride; |
| 3001 } | 3062 } |
| 3002 return true; | 3063 return true; |
| 3003 } | 3064 } |
| 3004 | 3065 |
| 3005 FormatConverter converter(sourceDataSubRectangle, sourceData, destinationData, | 3066 FormatConverter converter(sourceDataSubRectangle, depth, unpackImageHeight, |
| 3006 srcStride, srcRowOffset, dstStride); | 3067 sourceData, destinationData, srcStride, |
| 3068 srcRowOffset, dstStride); |
| 3007 converter.convert(sourceDataFormat, dstDataFormat, alphaOp); | 3069 converter.convert(sourceDataFormat, dstDataFormat, alphaOp); |
| 3008 if (!converter.Success()) | 3070 if (!converter.Success()) |
| 3009 return false; | 3071 return false; |
| 3010 return true; | 3072 return true; |
| 3011 } | 3073 } |
| 3012 | 3074 |
| 3013 void WebGLImageConversion::unpackPixels(const uint16_t* sourceData, | 3075 void WebGLImageConversion::unpackPixels(const uint16_t* sourceData, |
| 3014 DataFormat sourceDataFormat, | 3076 DataFormat sourceDataFormat, |
| 3015 unsigned pixelsPerRow, | 3077 unsigned pixelsPerRow, |
| 3016 uint8_t* destinationData) { | 3078 uint8_t* destinationData) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3106 pack<WebGLImageConversion::DataFormatRGB565, | 3168 pack<WebGLImageConversion::DataFormatRGB565, |
| 3107 WebGLImageConversion::AlphaDoNothing>(srcRowStart, dstRowStart, | 3169 WebGLImageConversion::AlphaDoNothing>(srcRowStart, dstRowStart, |
| 3108 pixelsPerRow); | 3170 pixelsPerRow); |
| 3109 } break; | 3171 } break; |
| 3110 default: | 3172 default: |
| 3111 break; | 3173 break; |
| 3112 } | 3174 } |
| 3113 } | 3175 } |
| 3114 | 3176 |
| 3115 } // namespace blink | 3177 } // namespace blink |
| OLD | NEW |