content/canvas/src/WebGLTexelConversions.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "WebGLContext.h"
michael@0 6 #include "WebGLTexelConversions.h"
michael@0 7
michael@0 8 namespace mozilla {
michael@0 9
michael@0 10 using namespace WebGLTexelConversions;
michael@0 11
michael@0 12 namespace {
michael@0 13
michael@0 14 /** @class WebGLImageConverter
michael@0 15 *
michael@0 16 * This class is just a helper to implement WebGLContext::ConvertImage below.
michael@0 17 *
michael@0 18 * Design comments:
michael@0 19 *
michael@0 20 * WebGLContext::ConvertImage has to handle hundreds of format conversion paths.
michael@0 21 * It is important to minimize executable code size here. Instead of passing around
michael@0 22 * a large number of function parameters hundreds of times, we create a
michael@0 23 * WebGLImageConverter object once, storing these parameters, and then we call
michael@0 24 * the run() method on it.
michael@0 25 */
michael@0 26 class WebGLImageConverter
michael@0 27 {
michael@0 28 const size_t mWidth, mHeight;
michael@0 29 const void* const mSrcStart;
michael@0 30 void* const mDstStart;
michael@0 31 const ptrdiff_t mSrcStride, mDstStride;
michael@0 32 bool mAlreadyRun;
michael@0 33 bool mSuccess;
michael@0 34
michael@0 35 /*
michael@0 36 * Returns sizeof(texel)/sizeof(type). The point is that we will iterate over
michael@0 37 * texels with typed pointers and this value will tell us by how much we need
michael@0 38 * to increment these pointers to advance to the next texel.
michael@0 39 */
michael@0 40 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
michael@0 41 static size_t NumElementsPerTexelForFormat() {
michael@0 42 switch (Format) {
michael@0 43 case WebGLTexelFormat::R8:
michael@0 44 case WebGLTexelFormat::A8:
michael@0 45 case WebGLTexelFormat::R16F:
michael@0 46 case WebGLTexelFormat::A16F:
michael@0 47 case WebGLTexelFormat::R32F:
michael@0 48 case WebGLTexelFormat::A32F:
michael@0 49 case WebGLTexelFormat::RGBA5551:
michael@0 50 case WebGLTexelFormat::RGBA4444:
michael@0 51 case WebGLTexelFormat::RGB565:
michael@0 52 return 1;
michael@0 53 case WebGLTexelFormat::RA8:
michael@0 54 case WebGLTexelFormat::RA16F:
michael@0 55 case WebGLTexelFormat::RA32F:
michael@0 56 return 2;
michael@0 57 case WebGLTexelFormat::RGB8:
michael@0 58 case WebGLTexelFormat::RGB16F:
michael@0 59 case WebGLTexelFormat::RGB32F:
michael@0 60 return 3;
michael@0 61 case WebGLTexelFormat::RGBA8:
michael@0 62 case WebGLTexelFormat::BGRA8:
michael@0 63 case WebGLTexelFormat::BGRX8:
michael@0 64 case WebGLTexelFormat::RGBA16F:
michael@0 65 case WebGLTexelFormat::RGBA32F:
michael@0 66 return 4;
michael@0 67 default:
michael@0 68 MOZ_ASSERT(false, "Unknown texel format. Coding mistake?");
michael@0 69 return 0;
michael@0 70 }
michael@0 71 }
michael@0 72
michael@0 73 /*
michael@0 74 * This is the completely format-specific templatized conversion function,
michael@0 75 * that will be instantiated hundreds of times for all different combinations.
michael@0 76 * It is important to avoid generating useless code here. In particular, many
michael@0 77 * instantiations of this function template will never be called, so we try
michael@0 78 * to return immediately in these cases to allow the compiler to avoid generating
michael@0 79 * useless code.
michael@0 80 */
michael@0 81 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) SrcFormat,
michael@0 82 MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) DstFormat,
michael@0 83 MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelPremultiplicationOp) PremultiplicationOp>
michael@0 84 void run()
michael@0 85 {
michael@0 86 // check for never-called cases. We early-return to allow the compiler
michael@0 87 // to avoid generating this code. It would be tempting to abort() instead,
michael@0 88 // as returning early does leave the destination surface with uninitialized
michael@0 89 // data, but that would not allow the compiler to avoid generating this code.
michael@0 90 // So instead, we return early, so Success() will return false, and the caller
michael@0 91 // must check that and abort in that case. See WebGLContext::ConvertImage.
michael@0 92
michael@0 93 if (SrcFormat == DstFormat &&
michael@0 94 PremultiplicationOp == WebGLTexelPremultiplicationOp::None)
michael@0 95 {
michael@0 96 // Should have used a fast exit path earlier, rather than entering this function.
michael@0 97 // we explicitly return here to allow the compiler to avoid generating this code
michael@0 98 return;
michael@0 99 }
michael@0 100
michael@0 101 // Only textures uploaded from DOM elements or ImageData can allow DstFormat != SrcFormat.
michael@0 102 // DOM elements can only give BGRA8, BGRX8, A8, RGB565 formats. See DOMElementToImageSurface.
michael@0 103 // ImageData is always RGBA8. So all other SrcFormat will always satisfy DstFormat==SrcFormat,
michael@0 104 // so we can avoid compiling the code for all the unreachable paths.
michael@0 105 const bool CanSrcFormatComeFromDOMElementOrImageData
michael@0 106 = SrcFormat == WebGLTexelFormat::BGRA8 ||
michael@0 107 SrcFormat == WebGLTexelFormat::BGRX8 ||
michael@0 108 SrcFormat == WebGLTexelFormat::A8 ||
michael@0 109 SrcFormat == WebGLTexelFormat::RGB565 ||
michael@0 110 SrcFormat == WebGLTexelFormat::RGBA8;
michael@0 111 if (!CanSrcFormatComeFromDOMElementOrImageData &&
michael@0 112 SrcFormat != DstFormat)
michael@0 113 {
michael@0 114 return;
michael@0 115 }
michael@0 116
michael@0 117 // Likewise, only textures uploaded from DOM elements or ImageData can possibly have to be unpremultiplied.
michael@0 118 if (!CanSrcFormatComeFromDOMElementOrImageData &&
michael@0 119 PremultiplicationOp == WebGLTexelPremultiplicationOp::Unpremultiply)
michael@0 120 {
michael@0 121 return;
michael@0 122 }
michael@0 123
michael@0 124 // there is no point in premultiplication/unpremultiplication
michael@0 125 // in the following cases:
michael@0 126 // - the source format has no alpha
michael@0 127 // - the source format has no color
michael@0 128 // - the destination format has no color
michael@0 129 if (!HasAlpha(SrcFormat) ||
michael@0 130 !HasColor(SrcFormat) ||
michael@0 131 !HasColor(DstFormat))
michael@0 132 {
michael@0 133
michael@0 134 if (PremultiplicationOp != WebGLTexelPremultiplicationOp::None)
michael@0 135 {
michael@0 136 return;
michael@0 137 }
michael@0 138 }
michael@0 139
michael@0 140 // end of early return cases.
michael@0 141
michael@0 142 MOZ_ASSERT(!mAlreadyRun, "converter should be run only once!");
michael@0 143 mAlreadyRun = true;
michael@0 144
michael@0 145 // gather some compile-time meta-data about the formats at hand.
michael@0 146
michael@0 147 typedef
michael@0 148 typename DataTypeForFormat<SrcFormat>::Type
michael@0 149 SrcType;
michael@0 150 typedef
michael@0 151 typename DataTypeForFormat<DstFormat>::Type
michael@0 152 DstType;
michael@0 153
michael@0 154 const MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) IntermediateSrcFormat
michael@0 155 = IntermediateFormat<SrcFormat>::Value;
michael@0 156 const MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) IntermediateDstFormat
michael@0 157 = IntermediateFormat<DstFormat>::Value;
michael@0 158 typedef
michael@0 159 typename DataTypeForFormat<IntermediateSrcFormat>::Type
michael@0 160 IntermediateSrcType;
michael@0 161 typedef
michael@0 162 typename DataTypeForFormat<IntermediateDstFormat>::Type
michael@0 163 IntermediateDstType;
michael@0 164
michael@0 165 const size_t NumElementsPerSrcTexel = NumElementsPerTexelForFormat<SrcFormat>();
michael@0 166 const size_t NumElementsPerDstTexel = NumElementsPerTexelForFormat<DstFormat>();
michael@0 167 const size_t MaxElementsPerTexel = 4;
michael@0 168 MOZ_ASSERT(NumElementsPerSrcTexel <= MaxElementsPerTexel, "unhandled format");
michael@0 169 MOZ_ASSERT(NumElementsPerDstTexel <= MaxElementsPerTexel, "unhandled format");
michael@0 170
michael@0 171 // we assume that the strides are multiples of the sizeof of respective types.
michael@0 172 // this assumption will allow us to iterate over src and dst images using typed
michael@0 173 // pointers, e.g. uint8_t* or uint16_t* or float*, instead of untyped pointers.
michael@0 174 // So this assumption allows us to write cleaner and safer code, but it might
michael@0 175 // not be true forever and if it eventually becomes wrong, we'll have to revert
michael@0 176 // to always iterating using uint8_t* pointers regardless of the types at hand.
michael@0 177 MOZ_ASSERT(mSrcStride % sizeof(SrcType) == 0 &&
michael@0 178 mDstStride % sizeof(DstType) == 0,
michael@0 179 "Unsupported: texture stride is not a multiple of sizeof(type)");
michael@0 180 const ptrdiff_t srcStrideInElements = mSrcStride / sizeof(SrcType);
michael@0 181 const ptrdiff_t dstStrideInElements = mDstStride / sizeof(DstType);
michael@0 182
michael@0 183 const SrcType *srcRowStart = static_cast<const SrcType*>(mSrcStart);
michael@0 184 DstType *dstRowStart = static_cast<DstType*>(mDstStart);
michael@0 185
michael@0 186 // the loop performing the texture format conversion
michael@0 187 for (size_t i = 0; i < mHeight; ++i) {
michael@0 188 const SrcType *srcRowEnd = srcRowStart + mWidth * NumElementsPerSrcTexel;
michael@0 189 const SrcType *srcPtr = srcRowStart;
michael@0 190 DstType *dstPtr = dstRowStart;
michael@0 191 while (srcPtr != srcRowEnd) {
michael@0 192 // convert a single texel. We proceed in 3 steps: unpack the source texel
michael@0 193 // so the corresponding interchange format (e.g. unpack RGB565 to RGBA8),
michael@0 194 // convert the resulting data type to the destination type (e.g. convert
michael@0 195 // from RGBA8 to RGBA32F), and finally pack the destination texel
michael@0 196 // (e.g. pack RGBA32F to RGB32F).
michael@0 197 IntermediateSrcType unpackedSrc[MaxElementsPerTexel];
michael@0 198 IntermediateDstType unpackedDst[MaxElementsPerTexel];
michael@0 199
michael@0 200 // unpack a src texel to corresponding intermediate src format.
michael@0 201 // for example, unpack RGB565 to RGBA8
michael@0 202 unpack<SrcFormat>(srcPtr, unpackedSrc);
michael@0 203 // convert the data type to the destination type, if needed.
michael@0 204 // for example, convert RGBA8 to RGBA32F
michael@0 205 convertType(unpackedSrc, unpackedDst);
michael@0 206 // pack the destination texel.
michael@0 207 // for example, pack RGBA32F to RGB32F
michael@0 208 pack<DstFormat, PremultiplicationOp>(unpackedDst, dstPtr);
michael@0 209
michael@0 210 srcPtr += NumElementsPerSrcTexel;
michael@0 211 dstPtr += NumElementsPerDstTexel;
michael@0 212 }
michael@0 213 srcRowStart += srcStrideInElements;
michael@0 214 dstRowStart += dstStrideInElements;
michael@0 215 }
michael@0 216
michael@0 217 mSuccess = true;
michael@0 218 return;
michael@0 219 }
michael@0 220
michael@0 221 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) SrcFormat,
michael@0 222 MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) DstFormat>
michael@0 223 void run(WebGLTexelPremultiplicationOp premultiplicationOp)
michael@0 224 {
michael@0 225 #define WEBGLIMAGECONVERTER_CASE_PREMULTIPLICATIONOP(PremultiplicationOp) \
michael@0 226 case PremultiplicationOp: \
michael@0 227 return run<SrcFormat, DstFormat, PremultiplicationOp>();
michael@0 228
michael@0 229 switch (premultiplicationOp) {
michael@0 230 WEBGLIMAGECONVERTER_CASE_PREMULTIPLICATIONOP(WebGLTexelPremultiplicationOp::None)
michael@0 231 WEBGLIMAGECONVERTER_CASE_PREMULTIPLICATIONOP(WebGLTexelPremultiplicationOp::Premultiply)
michael@0 232 WEBGLIMAGECONVERTER_CASE_PREMULTIPLICATIONOP(WebGLTexelPremultiplicationOp::Unpremultiply)
michael@0 233 default:
michael@0 234 MOZ_ASSERT(false, "unhandled case. Coding mistake?");
michael@0 235 }
michael@0 236
michael@0 237 #undef WEBGLIMAGECONVERTER_CASE_PREMULTIPLICATIONOP
michael@0 238 }
michael@0 239
michael@0 240 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) SrcFormat>
michael@0 241 void run(WebGLTexelFormat dstFormat,
michael@0 242 WebGLTexelPremultiplicationOp premultiplicationOp)
michael@0 243 {
michael@0 244 #define WEBGLIMAGECONVERTER_CASE_DSTFORMAT(DstFormat) \
michael@0 245 case DstFormat: \
michael@0 246 return run<SrcFormat, DstFormat>(premultiplicationOp);
michael@0 247
michael@0 248 switch (dstFormat) {
michael@0 249 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::R8)
michael@0 250 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::A8)
michael@0 251 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::R16F)
michael@0 252 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::A16F)
michael@0 253 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::R32F)
michael@0 254 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::A32F)
michael@0 255 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::RA8)
michael@0 256 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::RA16F)
michael@0 257 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::RA32F)
michael@0 258 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::RGB8)
michael@0 259 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::RGB565)
michael@0 260 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::RGB16F)
michael@0 261 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::RGB32F)
michael@0 262 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::RGBA8)
michael@0 263 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::RGBA5551)
michael@0 264 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::RGBA4444)
michael@0 265 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::RGBA16F)
michael@0 266 WEBGLIMAGECONVERTER_CASE_DSTFORMAT(WebGLTexelFormat::RGBA32F)
michael@0 267 default:
michael@0 268 MOZ_ASSERT(false, "unhandled case. Coding mistake?");
michael@0 269 }
michael@0 270
michael@0 271 #undef WEBGLIMAGECONVERTER_CASE_DSTFORMAT
michael@0 272 }
michael@0 273
michael@0 274 public:
michael@0 275
michael@0 276 void run(WebGLTexelFormat srcFormat,
michael@0 277 WebGLTexelFormat dstFormat,
michael@0 278 WebGLTexelPremultiplicationOp premultiplicationOp)
michael@0 279 {
michael@0 280 #define WEBGLIMAGECONVERTER_CASE_SRCFORMAT(SrcFormat) \
michael@0 281 case SrcFormat: \
michael@0 282 return run<SrcFormat>(dstFormat, premultiplicationOp);
michael@0 283
michael@0 284 switch (srcFormat) {
michael@0 285 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::R8)
michael@0 286 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::A8)
michael@0 287 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::R16F)
michael@0 288 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::A16F)
michael@0 289 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::R32F)
michael@0 290 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::A32F)
michael@0 291 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::RA8)
michael@0 292 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::RA16F)
michael@0 293 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::RA32F)
michael@0 294 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::RGB8)
michael@0 295 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::BGRX8) // source format only
michael@0 296 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::RGB565)
michael@0 297 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::RGB16F)
michael@0 298 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::RGB32F)
michael@0 299 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::RGBA8)
michael@0 300 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::BGRA8)
michael@0 301 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::RGBA5551)
michael@0 302 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::RGBA4444)
michael@0 303 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::RGBA16F)
michael@0 304 WEBGLIMAGECONVERTER_CASE_SRCFORMAT(WebGLTexelFormat::RGBA32F)
michael@0 305 default:
michael@0 306 MOZ_ASSERT(false, "unhandled case. Coding mistake?");
michael@0 307 }
michael@0 308
michael@0 309 #undef WEBGLIMAGECONVERTER_CASE_SRCFORMAT
michael@0 310 }
michael@0 311
michael@0 312 WebGLImageConverter(size_t width, size_t height,
michael@0 313 const void* srcStart, void* dstStart,
michael@0 314 ptrdiff_t srcStride, ptrdiff_t dstStride)
michael@0 315 : mWidth(width), mHeight(height),
michael@0 316 mSrcStart(srcStart), mDstStart(dstStart),
michael@0 317 mSrcStride(srcStride), mDstStride(dstStride),
michael@0 318 mAlreadyRun(false), mSuccess(false)
michael@0 319 {}
michael@0 320
michael@0 321 bool Success() const {
michael@0 322 return mSuccess;
michael@0 323 }
michael@0 324 };
michael@0 325
michael@0 326 } // end anonymous namespace
michael@0 327
michael@0 328 void
michael@0 329 WebGLContext::ConvertImage(size_t width, size_t height, size_t srcStride, size_t dstStride,
michael@0 330 const uint8_t* src, uint8_t *dst,
michael@0 331 WebGLTexelFormat srcFormat, bool srcPremultiplied,
michael@0 332 WebGLTexelFormat dstFormat, bool dstPremultiplied,
michael@0 333 size_t dstTexelSize)
michael@0 334 {
michael@0 335 if (width <= 0 || height <= 0)
michael@0 336 return;
michael@0 337
michael@0 338 const bool FormatsRequireNoPremultiplicationOp =
michael@0 339 !HasAlpha(srcFormat) ||
michael@0 340 !HasColor(srcFormat) ||
michael@0 341 !HasColor(dstFormat);
michael@0 342
michael@0 343 if (srcFormat == dstFormat &&
michael@0 344 (FormatsRequireNoPremultiplicationOp || srcPremultiplied == dstPremultiplied))
michael@0 345 {
michael@0 346 // fast exit path: we just have to memcpy all the rows.
michael@0 347 //
michael@0 348 // The case where absolutely nothing needs to be done is supposed to have
michael@0 349 // been handled earlier (in TexImage2D_base, etc).
michael@0 350 //
michael@0 351 // So the case we're handling here is when even though no format conversion is needed,
michael@0 352 // we still might have to flip vertically and/or to adjust to a different stride.
michael@0 353
michael@0 354 MOZ_ASSERT(mPixelStoreFlipY || srcStride != dstStride, "Performance trap -- should handle this case earlier, to avoid memcpy");
michael@0 355
michael@0 356 size_t row_size = width * dstTexelSize; // doesn't matter, src and dst formats agree
michael@0 357 const uint8_t* ptr = src;
michael@0 358 const uint8_t* src_end = src + height * srcStride;
michael@0 359
michael@0 360 uint8_t* dst_row = mPixelStoreFlipY
michael@0 361 ? dst + (height-1) * dstStride
michael@0 362 : dst;
michael@0 363 ptrdiff_t dstStrideSigned(dstStride);
michael@0 364 ptrdiff_t dst_delta = mPixelStoreFlipY ? -dstStrideSigned : dstStrideSigned;
michael@0 365
michael@0 366 while(ptr != src_end) {
michael@0 367 memcpy(dst_row, ptr, row_size);
michael@0 368 ptr += srcStride;
michael@0 369 dst_row += dst_delta;
michael@0 370 }
michael@0 371 return;
michael@0 372 }
michael@0 373
michael@0 374 uint8_t* dstStart = dst;
michael@0 375 ptrdiff_t signedDstStride = dstStride;
michael@0 376 if (mPixelStoreFlipY) {
michael@0 377 dstStart = dst + (height - 1) * dstStride;
michael@0 378 signedDstStride = -signedDstStride;
michael@0 379 }
michael@0 380
michael@0 381 WebGLImageConverter converter(width, height, src, dstStart, srcStride, signedDstStride);
michael@0 382
michael@0 383 const WebGLTexelPremultiplicationOp premultiplicationOp
michael@0 384 = FormatsRequireNoPremultiplicationOp ? WebGLTexelPremultiplicationOp::None
michael@0 385 : (!srcPremultiplied && dstPremultiplied) ? WebGLTexelPremultiplicationOp::Premultiply
michael@0 386 : (srcPremultiplied && !dstPremultiplied) ? WebGLTexelPremultiplicationOp::Unpremultiply
michael@0 387 : WebGLTexelPremultiplicationOp::None;
michael@0 388
michael@0 389 converter.run(srcFormat, dstFormat, premultiplicationOp);
michael@0 390
michael@0 391 if (!converter.Success()) {
michael@0 392 // the dst image may be left uninitialized, so we better not try to
michael@0 393 // continue even in release builds. This should never happen anyway,
michael@0 394 // and would be a bug in our code.
michael@0 395 NS_RUNTIMEABORT("programming mistake in WebGL texture conversions");
michael@0 396 }
michael@0 397 }
michael@0 398
michael@0 399 } // end namespace mozilla

mercurial