1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_image_SurfacePipeFactory_h
8 #define mozilla_image_SurfacePipeFactory_h
10 #include "SurfacePipe.h"
11 #include "SurfaceFilters.h"
19 * FilterPipeline is a helper template for SurfacePipeFactory that determines
20 * the full type of the sequence of SurfaceFilters that a sequence of
21 * configuration structs corresponds to. To make this work, all configuration
22 * structs must include a typedef 'Filter' that identifies the SurfaceFilter
25 template <typename
... Configs
>
26 struct FilterPipeline
;
28 template <typename Config
, typename
... Configs
>
29 struct FilterPipeline
<Config
, Configs
...> {
30 typedef typename
Config::template Filter
<
31 typename FilterPipeline
<Configs
...>::Type
>
35 template <typename Config
>
36 struct FilterPipeline
<Config
> {
37 typedef typename
Config::Filter Type
;
43 * Flags for SurfacePipeFactory, used in conjunction with the factory functions
44 * in SurfacePipeFactory to enable or disable various SurfacePipe
47 enum class SurfacePipeFlags
{
48 DEINTERLACE
= 1 << 0, // If set, deinterlace the image.
51 1 << 1, // If set, the caller is deinterlacing the
52 // image using ADAM7, and we may want to
53 // interpolate it for better intermediate results.
55 FLIP_VERTICALLY
= 1 << 2, // If set, flip the image vertically.
57 PROGRESSIVE_DISPLAY
= 1 << 3, // If set, we expect the image to be displayed
58 // progressively. This enables features that
59 // result in a better user experience for
60 // progressive display but which may be more
61 // computationally expensive.
63 PREMULTIPLY_ALPHA
= 1 << 4, // If set, we want to premultiply the alpha
64 // channel and the individual color channels.
66 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SurfacePipeFlags
)
68 class SurfacePipeFactory
{
71 * Creates and initializes a normal (i.e., non-paletted) SurfacePipe.
73 * @param aDecoder The decoder whose current frame the SurfacePipe will write
75 * @param aInputSize The original size of the image.
76 * @param aOutputSize The size the SurfacePipe should output. Must be the same
77 * as @aInputSize or smaller. If smaller, the image will be
78 * downscaled during decoding.
79 * @param aFrameRect The portion of the image that actually contains data.
80 * @param aFormat The surface format of the image; generally B8G8R8A8 or
82 * @param aAnimParams Extra parameters used by animated images.
83 * @param aFlags Flags enabling or disabling various functionality for the
84 * SurfacePipe; see the SurfacePipeFlags documentation for more
87 * @return A SurfacePipe if the parameters allowed one to be created
88 * successfully, or Nothing() if the SurfacePipe could not be
91 static Maybe
<SurfacePipe
> CreateSurfacePipe(
92 Decoder
* aDecoder
, const nsIntSize
& aInputSize
,
93 const nsIntSize
& aOutputSize
, const nsIntRect
& aFrameRect
,
94 gfx::SurfaceFormat aInFormat
, gfx::SurfaceFormat aOutFormat
,
95 const Maybe
<AnimationParams
>& aAnimParams
, qcms_transform
* aTransform
,
96 SurfacePipeFlags aFlags
) {
97 const bool deinterlace
= bool(aFlags
& SurfacePipeFlags::DEINTERLACE
);
98 const bool flipVertically
=
99 bool(aFlags
& SurfacePipeFlags::FLIP_VERTICALLY
);
100 const bool progressiveDisplay
=
101 bool(aFlags
& SurfacePipeFlags::PROGRESSIVE_DISPLAY
);
102 const bool downscale
= aInputSize
!= aOutputSize
;
103 const bool removeFrameRect
= !aFrameRect
.IsEqualEdges(
104 nsIntRect(0, 0, aInputSize
.width
, aInputSize
.height
));
105 const bool blendAnimation
= aAnimParams
.isSome();
106 const bool colorManagement
= aTransform
!= nullptr;
107 const bool premultiplyAlpha
=
108 bool(aFlags
& SurfacePipeFlags::PREMULTIPLY_ALPHA
);
110 MOZ_ASSERT(aInFormat
== gfx::SurfaceFormat::R8G8B8
||
111 aInFormat
== gfx::SurfaceFormat::R8G8B8A8
||
112 aInFormat
== gfx::SurfaceFormat::R8G8B8X8
||
113 aInFormat
== gfx::SurfaceFormat::OS_RGBA
||
114 aInFormat
== gfx::SurfaceFormat::OS_RGBX
);
116 MOZ_ASSERT(aOutFormat
== gfx::SurfaceFormat::OS_RGBA
||
117 aOutFormat
== gfx::SurfaceFormat::OS_RGBX
);
119 const bool inFormatRgb
= aInFormat
== gfx::SurfaceFormat::R8G8B8
;
121 const bool inFormatOpaque
= aInFormat
== gfx::SurfaceFormat::OS_RGBX
||
122 aInFormat
== gfx::SurfaceFormat::R8G8B8X8
||
124 const bool outFormatOpaque
= aOutFormat
== gfx::SurfaceFormat::OS_RGBX
;
126 const bool inFormatOrder
= aInFormat
== gfx::SurfaceFormat::R8G8B8A8
||
127 aInFormat
== gfx::SurfaceFormat::R8G8B8X8
;
128 const bool outFormatOrder
= aOutFormat
== gfx::SurfaceFormat::R8G8B8A8
||
129 aOutFormat
== gfx::SurfaceFormat::R8G8B8X8
;
131 // Early swizzles are for unpacking RGB or forcing RGBA/BGRA_U32 to
132 // RGBX/BGRX_U32. We should never want to premultiply in either case,
133 // because the image's alpha channel will always be opaque. This must be
134 // done before downscaling and color management.
135 bool unpackOrMaskSwizzle
=
137 (!inFormatOpaque
&& outFormatOpaque
&& inFormatOrder
== outFormatOrder
);
139 // Late swizzles are for premultiplying RGBA/BGRA_U32 and/or possible
140 // converting between RGBA and BGRA_U32. It must happen after color
141 // management, and before downscaling.
142 bool swapOrAlphaSwizzle
=
143 (!inFormatRgb
&& inFormatOrder
!= outFormatOrder
) || premultiplyAlpha
;
145 if (unpackOrMaskSwizzle
&& swapOrAlphaSwizzle
) {
146 MOZ_ASSERT_UNREACHABLE("Early and late swizzles not supported");
150 if (!unpackOrMaskSwizzle
&& !swapOrAlphaSwizzle
&&
151 aInFormat
!= aOutFormat
) {
152 MOZ_ASSERT_UNREACHABLE("Need to swizzle, but not configured to");
156 // Don't interpolate if we're sure we won't show this surface to the user
157 // until it's completely decoded. The final pass of an ADAM7 image doesn't
158 // need interpolation, so we only need to interpolate if we'll be displaying
159 // the image while it's still being decoded.
160 const bool adam7Interpolate
=
161 bool(aFlags
& SurfacePipeFlags::ADAM7_INTERPOLATE
) &&
164 if (deinterlace
&& adam7Interpolate
) {
165 MOZ_ASSERT_UNREACHABLE("ADAM7 deinterlacing is handled by libpng");
169 // Construct configurations for the SurfaceFilters. Note that the order of
170 // these filters is significant. We want to deinterlace or interpolate raw
171 // input rows, before any other transformations, and we want to remove the
172 // frame rect (which may involve adding blank rows or columns to the image)
173 // before any downscaling, so that the new rows and columns are taken into
175 DeinterlacingConfig
<uint32_t> deinterlacingConfig
{progressiveDisplay
};
176 ADAM7InterpolatingConfig interpolatingConfig
;
177 RemoveFrameRectConfig removeFrameRectConfig
{aFrameRect
};
178 BlendAnimationConfig blendAnimationConfig
{aDecoder
};
179 DownscalingConfig downscalingConfig
{aInputSize
, aOutFormat
};
180 ColorManagementConfig colorManagementConfig
{aTransform
};
181 SwizzleConfig swizzleConfig
{aInFormat
, aOutFormat
, premultiplyAlpha
};
182 SurfaceConfig surfaceConfig
{aDecoder
, aOutputSize
, aOutFormat
,
183 flipVertically
, aAnimParams
};
185 Maybe
<SurfacePipe
> pipe
;
187 if (unpackOrMaskSwizzle
) {
188 if (colorManagement
) {
190 MOZ_ASSERT(!blendAnimation
);
191 if (removeFrameRect
) {
193 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
194 removeFrameRectConfig
, downscalingConfig
,
195 colorManagementConfig
, surfaceConfig
);
196 } else if (adam7Interpolate
) {
197 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
198 removeFrameRectConfig
, downscalingConfig
,
199 colorManagementConfig
, surfaceConfig
);
200 } else { // (deinterlace and adam7Interpolate are false)
201 pipe
= MakePipe(swizzleConfig
, removeFrameRectConfig
,
202 downscalingConfig
, colorManagementConfig
,
205 } else { // (removeFrameRect is false)
207 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
208 downscalingConfig
, colorManagementConfig
,
210 } else if (adam7Interpolate
) {
211 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
212 downscalingConfig
, colorManagementConfig
,
214 } else { // (deinterlace and adam7Interpolate are false)
215 pipe
= MakePipe(swizzleConfig
, downscalingConfig
,
216 colorManagementConfig
, surfaceConfig
);
219 } else { // (downscale is false)
220 if (blendAnimation
) {
222 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
223 colorManagementConfig
, blendAnimationConfig
,
225 } else if (adam7Interpolate
) {
226 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
227 colorManagementConfig
, blendAnimationConfig
,
229 } else { // (deinterlace and adam7Interpolate are false)
230 pipe
= MakePipe(swizzleConfig
, colorManagementConfig
,
231 blendAnimationConfig
, surfaceConfig
);
233 } else if (removeFrameRect
) {
235 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
236 colorManagementConfig
, removeFrameRectConfig
,
238 } else if (adam7Interpolate
) {
239 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
240 colorManagementConfig
, removeFrameRectConfig
,
242 } else { // (deinterlace and adam7Interpolate are false)
243 pipe
= MakePipe(swizzleConfig
, colorManagementConfig
,
244 removeFrameRectConfig
, surfaceConfig
);
246 } else { // (blendAnimation and removeFrameRect is false)
248 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
249 colorManagementConfig
, surfaceConfig
);
250 } else if (adam7Interpolate
) {
251 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
252 colorManagementConfig
, surfaceConfig
);
253 } else { // (deinterlace and adam7Interpolate are false)
255 MakePipe(swizzleConfig
, colorManagementConfig
, surfaceConfig
);
259 } else { // (colorManagement is false)
261 MOZ_ASSERT(!blendAnimation
);
262 if (removeFrameRect
) {
264 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
265 removeFrameRectConfig
, downscalingConfig
,
267 } else if (adam7Interpolate
) {
268 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
269 removeFrameRectConfig
, downscalingConfig
,
271 } else { // (deinterlace and adam7Interpolate are false)
272 pipe
= MakePipe(swizzleConfig
, removeFrameRectConfig
,
273 downscalingConfig
, surfaceConfig
);
275 } else { // (removeFrameRect is false)
277 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
278 downscalingConfig
, surfaceConfig
);
279 } else if (adam7Interpolate
) {
280 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
281 downscalingConfig
, surfaceConfig
);
282 } else { // (deinterlace and adam7Interpolate are false)
283 pipe
= MakePipe(swizzleConfig
, downscalingConfig
, surfaceConfig
);
286 } else { // (downscale is false)
287 if (blendAnimation
) {
289 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
290 blendAnimationConfig
, surfaceConfig
);
291 } else if (adam7Interpolate
) {
292 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
293 blendAnimationConfig
, surfaceConfig
);
294 } else { // (deinterlace and adam7Interpolate are false)
296 MakePipe(swizzleConfig
, blendAnimationConfig
, surfaceConfig
);
298 } else if (removeFrameRect
) {
300 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
301 removeFrameRectConfig
, surfaceConfig
);
302 } else if (adam7Interpolate
) {
303 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
304 removeFrameRectConfig
, surfaceConfig
);
305 } else { // (deinterlace and adam7Interpolate are false)
307 MakePipe(swizzleConfig
, removeFrameRectConfig
, surfaceConfig
);
309 } else { // (blendAnimation and removeFrameRect is false)
312 MakePipe(swizzleConfig
, deinterlacingConfig
, surfaceConfig
);
313 } else if (adam7Interpolate
) {
315 MakePipe(swizzleConfig
, interpolatingConfig
, surfaceConfig
);
316 } else { // (deinterlace and adam7Interpolate are false)
317 pipe
= MakePipe(swizzleConfig
, surfaceConfig
);
322 } else if (swapOrAlphaSwizzle
) {
323 if (colorManagement
) {
325 MOZ_ASSERT(!blendAnimation
);
326 if (removeFrameRect
) {
328 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
329 deinterlacingConfig
, removeFrameRectConfig
,
330 downscalingConfig
, surfaceConfig
);
331 } else if (adam7Interpolate
) {
332 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
333 interpolatingConfig
, removeFrameRectConfig
,
334 downscalingConfig
, surfaceConfig
);
335 } else { // (deinterlace and adam7Interpolate are false)
336 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
337 removeFrameRectConfig
, downscalingConfig
,
340 } else { // (removeFrameRect is false)
342 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
343 deinterlacingConfig
, downscalingConfig
,
345 } else if (adam7Interpolate
) {
346 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
347 interpolatingConfig
, downscalingConfig
,
349 } else { // (deinterlace and adam7Interpolate are false)
350 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
351 downscalingConfig
, surfaceConfig
);
354 } else { // (downscale is false)
355 if (blendAnimation
) {
357 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
358 deinterlacingConfig
, blendAnimationConfig
,
360 } else if (adam7Interpolate
) {
361 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
362 interpolatingConfig
, blendAnimationConfig
,
364 } else { // (deinterlace and adam7Interpolate are false)
365 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
366 blendAnimationConfig
, surfaceConfig
);
368 } else if (removeFrameRect
) {
370 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
371 deinterlacingConfig
, removeFrameRectConfig
,
373 } else if (adam7Interpolate
) {
374 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
375 interpolatingConfig
, removeFrameRectConfig
,
377 } else { // (deinterlace and adam7Interpolate are false)
378 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
379 removeFrameRectConfig
, surfaceConfig
);
381 } else { // (blendAnimation and removeFrameRect is false)
383 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
384 deinterlacingConfig
, surfaceConfig
);
385 } else if (adam7Interpolate
) {
386 pipe
= MakePipe(colorManagementConfig
, swizzleConfig
,
387 interpolatingConfig
, surfaceConfig
);
388 } else { // (deinterlace and adam7Interpolate are false)
390 MakePipe(colorManagementConfig
, swizzleConfig
, surfaceConfig
);
394 } else { // (colorManagement is false)
396 MOZ_ASSERT(!blendAnimation
);
397 if (removeFrameRect
) {
399 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
400 removeFrameRectConfig
, downscalingConfig
,
402 } else if (adam7Interpolate
) {
403 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
404 removeFrameRectConfig
, downscalingConfig
,
406 } else { // (deinterlace and adam7Interpolate are false)
407 pipe
= MakePipe(swizzleConfig
, removeFrameRectConfig
,
408 downscalingConfig
, surfaceConfig
);
410 } else { // (removeFrameRect is false)
412 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
413 downscalingConfig
, surfaceConfig
);
414 } else if (adam7Interpolate
) {
415 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
416 downscalingConfig
, surfaceConfig
);
417 } else { // (deinterlace and adam7Interpolate are false)
418 pipe
= MakePipe(swizzleConfig
, downscalingConfig
, surfaceConfig
);
421 } else { // (downscale is false)
422 if (blendAnimation
) {
424 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
425 blendAnimationConfig
, surfaceConfig
);
426 } else if (adam7Interpolate
) {
427 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
428 blendAnimationConfig
, surfaceConfig
);
429 } else { // (deinterlace and adam7Interpolate are false)
431 MakePipe(swizzleConfig
, blendAnimationConfig
, surfaceConfig
);
433 } else if (removeFrameRect
) {
435 pipe
= MakePipe(swizzleConfig
, deinterlacingConfig
,
436 removeFrameRectConfig
, surfaceConfig
);
437 } else if (adam7Interpolate
) {
438 pipe
= MakePipe(swizzleConfig
, interpolatingConfig
,
439 removeFrameRectConfig
, surfaceConfig
);
440 } else { // (deinterlace and adam7Interpolate are false)
442 MakePipe(swizzleConfig
, removeFrameRectConfig
, surfaceConfig
);
444 } else { // (blendAnimation and removeFrameRect is false)
447 MakePipe(swizzleConfig
, deinterlacingConfig
, surfaceConfig
);
448 } else if (adam7Interpolate
) {
450 MakePipe(swizzleConfig
, interpolatingConfig
, surfaceConfig
);
451 } else { // (deinterlace and adam7Interpolate are false)
452 pipe
= MakePipe(swizzleConfig
, surfaceConfig
);
457 } else { // (unpackOrMaskSwizzle and swapOrAlphaSwizzle are false)
458 if (colorManagement
) {
460 MOZ_ASSERT(!blendAnimation
);
461 if (removeFrameRect
) {
463 pipe
= MakePipe(deinterlacingConfig
, removeFrameRectConfig
,
464 downscalingConfig
, colorManagementConfig
,
466 } else if (adam7Interpolate
) {
467 pipe
= MakePipe(interpolatingConfig
, removeFrameRectConfig
,
468 downscalingConfig
, colorManagementConfig
,
470 } else { // (deinterlace and adam7Interpolate are false)
471 pipe
= MakePipe(removeFrameRectConfig
, downscalingConfig
,
472 colorManagementConfig
, surfaceConfig
);
474 } else { // (removeFrameRect is false)
476 pipe
= MakePipe(deinterlacingConfig
, downscalingConfig
,
477 colorManagementConfig
, surfaceConfig
);
478 } else if (adam7Interpolate
) {
479 pipe
= MakePipe(interpolatingConfig
, downscalingConfig
,
480 colorManagementConfig
, surfaceConfig
);
481 } else { // (deinterlace and adam7Interpolate are false)
482 pipe
= MakePipe(downscalingConfig
, colorManagementConfig
,
486 } else { // (downscale is false)
487 if (blendAnimation
) {
489 pipe
= MakePipe(deinterlacingConfig
, colorManagementConfig
,
490 blendAnimationConfig
, surfaceConfig
);
491 } else if (adam7Interpolate
) {
492 pipe
= MakePipe(interpolatingConfig
, colorManagementConfig
,
493 blendAnimationConfig
, surfaceConfig
);
494 } else { // (deinterlace and adam7Interpolate are false)
495 pipe
= MakePipe(colorManagementConfig
, blendAnimationConfig
,
498 } else if (removeFrameRect
) {
500 pipe
= MakePipe(deinterlacingConfig
, colorManagementConfig
,
501 removeFrameRectConfig
, surfaceConfig
);
502 } else if (adam7Interpolate
) {
503 pipe
= MakePipe(interpolatingConfig
, colorManagementConfig
,
504 removeFrameRectConfig
, surfaceConfig
);
505 } else { // (deinterlace and adam7Interpolate are false)
506 pipe
= MakePipe(colorManagementConfig
, removeFrameRectConfig
,
509 } else { // (blendAnimation and removeFrameRect is false)
511 pipe
= MakePipe(deinterlacingConfig
, colorManagementConfig
,
513 } else if (adam7Interpolate
) {
514 pipe
= MakePipe(interpolatingConfig
, colorManagementConfig
,
516 } else { // (deinterlace and adam7Interpolate are false)
517 pipe
= MakePipe(colorManagementConfig
, surfaceConfig
);
521 } else { // (colorManagement is false)
523 MOZ_ASSERT(!blendAnimation
);
524 if (removeFrameRect
) {
526 pipe
= MakePipe(deinterlacingConfig
, removeFrameRectConfig
,
527 downscalingConfig
, surfaceConfig
);
528 } else if (adam7Interpolate
) {
529 pipe
= MakePipe(interpolatingConfig
, removeFrameRectConfig
,
530 downscalingConfig
, surfaceConfig
);
531 } else { // (deinterlace and adam7Interpolate are false)
532 pipe
= MakePipe(removeFrameRectConfig
, downscalingConfig
,
535 } else { // (removeFrameRect is false)
537 pipe
= MakePipe(deinterlacingConfig
, downscalingConfig
,
539 } else if (adam7Interpolate
) {
540 pipe
= MakePipe(interpolatingConfig
, downscalingConfig
,
542 } else { // (deinterlace and adam7Interpolate are false)
543 pipe
= MakePipe(downscalingConfig
, surfaceConfig
);
546 } else { // (downscale is false)
547 if (blendAnimation
) {
549 pipe
= MakePipe(deinterlacingConfig
, blendAnimationConfig
,
551 } else if (adam7Interpolate
) {
552 pipe
= MakePipe(interpolatingConfig
, blendAnimationConfig
,
554 } else { // (deinterlace and adam7Interpolate are false)
555 pipe
= MakePipe(blendAnimationConfig
, surfaceConfig
);
557 } else if (removeFrameRect
) {
559 pipe
= MakePipe(deinterlacingConfig
, removeFrameRectConfig
,
561 } else if (adam7Interpolate
) {
562 pipe
= MakePipe(interpolatingConfig
, removeFrameRectConfig
,
564 } else { // (deinterlace and adam7Interpolate are false)
565 pipe
= MakePipe(removeFrameRectConfig
, surfaceConfig
);
567 } else { // (blendAnimation and removeFrameRect is false)
569 pipe
= MakePipe(deinterlacingConfig
, surfaceConfig
);
570 } else if (adam7Interpolate
) {
571 pipe
= MakePipe(interpolatingConfig
, surfaceConfig
);
572 } else { // (deinterlace and adam7Interpolate are false)
573 pipe
= MakePipe(surfaceConfig
);
584 template <typename
... Configs
>
585 static Maybe
<SurfacePipe
> MakePipe(const Configs
&... aConfigs
) {
586 auto pipe
= MakeUnique
<typename
detail::FilterPipeline
<Configs
...>::Type
>();
587 nsresult rv
= pipe
->Configure(aConfigs
...);
592 return Some(SurfacePipe
{std::move(pipe
)});
595 virtual ~SurfacePipeFactory() = 0;
599 } // namespace mozilla
601 #endif // mozilla_image_SurfacePipeFactory_h