Flutter Engine
The Flutter Engine
Public Types | Public Member Functions | List of all members
DM::CodecSrc Class Reference

#include <DMSrcSink.h>

Inheritance diagram for DM::CodecSrc:
DM::Src

Public Types

enum  Mode {
  kCodec_Mode , kCodecZeroInit_Mode , kScanline_Mode , kStripe_Mode ,
  kCroppedScanline_Mode , kSubset_Mode , kAnimated_Mode
}
 
enum  DstColorType { kGetFromCanvas_DstColorType , kGrayscale_Always_DstColorType , kNonNative8888_Always_DstColorType }
 
- Public Types inherited from DM::Src
using GraphiteTestContext = skiatest::graphite::GraphiteTestContext
 

Public Member Functions

 CodecSrc (Path, Mode, DstColorType, SkAlphaType, float)
 
Result draw (SkCanvas *, GraphiteTestContext *) const override
 
SkISize size () const override
 
Name name () const override
 
bool veto (SinkFlags) const override
 
bool serial () const override
 
- Public Member Functions inherited from DM::Src
virtual ~Src ()
 
virtual Result draw (SkCanvas *canvas, GraphiteTestContext *) const =0
 
virtual SkISize size () const =0
 
virtual Name name () const =0
 
virtual void modifyGrContextOptions (GrContextOptions *) const
 
virtual void modifyGraphiteContextOptions (skgpu::graphite::ContextOptions *) const
 
virtual bool veto (SinkFlags) const
 
virtual int pageCount () const
 
virtual Result draw (int page, SkCanvas *canvas, GraphiteTestContext *graphiteTestContext) const
 
virtual SkISize size (int page) const
 
virtual bool serial () const
 

Detailed Description

Definition at line 152 of file DMSrcSink.h.

Member Enumeration Documentation

◆ DstColorType

Enumerator
kGetFromCanvas_DstColorType 
kGrayscale_Always_DstColorType 
kNonNative8888_Always_DstColorType 

Definition at line 166 of file DMSrcSink.h.

◆ Mode

Enumerator
kCodec_Mode 
kCodecZeroInit_Mode 
kScanline_Mode 
kStripe_Mode 
kCroppedScanline_Mode 
kSubset_Mode 
kAnimated_Mode 

Definition at line 154 of file DMSrcSink.h.

154 {
156 // We choose to test only one mode with zero initialized memory.
157 // This will exercise all of the interesting cases in SkSwizzler
158 // without doubling the size of our test suite.
161 kStripe_Mode, // Tests the skipping of scanlines
162 kCroppedScanline_Mode, // Tests (jpeg) cropped scanline optimization
163 kSubset_Mode, // For codecs that support subsets directly.
164 kAnimated_Mode, // For codecs that support animation.
165 };
@ kCroppedScanline_Mode
Definition: DMSrcSink.h:162
@ kCodecZeroInit_Mode
Definition: DMSrcSink.h:159

Constructor & Destructor Documentation

◆ CodecSrc()

DM::CodecSrc::CodecSrc ( Path  path,
Mode  mode,
DstColorType  dstColorType,
SkAlphaType  dstAlphaType,
float  scale 
)

Definition at line 395 of file DMSrcSink.cpp.

397 : fPath(path)
398 , fMode(mode)
399 , fDstColorType(dstColorType)
400 , fDstAlphaType(dstAlphaType)
401 , fScale(scale)
402 , fRunSerially(serial_from_path_name(path))
403{}
static bool serial_from_path_name(const SkString &path)
Definition: DMSrcSink.cpp:376
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
const Scalar scale

Member Function Documentation

◆ draw()

Result DM::CodecSrc::draw ( SkCanvas canvas,
GraphiteTestContext  
) const
overridevirtual

Implements DM::Src.

Definition at line 474 of file DMSrcSink.cpp.

474 {
476 if (!encoded) {
477 return Result::Fatal("Couldn't read %s.", fPath.c_str());
478 }
479
480 std::unique_ptr<SkCodec> codec(SkCodec::MakeFromData(encoded));
481 if (nullptr == codec) {
482 return Result::Fatal("Couldn't create codec for %s.", fPath.c_str());
483 }
484
485 SkImageInfo decodeInfo = codec->getInfo();
486 if (!get_decode_info(&decodeInfo, canvas->imageInfo().colorType(), fDstColorType,
487 fDstAlphaType)) {
488 return Result::Skip("Skipping uninteresting test.");
489 }
490
491 // Try to scale the image if it is desired
492 SkISize size = codec->getScaledDimensions(fScale);
493
494 std::unique_ptr<SkAndroidCodec> androidCodec;
495 if (1.0f != fScale && fMode == kAnimated_Mode) {
496 androidCodec = SkAndroidCodec::MakeFromData(encoded);
497 size = androidCodec->getSampledDimensions(1 / fScale);
498 }
499
500 if (size == decodeInfo.dimensions() && 1.0f != fScale) {
501 return Result::Skip("Test without scaling is uninteresting.");
502 }
503
504 // Visually inspecting very small output images is not necessary. We will
505 // cover these cases in unit testing.
506 if ((size.width() <= 10 || size.height() <= 10) && 1.0f != fScale) {
507 return Result::Skip("Scaling very small images is uninteresting.");
508 }
509 decodeInfo = decodeInfo.makeDimensions(size);
510
511 const int bpp = decodeInfo.bytesPerPixel();
512 const size_t rowBytes = size.width() * bpp;
513 const size_t safeSize = decodeInfo.computeByteSize(rowBytes);
514 SkAutoMalloc pixels(safeSize);
515
517 if (kCodecZeroInit_Mode == fMode) {
518 memset(pixels.get(), 0, size.height() * rowBytes);
519 options.fZeroInitialized = SkCodec::kYes_ZeroInitialized;
520 }
521
522 SkImageInfo bitmapInfo = decodeInfo;
523 set_bitmap_color_space(&bitmapInfo);
524 if (kRGBA_8888_SkColorType == decodeInfo.colorType() ||
525 kBGRA_8888_SkColorType == decodeInfo.colorType()) {
526 bitmapInfo = bitmapInfo.makeColorType(kN32_SkColorType);
527 }
528
529 switch (fMode) {
530 case kAnimated_Mode: {
531 SkAndroidCodec::AndroidOptions androidOptions;
532 if (fScale != 1.0f) {
533 SkASSERT(androidCodec);
534 androidOptions.fSampleSize = 1 / fScale;
535 auto dims = androidCodec->getSampledDimensions(androidOptions.fSampleSize);
536 decodeInfo = decodeInfo.makeDimensions(dims);
537 }
538
539 std::vector<SkCodec::FrameInfo> frameInfos = androidCodec
540 ? androidCodec->codec()->getFrameInfo() : codec->getFrameInfo();
541 if (frameInfos.size() <= 1) {
542 return Result::Fatal("%s is not an animated image.", fPath.c_str());
543 }
544
545 // As in CodecSrc::size(), compute a roughly square grid to draw the frames
546 // into. "factor" is the number of frames to draw on one row. There will be
547 // up to "factor" rows as well.
548 const float root = sqrt((float) frameInfos.size());
549 const int factor = sk_float_ceil2int(root);
550
551 // Used to cache a frame that future frames will depend on.
552 SkAutoMalloc priorFramePixels;
553 int cachedFrame = SkCodec::kNoFrame;
554 for (int i = 0; static_cast<size_t>(i) < frameInfos.size(); i++) {
555 androidOptions.fFrameIndex = i;
556 // Check for a prior frame
557 const int reqFrame = frameInfos[i].fRequiredFrame;
558 if (reqFrame != SkCodec::kNoFrame && reqFrame == cachedFrame
559 && priorFramePixels.get()) {
560 // Copy into pixels
561 memcpy(pixels.get(), priorFramePixels.get(), safeSize);
562 androidOptions.fPriorFrame = reqFrame;
563 } else {
564 androidOptions.fPriorFrame = SkCodec::kNoFrame;
565 }
566 SkCodec::Result result = androidCodec
567 ? androidCodec->getAndroidPixels(decodeInfo, pixels.get(), rowBytes,
568 &androidOptions)
569 : codec->getPixels(decodeInfo, pixels.get(), rowBytes, &androidOptions);
570 if (SkCodec::kInvalidInput == result && i > 0) {
571 // Some of our test images have truncated later frames. Treat that
572 // the same as incomplete.
574 }
575 switch (result) {
579 // If the next frame depends on this one, store it in priorFrame.
580 // It is possible that we may discard a frame that future frames depend on,
581 // but the codec will simply redecode the discarded frame.
582 // Do this before calling draw_to_canvas, which premultiplies in place. If
583 // we're decoding to unpremul, we want to pass the unmodified frame to the
584 // codec for decoding the next frame.
585 if (static_cast<size_t>(i+1) < frameInfos.size()
586 && frameInfos[i+1].fRequiredFrame == i) {
587 memcpy(priorFramePixels.reset(safeSize), pixels.get(), safeSize);
588 cachedFrame = i;
589 }
590
591 SkAutoCanvasRestore acr(canvas, true);
592 const int xTranslate = (i % factor) * decodeInfo.width();
593 const int yTranslate = (i / factor) * decodeInfo.height();
594 canvas->translate(SkIntToScalar(xTranslate), SkIntToScalar(yTranslate));
595 draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, fDstColorType);
596 if (result != SkCodec::kSuccess) {
597 return Result::Ok();
598 }
599 break;
600 }
602 if (i > 0 && (decodeInfo.colorType() == kRGB_565_SkColorType)) {
603 return Result::Skip(
604 "Cannot decode frame %i to 565 (%s).", i, fPath.c_str());
605 }
606 [[fallthrough]];
607 default:
608 return Result::Fatal(
609 "Couldn't getPixels for frame %i in %s.", i, fPath.c_str());
610 }
611 }
612 break;
613 }
615 case kCodec_Mode: {
616 switch (codec->getPixels(decodeInfo, pixels.get(), rowBytes, &options)) {
618 // We consider these to be valid, since we should still decode what is
619 // available.
622 break;
623 default:
624 // Everything else is considered a failure.
625 return Result::Fatal("Couldn't getPixels %s.", fPath.c_str());
626 }
627
628 draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, fDstColorType);
629 break;
630 }
631 case kScanline_Mode: {
632 void* dst = pixels.get();
633 uint32_t height = decodeInfo.height();
634 const bool useIncremental = [this]() {
635 auto exts = { "png", "PNG", "gif", "GIF" };
636 for (auto ext : exts) {
637 if (fPath.endsWith(ext)) {
638 return true;
639 }
640 }
641 return false;
642 }();
643 // ico may use the old scanline method or the new one, depending on whether it
644 // internally holds a bmp or a png.
645 const bool ico = fPath.endsWith("ico");
646 bool useOldScanlineMethod = !useIncremental && !ico;
647 if (useIncremental || ico) {
648 if (SkCodec::kSuccess == codec->startIncrementalDecode(decodeInfo, dst,
649 rowBytes, &options)) {
650 int rowsDecoded;
651 auto result = codec->incrementalDecode(&rowsDecoded);
653 codec->fillIncompleteImage(decodeInfo, dst, rowBytes,
655 rowsDecoded);
656 }
657 } else {
658 if (useIncremental) {
659 // Error: These should support incremental decode.
660 return Result::Fatal("Could not start incremental decode");
661 }
662 // Otherwise, this is an ICO. Since incremental failed, it must contain a BMP,
663 // which should work via startScanlineDecode
664 useOldScanlineMethod = true;
665 }
666 }
667
668 if (useOldScanlineMethod) {
669 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo)) {
670 return Result::Fatal("Could not start scanline decoder");
671 }
672
673 // We do not need to check the return value. On an incomplete
674 // image, memory will be filled with a default value.
675 codec->getScanlines(dst, height, rowBytes);
676 }
677
678 draw_to_canvas(canvas, bitmapInfo, dst, rowBytes, fDstColorType);
679 break;
680 }
681 case kStripe_Mode: {
682 const int height = decodeInfo.height();
683 // This value is chosen arbitrarily. We exercise more cases by choosing a value that
684 // does not align with image blocks.
685 const int stripeHeight = 37;
686 const int numStripes = (height + stripeHeight - 1) / stripeHeight;
687 void* dst = pixels.get();
688
689 // Decode odd stripes
690 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &options)) {
691 return Result::Fatal("Could not start scanline decoder");
692 }
693
694 // This mode was designed to test the new skip scanlines API in libjpeg-turbo.
695 // Jpegs have kTopDown_SkScanlineOrder, and at this time, it is not interesting
696 // to run this test for image types that do not have this scanline ordering.
697 // We only run this on Jpeg, which is always kTopDown.
698 SkASSERT(SkCodec::kTopDown_SkScanlineOrder == codec->getScanlineOrder());
699
700 for (int i = 0; i < numStripes; i += 2) {
701 // Skip a stripe
702 const int linesToSkip = std::min(stripeHeight, height - i * stripeHeight);
703 codec->skipScanlines(linesToSkip);
704
705 // Read a stripe
706 const int startY = (i + 1) * stripeHeight;
707 const int linesToRead = std::min(stripeHeight, height - startY);
708 if (linesToRead > 0) {
709 codec->getScanlines(SkTAddOffset<void>(dst, rowBytes * startY), linesToRead,
710 rowBytes);
711 }
712 }
713
714 // Decode even stripes
715 const SkCodec::Result startResult = codec->startScanlineDecode(decodeInfo);
716 if (SkCodec::kSuccess != startResult) {
717 return Result::Fatal("Failed to restart scanline decoder with same parameters.");
718 }
719 for (int i = 0; i < numStripes; i += 2) {
720 // Read a stripe
721 const int startY = i * stripeHeight;
722 const int linesToRead = std::min(stripeHeight, height - startY);
723 codec->getScanlines(SkTAddOffset<void>(dst, rowBytes * startY), linesToRead,
724 rowBytes);
725
726 // Skip a stripe
727 const int linesToSkip = std::min(stripeHeight, height - (i + 1) * stripeHeight);
728 if (linesToSkip > 0) {
729 codec->skipScanlines(linesToSkip);
730 }
731 }
732
733 draw_to_canvas(canvas, bitmapInfo, dst, rowBytes, fDstColorType);
734 break;
735 }
737 const int width = decodeInfo.width();
738 const int height = decodeInfo.height();
739 // This value is chosen because, as we move across the image, it will sometimes
740 // align with the jpeg block sizes and it will sometimes not. This allows us
741 // to test interestingly different code paths in the implementation.
742 const int tileSize = 36;
743 SkIRect subset;
744 for (int x = 0; x < width; x += tileSize) {
745 subset = SkIRect::MakeXYWH(x, 0, std::min(tileSize, width - x), height);
746 options.fSubset = &subset;
747 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &options)) {
748 return Result::Fatal("Could not start scanline decoder.");
749 }
750
751 codec->getScanlines(SkTAddOffset<void>(pixels.get(), x * bpp), height, rowBytes);
752 }
753
754 draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, fDstColorType);
755 break;
756 }
757 case kSubset_Mode: {
758 // Arbitrarily choose a divisor.
759 int divisor = 2;
760 // Total width/height of the image.
761 const int W = codec->getInfo().width();
762 const int H = codec->getInfo().height();
763 if (divisor > W || divisor > H) {
764 return Result::Skip("Cannot codec subset: divisor %d is too big "
765 "for %s with dimensions (%d x %d)", divisor,
766 fPath.c_str(), W, H);
767 }
768 // subset dimensions
769 // SkWebpCodec, the only one that supports subsets, requires even top/left boundaries.
770 const int w = SkAlign2(W / divisor);
771 const int h = SkAlign2(H / divisor);
772 SkIRect subset;
773 options.fSubset = &subset;
774 SkBitmap subsetBm;
775 // We will reuse pixel memory from bitmap.
776 void* dst = pixels.get();
777 // Keep track of left and top (for drawing subsetBm into canvas). We could use
778 // fScale * x and fScale * y, but we want integers such that the next subset will start
779 // where the last one ended. So we'll add decodeInfo.width() and height().
780 int left = 0;
781 for (int x = 0; x < W; x += w) {
782 int top = 0;
783 for (int y = 0; y < H; y+= h) {
784 // Do not make the subset go off the edge of the image.
785 const int preScaleW = std::min(w, W - x);
786 const int preScaleH = std::min(h, H - y);
787 subset.setXYWH(x, y, preScaleW, preScaleH);
788 // And scale
789 // FIXME: Should we have a version of getScaledDimensions that takes a subset
790 // into account?
791 const int scaledW = std::max(1, SkScalarRoundToInt(preScaleW * fScale));
792 const int scaledH = std::max(1, SkScalarRoundToInt(preScaleH * fScale));
793 decodeInfo = decodeInfo.makeWH(scaledW, scaledH);
794 SkImageInfo subsetBitmapInfo = bitmapInfo.makeWH(scaledW, scaledH);
795 size_t subsetRowBytes = subsetBitmapInfo.minRowBytes();
796 const SkCodec::Result result = codec->getPixels(decodeInfo, dst, subsetRowBytes,
797 &options);
798 switch (result) {
802 break;
803 default:
804 return Result::Fatal("subset codec failed to decode (%d, %d, %d, %d) "
805 "from %s with dimensions (%d x %d)\t error %d",
806 x, y, decodeInfo.width(), decodeInfo.height(),
807 fPath.c_str(), W, H, result);
808 }
809 draw_to_canvas(canvas, subsetBitmapInfo, dst, subsetRowBytes, fDstColorType,
810 SkIntToScalar(left), SkIntToScalar(top));
811
812 // translate by the scaled height.
813 top += decodeInfo.height();
814 }
815 // translate by the scaled width.
816 left += decodeInfo.width();
817 }
818 return Result::Ok();
819 }
820 default:
821 SkASSERT(false);
822 return Result::Fatal("Invalid fMode");
823 }
824 return Result::Ok();
825}
const char * options
static constexpr T SkAlign2(T x)
Definition: SkAlign.h:15
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition: SkColorType.h:22
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
#define sk_float_ceil2int(x)
#define SkScalarRoundToInt(x)
Definition: SkScalar.h:37
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define W
Definition: aaa.cpp:17
SkISize size() const override
Definition: DMSrcSink.cpp:827
static Result Skip(const char *fmt,...) SK_PRINTF_LIKE(1
static Result Ok()
Definition: DMSrcSink.h:50
static Result Fatal(const char *fmt,...) SK_PRINTF_LIKE(1
static std::unique_ptr< SkAndroidCodec > MakeFromData(sk_sp< SkData >, SkPngChunkReader *=nullptr)
void * reset(size_t size=0, OnShrink shrink=kAlloc_OnShrink)
Definition: SkAutoMalloc.h:53
void * get()
Definition: SkAutoMalloc.h:64
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
SkImageInfo imageInfo() const
Definition: SkCanvas.cpp:1206
static std::unique_ptr< SkCodec > MakeFromData(sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
Definition: SkCodec.cpp:241
@ kYes_ZeroInitialized
Definition: SkCodec.h:308
@ kNo_ZeroInitialized
Definition: SkCodec.h:315
@ kTopDown_SkScanlineOrder
Definition: SkCodec.h:581
Result
Definition: SkCodec.h:76
@ kInvalidConversion
Definition: SkCodec.h:96
@ kIncompleteInput
Definition: SkCodec.h:84
@ kInvalidInput
Definition: SkCodec.h:109
@ kSuccess
Definition: SkCodec.h:80
@ kErrorInInput
Definition: SkCodec.h:91
static constexpr int kNoFrame
Definition: SkCodec.h:650
static sk_sp< SkData > MakeFromFileName(const char path[])
Definition: SkData.cpp:148
bool endsWith(const char suffixStr[]) const
Definition: SkString.h:146
const char * c_str() const
Definition: SkString.h:133
#define H
GAsyncResult * result
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
double y
double x
static void draw_to_canvas(SkCanvas *canvas, const SkImageInfo &info, void *pixels, size_t rowBytes, CodecSrc::DstColorType dstColorType, SkScalar left=0, SkScalar top=0)
Definition: DMSrcSink.cpp:456
static void set_bitmap_color_space(SkImageInfo *info)
Definition: DMSrcSink.cpp:470
static bool get_decode_info(SkImageInfo *decodeInfo, SkColorType canvasColorType, CodecSrc::DstColorType dstColorType, SkAlphaType dstAlphaType)
Definition: DMSrcSink.cpp:422
dst
Definition: cp.py:12
string root
Definition: scale_cpu.py:20
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
Definition: SkVx.h:706
SkScalar w
SkScalar h
int32_t height
int32_t width
Definition: SkMD5.cpp:130
Definition: SkRect.h:32
void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height)
Definition: SkRect.h:268
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition: SkRect.h:104
Definition: SkSize.h:16
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37
SkImageInfo makeWH(int newWidth, int newHeight) const
Definition: SkImageInfo.h:444
size_t minRowBytes() const
Definition: SkImageInfo.h:517
size_t computeByteSize(size_t rowBytes) const
SkImageInfo makeDimensions(SkISize newSize) const
Definition: SkImageInfo.h:454
int bytesPerPixel() const
Definition: SkImageInfo.h:492
SkISize dimensions() const
Definition: SkImageInfo.h:421
int width() const
Definition: SkImageInfo.h:365
SkColorType colorType() const
Definition: SkImageInfo.h:373
int height() const
Definition: SkImageInfo.h:371
SkImageInfo makeColorType(SkColorType newColorType) const
Definition: SkImageInfo.h:475

◆ name()

Name DM::CodecSrc::name ( ) const
overridevirtual

Implements DM::Src.

Definition at line 852 of file DMSrcSink.cpp.

852 {
854 if (fMode == kAnimated_Mode) {
855 name.append("_animated");
856 }
857 if (1.0f == fScale) {
858 return name;
859 }
860 return get_scaled_name(name.c_str(), fScale);
861}
Name name() const override
Definition: DMSrcSink.cpp:852
static SkString Basename(const char *fullPath)
Definition: SkOSPath.cpp:23
void append(const char text[])
Definition: SkString.h:203
ImplicitString Name
Definition: DMSrcSink.h:38
static SkString get_scaled_name(const Path &path, float scale)
Definition: DMSrcSink.cpp:199

◆ serial()

bool DM::CodecSrc::serial ( ) const
inlineoverridevirtual

Reimplemented from DM::Src.

Definition at line 177 of file DMSrcSink.h.

177{ return fRunSerially; }

◆ size()

SkISize DM::CodecSrc::size ( ) const
overridevirtual

Implements DM::Src.

Definition at line 827 of file DMSrcSink.cpp.

827 {
829 std::unique_ptr<SkCodec> codec(SkCodec::MakeFromData(encoded));
830 if (nullptr == codec) {
831 return {0, 0};
832 }
833
834 if (fMode != kAnimated_Mode) {
835 return codec->getScaledDimensions(fScale);
836 }
837
838 // We'll draw one of each frame, so make it big enough to hold them all
839 // in a grid. The grid will be roughly square, with "factor" frames per
840 // row and up to "factor" rows.
841 const size_t count = codec->getFrameInfo().size();
842 const float root = sqrt((float) count);
843 const int factor = sk_float_ceil2int(root);
844
845 auto androidCodec = SkAndroidCodec::MakeFromCodec(std::move(codec));
846 auto imageSize = androidCodec->getSampledDimensions(1 / fScale);
847 imageSize.fWidth = imageSize.fWidth * factor;
848 imageSize.fHeight = imageSize.fHeight * sk_float_ceil2int((float) count / (float) factor);
849 return imageSize;
850}
int count
Definition: FontMgrTest.cpp:50
static std::unique_ptr< SkAndroidCodec > MakeFromCodec(std::unique_ptr< SkCodec >)

◆ veto()

bool DM::CodecSrc::veto ( SinkFlags  flags) const
overridevirtual

Reimplemented from DM::Src.

Definition at line 405 of file DMSrcSink.cpp.

405 {
406 // Test to direct raster backends (8888 and 565).
407 return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDirect;
408}
FlutterSemanticsFlag flags

The documentation for this class was generated from the following files: