Flutter Engine
The Flutter Engine
Classes | Typedefs | Functions | Variables
impeller::testing Namespace Reference

Classes

class  BlendFilterContentsTest
 
struct  BlendModeSelection
 
struct  CheckSameSignature
 
struct  CheckSameSignature< Ret(Args...), Ret(Args...)>
 
struct  ColorBlendTestData
 
class  CommandBufferMock
 
class  CompareFunctionUIData
 
class  ContextMock
 
class  ContextSpy
 
struct  CVTest
 
struct  Foo
 
class  GaussianBlurFilterContentsTest
 
class  GoldenDigest
 Manages a global variable for tracking instances of golden images. More...
 
class  GoldenTests
 
struct  MaskBlurTestConfig
 
class  MatrixFilterContentsTest
 
class  MetalScreenshot
 A screenshot that was produced from MetalScreenshotter. More...
 
class  MetalScreenshotter
 
class  MockAllocator
 
class  MockBlitPass
 
class  MockCapabilities
 
class  MockCommandBuffer
 
class  MockCommandQueue
 
class  MockDeviceBuffer
 
class  MockFence
 
class  MockGLES
 Provides a mocked version of the |ProcTableGLES| class. More...
 
class  MockImpellerContext
 
class  MockRenderPass
 
class  MockSampler
 
class  MockSamplerLibrary
 
class  MockTexture
 
class  MockVulkanContextBuilder
 
class  NoopCommandQueue
 
class  RendererDartTest
 
struct  RWFoo
 
class  Screenshot
 
class  Screenshotter
 
class  TestAllocator
 
class  TestPassDelegate
 
struct  TextRenderOptions
 
class  VulkanScreenshotter
 
class  WorkingDirectory
 

Typedefs

using AiksTest = AiksPlayground
 
using AiksCanvasTest = ::testing::Test
 
using DisplayListTest = DlPlayground
 
using EntityTest = EntityPlayground
 
using HostBufferTest = EntityPlayground
 
using EntityPassTargetTest = EntityPlayground
 
using RenderTargetCacheTest = EntityPlayground
 
using DriverInfoVKTest = PlaygroundTest
 
using RendererTest = PlaygroundTest
 
using BlitPassTest = PlaygroundTest
 
using ComputeTest = ComputePlaygroundTest
 
using DeviceBufferTest = Playground
 
using RuntimeStageTest = RuntimeStagePlayground
 
using TypographerTest = PlaygroundTest
 

Functions

 TEST_P (AiksTest, CanRenderAdvancedBlendColorFilterWithSaveLayer)
 
 TEST_P (AiksTest, BlendModeShouldCoverWholeScreen)
 
 TEST_P (AiksTest, CanDrawPaintWithAdvancedBlend)
 
 TEST_P (AiksTest, DrawPaintWithAdvancedBlendOverFilter)
 
 TEST_P (AiksTest, DrawAdvancedBlendPartlyOffscreen)
 
 TEST_P (AiksTest, PaintBlendModeIsRespected)
 
 TEST_P (AiksTest, BlendModePlusAlphaWideGamut)
 
 TEST_P (AiksTest, BlendModePlusAlphaColorFilterWideGamut)
 
static BlendModeSelection GetBlendModeSelection ()
 
 TEST_P (AiksTest, ColorWheel)
 
 TEST_P (AiksTest, ForegroundBlendSubpassCollapseOptimization)
 
 TEST_P (AiksTest, ClearBlend)
 
static Picture BlendModeTest (Vector2 content_scale, BlendMode blend_mode, const std::shared_ptr< Image > &src_image, const std::shared_ptr< Image > &dst_image, Scalar src_alpha)
 
 TEST_P (AiksTest, CanDrawPaintMultipleTimesInteractive)
 
 TEST_P (AiksTest, ForegroundPipelineBlendAppliesTransformCorrectly)
 
 TEST_P (AiksTest, ForegroundAdvancedBlendAppliesTransformCorrectly)
 
 TEST_P (AiksTest, FramebufferAdvancedBlendCoverage)
 
 TEST_P (AiksTest, CanRenderMaskBlurHugeSigma)
 
 TEST_P (AiksTest, CanRenderForegroundBlendWithMaskBlur)
 
 TEST_P (AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur)
 
 TEST_P (AiksTest, CanRenderBackdropBlurInteractive)
 
 TEST_P (AiksTest, CanRenderBackdropBlur)
 
 TEST_P (AiksTest, CanRenderBackdropBlurHugeSigma)
 
 TEST_P (AiksTest, CanRenderClippedBlur)
 
 TEST_P (AiksTest, ClippedBlurFilterRendersCorrectlyInteractive)
 
 TEST_P (AiksTest, ClippedBlurFilterRendersCorrectly)
 
 TEST_P (AiksTest, ClearBlendWithBlur)
 
 TEST_P (AiksTest, BlurHasNoEdge)
 
 TEST_P (AiksTest, BlurredRectangleWithShader)
 
 TEST_P (AiksTest, MaskBlurWithZeroSigmaIsSkipped)
 
static Picture MaskBlurVariantTest (const AiksTest &test_context, const MaskBlurTestConfig &config)
 
 TEST_P (AiksTest, GaussianBlurAtPeripheryVertical)
 
 TEST_P (AiksTest, GaussianBlurAtPeripheryHorizontal)
 
 TEST_P (AiksTest, GaussianBlurWithoutDecalSupport)
 
 TEST_P (AiksTest, GaussianBlurOneDimension)
 
 TEST_P (AiksTest, GaussianBlurRotatedAndClipped)
 
 TEST_P (AiksTest, GaussianBlurScaledAndClipped)
 
 TEST_P (AiksTest, GaussianBlurRotatedAndClippedInteractive)
 
 TEST_P (AiksTest, GaussianBlurRotatedNonUniform)
 
 TEST_P (AiksTest, GaussianBlurSolidColorTinyMipMap)
 
 TEST_P (AiksTest, GaussianBlurBackdropTinyMipMap)
 
 TEST_P (AiksTest, GaussianBlurAnimatedBackdrop)
 
 TEST_P (AiksTest, GaussianBlurStyleInnerGradient)
 
 TEST_P (AiksTest, GaussianBlurStyleSolidGradient)
 
 TEST_P (AiksTest, GaussianBlurStyleOuterGradient)
 
 TEST_P (AiksTest, GaussianBlurStyleInner)
 
 TEST_P (AiksTest, GaussianBlurStyleOuter)
 
 TEST_P (AiksTest, GaussianBlurStyleSolid)
 
 TEST_P (AiksTest, MaskBlurTexture)
 
 TEST_P (AiksTest, GuassianBlurUpdatesMipmapContents)
 
 TEST_P (AiksTest, GaussianBlurSetsMipCountOnPass)
 
 TEST_P (AiksTest, GaussianBlurAllocatesCorrectMipCountRenderTarget)
 
 TEST_P (AiksTest, GaussianBlurMipMapNestedLayer)
 
 TEST_P (AiksTest, GaussianBlurMipMapImageFilter)
 
 TEST_P (AiksTest, GaussianBlurMipMapSolidColor)
 
 TEST_P (AiksTest, MaskBlurDoesntStretchContents)
 
 APPLY_COLOR_FILTER_GRADIENT_TEST (Linear)
 
 APPLY_COLOR_FILTER_GRADIENT_TEST (Radial)
 
 APPLY_COLOR_FILTER_GRADIENT_TEST (Conical)
 
 APPLY_COLOR_FILTER_GRADIENT_TEST (Sweep)
 
 TEST_P (AiksTest, CanRenderStrokes)
 
 TEST_P (AiksTest, CanRenderCurvedStrokes)
 
 TEST_P (AiksTest, CanRenderThickCurvedStrokes)
 
 TEST_P (AiksTest, CanRenderThinCurvedStrokes)
 
 TEST_P (AiksTest, CanRenderStrokePathThatEndsAtSharpTurn)
 
 TEST_P (AiksTest, CanRenderStrokePathWithCubicLine)
 
 TEST_P (AiksTest, CanRenderQuadraticStrokeWithInstantTurn)
 
 TEST_P (AiksTest, CanRenderDifferencePaths)
 
 TEST_P (AiksTest, CanDrawAnOpenPath)
 
 TEST_P (AiksTest, CanDrawAnOpenPathThatIsntARect)
 
 TEST_P (AiksTest, SolidStrokesRenderCorrectly)
 
 TEST_P (AiksTest, DrawLinesRenderCorrectly)
 
 TEST_P (AiksTest, DrawRectStrokesRenderCorrectly)
 
 TEST_P (AiksTest, DrawRectStrokesWithBevelJoinRenderCorrectly)
 
 TEST_P (AiksTest, CanDrawMultiContourConvexPath)
 
 TEST_P (AiksTest, ArcWithZeroSweepAndBlur)
 
 TEST_P (AiksTest, CanRenderClips)
 
 TEST_P (AiksTest, CanRenderOverlappingMultiContourPath)
 
 INSTANTIATE_PLAYGROUND_SUITE (AiksTest)
 
 TEST_P (AiksTest, CanvasCTMCanBeUpdated)
 
 TEST_P (AiksTest, CanvasCanPushPopCTM)
 
 TEST_P (AiksTest, CanRenderColoredRect)
 
 TEST_P (AiksTest, CanRenderImage)
 
 TEST_P (AiksTest, CanRenderInvertedImageWithColorFilter)
 
 TEST_P (AiksTest, CanRenderColorFilterWithInvertColors)
 
 TEST_P (AiksTest, CanRenderColorFilterWithInvertColorsDrawPaint)
 
 TEST_P (AiksTest, CanRenderTiledTextureClamp)
 
 TEST_P (AiksTest, CanRenderTiledTextureRepeat)
 
 TEST_P (AiksTest, CanRenderTiledTextureMirror)
 
 TEST_P (AiksTest, CanRenderTiledTextureDecal)
 
 TEST_P (AiksTest, CanRenderTiledTextureClampWithTranslate)
 
 TEST_P (AiksTest, CanRenderImageRect)
 
 TEST_P (AiksTest, CanRenderSimpleClips)
 
 TEST_P (AiksTest, CanSaveLayerStandalone)
 
 TEST_P (AiksTest, CanRenderDifferentShapesWithSameColorSource)
 
 TEST_P (AiksTest, CanPictureConvertToImage)
 
 TEST_P (AiksTest, CanEmptyPictureConvertToImage)
 
 TEST_P (AiksTest, CoordinateConversionsAreCorrect)
 
 TEST_P (AiksTest, CanPerformFullScreenMSAA)
 
 TEST_P (AiksTest, CanPerformSkew)
 
 TEST_P (AiksTest, CanPerformSaveLayerWithBounds)
 
 TEST_P (AiksTest, CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated)
 
 TEST_P (AiksTest, CanRenderRoundedRectWithNonUniformRadii)
 
bool RenderTextInCanvasSkia (const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string_view &font_fixture, TextRenderOptions options={})
 
bool RenderTextInCanvasSTB (const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string &font_fixture, TextRenderOptions options={})
 
 TEST_P (AiksTest, CanRenderTextFrame)
 
 TEST_P (AiksTest, CanRenderStrokedTextFrame)
 
 TEST_P (AiksTest, CanRenderTextFrameWithHalfScaling)
 
 TEST_P (AiksTest, CanRenderTextFrameWithFractionScaling)
 
 TEST_P (AiksTest, CanRenderTextFrameSTB)
 
 TEST_P (AiksTest, TextFrameSubpixelAlignment)
 
 TEST_P (AiksTest, CanRenderItalicizedText)
 
 TEST_P (AiksTest, CanRenderEmojiTextFrame)
 
 TEST_P (AiksTest, CanRenderEmojiTextFrameWithBlur)
 
 TEST_P (AiksTest, CanRenderEmojiTextFrameWithAlpha)
 
 TEST_P (AiksTest, CanRenderTextInSaveLayer)
 
 TEST_P (AiksTest, CanRenderTextOutsideBoundaries)
 
 TEST_P (AiksTest, TextRotated)
 
 TEST_P (AiksTest, CanDrawPaint)
 
 TEST_P (AiksTest, CanDrawPaintMultipleTimes)
 
 TEST_P (AiksTest, FormatWideGamut)
 
 TEST_P (AiksTest, FormatSRGB)
 
 TEST_P (AiksTest, TransformMultipliesCorrectly)
 
 TEST_P (AiksTest, FilledCirclesRenderCorrectly)
 
 TEST_P (AiksTest, StrokedCirclesRenderCorrectly)
 
 TEST_P (AiksTest, FilledEllipsesRenderCorrectly)
 
 TEST_P (AiksTest, FilledRoundRectsRenderCorrectly)
 
 TEST_P (AiksTest, SolidColorCirclesOvalsRRectsMaskBlurCorrectly)
 
 TEST_P (AiksTest, FilledRoundRectPathsRenderCorrectly)
 
 TEST_P (AiksTest, CoverageOriginShouldBeAccountedForInSubpasses)
 
 TEST_P (AiksTest, SaveLayerDrawsBehindSubsequentEntities)
 
 TEST_P (AiksTest, SiblingSaveLayerBoundsAreRespected)
 
 TEST_P (AiksTest, CanRenderClippedLayers)
 
 TEST_P (AiksTest, SaveLayerFiltersScaleWithTransform)
 
 TEST_P (AiksTest, PaintWithFilters)
 
 TEST_P (AiksTest, DrawPaintAbsorbsClears)
 
 TEST_P (AiksTest, ParentSaveLayerCreatesRenderPassWhenChildBackdropFilterIsPresent)
 
 TEST_P (AiksTest, DrawRectAbsorbsClears)
 
 TEST_P (AiksTest, DrawRectAbsorbsClearsNegativeRRect)
 
 TEST_P (AiksTest, DrawRectAbsorbsClearsNegativeRotation)
 
 TEST_P (AiksTest, DrawRectAbsorbsClearsNegative)
 
 TEST_P (AiksTest, ClipRectElidesNoOpClips)
 
 TEST_P (AiksTest, ClearColorOptimizationDoesNotApplyForBackdropFilters)
 
 TEST_P (AiksTest, CollapsedDrawPaintInSubpass)
 
 TEST_P (AiksTest, CollapsedDrawPaintInSubpassBackdropFilter)
 
 TEST_P (AiksTest, ColorMatrixFilterSubpassCollapseOptimization)
 
 TEST_P (AiksTest, LinearToSrgbFilterSubpassCollapseOptimization)
 
 TEST_P (AiksTest, SrgbToLinearFilterSubpassCollapseOptimization)
 
 TEST_P (AiksTest, TranslucentSaveLayerDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly)
 
 TEST_P (AiksTest, ImageFilteredSaveLayerWithUnboundedContents)
 
 TEST_P (AiksTest, ImageFilteredUnboundedSaveLayerWithUnboundedContents)
 
 TEST_P (AiksTest, TranslucentSaveLayerImageDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly)
 
 TEST_P (AiksTest, CanRenderTinyOverlappingSubpasses)
 
 TEST_P (AiksTest, OpaqueEntitiesGetCoercedToSource)
 
 TEST_P (AiksTest, CanRenderDestructiveSaveLayer)
 
 TEST_P (AiksTest, CanRenderClippedRuntimeEffects)
 
 TEST_P (AiksTest, DrawPaintTransformsBounds)
 
 TEST_P (AiksTest, CanDrawPoints)
 
 TEST_P (AiksTest, CanDrawPointsWithTextureMap)
 
 TEST_P (AiksTest, TextForegroundShaderWithTransform)
 
 TEST_P (AiksTest, MatrixSaveLayerFilter)
 
 TEST_P (AiksTest, MatrixBackdropFilter)
 
 TEST_P (AiksTest, SolidColorApplyColorFilter)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveSaveLayer)
 
 TEST_P (AiksTest, PipelineBlendSingleParameter)
 
 TEST_P (AiksTest, ReleasesTextureOnTeardown)
 
 TEST_P (AiksTest, MatrixImageFilterMagnify)
 
 TEST_P (AiksTest, MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen)
 
 TEST_P (AiksTest, MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen)
 
 TEST_P (AiksTest, ClearColorOptimizationWhenSubpassIsBiggerThanParentPass)
 
 TEST_P (AiksTest, EmptySaveLayerIgnoresPaint)
 
 TEST_P (AiksTest, EmptySaveLayerRendersWithClear)
 
 TEST_P (AiksTest, SubpassWithClearColorOptimization)
 
 TEST_P (AiksTest, ImageColorSourceEffectTransform)
 
 TEST_P (AiksTest, CorrectClipDepthAssignedToEntities)
 
 TEST_P (AiksTest, CanDrawPerspectiveTransformWithClips)
 
 TEST_P (AiksTest, CanRenderClippedBackdropFilter)
 
 TEST_P (AiksTest, MipmapGenerationWorksCorrectly)
 
 TEST_P (AiksTest, StrokedPathWithMoveToThenCloseDrawnCorrectly)
 
 TEST_P (AiksTest, CanRenderTextWithLargePerspectiveTransform)
 
 TEST_P (AiksTest, SetContentsWithRegion)
 
 TEST (AiksCanvasTest, EmptyCullRect)
 
 TEST (AiksCanvasTest, InitialCullRect)
 
 TEST (AiksCanvasTest, TranslatedCullRect)
 
 TEST (AiksCanvasTest, ScaledCullRect)
 
 TEST (AiksCanvasTest, RectClipIntersectAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RectClipIntersectAgainstCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstNonCoveredCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAboveCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffBelowCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffLeftOfCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffRightOfCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstVCoveredCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstHCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipIntersectAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RRectClipIntersectAgainstCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstNonCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstVPartiallyCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstVFullyCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstHPartiallyCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstHFullyCoveredCullRect)
 
 TEST (AiksCanvasTest, PathClipIntersectAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, PathClipDiffAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, PathClipIntersectAgainstCullRect)
 
 TEST (AiksCanvasTest, PathClipDiffAgainstNonCoveredCullRect)
 
 TEST (AiksCanvasTest, PathClipDiffAgainstFullyCoveredCullRect)
 
 TEST (AiksCanvasTest, DisableLocalBoundsRectForFilteredSaveLayers)
 
 TEST (ThreadTest, CanCreateMutex)
 
 TEST (ThreadTest, CanCreateMutexLock)
 
 TEST (ThreadTest, CanCreateRWMutex)
 
 TEST (ThreadTest, CanCreateRWMutexLock)
 
 TEST (StringsTest, CanSPrintF)
 
 TEST (ConditionVariableTest, WaitUntil)
 
 TEST (ConditionVariableTest, WaitFor)
 
 TEST (ConditionVariableTest, WaitForever)
 
 TEST (ConditionVariableTest, TestsCriticalSectionAfterWaitForUntil)
 
 TEST (ConditionVariableTest, TestsCriticalSectionAfterWait)
 
 TEST (BaseTest, NoExceptionPromiseValue)
 
 TEST (BaseTest, NoExceptionPromiseEmpty)
 
 TEST (BaseTest, CanUseTypedMasks)
 
 TEST (AllocatorTest, TextureDescriptorCompatibility)
 
 TEST_P (AiksTest, DrawAtlasNoColor)
 
 TEST_P (AiksTest, DrawAtlasWithColorAdvanced)
 
 TEST_P (AiksTest, DrawAtlasWithColorSimple)
 
 TEST_P (AiksTest, DrawAtlasWithOpacity)
 
 TEST_P (AiksTest, DrawAtlasNoColorFullSize)
 
 TEST_P (AiksTest, DrawAtlasAdvancedAndTransform)
 
 TEST_P (AiksTest, DrawAtlasWithColorAdvancedAndTransform)
 
 TEST_P (AiksTest, DrawAtlasPlusWideGamut)
 
 TEST_P (AiksTest, CanRenderNestedClips)
 
 TEST_P (AiksTest, CanRenderDifferenceClips)
 
 TEST_P (AiksTest, CanRenderWithContiguousClipRestores)
 
 TEST_P (AiksTest, ClipsUseCurrentTransform)
 
 TEST_P (AiksTest, CanRenderLinearGradientClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientRepeat)
 
 TEST_P (AiksTest, CanRenderLinearGradientMirror)
 
 TEST_P (AiksTest, CanRenderLinearGradientDecal)
 
 TEST_P (AiksTest, CanRenderLinearGradientDecalWithColorFilter)
 
static void CanRenderLinearGradientWithDithering (AiksTest *aiks_test)
 
 TEST_P (AiksTest, CanRenderLinearGradientWithDitheringEnabled)
 
static void CanRenderRadialGradientWithDithering (AiksTest *aiks_test)
 
 TEST_P (AiksTest, CanRenderRadialGradientWithDitheringEnabled)
 
static void CanRenderSweepGradientWithDithering (AiksTest *aiks_test)
 
 TEST_P (AiksTest, CanRenderSweepGradientWithDitheringEnabled)
 
static void CanRenderConicalGradientWithDithering (AiksTest *aiks_test)
 
 TEST_P (AiksTest, CanRenderConicalGradientWithDitheringEnabled)
 
 TEST_P (AiksTest, CanRenderLinearGradientWithOverlappingStopsClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsRepeat)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsMirror)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsDecal)
 
 TEST_P (AiksTest, CanRenderLinearGradientWayManyColorsClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsUnevenStops)
 
 TEST_P (AiksTest, CanRenderLinearGradientMaskBlur)
 
 TEST_P (AiksTest, CanRenderRadialGradient)
 
 TEST_P (AiksTest, CanRenderRadialGradientManyColors)
 
 TEST_P (AiksTest, CanRenderSweepGradientClamp)
 
 TEST_P (AiksTest, CanRenderSweepGradientRepeat)
 
 TEST_P (AiksTest, CanRenderSweepGradientMirror)
 
 TEST_P (AiksTest, CanRenderSweepGradientDecal)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsClamp)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsRepeat)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsMirror)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsDecal)
 
 TEST_P (AiksTest, CanRenderConicalGradient)
 
 TEST_P (AiksTest, CanRenderGradientDecalWithBackground)
 
 TEST_P (AiksTest, GradientStrokesRenderCorrectly)
 
 TEST_P (AiksTest, FastGradientTestHorizontal)
 
 TEST_P (AiksTest, FastGradientTestVertical)
 
 TEST_P (AiksTest, FastGradientTestHorizontalReversed)
 
 TEST_P (AiksTest, FastGradientTestVerticalReversed)
 
 TEST_P (AiksTest, VerifyNonOptimizedGradient)
 
 TEST_P (AiksTest, DrawOpacityPeephole)
 
 TEST_P (AiksTest, CanRenderGroupOpacity)
 
 TEST_P (AiksTest, CanRenderGroupOpacityToSavelayer)
 
 TEST_P (AiksTest, RotateColorFilteredPath)
 
 TEST_P (AiksTest, VerticesGeometryUVPositionData)
 
 TEST_P (AiksTest, VerticesGeometryUVPositionDataWithTranslate)
 
 TEST_P (AiksTest, VerticesGeometryColorUVPositionData)
 
 TEST_P (AiksTest, VerticesGeometryColorUVPositionDataAdvancedBlend)
 
 TEST_P (AiksTest, CanConvertTriangleFanToTriangles)
 
 TEST_P (AiksTest, DrawVerticesSolidColorTrianglesWithoutIndices)
 
 TEST_P (AiksTest, DrawVerticesLinearGradientWithoutIndices)
 
 TEST_P (AiksTest, DrawVerticesLinearGradientWithTextureCoordinates)
 
 TEST_P (AiksTest, DrawVerticesImageSourceWithTextureCoordinates)
 
 TEST_P (AiksTest, DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending)
 
 TEST_P (AiksTest, DrawVerticesSolidColorTrianglesWithIndices)
 
 TEST_P (AiksTest, DrawVerticesPremultipliesColors)
 
flutter::DlColor toColor (const float *components)
 
 INSTANTIATE_PLAYGROUND_SUITE (DisplayListTest)
 
 TEST_P (DisplayListTest, CanDrawRect)
 
 TEST_P (DisplayListTest, CanDrawTextBlob)
 
 TEST_P (DisplayListTest, CanDrawTextBlobWithGradient)
 
 TEST_P (DisplayListTest, CanDrawTextWithSaveLayer)
 
 TEST_P (DisplayListTest, CanDrawImage)
 
 TEST_P (DisplayListTest, CanDrawCapsAndJoins)
 
 TEST_P (DisplayListTest, CanDrawArc)
 
 TEST_P (DisplayListTest, StrokedPathsDrawCorrectly)
 
 TEST_P (DisplayListTest, CanDrawWithOddPathWinding)
 
 TEST_P (DisplayListTest, CanDrawAnOpenPath)
 
 TEST_P (DisplayListTest, CanDrawWithMaskBlur)
 
 TEST_P (DisplayListTest, CanDrawStrokedText)
 
 TEST_P (DisplayListTest, StrokedTextNotOffsetFromNormalText)
 
 TEST_P (DisplayListTest, IgnoreMaskFilterWhenSavingLayer)
 
 TEST_P (DisplayListTest, CanDrawWithBlendColorFilter)
 
 TEST_P (DisplayListTest, CanDrawWithColorFilterImageFilter)
 
 TEST_P (DisplayListTest, CanDrawWithImageBlurFilter)
 
 TEST_P (DisplayListTest, CanDrawWithComposeImageFilter)
 
 TEST_P (DisplayListTest, CanClampTheResultingColorOfColorMatrixFilter)
 
 TEST_P (DisplayListTest, CanDrawBackdropFilter)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImage)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCenterWidthBiggerThanDest)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCenterHeightBiggerThanDest)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCenterBiggerThanDest)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCornersScaledDown)
 
 TEST_P (DisplayListTest, NinePatchImagePrecision)
 
 TEST_P (DisplayListTest, CanDrawPoints)
 
 TEST_P (DisplayListTest, CanDrawZeroLengthLine)
 
 TEST_P (DisplayListTest, CanDrawShadow)
 
 TEST_P (DisplayListTest, DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists)
 
 TEST_P (DisplayListTest, TransparentShadowProducesCorrectColor)
 
 TEST_P (DisplayListTest, CanDrawZeroWidthLine)
 
 TEST_P (DisplayListTest, CanDrawWithMatrixFilter)
 
 TEST_P (DisplayListTest, CanDrawWithMatrixFilterWhenSavingLayer)
 
 TEST_P (DisplayListTest, CanDrawRectWithLinearToSrgbColorFilter)
 
 TEST_P (DisplayListTest, CanDrawPaintWithColorSource)
 
 TEST_P (DisplayListTest, CanBlendDstOverAndDstCorrectly)
 
 TEST_P (DisplayListTest, CanDrawCorrectlyWithColorFilterAndImageFilter)
 
 TEST_P (DisplayListTest, MaskBlursApplyCorrectlyToColorSources)
 
 TEST_P (DisplayListTest, DrawShapes)
 
 TEST_P (DisplayListTest, ClipDrawRRectWithNonCircularRadii)
 
 TEST_P (DisplayListTest, DrawVerticesBlendModes)
 
template<typename Contents >
static std::optional< RectGetCoverageOfFirstEntity (const Picture &picture)
 
 TEST (DisplayListTest, RRectBoundsComputation)
 
 TEST (DisplayListTest, CircleBoundsComputation)
 
 TEST_P (DisplayListTest, DrawPaintIgnoresMaskFilter)
 
 TEST_P (DisplayListTest, DrawMaskBlursThatMightUseSaveLayers)
 
 TEST (SkiaConversionsTest, SkPointToPoint)
 
 TEST (SkiaConversionsTest, SkPointToSize)
 
 TEST (SkiaConversionsTest, ToColor)
 
 TEST (SkiaConversionsTest, GradientStopConversion)
 
 TEST (SkiaConversionsTest, GradientMissing0)
 
 TEST (SkiaConversionsTest, GradientMissingLastValue)
 
 TEST (SkiaConversionsTest, GradientStopGreaterThan1)
 
 TEST (SkiaConversionsTest, GradientConversionNonMonotonic)
 
 TEST (SkiaConversionsTest, IsNearlySimpleRRect)
 
 TEST_P (EntityTest, ClipContentsOptimizesFullScreenIntersectClips)
 
 INSTANTIATE_PLAYGROUND_SUITE (BlendFilterContentsTest)
 
 TEST_P (BlendFilterContentsTest, AdvancedBlendColorAlignsColorTo4)
 
 INSTANTIATE_PLAYGROUND_SUITE (GaussianBlurFilterContentsTest)
 
 TEST (GaussianBlurFilterContentsTest, Create)
 
 TEST (GaussianBlurFilterContentsTest, CoverageEmpty)
 
 TEST (GaussianBlurFilterContentsTest, CoverageSimple)
 
 TEST (GaussianBlurFilterContentsTest, CoverageWithSigma)
 
 TEST_P (GaussianBlurFilterContentsTest, CoverageWithTexture)
 
 TEST_P (GaussianBlurFilterContentsTest, CoverageWithEffectTransform)
 
 TEST (GaussianBlurFilterContentsTest, FilterSourceCoverage)
 
 TEST (GaussianBlurFilterContentsTest, CalculateSigmaValues)
 
 TEST_P (GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverage)
 
 TEST_P (GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverageTranslate)
 
 TEST_P (GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverageRotated)
 
 TEST_P (GaussianBlurFilterContentsTest, CalculateUVsSimple)
 
 TEST_P (GaussianBlurFilterContentsTest, TextureContentsWithDestinationRect)
 
 TEST_P (GaussianBlurFilterContentsTest, TextureContentsWithDestinationRectScaled)
 
 TEST_P (GaussianBlurFilterContentsTest, TextureContentsWithEffectTransform)
 
 TEST (GaussianBlurFilterContentsTest, CalculateSigmaForBlurRadius)
 
 TEST (GaussianBlurFilterContentsTest, Coefficients)
 
 TEST (GaussianBlurFilterContentsTest, LerpHackKernelSamplesSimple)
 
 TEST (GaussianBlurFilterContentsTest, LerpHackKernelSamplesComplex)
 
 TEST (FilterInputTest, CanSetLocalTransformForTexture)
 
 TEST (FilterInputTest, IsLeaf)
 
 TEST (FilterInputTest, SetCoverageInputs)
 
 INSTANTIATE_PLAYGROUND_SUITE (MatrixFilterContentsTest)
 
 TEST (MatrixFilterContentsTest, Create)
 
 TEST (MatrixFilterContentsTest, CoverageEmpty)
 
 TEST (MatrixFilterContentsTest, CoverageSimple)
 
 TEST (MatrixFilterContentsTest, Coverage2x)
 
 TEST (MatrixFilterContentsTest, Coverage2xEffect)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageIdentity)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageTranslate)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageClippedSubpassTranslate)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageScale)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageClippedSubpassScale)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageSubpassScale)
 
 INSTANTIATE_PLAYGROUND_SUITE (HostBufferTest)
 
 TEST_P (HostBufferTest, CanEmplace)
 
 TEST_P (HostBufferTest, CanEmplaceWithAlignment)
 
 TEST_P (HostBufferTest, HostBufferInitialState)
 
 TEST_P (HostBufferTest, ResetIncrementsFrameCounter)
 
 TEST_P (HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback)
 
 TEST_P (HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBuffer)
 
 TEST_P (HostBufferTest, UnusedBuffersAreDiscardedWhenResetting)
 
 TEST_P (HostBufferTest, EmplaceWithProcIsAligned)
 
 TEST_P (EntityTest, TiledTextureContentsRendersWithCorrectPipeline)
 
 TEST_P (EntityTest, TiledTextureContentsRendersWithCorrectPipelineExternalOES)
 
 TEST_P (EntityPassTargetTest, SwapWithMSAATexture)
 
 TEST_P (EntityPassTargetTest, SwapWithMSAAImplicitResolve)
 
 TEST (EntityPassClipStackTest, CanPushAndPopEntities)
 
 TEST (EntityPassClipStackTest, CanPopEntitiesSafely)
 
 TEST (EntityPassClipStackTest, CanAppendNoChange)
 
 TEST (EntityPassClipStackTest, AppendCoverageNoChange)
 
 TEST (EntityPassClipStackTest, AppendAndRestoreClipCoverage)
 
 TEST (EntityPassClipStackTest, UnbalancedRestore)
 
 TEST (EntityPassClipStackTest, ClipAndRestoreWithSubpasses)
 
 TEST_P (EntityTest, CanCreateEntity)
 
auto CreatePassWithRectPath (Rect rect, std::optional< Rect > bounds_hint, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown, bool collapse=false)
 
 TEST_P (EntityTest, EntityPassRespectsUntrustedSubpassBoundsLimit)
 
 TEST_P (EntityTest, EntityPassTrustsSnugSubpassBoundsLimit)
 
 TEST_P (EntityTest, EntityPassCanMergeSubpassIntoParent)
 
 TEST_P (EntityTest, EntityPassCoverageRespectsCoverageLimit)
 
 TEST_P (EntityTest, FilterCoverageRespectsCropRect)
 
 TEST_P (EntityTest, CanDrawRect)
 
 TEST_P (EntityTest, CanDrawRRect)
 
 TEST_P (EntityTest, GeometryBoundsAreTransformed)
 
 TEST_P (EntityTest, ThreeStrokesInOnePath)
 
 TEST_P (EntityTest, StrokeWithTextureContents)
 
 TEST_P (EntityTest, TriangleInsideASquare)
 
 TEST_P (EntityTest, StrokeCapAndJoinTest)
 
 TEST_P (EntityTest, CubicCurveTest)
 
 TEST_P (EntityTest, CanDrawCorrectlyWithRotatedTransform)
 
 TEST_P (EntityTest, CubicCurveAndOverlapTest)
 
 TEST_P (EntityTest, SolidColorContentsStrokeSetStrokeCapsAndJoins)
 
 TEST_P (EntityTest, SolidColorContentsStrokeSetMiterLimit)
 
 TEST_P (EntityTest, BlendingModeOptions)
 
 TEST_P (EntityTest, BezierCircleScaled)
 
 TEST_P (EntityTest, Filters)
 
 TEST_P (EntityTest, GaussianBlurFilter)
 
 TEST_P (EntityTest, MorphologyFilter)
 
 TEST_P (EntityTest, SetBlendMode)
 
 TEST_P (EntityTest, ContentsGetBoundsForEmptyPathReturnsNullopt)
 
 TEST_P (EntityTest, SolidStrokeCoverageIsCorrect)
 
 TEST_P (EntityTest, BorderMaskBlurCoverageIsCorrect)
 
 TEST_P (EntityTest, SolidFillCoverageIsCorrect)
 
 TEST_P (EntityTest, SolidFillShouldRenderIsCorrect)
 
 TEST_P (EntityTest, DoesNotCullEntitiesByDefault)
 
 TEST_P (EntityTest, ClipContentsShouldRenderIsCorrect)
 
 TEST_P (EntityTest, ClipContentsGetClipCoverageIsCorrect)
 
 TEST_P (EntityTest, RRectShadowTest)
 
 TEST_P (EntityTest, ColorMatrixFilterCoverageIsCorrect)
 
 TEST_P (EntityTest, ColorMatrixFilterEditable)
 
 TEST_P (EntityTest, LinearToSrgbFilterCoverageIsCorrect)
 
 TEST_P (EntityTest, LinearToSrgbFilter)
 
 TEST_P (EntityTest, SrgbToLinearFilterCoverageIsCorrect)
 
 TEST_P (EntityTest, SrgbToLinearFilter)
 
static Vector3 RGBToYUV (Vector3 rgb, YUVColorSpace yuv_color_space)
 
static std::vector< std::shared_ptr< Texture > > CreateTestYUVTextures (Context *context, YUVColorSpace yuv_color_space)
 
 TEST_P (EntityTest, YUVToRGBFilter)
 
 TEST_P (EntityTest, RuntimeEffect)
 
 TEST_P (EntityTest, RuntimeEffectCanSuccessfullyRender)
 
 TEST_P (EntityTest, RuntimeEffectCanPrecache)
 
 TEST_P (EntityTest, RuntimeEffectSetsRightSizeWhenUniformIsStruct)
 
 TEST_P (EntityTest, InheritOpacityTest)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorAdvancedBlend)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorClearBlend)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorSrcBlend)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorDstBlend)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorSrcInBlend)
 
 TEST_P (EntityTest, CoverageForStrokePathWithNegativeValuesInTransform)
 
 TEST_P (EntityTest, SolidColorContentsIsOpaque)
 
 TEST_P (EntityTest, ConicalGradientContentsIsOpaque)
 
 TEST_P (EntityTest, LinearGradientContentsIsOpaque)
 
 TEST_P (EntityTest, RadialGradientContentsIsOpaque)
 
 TEST_P (EntityTest, SweepGradientContentsIsOpaque)
 
 TEST_P (EntityTest, TiledTextureContentsIsOpaque)
 
 TEST_P (EntityTest, PointFieldGeometryCoverage)
 
 TEST_P (EntityTest, ColorFilterContentsWithLargeGeometry)
 
 TEST_P (EntityTest, TextContentsCeilsGlyphScaleToDecimal)
 
 TEST_P (EntityTest, AdvancedBlendCoverageHintIsNotResetByEntityPass)
 
 TEST_P (EntityTest, SpecializationConstantsAreAppliedToVariants)
 
 TEST_P (EntityTest, DecalSpecializationAppliedToMorphologyFilter)
 
 TEST_P (EntityTest, ContentContextOptionsHasReasonableHashFunctions)
 
 TEST_P (EntityTest, FillPathGeometryGetPositionBufferReturnsExpectedMode)
 
 TEST_P (EntityTest, FailOnValidationError)
 
 TEST_P (EntityTest, CanComputeGeometryForEmptyPathsWithoutCrashing)
 
 TEST_P (EntityTest, CanRenderEmptyPathsWithoutCrashing)
 
 TEST (EntityGeometryTest, RectGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversAreaNoInnerRect)
 
 TEST (EntityGeometryTest, LineGeometryCoverage)
 
 TEST (EntityGeometryTest, RoundRectGeometryCoversArea)
 
 TEST (EntityGeometryTest, GeometryResultHasReasonableDefaults)
 
 TEST (EntityGeometryTest, AlphaCoverageStrokePaths)
 
 TEST_P (RenderTargetCacheTest, CachesUsedTexturesAcrossFrames)
 
 TEST_P (RenderTargetCacheTest, DoesNotPersistFailedAllocations)
 
 TEST_P (RenderTargetCacheTest, CachedTextureGetsNewAttachmentConfig)
 
 TEST_P (RenderTargetCacheTest, CreateWithEmptySize)
 
 TEST (GeometryTest, ScalarNearlyEqual)
 
 TEST (GeometryTest, MakeColumn)
 
 TEST (GeometryTest, MakeRow)
 
 TEST (GeometryTest, RotationMatrix)
 
 TEST (GeometryTest, InvertMultMatrix)
 
 TEST (GeometryTest, MatrixBasis)
 
 TEST (GeometryTest, MutliplicationMatrix)
 
 TEST (GeometryTest, DeterminantTest)
 
 TEST (GeometryTest, InvertMatrix)
 
 TEST (GeometryTest, TestDecomposition)
 
 TEST (GeometryTest, TestDecomposition2)
 
 TEST (GeometryTest, TestRecomposition)
 
 TEST (GeometryTest, TestRecomposition2)
 
 TEST (GeometryTest, MatrixVectorMultiplication)
 
 TEST (GeometryTest, MatrixMakeRotationFromQuaternion)
 
 TEST (GeometryTest, MatrixTransformDirection)
 
 TEST (GeometryTest, MatrixGetMaxBasisLength)
 
 TEST (GeometryTest, MatrixGetMaxBasisLengthXY)
 
 TEST (GeometryTest, MatrixMakeOrthographic)
 
 TEST (GeometryTest, MatrixMakePerspective)
 
 TEST (GeometryTest, MatrixGetBasisVectors)
 
 TEST (GeometryTest, MatrixGetDirectionScale)
 
 TEST (GeometryTest, MatrixTranslationScaleOnly)
 
 TEST (GeometryTest, MatrixLookAt)
 
 TEST (GeometryTest, QuaternionLerp)
 
 TEST (GeometryTest, QuaternionVectorMultiply)
 
 TEST (GeometryTest, CanGenerateMipCounts)
 
 TEST (GeometryTest, CanConvertTTypesExplicitly)
 
 TEST (GeometryTest, CanPerformAlgebraicPointOps)
 
 TEST (GeometryTest, CanPerformAlgebraicPointOpsWithArithmeticTypes)
 
 TEST (GeometryTest, PointIntegerCoercesToFloat)
 
 TEST (GeometryTest, SizeCoercesToPoint)
 
 TEST (GeometryTest, CanUsePointAssignmentOperators)
 
 TEST (GeometryTest, PointDotProduct)
 
 TEST (GeometryTest, PointCrossProduct)
 
 TEST (GeometryTest, PointReflect)
 
 TEST (GeometryTest, PointAbs)
 
 TEST (GeometryTest, PointRotate)
 
 TEST (GeometryTest, PointAngleTo)
 
 TEST (GeometryTest, PointMin)
 
 TEST (GeometryTest, Vector3Min)
 
 TEST (GeometryTest, Vector4Min)
 
 TEST (GeometryTest, PointMax)
 
 TEST (GeometryTest, Vector3Max)
 
 TEST (GeometryTest, Vector4Max)
 
 TEST (GeometryTest, PointFloor)
 
 TEST (GeometryTest, Vector3Floor)
 
 TEST (GeometryTest, Vector4Floor)
 
 TEST (GeometryTest, PointCeil)
 
 TEST (GeometryTest, Vector3Ceil)
 
 TEST (GeometryTest, Vector4Ceil)
 
 TEST (GeometryTest, PointRound)
 
 TEST (GeometryTest, Vector3Round)
 
 TEST (GeometryTest, Vector4Round)
 
 TEST (GeometryTest, PointLerp)
 
 TEST (GeometryTest, Vector3Lerp)
 
 TEST (GeometryTest, Vector4Lerp)
 
 TEST (GeometryTest, SeparatedVector2NormalizesWithConstructor)
 
 TEST (GeometryTest, SeparatedVector2GetVector)
 
 TEST (GeometryTest, SeparatedVector2GetAlignment)
 
 TEST (GeometryTest, SeparatedVector2AngleTo)
 
 TEST (GeometryTest, CanUseVector3AssignmentOperators)
 
 TEST (GeometryTest, CanPerformAlgebraicVector3Ops)
 
 TEST (GeometryTest, CanPerformAlgebraicVector3OpsWithArithmeticTypes)
 
 TEST (GeometryTest, ColorPremultiply)
 
 TEST (GeometryTest, ColorR8G8B8A8)
 
 TEST (GeometryTest, ColorLerp)
 
 TEST (GeometryTest, ColorClamp01)
 
 TEST (GeometryTest, ColorMakeRGBA8)
 
 TEST (GeometryTest, ColorApplyColorMatrix)
 
 TEST (GeometryTest, ColorLinearToSRGB)
 
 TEST (GeometryTest, ColorSRGBToLinear)
 
 TEST (GeometryTest, ColorBlendReturnsExpectedResults)
 
 TEST (GeometryTest, BlendModeToString)
 
 TEST (GeometryTest, CanConvertBetweenDegressAndRadians)
 
 TEST (GeometryTest, MatrixPrinting)
 
 TEST (GeometryTest, PointPrinting)
 
 TEST (GeometryTest, Vector3Printing)
 
 TEST (GeometryTest, Vector4Printing)
 
 TEST (GeometryTest, ColorPrinting)
 
 TEST (GeometryTest, ToIColor)
 
 TEST (GeometryTest, Gradient)
 
 TEST (GeometryTest, HalfConversions)
 
 TEST (MatrixTest, Multiply)
 
 TEST (MatrixTest, HasPerspective2D)
 
 TEST (MatrixTest, HasPerspective)
 
 TEST (MatrixTest, HasTranslation)
 
 TEST (MatrixTest, IsAligned2D)
 
 TEST (MatrixTest, IsAligned)
 
 TEST (MatrixTest, TransformHomogenous)
 
 TEST (PathTest, CubicPathComponentPolylineDoesNotIncludePointOne)
 
 TEST (PathTest, PathCreatePolyLineDoesNotDuplicatePoints)
 
 TEST (PathTest, PathBuilderSetsCorrectContourPropertiesForAddCommands)
 
 TEST (PathTest, PathCreatePolylineGeneratesCorrectContourData)
 
 TEST (PathTest, PolylineGetContourPointBoundsReturnsCorrectRanges)
 
 TEST (PathTest, PathAddRectPolylineHasCorrectContourData)
 
 TEST (PathTest, PathPolylineDuplicatesAreRemovedForSameContour)
 
 TEST (PathTest, PolylineBufferReuse)
 
 TEST (PathTest, PolylineFailsWithNullptrBuffer)
 
 TEST (PathTest, PathShifting)
 
 TEST (PathTest, PathBuilderWillComputeBounds)
 
 TEST (PathTest, PathHorizontalLine)
 
 TEST (PathTest, PathVerticalLine)
 
 TEST (PathTest, QuadradicPath)
 
 TEST (PathTest, CubicPath)
 
 TEST (PathTest, BoundingBoxCubic)
 
 TEST (PathTest, BoundingBoxOfCompositePathIsCorrect)
 
 TEST (PathTest, ExtremaOfCubicPathComponentIsCorrect)
 
 TEST (PathTest, PathGetBoundingBoxForCubicWithNoDerivativeRootsIsCorrect)
 
 TEST (PathTest, EmptyPath)
 
 TEST (PathTest, SimplePath)
 
 TEST (PathTest, RepeatCloseDoesNotAddNewLines)
 
 TEST (PathTest, CloseAfterMoveDoesNotAddNewLines)
 
 TEST (PathTest, CloseAtOriginDoesNotAddNewLineSegment)
 
 TEST (PathTest, CanBeCloned)
 
 TEST (PathTest, PathBuilderDoesNotMutateCopiedPaths)
 
 TEST (RectTest, RectEmptyDeclaration)
 
 TEST (RectTest, IRectEmptyDeclaration)
 
 TEST (RectTest, RectDefaultConstructor)
 
 TEST (RectTest, IRectDefaultConstructor)
 
 TEST (RectTest, RectSimpleLTRB)
 
 TEST (RectTest, IRectSimpleLTRB)
 
 TEST (RectTest, RectSimpleXYWH)
 
 TEST (RectTest, IRectSimpleXYWH)
 
 TEST (RectTest, RectOverflowXYWH)
 
 TEST (RectTest, IRectOverflowXYWH)
 
 TEST (RectTest, RectOverflowLTRB)
 
 TEST (RectTest, IRectOverflowLTRB)
 
 TEST (RectTest, RectMakeSize)
 
 TEST (RectTest, RectMakeMaximum)
 
 TEST (RectTest, IRectMakeMaximum)
 
 TEST (RectTest, RectFromRect)
 
 TEST (RectTest, IRectFromIRect)
 
 TEST (RectTest, RectCopy)
 
 TEST (RectTest, IRectCopy)
 
 TEST (RectTest, RectOriginSizeXYWHGetters)
 
 TEST (RectTest, IRectOriginSizeXYWHGetters)
 
 TEST (RectTest, RectRoundOutEmpty)
 
 TEST (RectTest, RectRoundOutSimple)
 
 TEST (RectTest, RectRoundOutToIRectHuge)
 
 TEST (RectTest, RectDoesNotIntersectEmpty)
 
 TEST (RectTest, IRectDoesNotIntersectEmpty)
 
 TEST (RectTest, EmptyRectDoesNotIntersect)
 
 TEST (RectTest, EmptyIRectDoesNotIntersect)
 
 TEST (RectTest, RectScale)
 
 TEST (RectTest, IRectScale)
 
 TEST (RectTest, RectArea)
 
 TEST (RectTest, IRectArea)
 
 TEST (RectTest, RectGetNormalizingTransform)
 
 TEST (RectTest, IRectGetNormalizingTransform)
 
 TEST (RectTest, RectXYWHIsEmpty)
 
 TEST (RectTest, IRectXYWHIsEmpty)
 
 TEST (RectTest, MakePointBoundsQuad)
 
 TEST (RectTest, IsSquare)
 
 TEST (RectTest, GetCenter)
 
 TEST (RectTest, RectExpand)
 
 TEST (RectTest, IRectExpand)
 
 TEST (RectTest, ContainsFloatingPoint)
 
template<typename R >
static constexpr R flip_lr (R rect)
 
template<typename R >
static constexpr R flip_tb (R rect)
 
template<typename R >
static constexpr R flip_lrtb (R rect)
 
static constexpr Rect swap_nan (const Rect &rect, int index)
 
static constexpr Point swap_nan (const Point &point, int index)
 
 TEST (RectTest, RectUnion)
 
 TEST (RectTest, OptRectUnion)
 
 TEST (RectTest, IRectUnion)
 
 TEST (RectTest, OptIRectUnion)
 
 TEST (RectTest, RectIntersection)
 
 TEST (RectTest, OptRectIntersection)
 
 TEST (RectTest, IRectIntersection)
 
 TEST (RectTest, OptIRectIntersection)
 
 TEST (RectTest, RectIntersectsWithRect)
 
 TEST (RectTest, IRectIntersectsWithRect)
 
 TEST (RectTest, RectContainsPoint)
 
 TEST (RectTest, IRectContainsIPoint)
 
 TEST (RectTest, RectContainsInclusivePoint)
 
 TEST (RectTest, IRectContainsInclusiveIPoint)
 
 TEST (RectTest, RectContainsRect)
 
 TEST (RectTest, IRectContainsIRect)
 
 TEST (RectTest, RectCutOut)
 
 TEST (RectTest, IRectCutOut)
 
 TEST (RectTest, RectGetPoints)
 
 TEST (RectTest, RectShift)
 
 TEST (RectTest, RectGetTransformedPoints)
 
 TEST (RectTest, RectMakePointBounds)
 
 TEST (RectTest, RectGetPositive)
 
 TEST (RectTest, RectDirections)
 
 TEST (RectTest, RectProject)
 
 TEST (RectTest, RectRoundOut)
 
 TEST (RectTest, IRectRoundOut)
 
 TEST (RectTest, RectRound)
 
 TEST (RectTest, IRectRound)
 
 TEST (RectTest, TransformAndClipBounds)
 
 TEST (SaturatedMath, ExplicitAddOfSignedInts)
 
 TEST (SaturatedMath, ImplicitAddOfSignedInts)
 
 TEST (SaturatedMath, ExplicitAddOfFloatingPoint)
 
 TEST (SaturatedMath, ImplicitAddOfFloatingPoint)
 
 TEST (SaturatedMath, ExplicitSubOfSignedInts)
 
 TEST (SaturatedMath, ImplicitSubOfSignedInts)
 
 TEST (SaturatedMath, ExplicitSubOfFloatingPoint)
 
 TEST (SaturatedMath, ImplicitSubOfFloatingPoint)
 
 TEST (SaturatedMath, ExplicitAverageScalarOfSignedInts)
 
 TEST (SaturatedMath, ImplicitAverageScalarOfSignedInts)
 
 TEST (SaturatedMath, ExplicitAverageScalarOfFloatingPoint)
 
 TEST (SaturatedMath, ImplicitAverageScalarOfFloatingPoint)
 
 TEST (SaturatedMath, CastingFiniteDoubleToFloatStaysFinite)
 
 TEST (SaturatedMath, CastingInfiniteDoubleToFloatStaysInfinite)
 
 TEST (SaturatedMath, CastingNaNDoubleToFloatStaysNaN)
 
 TEST (SaturatedMath, CastingLargeScalarToSignedIntProducesLimit)
 
 TEST (SaturatedMath, CastingInfiniteScalarToSignedIntProducesLimit)
 
 TEST (SaturatedMath, CastingNaNScalarToSignedIntProducesZero)
 
 TEST (SizeTest, SizeIsEmpty)
 
 TEST (SizeTest, ISizeIsEmpty)
 
 TEST (SizeTest, IsSquare)
 
 TEST (SizeTest, MaxDimension)
 
 TEST (SizeTest, NegationOperator)
 
 TEST (TrigTest, TrigAngles)
 
 TEST (TrigTest, MultiplyByScalarRadius)
 
 TEST_F (GoldenTests, ConicalGradient)
 
 TEST (CapabilitiesGLES, CanInitializeWithDefaults)
 
 TEST (CapabilitiesGLES, SupportsDecalSamplerAddressMode)
 
 TEST (CapabilitiesGLES, SupportsDecalSamplerAddressModeNotOES)
 
 TEST (CapabilitiesGLES, SupportsFramebufferFetch)
 
 TEST (FormatsGLES, CanFormatFramebufferErrorMessage)
 
void RecordGLCall (const char *name)
 
void doNothing ()
 
const unsigned char * mockGetString (GLenum name)
 
const unsigned char * mockGetStringi (GLenum name, GLuint index)
 
void mockGetIntegerv (GLenum name, int *value)
 
GLenum mockGetError ()
 
void mockPopDebugGroupKHR ()
 
void mockPushDebugGroupKHR (GLenum source, GLuint id, GLsizei length, const GLchar *message)
 
void mockGenQueriesEXT (GLsizei n, GLuint *ids)
 
void mockBeginQueryEXT (GLenum target, GLuint id)
 
void mockEndQueryEXT (GLuint id)
 
void mockGetQueryObjectuivEXT (GLuint id, GLenum target, GLuint *result)
 
void mockGetQueryObjectui64vEXT (GLuint id, GLenum target, GLuint64 *result)
 
void mockDeleteQueriesEXT (GLsizei size, const GLuint *queries)
 
 TEST (MockGLES, CanInitialize)
 
 TEST (MockGLES, CapturesPushAndPopDebugGroup)
 
 TEST (MockGLES, CanCallUnmockedFunction)
 
 TEST (ProcTableGLES, ResolvesCorrectClearDepthProcOnES)
 
 TEST (ProcTableGLES, ResolvesCorrectClearDepthProcOnDesktopGL)
 
 TEST (SpecConstant, CanCreateShaderWithSpecializationConstant)
 
 TEST (SpecConstant, CanCreateShaderWithSpecializationConstantMultipleValues)
 
 TEST (TextureMTL, CreateFromDrawable)
 
 TEST (AllocatorVKTest, ToVKImageUsageFlags)
 
 TEST (AllocatorVKTest, MemoryTypeSelectionSingleHeap)
 
 TEST (AllocatorVKTest, MemoryTypeSelectionTwoHeap)
 
 TEST (CommandEncoderVKTest, DeleteEncoderAfterThreadDies)
 
 TEST (CommandEncoderVKTest, CleanupAfterSubmit)
 
 TEST (CommandPoolRecyclerVKTest, GetsACommandPoolPerThread)
 
 TEST (CommandPoolRecyclerVKTest, GetsTheSameCommandPoolOnSameThread)
 
 TEST (CommandPoolRecyclerVKTest, ReclaimMakesCommandPoolAvailable)
 
 TEST (CommandPoolRecyclerVKTest, CommandBuffersAreRecycled)
 
 TEST (ContextVKTest, CommonHardwareConcurrencyConfigurations)
 
 TEST (ContextVKTest, DeletesCommandPools)
 
 TEST (ContextVKTest, DeletesCommandPoolsOnAllThreads)
 
 TEST (ContextVKTest, DeletePipelineAfterContext)
 
 TEST (ContextVKTest, DeleteShaderFunctionAfterContext)
 
 TEST (ContextVKTest, DeletePipelineLibraryAfterContext)
 
 TEST (ContextVKTest, CanCreateContextInAbsenceOfValidationLayers)
 
 TEST (ContextVKTest, CanCreateContextWithValidationLayers)
 
 TEST (CapabilitiesVKTest, ContextInitializesWithNoStencilFormat)
 
 TEST (CapabilitiesVKTest, ContextFailsInitializationForNoCombinedDepthStencilFormat)
 
 TEST (ContextVKTest, WarmUpFunctionCreatesRenderPass)
 
 TEST (ContextVKTest, FatalMissingValidations)
 
 TEST (ContextVKTest, HasDefaultColorFormat)
 
 TEST (DescriptorPoolRecyclerVKTest, GetDescriptorPoolRecyclerCreatesNewPools)
 
 TEST (DescriptorPoolRecyclerVKTest, ReclaimMakesDescriptorPoolAvailable)
 
 TEST (DescriptorPoolRecyclerVKTest, ReclaimDropsDescriptorPoolIfSizeIsExceeded)
 
 INSTANTIATE_VULKAN_PLAYGROUND_SUITE (DriverInfoVKTest)
 
 TEST_P (DriverInfoVKTest, CanQueryDriverInfo)
 
 TEST_P (DriverInfoVKTest, CanDumpToLog)
 
 TEST (FenceWaiterVKTest, IgnoresNullFence)
 
 TEST (FenceWaiterVKTest, IgnoresNullCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallbackX2)
 
 TEST (FenceWaiterVKTest, ExecutesNewFenceThenOldFence)
 
 TEST (FenceWaiterVKTest, AddFenceDoesNothingIfTerminating)
 
 TEST (FenceWaiterVKTest, InProgressFencesStillWaitIfTerminated)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithNoDepthStencil)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithCombinedDepthStencil)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithOnlyStencil)
 
 TEST (RenderPassBuilder, CreatesMSAAResolveWithCorrectStore)
 
 TEST_P (RendererTest, CachesRenderPassAndFramebuffer)
 
 TEST (ResourceManagerVKTest, CreatesANewInstance)
 
 TEST (ResourceManagerVKTest, ReclaimMovesAResourceAndDestroysIt)
 
 TEST (ResourceManagerVKTest, TerminatesWhenOutOfScope)
 
 TEST (ResourceManagerVKTest, IsThreadSafe)
 
std::shared_ptr< std::vector< std::string > > GetMockVulkanFunctions (VkDevice device)
 
void SetSwapchainImageSize (ISize size)
 Override the image size returned by all swapchain images. More...
 
 TEST (MockVulkanContextTest, IsThreadSafe)
 
 TEST (MockVulkanContextTest, DefaultFenceAlwaysReportsSuccess)
 
 TEST (MockVulkanContextTest, MockedFenceReportsStatus)
 
vk::UniqueSurfaceKHR CreateSurface (const ContextVK &context)
 
 TEST (SwapchainTest, CanCreateSwapchain)
 
 TEST (SwapchainTest, RecreateSwapchainWhenSizeChanges)
 
 TEST (SwapchainTest, CachesRenderPassOnSwapchainImage)
 
 INSTANTIATE_PLAYGROUND_SUITE (BlitPassTest)
 
 TEST_P (BlitPassTest, BlitAcrossDifferentPixelFormatsFails)
 
 TEST_P (BlitPassTest, BlitAcrossDifferentSampleCountsFails)
 
 TEST_P (BlitPassTest, BlitPassesForMatchingFormats)
 
 TEST_P (BlitPassTest, ChecksInvalidSliceParameters)
 
 TEST_P (BlitPassTest, CanBlitSmallRegionToUninitializedTexture)
 
 CAPABILITY_TEST (SupportsOffscreenMSAA, false)
 
 CAPABILITY_TEST (SupportsSSBO, false)
 
 CAPABILITY_TEST (SupportsTextureToTextureBlits, false)
 
 CAPABILITY_TEST (SupportsFramebufferFetch, false)
 
 CAPABILITY_TEST (SupportsCompute, false)
 
 CAPABILITY_TEST (SupportsComputeSubgroups, false)
 
 CAPABILITY_TEST (SupportsReadFromResolve, false)
 
 CAPABILITY_TEST (SupportsDecalSamplerAddressMode, false)
 
 CAPABILITY_TEST (SupportsDeviceTransientTextures, false)
 
 TEST (CapabilitiesTest, DefaultColorFormat)
 
 TEST (CapabilitiesTest, DefaultStencilFormat)
 
 TEST (CapabilitiesTest, DefaultDepthStencilFormat)
 
 TEST (CapabilitiesTest, DefaultGlyphAtlasFormat)
 
 INSTANTIATE_COMPUTE_SUITE (ComputeTest)
 
 TEST_P (ComputeTest, CapabilitiesReportSupport)
 
 TEST_P (ComputeTest, CanCreateComputePass)
 
 TEST_P (ComputeTest, CanComputePrefixSum)
 
 TEST_P (ComputeTest, 1DThreadgroupSizingIsCorrect)
 
 TEST_P (ComputeTest, CanComputePrefixSumLargeInteractive)
 
 TEST_P (ComputeTest, MultiStageInputAndOutput)
 
 TEST_P (ComputeTest, CanCompute1DimensionalData)
 
 TEST_P (ComputeTest, ReturnsEarlyWhenAnyGridDimensionIsZero)
 
 TEST (PipelineDescriptorTest, PrimitiveTypeHashEquality)
 
 TEST (PoolTest, Simple)
 
 TEST (PoolTest, Overload)
 
static void InstantiateTestShaderLibrary (Context::BackendType backend_type)
 
 INSTANTIATE_PLAYGROUND_SUITE (RendererDartTest)
 
 TEST_P (RendererDartTest, CanRunDartInPlaygroundFrame)
 
 TEST_P (RendererDartTest, CanInstantiateFlutterGPUContext)
 
 TEST_P (RendererDartTest, CanCreateShaderLibrary)
 
 TEST_P (RendererDartTest, CanReflectUniformStructs)
 
 TEST_P (RendererDartTest, UniformBindFailsForInvalidHostBufferOffset)
 
 TEST_P (RendererDartTest, CanCreateRenderPassAndSubmit)
 
 TEST_P (RendererTest, CanCreateBoxPrimitive)
 
 TEST_P (RendererTest, BabysFirstTriangle)
 
 TEST_P (RendererTest, CanRenderPerspectiveCube)
 
 TEST_P (RendererTest, CanRenderMultiplePrimitives)
 
 TEST_P (RendererTest, CanRenderToTexture)
 
 TEST_P (RendererTest, CanRenderInstanced)
 
 TEST_P (RendererTest, CanBlitTextureToTexture)
 
 TEST_P (RendererTest, CanBlitTextureToBuffer)
 
 TEST_P (RendererTest, CanGenerateMipmaps)
 
 TEST_P (RendererTest, TheImpeller)
 
 TEST_P (RendererTest, Planet)
 
 TEST_P (RendererTest, ArrayUniforms)
 
 TEST_P (RendererTest, InactiveUniforms)
 
 TEST_P (RendererTest, DefaultIndexSize)
 
 TEST_P (RendererTest, DefaultIndexBehavior)
 
 TEST_P (RendererTest, VertexBufferBuilder)
 
static const CompareFunctionUIDataCompareFunctionUI ()
 
 TEST_P (RendererTest, StencilMask)
 
 TEST_P (RendererTest, CanLookupRenderTargetProperties)
 
 TEST_P (RendererTest, RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat)
 
template<class VertexShader , class FragmentShader >
std::shared_ptr< Pipeline< PipelineDescriptor > > CreateDefaultPipeline (const std::shared_ptr< Context > &context)
 
 TEST_P (RendererTest, CanSepiaToneWithSubpasses)
 
 TEST_P (RendererTest, CanSepiaToneThenSwizzleWithSubpasses)
 
 INSTANTIATE_PLAYGROUND_SUITE (RuntimeStageTest)
 
 TEST_P (RuntimeStageTest, CanReadValidBlob)
 
 TEST_P (RuntimeStageTest, CanRejectInvalidBlob)
 
 TEST_P (RuntimeStageTest, CanReadUniforms)
 
 TEST_P (RuntimeStageTest, CanReadUniformsSamplerBeforeUBO)
 
 TEST_P (RuntimeStageTest, CanReadUniformsSamplerAfterUBO)
 
 TEST_P (RuntimeStageTest, CanRegisterStage)
 
 TEST_P (RuntimeStageTest, CanCreatePipelineFromRuntimeStage)
 
 TEST_P (RuntimeStageTest, ContainsExpectedShaderTypes)
 
static std::shared_ptr< fml::MappingCreateMappingFromString (std::string p_string)
 
const std::string CreateStringFromMapping (const fml::Mapping &mapping)
 
 TEST (ShaderArchiveTest, CanReadAndWriteBlobs)
 
 TEST (TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus)
 
 TEST (TessellatorTest, TessellateConvex)
 
 TEST (TessellatorTest, TessellateConvexUnclosedPath)
 
 TEST (TessellatorTest, CircleVertexCounts)
 
 TEST (TessellatorTest, FilledCircleTessellationVertices)
 
 TEST (TessellatorTest, StrokedCircleTessellationVertices)
 
 TEST (TessellatorTest, RoundCapLineTessellationVertices)
 
 TEST (TessellatorTest, FilledEllipseTessellationVertices)
 
 TEST (TessellatorTest, FilledRoundRectTessellationVertices)
 
 TEST (TessellatorTest, EarlyReturnEmptyConvexShape)
 
 TEST (TessellatorTest, ChecksConcurrentPolylineUsage)
 
static std::shared_ptr< GlyphAtlasCreateGlyphAtlas (Context &context, const TypographerContext *typographer_context, HostBuffer &host_buffer, GlyphAtlas::Type type, Scalar scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const TextFrame &frame)
 
static std::shared_ptr< GlyphAtlasCreateGlyphAtlas (Context &context, const TypographerContext *typographer_context, HostBuffer &host_buffer, GlyphAtlas::Type type, Scalar scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const std::vector< std::shared_ptr< TextFrame > > &frames, const std::vector< GlyphProperties > &properties)
 
 TEST_P (TypographerTest, CanConvertTextBlob)
 
 TEST_P (TypographerTest, CanCreateRenderContext)
 
 TEST_P (TypographerTest, CanCreateGlyphAtlas)
 
 TEST_P (TypographerTest, LazyAtlasTracksColor)
 
 TEST_P (TypographerTest, GlyphAtlasWithOddUniqueGlyphSize)
 
 TEST_P (TypographerTest, GlyphAtlasIsRecycledIfUnchanged)
 
 TEST_P (TypographerTest, GlyphAtlasWithLotsOfdUniqueGlyphSize)
 
 TEST_P (TypographerTest, GlyphAtlasTextureIsRecycledIfUnchanged)
 
 TEST_P (TypographerTest, GlyphColorIsPartOfCacheKey)
 
 TEST_P (TypographerTest, GlyphColorIsIgnoredForNonEmojiFonts)
 
 TEST_P (TypographerTest, RectanglePackerAddsNonoverlapingRectangles)
 
 TEST (TypographerTest, RectanglePackerFillsRows)
 
 TEST_P (TypographerTest, GlyphAtlasTextureWillGrowTilMaxTextureSize)
 

Variables

static const std::map< std::string, MaskBlurTestConfigkPaintVariations
 
static constexpr std::string_view kFontFixture
 
std::vector< Pointgolden_cubic_and_quad_points
 
static std::mutex g_test_lock
 
static std::weak_ptr< MockGLESg_mock_gles
 
static ProcTableGLES::Resolver g_resolver
 
static std::vector< const unsigned char * > g_extensions
 
static const unsigned char * g_version
 
auto const kMockVendor = (unsigned char*)"MockGLES"
 
const auto kMockShadingLanguageVersion = (unsigned char*)"GLSL ES 1.0"
 
auto const kExtensions
 
const ProcTableGLES::Resolver kMockResolverGLES
 

Typedef Documentation

◆ AiksCanvasTest

using impeller::testing::AiksCanvasTest = typedef ::testing::Test

Definition at line 16 of file canvas_unittests.cc.

◆ AiksTest

Definition at line 17 of file aiks_unittests.h.

◆ BlitPassTest

Definition at line 16 of file blit_pass_unittests.cc.

◆ ComputeTest

Definition at line 21 of file compute_unittests.cc.

◆ DeviceBufferTest

Definition at line 12 of file device_buffer_unittests.cc.

◆ DisplayListTest

Definition at line 46 of file dl_unittests.cc.

◆ DriverInfoVKTest

Definition at line 11 of file driver_info_vk_unittests.cc.

◆ EntityPassTargetTest

Definition at line 16 of file entity_pass_target_unittests.cc.

◆ EntityTest

Definition at line 21 of file clip_contents_unittests.cc.

◆ HostBufferTest

Definition at line 12 of file host_buffer_unittests.cc.

◆ RendererTest

Definition at line 14 of file render_pass_cache_unittests.cc.

◆ RenderTargetCacheTest

Definition at line 19 of file render_target_cache_unittests.cc.

◆ RuntimeStageTest

Definition at line 26 of file runtime_stage_unittests.cc.

◆ TypographerTest

Definition at line 29 of file typographer_unittests.cc.

Function Documentation

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [1/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Conical  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [2/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Linear  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [3/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Radial  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [4/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Sweep  )

◆ BlendModeTest()

static Picture impeller::testing::BlendModeTest ( Vector2  content_scale,
BlendMode  blend_mode,
const std::shared_ptr< Image > &  src_image,
const std::shared_ptr< Image > &  dst_image,
Scalar  src_alpha 
)
static
  1. Save layer blending (top squares).
  2. CPU blend modes (bottom squares).
  3. Image blending (bottom images).

Compare these results with the images in the Flutter blend mode documentation: https://api.flutter.dev/flutter/dart-ui/BlendMode.html

Definition at line 368 of file aiks_blend_unittests.cc.

372 {
373 if (AiksTest::ImGuiBegin("Controls", nullptr,
374 ImGuiWindowFlags_AlwaysAutoResize)) {
375 ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
376 ImGui::End();
377 }
378
379 Color destination_color = Color::CornflowerBlue().WithAlpha(0.75);
380 auto source_colors = std::vector<Color>({Color::White().WithAlpha(0.75),
381 Color::LimeGreen().WithAlpha(0.75),
382 Color::Black().WithAlpha(0.75)});
383
384 Canvas canvas;
385 canvas.DrawPaint({.color = Color::Black()});
386 // TODO(bdero): Why does this cause the left image to double scale on high DPI
387 // displays.
388 // canvas.Scale(content_scale);
389
390 //----------------------------------------------------------------------------
391 /// 1. Save layer blending (top squares).
392 ///
393
394 canvas.Save();
395 for (const auto& color : source_colors) {
396 canvas.Save();
397 {
398 canvas.ClipRect(Rect::MakeXYWH(25, 25, 100, 100));
399 // Perform the blend in a SaveLayer so that the initial backdrop color is
400 // fully transparent black. SourceOver blend the result onto the parent
401 // pass.
402 canvas.SaveLayer({});
403 {
404 canvas.DrawPaint({.color = destination_color});
405 // Draw the source color in an offscreen pass and blend it to the parent
406 // pass.
407 canvas.SaveLayer({.blend_mode = blend_mode});
408 { //
409 canvas.DrawRect(Rect::MakeXYWH(25, 25, 100, 100), {.color = color});
410 }
411 canvas.Restore();
412 }
413 canvas.Restore();
414 }
415 canvas.Restore();
416 canvas.Translate(Vector2(100, 0));
417 }
418 canvas.RestoreToCount(0);
419
420 //----------------------------------------------------------------------------
421 /// 2. CPU blend modes (bottom squares).
422 ///
423
424 canvas.Save();
425 canvas.Translate({0, 100});
426 // Perform the blend in a SaveLayer so that the initial backdrop color is
427 // fully transparent black. SourceOver blend the result onto the parent pass.
428 canvas.SaveLayer({});
429 for (const auto& color : source_colors) {
430 // Simply write the CPU blended color to the pass.
431 canvas.DrawRect(Rect::MakeXYWH(25, 25, 100, 100),
432 {.color = destination_color.Blend(color, blend_mode),
433 .blend_mode = BlendMode::kSourceOver});
434 canvas.Translate(Vector2(100, 0));
435 }
436 canvas.Restore();
437 canvas.Restore();
438
439 //----------------------------------------------------------------------------
440 /// 3. Image blending (bottom images).
441 ///
442 /// Compare these results with the images in the Flutter blend mode
443 /// documentation: https://api.flutter.dev/flutter/dart-ui/BlendMode.html
444 ///
445
446 canvas.Translate({0, 250});
447
448 // Draw grid behind the images.
449 canvas.DrawRect(Rect::MakeLTRB(0, 0, 800, 400),
450 {.color = Color::MakeRGBA8(41, 41, 41, 255)});
451 Paint square_paint = {.color = Color::MakeRGBA8(15, 15, 15, 255)};
452 for (int y = 0; y < 400 / 8; y++) {
453 for (int x = 0; x < 800 / 16; x++) {
454 canvas.DrawRect(Rect::MakeXYWH(x * 16 + (y % 2) * 8, y * 8, 8, 8),
455 square_paint);
456 }
457 }
458
459 // Uploaded image source (left image).
460 canvas.Save();
461 canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver});
462 {
463 canvas.DrawImage(dst_image, {0, 0},
464 {
465 .blend_mode = BlendMode::kSourceOver,
466 });
467 canvas.DrawImage(src_image, {0, 0},
468 {
469 .color = Color::White().WithAlpha(src_alpha),
470 .blend_mode = blend_mode,
471 });
472 }
473 canvas.Restore();
474 canvas.Restore();
475
476 // Rendered image source (right image).
477 canvas.Save();
478 canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver});
479 {
480 canvas.DrawImage(dst_image, {400, 0},
481 {.blend_mode = BlendMode::kSourceOver});
482 canvas.SaveLayer({.color = Color::White().WithAlpha(src_alpha),
483 .blend_mode = blend_mode});
484 {
485 canvas.DrawImage(src_image, {400, 0},
486 {.blend_mode = BlendMode::kSourceOver});
487 }
488 canvas.Restore();
489 }
490 canvas.Restore();
491 canvas.Restore();
492
493 return canvas.EndRecordingAsPicture();
494}
DlColor color
double y
double x
Point Vector2
Definition: point.h:326
constexpr Color WithAlpha(Scalar new_alpha) const
Definition: color.h:280
Color Blend(Color source, BlendMode blend_mode) const
Blends an unpremultiplied destination color into a given unpremultiplied source color to form a new u...
Definition: color.cc:234

◆ CanRenderConicalGradientWithDithering()

static void impeller::testing::CanRenderConicalGradientWithDithering ( AiksTest aiks_test)
static

Definition at line 167 of file aiks_dl_gradient_unittests.cc.

167 {
169 builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
171 builder.Translate(100.0, 100.0);
172
173 // #FFF -> #000
174 std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
175 DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
176 std::vector<Scalar> stops = {0.0, 1.0};
177
178 paint.setColorSource(DlColorSource::MakeConical({0, 1}, 0, {100, 100}, 100, 2,
179 colors.data(), stops.data(),
180 DlTileMode::kMirror));
181
182 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
183 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
184}
static sk_sp< SkShader > MakeConical(const SkPoint pts[2], const GradData &data, SkTileMode tm, float scale)
Ignores scale.
bool OpenPlaygroundHere(Picture picture)
Point GetContentScale() const
Definition: playground.cc:192
const Paint & paint
Definition: color_source.cc:38
PODArray< SkColor > colors
Definition: SkRecords.h:276
flutter::DlColor DlColor
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
constexpr uint32_t ToARGB() const
Convert to ARGB 32 bit color.
Definition: color.h:261

◆ CanRenderLinearGradientWithDithering()

static void impeller::testing::CanRenderLinearGradientWithDithering ( AiksTest aiks_test)
static

Definition at line 104 of file aiks_dl_gradient_unittests.cc.

104 {
107 builder.Translate(100.0, 100.0);
108
109 // 0xffcccccc --> 0xff333333, taken from
110 // https://github.com/flutter/flutter/issues/118073#issue-1521699748
111 std::vector<DlColor> colors = {DlColor(0xFFCCCCCC), DlColor(0xFF333333)};
112 std::vector<Scalar> stops = {0.0, 1.0};
113
114 paint.setColorSource(DlColorSource::MakeLinear(
115 {0, 0}, {800, 500}, 2, colors.data(), stops.data(), DlTileMode::kClamp));
116 builder.DrawRect(SkRect::MakeXYWH(0, 0, 800, 500), paint);
117 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
118}
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const GradData &data, SkTileMode tm, float scale)
Ignores scale.

◆ CanRenderRadialGradientWithDithering()

static void impeller::testing::CanRenderRadialGradientWithDithering ( AiksTest aiks_test)
static

Definition at line 124 of file aiks_dl_gradient_unittests.cc.

124 {
127 builder.Translate(100.0, 100.0);
128
129 // #FFF -> #000
130 std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
131 DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
132 std::vector<Scalar> stops = {0.0, 1.0};
133
134 paint.setColorSource(DlColorSource::MakeRadial(
135 {600, 600}, 600, 2, colors.data(), stops.data(), DlTileMode::kClamp));
136 builder.DrawRect(SkRect::MakeXYWH(0, 0, 1200, 1200), paint);
137 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
138}
static sk_sp< SkShader > MakeRadial(const SkPoint pts[2], const GradData &data, SkTileMode tm, float scale)

◆ CanRenderSweepGradientWithDithering()

static void impeller::testing::CanRenderSweepGradientWithDithering ( AiksTest aiks_test)
static

Definition at line 144 of file aiks_dl_gradient_unittests.cc.

144 {
146 builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
148 builder.Translate(100.0, 100.0);
149
150 // #FFF -> #000
151 std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
152 DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
153 std::vector<Scalar> stops = {0.0, 1.0};
154
155 paint.setColorSource(DlColorSource::MakeSweep(
156 {100, 100}, /*start=*/45, /*end=*/135, 2, colors.data(), stops.data(),
157 DlTileMode::kMirror));
158
159 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
160 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
161}
static sk_sp< SkShader > MakeSweep(const SkPoint pts[2], const GradData &data, SkTileMode tm, float scale)
Ignores scale.

◆ CAPABILITY_TEST() [1/9]

impeller::testing::CAPABILITY_TEST ( SupportsCompute  ,
false   
)

◆ CAPABILITY_TEST() [2/9]

impeller::testing::CAPABILITY_TEST ( SupportsComputeSubgroups  ,
false   
)

◆ CAPABILITY_TEST() [3/9]

impeller::testing::CAPABILITY_TEST ( SupportsDecalSamplerAddressMode  ,
false   
)

◆ CAPABILITY_TEST() [4/9]

impeller::testing::CAPABILITY_TEST ( SupportsDeviceTransientTextures  ,
false   
)

◆ CAPABILITY_TEST() [5/9]

impeller::testing::CAPABILITY_TEST ( SupportsFramebufferFetch  ,
false   
)

◆ CAPABILITY_TEST() [6/9]

impeller::testing::CAPABILITY_TEST ( SupportsOffscreenMSAA  ,
false   
)

◆ CAPABILITY_TEST() [7/9]

impeller::testing::CAPABILITY_TEST ( SupportsReadFromResolve  ,
false   
)

◆ CAPABILITY_TEST() [8/9]

impeller::testing::CAPABILITY_TEST ( SupportsSSBO  ,
false   
)

◆ CAPABILITY_TEST() [9/9]

impeller::testing::CAPABILITY_TEST ( SupportsTextureToTextureBlits  ,
false   
)

◆ CompareFunctionUI()

static const CompareFunctionUIData & impeller::testing::CompareFunctionUI ( )
static

Definition at line 1184 of file renderer_unittests.cc.

1184 {
1186 return data;
1187}
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ CreateDefaultPipeline()

template<class VertexShader , class FragmentShader >
std::shared_ptr< Pipeline< PipelineDescriptor > > impeller::testing::CreateDefaultPipeline ( const std::shared_ptr< Context > &  context)

Definition at line 1376 of file renderer_unittests.cc.

1377 {
1378 using TexturePipelineBuilder = PipelineBuilder<VertexShader, FragmentShader>;
1379 auto pipeline_desc =
1380 TexturePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1381 if (!pipeline_desc.has_value()) {
1382 return nullptr;
1383 }
1384 pipeline_desc->SetSampleCount(SampleCount::kCount4);
1385 pipeline_desc->SetStencilAttachmentDescriptors(std::nullopt);
1386 auto pipeline =
1387 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
1388 if (!pipeline || !pipeline->IsValid()) {
1389 return nullptr;
1390 }
1391 return pipeline;
1392}
An optional (but highly recommended) utility for creating pipelines from reflected shader information...

◆ CreateGlyphAtlas() [1/2]

static std::shared_ptr< GlyphAtlas > impeller::testing::CreateGlyphAtlas ( Context context,
const TypographerContext typographer_context,
HostBuffer host_buffer,
GlyphAtlas::Type  type,
Scalar  scale,
const std::shared_ptr< GlyphAtlasContext > &  atlas_context,
const std::vector< std::shared_ptr< TextFrame > > &  frames,
const std::vector< GlyphProperties > &  properties 
)
static

Definition at line 46 of file typographer_unittests.cc.

54 {
55 FontGlyphMap font_glyph_map;
56 size_t offset = 0;
57 for (auto& frame : frames) {
58 frame->CollectUniqueFontGlyphPairs(font_glyph_map, scale, {0, 0},
59 properties[offset++]);
60 }
61 return typographer_context->CreateGlyphAtlas(context, type, host_buffer,
62 atlas_context, font_glyph_map);
63}
GLenum type
virtual std::shared_ptr< GlyphAtlas > CreateGlyphAtlas(Context &context, GlyphAtlas::Type type, HostBuffer &host_buffer, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const FontGlyphMap &font_glyph_map) const =0
double frame
Definition: examples.cpp:31
std::unordered_map< ScaledFont, std::unordered_set< SubpixelGlyph > > FontGlyphMap
const Scalar scale
SeparatedVector2 offset

◆ CreateGlyphAtlas() [2/2]

static std::shared_ptr< GlyphAtlas > impeller::testing::CreateGlyphAtlas ( Context context,
const TypographerContext typographer_context,
HostBuffer host_buffer,
GlyphAtlas::Type  type,
Scalar  scale,
const std::shared_ptr< GlyphAtlasContext > &  atlas_context,
const TextFrame frame 
)
static

Definition at line 32 of file typographer_unittests.cc.

39 {
40 FontGlyphMap font_glyph_map;
41 frame.CollectUniqueFontGlyphPairs(font_glyph_map, scale, {0, 0}, {});
42 return typographer_context->CreateGlyphAtlas(context, type, host_buffer,
43 atlas_context, font_glyph_map);
44}

◆ CreateMappingFromString()

static std::shared_ptr< fml::Mapping > impeller::testing::CreateMappingFromString ( std::string  p_string)
static

Definition at line 15 of file shader_archive_unittests.cc.

16 {
17 auto string = std::make_shared<std::string>(std::move(p_string));
18 return std::make_shared<fml::NonOwnedMapping>(
19 reinterpret_cast<const uint8_t*>(string->data()), string->size(),
20 [string](auto, auto) {});
21}

◆ CreatePassWithRectPath()

auto impeller::testing::CreatePassWithRectPath ( Rect  rect,
std::optional< Rect bounds_hint,
ContentBoundsPromise  bounds_promise = ContentBoundsPromise::kUnknown,
bool  collapse = false 
)

Definition at line 110 of file entity_unittests.cc.

114 {
115 auto subpass = std::make_unique<EntityPass>();
116 Entity entity;
118 PathBuilder{}.AddRect(rect).TakePath(), Color::Red()));
119 subpass->AddEntity(std::move(entity));
120 subpass->SetDelegate(std::make_unique<TestPassDelegate>(collapse));
121 subpass->SetBoundsLimit(bounds_hint, bounds_promise);
122 return subpass;
123}
void SetContents(std::shared_ptr< Contents > contents)
Definition: entity.cc:90
PathBuilder & AddRect(Rect rect)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350

◆ CreateStringFromMapping()

const std::string impeller::testing::CreateStringFromMapping ( const fml::Mapping mapping)

Definition at line 23 of file shader_archive_unittests.cc.

23 {
24 return std::string{reinterpret_cast<const char*>(mapping.GetMapping()),
25 mapping.GetSize()};
26}
virtual const uint8_t * GetMapping() const =0
virtual size_t GetSize() const =0

◆ CreateSurface()

vk::UniqueSurfaceKHR impeller::testing::CreateSurface ( const ContextVK context)

Definition at line 17 of file swapchain_unittests.cc.

17 {
18#if FML_OS_DARWIN
19 impeller::vk::MetalSurfaceCreateInfoEXT createInfo = {};
20 auto [result, surface] =
21 context.GetInstance().createMetalSurfaceEXTUnique(createInfo);
22 FML_DCHECK(result == vk::Result::eSuccess);
23 return std::move(surface);
24#else
25 return {};
26#endif // FML_OS_DARWIN
27}
vk::Instance GetInstance() const
Definition: context_vk.cc:509
VkSurfaceKHR surface
Definition: main.cc:49
GAsyncResult * result
#define FML_DCHECK(condition)
Definition: logging.h:103

◆ CreateTestYUVTextures()

static std::vector< std::shared_ptr< Texture > > impeller::testing::CreateTestYUVTextures ( Context context,
YUVColorSpace  yuv_color_space 
)
static

Definition at line 1855 of file entity_unittests.cc.

1857 {
1858 Vector3 red = {244.0 / 255.0, 67.0 / 255.0, 54.0 / 255.0};
1859 Vector3 green = {76.0 / 255.0, 175.0 / 255.0, 80.0 / 255.0};
1860 Vector3 blue = {33.0 / 255.0, 150.0 / 255.0, 243.0 / 255.0};
1861 Vector3 white = {1.0, 1.0, 1.0};
1862 Vector3 red_yuv = RGBToYUV(red, yuv_color_space);
1863 Vector3 green_yuv = RGBToYUV(green, yuv_color_space);
1864 Vector3 blue_yuv = RGBToYUV(blue, yuv_color_space);
1865 Vector3 white_yuv = RGBToYUV(white, yuv_color_space);
1866 std::vector<Vector3> yuvs{red_yuv, green_yuv, blue_yuv, white_yuv};
1867 std::vector<uint8_t> y_data;
1868 std::vector<uint8_t> uv_data;
1869 for (int i = 0; i < 4; i++) {
1870 auto yuv = yuvs[i];
1871 uint8_t y = std::round(yuv.x * 255.0);
1872 uint8_t u = std::round(yuv.y * 255.0);
1873 uint8_t v = std::round(yuv.z * 255.0);
1874 for (int j = 0; j < 16; j++) {
1875 y_data.push_back(y);
1876 }
1877 for (int j = 0; j < 8; j++) {
1878 uv_data.push_back(j % 2 == 0 ? u : v);
1879 }
1880 }
1881 auto cmd_buffer = context->CreateCommandBuffer();
1882 auto blit_pass = cmd_buffer->CreateBlitPass();
1883
1884 impeller::TextureDescriptor y_texture_descriptor;
1886 y_texture_descriptor.format = PixelFormat::kR8UNormInt;
1887 y_texture_descriptor.size = {8, 8};
1888 auto y_texture =
1889 context->GetResourceAllocator()->CreateTexture(y_texture_descriptor);
1890 auto y_mapping = std::make_shared<fml::DataMapping>(y_data);
1891 auto y_mapping_buffer =
1892 context->GetResourceAllocator()->CreateBufferWithCopy(*y_mapping);
1893
1894 blit_pass->AddCopy(DeviceBuffer::AsBufferView(y_mapping_buffer), y_texture);
1895
1896 impeller::TextureDescriptor uv_texture_descriptor;
1897 uv_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
1898 uv_texture_descriptor.format = PixelFormat::kR8G8UNormInt;
1899 uv_texture_descriptor.size = {4, 4};
1900 auto uv_texture =
1901 context->GetResourceAllocator()->CreateTexture(uv_texture_descriptor);
1902 auto uv_mapping = std::make_shared<fml::DataMapping>(uv_data);
1903 auto uv_mapping_buffer =
1904 context->GetResourceAllocator()->CreateBufferWithCopy(*uv_mapping);
1905
1906 blit_pass->AddCopy(DeviceBuffer::AsBufferView(uv_mapping_buffer), uv_texture);
1907
1908 if (!blit_pass->EncodeCommands(context->GetResourceAllocator()) ||
1909 !context->GetCommandQueue()->Submit({cmd_buffer}).ok()) {
1910 FML_DLOG(ERROR) << "Could not copy contents into Y/UV texture.";
1911 }
1912
1913 return {y_texture, uv_texture};
1914}
static void round(SkPoint *p)
virtual std::shared_ptr< CommandQueue > GetCommandQueue() const =0
Return the graphics queue for submitting command buffers.
virtual std::shared_ptr< CommandBuffer > CreateCommandBuffer() const =0
Create a new command buffer. Command buffers can be used to encode graphics, blit,...
virtual std::shared_ptr< Allocator > GetResourceAllocator() const =0
Returns the allocator used to create textures and buffers on the device.
#define FML_DLOG(severity)
Definition: logging.h:102
static Vector3 RGBToYUV(Vector3 rgb, YUVColorSpace yuv_color_space)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
#define ERROR(message)
Definition: elf_loader.cc:260

◆ doNothing()

void impeller::testing::doNothing ( )

Definition at line 42 of file mock_gles.cc.

42{}

◆ flip_lr()

template<typename R >
static constexpr R impeller::testing::flip_lr ( R  rect)
inlinestaticconstexpr

Definition at line 1279 of file rect_unittests.cc.

1279 {
1280 return R::MakeLTRB(rect.GetRight(), rect.GetTop(), //
1281 rect.GetLeft(), rect.GetBottom());
1282}

◆ flip_lrtb()

template<typename R >
static constexpr R impeller::testing::flip_lrtb ( R  rect)
inlinestaticconstexpr

Definition at line 1291 of file rect_unittests.cc.

1291 {
1292 return flip_lr(flip_tb(rect));
1293}
static constexpr R flip_tb(R rect)
static constexpr R flip_lr(R rect)

◆ flip_tb()

template<typename R >
static constexpr R impeller::testing::flip_tb ( R  rect)
inlinestaticconstexpr

Definition at line 1285 of file rect_unittests.cc.

1285 {
1286 return R::MakeLTRB(rect.GetLeft(), rect.GetBottom(), //
1287 rect.GetRight(), rect.GetTop());
1288}

◆ GetBlendModeSelection()

static BlendModeSelection impeller::testing::GetBlendModeSelection ( )
static

Definition at line 188 of file aiks_blend_unittests.cc.

188 {
189 std::vector<const char*> blend_mode_names;
190 std::vector<BlendMode> blend_mode_values;
191 {
192 const std::vector<std::tuple<const char*, BlendMode>> blends = {
194 assert(blends.size() ==
195 static_cast<size_t>(Entity::kLastAdvancedBlendMode) + 1);
196 for (const auto& [name, mode] : blends) {
197 blend_mode_names.push_back(name);
198 blend_mode_values.push_back(mode);
199 }
200 }
201
202 return {blend_mode_names, blend_mode_values};
203}
#define BLEND_MODE_TUPLE(blend_mode)
#define IMPELLER_FOR_EACH_BLEND_MODE(V)
Definition: color.h:19
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
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

◆ GetCoverageOfFirstEntity()

template<typename Contents >
static std::optional< Rect > impeller::testing::GetCoverageOfFirstEntity ( const Picture picture)
static

Definition at line 1547 of file dl_unittests.cc.

1547 {
1548 std::optional<Rect> coverage;
1549 picture.pass->IterateAllEntities([&coverage](Entity& entity) {
1550 if (std::static_pointer_cast<Contents>(entity.GetContents())) {
1551 auto contents = std::static_pointer_cast<Contents>(entity.GetContents());
1552 Entity entity;
1553 coverage = contents->GetCoverage(entity);
1554 return false;
1555 }
1556 return true;
1557 });
1558 return coverage;
1559}
const std::shared_ptr< Contents > & GetContents() const
Definition: entity.cc:94
sk_sp< const SkPicture > picture
Definition: SkRecords.h:299

◆ GetMockVulkanFunctions()

std::shared_ptr< std::vector< std::string > > impeller::testing::GetMockVulkanFunctions ( VkDevice  device)

Definition at line 926 of file mock_vulkan.cc.

927 {
928 MockDevice* mock_device = reinterpret_cast<MockDevice*>(device);
929 return mock_device->GetCalledFunctions();
930}
VkDevice device
Definition: main.cc:53

◆ INSTANTIATE_COMPUTE_SUITE()

impeller::testing::INSTANTIATE_COMPUTE_SUITE ( ComputeTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [1/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( AiksTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [2/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( BlendFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [3/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( BlitPassTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [4/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( DisplayListTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [5/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( GaussianBlurFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [6/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( HostBufferTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [7/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( MatrixFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [8/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RendererDartTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [9/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RuntimeStageTest  )

◆ INSTANTIATE_VULKAN_PLAYGROUND_SUITE()

impeller::testing::INSTANTIATE_VULKAN_PLAYGROUND_SUITE ( DriverInfoVKTest  )

◆ InstantiateTestShaderLibrary()

static void impeller::testing::InstantiateTestShaderLibrary ( Context::BackendType  backend_type)
static

Definition at line 34 of file renderer_dart_unittests.cc.

34 {
35 auto fixture =
36 flutter::testing::OpenFixtureAsMapping("playground.shaderbundle");
38 backend_type, std::move(fixture));
40}
static void SetOverride(fml::RefPtr< ShaderLibrary > override_shader_library)
Sets a return override for MakeFromAsset for testing purposes.
static fml::RefPtr< ShaderLibrary > MakeFromFlatbuffer(impeller::Context::BackendType backend_type, std::shared_ptr< fml::Mapping > payload)
std::unique_ptr< fml::Mapping > OpenFixtureAsMapping(const std::string &fixture_name)
Opens a fixture of the given file name and returns a mapping to its contents.
Definition: testing.cc:59

◆ MaskBlurVariantTest()

static Picture impeller::testing::MaskBlurVariantTest ( const AiksTest test_context,
const MaskBlurTestConfig config 
)
static

Definition at line 304 of file aiks_blur_unittests.cc.

305 {
306 Canvas canvas;
307 canvas.Scale(test_context.GetContentScale());
308 canvas.Scale(Vector2{0.8f, 0.8f});
309 Paint paint;
310 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
312 .sigma = Sigma{1},
313 };
314
315 canvas.DrawPaint({.color = Color::AntiqueWhite()});
316
317 paint.mask_blur_descriptor->style = config.style;
318 paint.mask_blur_descriptor->sigma = Sigma{config.sigma};
319 paint.image_filter = config.image_filter;
320 paint.invert_colors = config.invert_colors;
321 paint.blend_mode = config.blend_mode;
322
323 const Scalar x = 50;
324 const Scalar radius = 20.0f;
325 const Scalar y_spacing = 100.0f;
326
327 Scalar y = 50;
328 paint.color = Color::Crimson().WithAlpha(config.alpha);
329 canvas.DrawRect(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
330 radius, 60.0f - radius),
331 paint);
332
333 y += y_spacing;
334 paint.color = Color::Blue().WithAlpha(config.alpha);
335 canvas.DrawCircle({x + 25, y + 25}, radius, paint);
336
337 y += y_spacing;
338 paint.color = Color::Green().WithAlpha(config.alpha);
339 canvas.DrawOval(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
340 radius, 60.0f - radius),
341 paint);
342
343 y += y_spacing;
344 paint.color = Color::Purple().WithAlpha(config.alpha);
345 canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
346 {radius, radius}, //
347 paint);
348
349 y += y_spacing;
350 paint.color = Color::Orange().WithAlpha(config.alpha);
351 canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
352 {radius, 5.0f}, paint);
353
354 y += y_spacing;
355 paint.color = Color::Maroon().WithAlpha(config.alpha);
356 canvas.DrawPath(PathBuilder{}
357 .MoveTo({x + 0, y + 60})
358 .LineTo({x + 30, y + 0})
359 .LineTo({x + 60, y + 60})
360 .Close()
361 .TakePath(),
362 paint);
363
364 y += y_spacing;
365 paint.color = Color::Maroon().WithAlpha(config.alpha);
366 canvas.DrawPath(PathBuilder{}
367 .AddArc(Rect::MakeXYWH(x + 5, y, 50, 50),
368 Radians{kPi / 2}, Radians{kPi})
369 .AddArc(Rect::MakeXYWH(x + 25, y, 50, 50),
370 Radians{kPi / 2}, Radians{kPi})
371 .Close()
372 .TakePath(),
373 paint);
374
375 return canvas.EndRecordingAsPicture();
376}
@ kNormal
Default priority level.
Definition: embedder.h:262
constexpr float kPi
Definition: math.h:27
float Scalar
Definition: scalar.h:18
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:24
void Close(PathBuilder *builder)
Definition: tessellator.cc:38
FilterContents::BlurStyle style
Definition: paint.h:49
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition: sigma.h:32
std::shared_ptr< ImageFilter > image_filter

◆ mockBeginQueryEXT()

void impeller::testing::mockBeginQueryEXT ( GLenum  target,
GLuint  id 
)

Definition at line 129 of file mock_gles.cc.

129 {
130 RecordGLCall("glBeginQueryEXT");
131}
void RecordGLCall(const char *name)
Definition: mock_gles.cc:29

◆ mockDeleteQueriesEXT()

void impeller::testing::mockDeleteQueriesEXT ( GLsizei  size,
const GLuint *  queries 
)

Definition at line 159 of file mock_gles.cc.

159 {
160 RecordGLCall("glDeleteQueriesEXT");
161}

◆ mockEndQueryEXT()

void impeller::testing::mockEndQueryEXT ( GLuint  id)

Definition at line 136 of file mock_gles.cc.

136 {
137 RecordGLCall("glEndQueryEXT");
138}

◆ mockGenQueriesEXT()

void impeller::testing::mockGenQueriesEXT ( GLsizei  n,
GLuint *  ids 
)

Definition at line 119 of file mock_gles.cc.

119 {
120 RecordGLCall("glGenQueriesEXT");
121 for (auto i = 0; i < n; i++) {
122 ids[i] = i + 1;
123 }
124}

◆ mockGetError()

GLenum impeller::testing::mockGetError ( )

Definition at line 95 of file mock_gles.cc.

95 {
96 return GL_NO_ERROR;
97}

◆ mockGetIntegerv()

void impeller::testing::mockGetIntegerv ( GLenum  name,
int value 
)

Definition at line 78 of file mock_gles.cc.

78 {
79 switch (name) {
80 case GL_NUM_EXTENSIONS: {
81 *value = g_extensions.size();
82 } break;
83 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
84 *value = 8;
85 break;
86 default:
87 *value = 0;
88 break;
89 }
90}
uint8_t value
static std::vector< const unsigned char * > g_extensions
Definition: mock_gles.cc:24

◆ mockGetQueryObjectui64vEXT()

void impeller::testing::mockGetQueryObjectui64vEXT ( GLuint  id,
GLenum  target,
GLuint64 *  result 
)

Definition at line 151 of file mock_gles.cc.

151 {
152 RecordGLCall("glGetQueryObjectui64vEXT");
153 *result = 1000u;
154}

◆ mockGetQueryObjectuivEXT()

void impeller::testing::mockGetQueryObjectuivEXT ( GLuint  id,
GLenum  target,
GLuint *  result 
)

Definition at line 143 of file mock_gles.cc.

143 {
144 RecordGLCall("glGetQueryObjectuivEXT");
145 *result = GL_TRUE;
146}

◆ mockGetString()

const unsigned char * impeller::testing::mockGetString ( GLenum  name)

Definition at line 50 of file mock_gles.cc.

50 {
51 switch (name) {
52 case GL_VENDOR:
53 return kMockVendor;
54 case GL_VERSION:
55 return g_version;
56 case GL_SHADING_LANGUAGE_VERSION:
58 default:
59 return (unsigned char*)"";
60 }
61}
const auto kMockShadingLanguageVersion
Definition: mock_gles.cc:45
auto const kMockVendor
Definition: mock_gles.cc:44
static const unsigned char * g_version
Definition: mock_gles.cc:26

◆ mockGetStringi()

const unsigned char * impeller::testing::mockGetStringi ( GLenum  name,
GLuint  index 
)

Definition at line 66 of file mock_gles.cc.

66 {
67 switch (name) {
68 case GL_EXTENSIONS:
69 return g_extensions[index];
70 default:
71 return (unsigned char*)"";
72 }
73}

◆ mockPopDebugGroupKHR()

void impeller::testing::mockPopDebugGroupKHR ( )

Definition at line 102 of file mock_gles.cc.

102 {
103 RecordGLCall("PopDebugGroupKHR");
104}

◆ mockPushDebugGroupKHR()

void impeller::testing::mockPushDebugGroupKHR ( GLenum  source,
GLuint  id,
GLsizei  length,
const GLchar *  message 
)

Definition at line 109 of file mock_gles.cc.

112 {
113 RecordGLCall("PushDebugGroupKHR");
114}

◆ RecordGLCall()

void impeller::testing::RecordGLCall ( const char *  name)

Definition at line 29 of file mock_gles.cc.

29 {
30 if (auto mock_gles = g_mock_gles.lock()) {
31 mock_gles->RecordCall(name);
32 }
33}
static std::weak_ptr< MockGLES > g_mock_gles
Definition: mock_gles.cc:20

◆ RenderTextInCanvasSkia()

bool impeller::testing::RenderTextInCanvasSkia ( const std::shared_ptr< Context > &  context,
Canvas canvas,
const std::string &  text,
const std::string_view &  font_fixture,
TextRenderOptions  options = {} 
)

Definition at line 550 of file aiks_unittests.cc.

554 {}) {
555 // Draw the baseline.
556 canvas.DrawRect(
557 Rect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
558 Paint{.color = Color::Aqua().WithAlpha(0.25)});
559
560 // Mark the point at which the text is drawn.
561 canvas.DrawCircle(options.position, 5.0,
562 Paint{.color = Color::Red().WithAlpha(0.25)});
563
564 // Construct the text blob.
565 auto c_font_fixture = std::string(font_fixture);
566 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
567 if (!mapping) {
568 return false;
569 }
571 SkFont sk_font(font_mgr->makeFromData(mapping), options.font_size);
572 auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font);
573 if (!blob) {
574 return false;
575 }
576
577 // Create the Impeller text frame and draw it at the designated baseline.
579
580 Paint text_paint;
581 text_paint.color = options.color;
582 text_paint.mask_blur_descriptor = options.mask_blur_descriptor;
583 text_paint.stroke_width = 1;
584 text_paint.style =
585 options.stroke ? Paint::Style::kStroke : Paint::Style::kFill;
586 canvas.DrawTextFrame(frame, options.position, text_paint);
587 return true;
588}
const char * options
sk_sp< SkTypeface > makeFromData(sk_sp< SkData >, int ttcIndex=0) const
Definition: SkFontMgr.cpp:120
Definition: SkFont.h:35
static sk_sp< SkTextBlob > MakeFromString(const char *string, const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
Definition: SkTextBlob.h:115
std::u16string text
sk_sp< SkData > OpenFixtureAsSkData(const std::string &fixture_name)
Opens a fixture of the given file name and returns a Skia SkData holding its contents.
Definition: testing.cc:64
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)
sk_sp< SkFontMgr > GetDefaultFontManager(uint32_t font_initialization_data)
Definition: platform.cc:17
Color color
Definition: paint.h:68

◆ RenderTextInCanvasSTB()

bool impeller::testing::RenderTextInCanvasSTB ( const std::shared_ptr< Context > &  context,
Canvas canvas,
const std::string &  text,
const std::string &  font_fixture,
TextRenderOptions  options = {} 
)

Definition at line 590 of file aiks_unittests.cc.

594 {}) {
595 // Draw the baseline.
596 canvas.DrawRect(
597 Rect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
598 Paint{.color = Color::Aqua().WithAlpha(0.25)});
599
600 // Mark the point at which the text is drawn.
601 canvas.DrawCircle(options.position, 5.0,
602 Paint{.color = Color::Red().WithAlpha(0.25)});
603
604 // Construct the text blob.
605 auto mapping = flutter::testing::OpenFixtureAsMapping(font_fixture.c_str());
606 if (!mapping) {
607 return false;
608 }
609 auto typeface_stb = std::make_shared<TypefaceSTB>(std::move(mapping));
610
611 auto frame = MakeTextFrameSTB(
612 typeface_stb, Font::Metrics{.point_size = options.font_size}, text);
613
614 Paint text_paint;
615 text_paint.color = options.color;
616 canvas.DrawTextFrame(frame, options.position, text_paint);
617 return true;
618}
std::shared_ptr< TextFrame > MakeTextFrameSTB(const std::shared_ptr< TypefaceSTB > &typeface_stb, Font::Metrics metrics, const std::string &text)

◆ RGBToYUV()

static Vector3 impeller::testing::RGBToYUV ( Vector3  rgb,
YUVColorSpace  yuv_color_space 
)
static

Definition at line 1838 of file entity_unittests.cc.

1838 {
1839 Vector3 yuv;
1840 switch (yuv_color_space) {
1842 yuv.x = rgb.x * 0.299 + rgb.y * 0.587 + rgb.z * 0.114;
1843 yuv.y = rgb.x * -0.169 + rgb.y * -0.331 + rgb.z * 0.5 + 0.5;
1844 yuv.z = rgb.x * 0.5 + rgb.y * -0.419 + rgb.z * -0.081 + 0.5;
1845 break;
1847 yuv.x = rgb.x * 0.257 + rgb.y * 0.516 + rgb.z * 0.100 + 0.063;
1848 yuv.y = rgb.x * -0.145 + rgb.y * -0.291 + rgb.z * 0.439 + 0.5;
1849 yuv.z = rgb.x * 0.429 + rgb.y * -0.368 + rgb.z * -0.071 + 0.5;
1850 break;
1851 }
1852 return yuv;
1853}
@ kBT601LimitedRange
Definition: embedder.h:613
@ kBT601FullRange
Definition: embedder.h:612

◆ SetSwapchainImageSize()

void impeller::testing::SetSwapchainImageSize ( ISize  size)

Override the image size returned by all swapchain images.

Definition at line 932 of file mock_vulkan.cc.

932 {
933 currentImageSize = size;
934}
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 keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259

◆ swap_nan() [1/2]

static constexpr Point impeller::testing::swap_nan ( const Point point,
int  index 
)
inlinestaticconstexpr

Definition at line 1305 of file rect_unittests.cc.

1305 {
1306 Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1307 FML_DCHECK(index >= 0 && index <= 3);
1308 Scalar x = ((index & (1 << 0)) != 0) ? nan : point.x;
1309 Scalar y = ((index & (1 << 1)) != 0) ? nan : point.y;
1310 return Point(x, y);
1311}
TPoint< Scalar > Point
Definition: point.h:322

◆ swap_nan() [2/2]

static constexpr Rect impeller::testing::swap_nan ( const Rect rect,
int  index 
)
inlinestaticconstexpr

Definition at line 1295 of file rect_unittests.cc.

1295 {
1296 Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1297 FML_DCHECK(index >= 0 && index <= 15);
1298 Scalar l = ((index & (1 << 0)) != 0) ? nan : rect.GetLeft();
1299 Scalar t = ((index & (1 << 1)) != 0) ? nan : rect.GetTop();
1300 Scalar r = ((index & (1 << 2)) != 0) ? nan : rect.GetRight();
1301 Scalar b = ((index & (1 << 3)) != 0) ? nan : rect.GetBottom();
1302 return Rect::MakeLTRB(l, t, r, b);
1303}
static bool b

◆ TEST() [1/377]

impeller::testing::TEST ( AiksCanvasTest  ,
DisableLocalBoundsRectForFilteredSaveLayers   
)

Definition at line 340 of file canvas_unittests.cc.

340 {
341 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
342
343 Canvas canvas(initial_cull);
344 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
345
346 canvas.Save();
347 canvas.SaveLayer(
348 Paint{.image_filter = ImageFilter::MakeBlur(
350 Entity::TileMode::kDecal)});
351 ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
352
353 canvas.Restore();
354 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
355}

◆ TEST() [2/377]

impeller::testing::TEST ( AiksCanvasTest  ,
EmptyCullRect   
)

Definition at line 18 of file canvas_unittests.cc.

18 {
19 Canvas canvas;
20
21 ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
22}

◆ TEST() [3/377]

impeller::testing::TEST ( AiksCanvasTest  ,
InitialCullRect   
)

Definition at line 24 of file canvas_unittests.cc.

24 {
25 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
26
27 Canvas canvas(initial_cull);
28
29 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
30 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), initial_cull);
31}

◆ TEST() [4/377]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipDiffAgainstEmptyCullRect   
)

Definition at line 277 of file canvas_unittests.cc.

277 {
279 builder.AddRect(Rect::MakeXYWH(5, 5, 1, 1));
280 builder.AddRect(Rect::MakeXYWH(5, 14, 1, 1));
281 builder.AddRect(Rect::MakeXYWH(14, 5, 1, 1));
282 builder.AddRect(Rect::MakeXYWH(14, 14, 1, 1));
283 Path path = builder.TakePath();
284
285 Canvas canvas;
286 canvas.ClipPath(path, Entity::ClipOperation::kDifference);
287
288 ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
289}
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

◆ TEST() [5/377]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipDiffAgainstFullyCoveredCullRect   
)

Definition at line 325 of file canvas_unittests.cc.

325 {
326 Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
328 builder.AddRect(Rect::MakeXYWH(0, 0, 100, 100));
329 Path path = builder.TakePath();
330 // Diff clip of Paths is ignored due to complexity
331 Rect result_cull = Rect::MakeXYWH(5, 5, 10, 10);
332
333 Canvas canvas(initial_cull);
334 canvas.ClipPath(path, Entity::ClipOperation::kDifference);
335
336 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
337 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
338}

◆ TEST() [6/377]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipDiffAgainstNonCoveredCullRect   
)

Definition at line 308 of file canvas_unittests.cc.

308 {
309 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
311 builder.AddRect(Rect::MakeXYWH(5, 5, 1, 1));
312 builder.AddRect(Rect::MakeXYWH(5, 14, 1, 1));
313 builder.AddRect(Rect::MakeXYWH(14, 5, 1, 1));
314 builder.AddRect(Rect::MakeXYWH(14, 14, 1, 1));
315 Path path = builder.TakePath();
316 Rect result_cull = Rect::MakeXYWH(0, 0, 10, 10);
317
318 Canvas canvas(initial_cull);
319 canvas.ClipPath(path, Entity::ClipOperation::kDifference);
320
321 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
322 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
323}

◆ TEST() [7/377]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipIntersectAgainstCullRect   
)

Definition at line 291 of file canvas_unittests.cc.

291 {
292 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
294 builder.AddRect(Rect::MakeXYWH(5, 5, 1, 1));
295 builder.AddRect(Rect::MakeXYWH(5, 14, 1, 1));
296 builder.AddRect(Rect::MakeXYWH(14, 5, 1, 1));
297 builder.AddRect(Rect::MakeXYWH(14, 14, 1, 1));
298 Path path = builder.TakePath();
299 Rect result_cull = Rect::MakeXYWH(5, 5, 5, 5);
300
301 Canvas canvas(initial_cull);
302 canvas.ClipPath(path, Entity::ClipOperation::kIntersect);
303
304 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
305 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
306}

◆ TEST() [8/377]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipIntersectAgainstEmptyCullRect   
)

Definition at line 261 of file canvas_unittests.cc.

261 {
263 builder.AddRect(Rect::MakeXYWH(5, 5, 1, 1));
264 builder.AddRect(Rect::MakeXYWH(5, 14, 1, 1));
265 builder.AddRect(Rect::MakeXYWH(14, 5, 1, 1));
266 builder.AddRect(Rect::MakeXYWH(14, 14, 1, 1));
267 Path path = builder.TakePath();
268 Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
269
270 Canvas canvas;
271 canvas.ClipPath(path, Entity::ClipOperation::kIntersect);
272
273 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
274 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip);
275}

◆ TEST() [9/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAboveCullRect   
)

Definition at line 98 of file canvas_unittests.cc.

98 {
99 Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
100 Rect rect_clip = Rect::MakeXYWH(0, 0, 20, 4);
101 Rect result_cull = Rect::MakeXYWH(5, 5, 10, 10);
102
103 Canvas canvas(initial_cull);
104 canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
105
106 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
107 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
108}

◆ TEST() [10/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAgainstEmptyCullRect   
)

Definition at line 65 of file canvas_unittests.cc.

65 {
66 Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
67
68 Canvas canvas;
69 canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
70
71 ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
72}

◆ TEST() [11/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAgainstHCoveredCullRect   
)

Definition at line 158 of file canvas_unittests.cc.

158 {
159 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
160 Rect rect_clip = Rect::MakeXYWH(0, 5, 10, 10);
161 Rect result_cull = Rect::MakeXYWH(0, 0, 10, 5);
162
163 Canvas canvas(initial_cull);
164 canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
165
166 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
167 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
168}

◆ TEST() [12/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAgainstNonCoveredCullRect   
)

Definition at line 86 of file canvas_unittests.cc.

86 {
87 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
88 Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
89 Rect result_cull = Rect::MakeXYWH(0, 0, 10, 10);
90
91 Canvas canvas(initial_cull);
92 canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
93
94 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
95 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
96}

◆ TEST() [13/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAgainstVCoveredCullRect   
)

Definition at line 146 of file canvas_unittests.cc.

146 {
147 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
148 Rect rect_clip = Rect::MakeXYWH(5, 0, 10, 10);
149 Rect result_cull = Rect::MakeXYWH(0, 0, 5, 10);
150
151 Canvas canvas(initial_cull);
152 canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
153
154 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
155 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
156}

◆ TEST() [14/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffBelowCullRect   
)

Definition at line 110 of file canvas_unittests.cc.

110 {
111 Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
112 Rect rect_clip = Rect::MakeXYWH(0, 16, 20, 4);
113 Rect result_cull = Rect::MakeXYWH(5, 5, 10, 10);
114
115 Canvas canvas(initial_cull);
116 canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
117
118 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
119 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
120}

◆ TEST() [15/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffLeftOfCullRect   
)

Definition at line 122 of file canvas_unittests.cc.

122 {
123 Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
124 Rect rect_clip = Rect::MakeXYWH(0, 0, 4, 20);
125 Rect result_cull = Rect::MakeXYWH(5, 5, 10, 10);
126
127 Canvas canvas(initial_cull);
128 canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
129
130 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
131 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
132}

◆ TEST() [16/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffRightOfCullRect   
)

Definition at line 134 of file canvas_unittests.cc.

134 {
135 Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
136 Rect rect_clip = Rect::MakeXYWH(16, 0, 4, 20);
137 Rect result_cull = Rect::MakeXYWH(5, 5, 10, 10);
138
139 Canvas canvas(initial_cull);
140 canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
141
142 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
143 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
144}

◆ TEST() [17/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipIntersectAgainstCullRect   
)

Definition at line 74 of file canvas_unittests.cc.

74 {
75 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
76 Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
77 Rect result_cull = Rect::MakeXYWH(5, 5, 5, 5);
78
79 Canvas canvas(initial_cull);
80 canvas.ClipRect(rect_clip, Entity::ClipOperation::kIntersect);
81
82 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
83 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
84}

◆ TEST() [18/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipIntersectAgainstEmptyCullRect   
)

Definition at line 55 of file canvas_unittests.cc.

55 {
56 Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
57
58 Canvas canvas;
59 canvas.ClipRect(rect_clip, Entity::ClipOperation::kIntersect);
60
61 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
62 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip);
63}

◆ TEST() [19/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstEmptyCullRect   
)

Definition at line 180 of file canvas_unittests.cc.

180 {
181 Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
182
183 Canvas canvas;
184 canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference);
185
186 ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
187}

◆ TEST() [20/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstHFullyCoveredCullRect   
)

Definition at line 249 of file canvas_unittests.cc.

249 {
250 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
251 Rect rect_clip = Rect::MakeXYWH(-2, 5, 14, 10);
252 Rect result_cull = Rect::MakeXYWH(0, 0, 10, 5);
253
254 Canvas canvas(initial_cull);
255 canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference);
256
257 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
258 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
259}

◆ TEST() [21/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstHPartiallyCoveredCullRect   
)

Definition at line 237 of file canvas_unittests.cc.

237 {
238 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
239 Rect rect_clip = Rect::MakeXYWH(0, 5, 10, 10);
240 Rect result_cull = Rect::MakeXYWH(0, 0, 10, 6);
241
242 Canvas canvas(initial_cull);
243 canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference);
244
245 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
246 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
247}

◆ TEST() [22/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstNonCoveredCullRect   
)

Definition at line 201 of file canvas_unittests.cc.

201 {
202 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
203 Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
204 Rect result_cull = Rect::MakeXYWH(0, 0, 10, 10);
205
206 Canvas canvas(initial_cull);
207 canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference);
208
209 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
210 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
211}

◆ TEST() [23/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstVFullyCoveredCullRect   
)

Definition at line 225 of file canvas_unittests.cc.

225 {
226 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
227 Rect rect_clip = Rect::MakeXYWH(5, -2, 10, 14);
228 Rect result_cull = Rect::MakeXYWH(0, 0, 5, 10);
229
230 Canvas canvas(initial_cull);
231 canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference);
232
233 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
234 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
235}

◆ TEST() [24/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstVPartiallyCoveredCullRect   
)

Definition at line 213 of file canvas_unittests.cc.

213 {
214 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
215 Rect rect_clip = Rect::MakeXYWH(5, 0, 10, 10);
216 Rect result_cull = Rect::MakeXYWH(0, 0, 6, 10);
217
218 Canvas canvas(initial_cull);
219 canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference);
220
221 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
222 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
223}

◆ TEST() [25/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipIntersectAgainstCullRect   
)

Definition at line 189 of file canvas_unittests.cc.

189 {
190 Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
191 Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
192 Rect result_cull = Rect::MakeXYWH(5, 5, 5, 5);
193
194 Canvas canvas(initial_cull);
195 canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kIntersect);
196
197 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
198 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
199}

◆ TEST() [26/377]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipIntersectAgainstEmptyCullRect   
)

Definition at line 170 of file canvas_unittests.cc.

170 {
171 Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
172
173 Canvas canvas;
174 canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kIntersect);
175
176 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
177 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip);
178}

◆ TEST() [27/377]

impeller::testing::TEST ( AiksCanvasTest  ,
ScaledCullRect   
)

Definition at line 44 of file canvas_unittests.cc.

44 {
45 Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
46 Rect scaled_cull = Rect::MakeXYWH(10, 10, 20, 20);
47
48 Canvas canvas(initial_cull);
49 canvas.Scale(Vector2(0.5, 0.5));
50
51 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
52 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), scaled_cull);
53}

◆ TEST() [28/377]

impeller::testing::TEST ( AiksCanvasTest  ,
TranslatedCullRect   
)

Definition at line 33 of file canvas_unittests.cc.

33 {
34 Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
35 Rect translated_cull = Rect::MakeXYWH(0, 0, 10, 10);
36
37 Canvas canvas(initial_cull);
38 canvas.Translate(Vector3(5, 5, 0));
39
40 ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
41 ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), translated_cull);
42}

◆ TEST() [29/377]

impeller::testing::TEST ( AllocatorTest  ,
TextureDescriptorCompatibility   
)

Definition at line 16 of file allocator_unittests.cc.

16 {
17 // Size.
18 {
19 TextureDescriptor desc_a = {.size = ISize(100, 100)};
20 TextureDescriptor desc_b = {.size = ISize(100, 100)};
21 TextureDescriptor desc_c = {.size = ISize(101, 100)};
22
23 ASSERT_EQ(desc_a, desc_b);
24 ASSERT_NE(desc_a, desc_c);
25 }
26 // Storage Mode.
27 {
28 TextureDescriptor desc_a = {.storage_mode = StorageMode::kDevicePrivate};
29 TextureDescriptor desc_b = {.storage_mode = StorageMode::kDevicePrivate};
30 TextureDescriptor desc_c = {.storage_mode = StorageMode::kHostVisible};
31
32 ASSERT_EQ(desc_a, desc_b);
33 ASSERT_NE(desc_a, desc_c);
34 }
35 // Format.
36 {
37 TextureDescriptor desc_a = {.format = PixelFormat::kR8G8B8A8UNormInt};
38 TextureDescriptor desc_b = {.format = PixelFormat::kR8G8B8A8UNormInt};
39 TextureDescriptor desc_c = {.format = PixelFormat::kB10G10R10A10XR};
40
41 ASSERT_EQ(desc_a, desc_b);
42 ASSERT_NE(desc_a, desc_c);
43 }
44 // Sample Count.
45 {
46 TextureDescriptor desc_a = {.sample_count = SampleCount::kCount4};
47 TextureDescriptor desc_b = {.sample_count = SampleCount::kCount4};
48 TextureDescriptor desc_c = {.sample_count = SampleCount::kCount1};
49
50 ASSERT_EQ(desc_a, desc_b);
51 ASSERT_NE(desc_a, desc_c);
52 }
53 // Sample Count.
54 {
55 TextureDescriptor desc_a = {.type = TextureType::kTexture2DMultisample};
56 TextureDescriptor desc_b = {.type = TextureType::kTexture2DMultisample};
57 TextureDescriptor desc_c = {.type = TextureType::kTexture2D};
58
59 ASSERT_EQ(desc_a, desc_b);
60 ASSERT_NE(desc_a, desc_c);
61 }
62 // Compression.
63 {
64 TextureDescriptor desc_a = {.compression_type = CompressionType::kLossless};
65 TextureDescriptor desc_b = {.compression_type = CompressionType::kLossless};
66 TextureDescriptor desc_c = {.compression_type = CompressionType::kLossy};
67
68 ASSERT_EQ(desc_a, desc_b);
69 ASSERT_NE(desc_a, desc_c);
70 }
71 // Mip Count.
72 {
73 TextureDescriptor desc_a = {.mip_count = 1};
74 TextureDescriptor desc_b = {.mip_count = 1};
75 TextureDescriptor desc_c = {.mip_count = 4};
76
77 ASSERT_EQ(desc_a, desc_b);
78 ASSERT_NE(desc_a, desc_c);
79 }
80}
ISize64 ISize
Definition: size.h:140

◆ TEST() [30/377]

impeller::testing::TEST ( AllocatorVKTest  ,
MemoryTypeSelectionSingleHeap   
)

Definition at line 35 of file allocator_vk_unittests.cc.

35 {
36 vk::PhysicalDeviceMemoryProperties properties;
37 properties.memoryTypeCount = 1;
38 properties.memoryHeapCount = 1;
39 properties.memoryTypes[0].heapIndex = 0;
40 properties.memoryTypes[0].propertyFlags =
41 vk::MemoryPropertyFlagBits::eDeviceLocal;
42 properties.memoryHeaps[0].size = 1024 * 1024 * 1024;
43 properties.memoryHeaps[0].flags = vk::MemoryHeapFlagBits::eDeviceLocal;
44
45 EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(1, properties), 0);
46 EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(2, properties), -1);
47 EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(3, properties), 0);
48}

◆ TEST() [31/377]

impeller::testing::TEST ( AllocatorVKTest  ,
MemoryTypeSelectionTwoHeap   
)

Definition at line 50 of file allocator_vk_unittests.cc.

50 {
51 vk::PhysicalDeviceMemoryProperties properties;
52 properties.memoryTypeCount = 2;
53 properties.memoryHeapCount = 2;
54 properties.memoryTypes[0].heapIndex = 0;
55 properties.memoryTypes[0].propertyFlags =
56 vk::MemoryPropertyFlagBits::eHostVisible;
57 properties.memoryHeaps[0].size = 1024 * 1024 * 1024;
58 properties.memoryHeaps[0].flags = vk::MemoryHeapFlagBits::eDeviceLocal;
59
60 properties.memoryTypes[1].heapIndex = 1;
61 properties.memoryTypes[1].propertyFlags =
62 vk::MemoryPropertyFlagBits::eDeviceLocal;
63 properties.memoryHeaps[1].size = 1024 * 1024 * 1024;
64 properties.memoryHeaps[1].flags = vk::MemoryHeapFlagBits::eDeviceLocal;
65
66 // First fails because this only looks for eDeviceLocal.
67 EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(1, properties), -1);
68 EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(2, properties), 1);
69 EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(3, properties), 1);
70 EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(4, properties), -1);
71}

◆ TEST() [32/377]

impeller::testing::TEST ( AllocatorVKTest  ,
ToVKImageUsageFlags   
)

Definition at line 16 of file allocator_vk_unittests.cc.

16 {
17 EXPECT_EQ(AllocatorVK::ToVKImageUsageFlags(
18 PixelFormat::kR8G8B8A8UNormInt,
19 static_cast<TextureUsageMask>(TextureUsage::kRenderTarget),
20 StorageMode::kDeviceTransient,
21 /*supports_memoryless_textures=*/true),
22 vk::ImageUsageFlagBits::eInputAttachment |
23 vk::ImageUsageFlagBits::eColorAttachment |
24 vk::ImageUsageFlagBits::eTransientAttachment);
25
26 EXPECT_EQ(AllocatorVK::ToVKImageUsageFlags(
27 PixelFormat::kD24UnormS8Uint,
28 static_cast<TextureUsageMask>(TextureUsage::kRenderTarget),
29 StorageMode::kDeviceTransient,
30 /*supports_memoryless_textures=*/true),
31 vk::ImageUsageFlagBits::eDepthStencilAttachment |
32 vk::ImageUsageFlagBits::eTransientAttachment);
33}

◆ TEST() [33/377]

impeller::testing::TEST ( BaseTest  ,
CanUseTypedMasks   
)

Definition at line 266 of file base_unittests.cc.

266 {
267 {
268 MyMask mask;
269 ASSERT_EQ(static_cast<uint32_t>(mask), 0u);
270 ASSERT_FALSE(mask);
271 }
272
273 {
275 ASSERT_EQ(static_cast<uint32_t>(mask), 1u);
276 ASSERT_TRUE(mask);
277 }
278
279 {
281 MyMask mask(mask2);
282 ASSERT_EQ(static_cast<uint32_t>(mask), 1u);
283 ASSERT_TRUE(mask);
284 }
285
286 {
288 MyMask mask(std::move(mask2)); // NOLINT
289 ASSERT_EQ(static_cast<uint32_t>(mask), 1u);
290 ASSERT_TRUE(mask);
291 }
292
298 ASSERT_NE(MyMaskBits::kBaz, MyMaskBits::kBang);
299
300 {
303 ASSERT_EQ(static_cast<uint32_t>(m1 & m2), 0u);
304 ASSERT_FALSE(m1 & m2);
305 }
306
307 {
310 ASSERT_EQ(static_cast<uint32_t>(m1 | m2), ((1u << 0u) | (1u << 1u)));
311 ASSERT_TRUE(m1 | m2);
312 }
313
314 {
317 ASSERT_EQ(static_cast<uint32_t>(m1 ^ m2), ((1u << 0u) ^ (1u << 1u)));
318 ASSERT_TRUE(m1 ^ m2);
319 }
320
321 {
323 ASSERT_EQ(static_cast<uint32_t>(~m1), (~(1u << 0u)));
324 ASSERT_TRUE(m1);
325 }
326
327 {
330 m2 = m1;
331 ASSERT_EQ(m2, MyMaskBits::kBar);
332 }
333
334 {
336 ASSERT_TRUE(m);
337 }
338
339 {
341 ASSERT_FALSE(m);
342 }
343
344 {
346 ASSERT_TRUE(m);
347 }
348
349 {
350 MyMask m = ~MyMaskBits::kBar;
351 ASSERT_TRUE(m);
352 }
353
354 {
357 m2 |= m1;
358 ASSERT_EQ(m1, MyMaskBits::kBar);
360 ASSERT_EQ(m2, pred);
361 }
362
363 {
366 m2 &= m1;
367 ASSERT_EQ(m1, MyMaskBits::kBar);
369 ASSERT_EQ(m2, pred);
370 }
371
372 {
375 m2 ^= m1;
376 ASSERT_EQ(m1, MyMaskBits::kBar);
378 ASSERT_EQ(m2, pred);
379 }
380
381 {
384 ASSERT_TRUE(m);
385 }
386
387 {
390 ASSERT_TRUE(m);
391 }
392
393 {
396 ASSERT_FALSE(m);
397 }
398
399 {
402 ASSERT_FALSE(m);
403 }
404
405 {
408 ASSERT_TRUE(m);
409 }
410
411 {
414 ASSERT_TRUE(m);
415 }
416
417 {
419 MyMask m = ~x;
420 ASSERT_TRUE(m);
421 }
422
423 {
426 ASSERT_TRUE(x < m);
427 ASSERT_TRUE(x <= m);
428 }
429
430 {
433 ASSERT_FALSE(x == m);
434 }
435
436 {
439 ASSERT_TRUE(x != m);
440 }
441
442 {
445 ASSERT_FALSE(x > m);
446 ASSERT_FALSE(x >= m);
447 }
448}
@ kBaz
Definition: FitsInTest.cpp:20
@ kBar
Definition: FitsInTest.cpp:19
skvx::Vec< 2, uint32_t > mask2
Mask< MyMaskBits > MyMask
Definition: SkVx.h:83

◆ TEST() [34/377]

impeller::testing::TEST ( BaseTest  ,
NoExceptionPromiseEmpty   
)

Definition at line 257 of file base_unittests.cc.

257 {
258 auto wrapper = std::make_shared<NoExceptionPromise<int>>();
259 std::future future = wrapper->get_future();
260
261 // Destroy the empty promise with the future still pending. Verify that the
262 // process does not abort while destructing the promise.
263 wrapper.reset();
264}

◆ TEST() [35/377]

impeller::testing::TEST ( BaseTest  ,
NoExceptionPromiseValue   
)

Definition at line 250 of file base_unittests.cc.

250 {
252 std::future future = wrapper.get_future();
253 wrapper.set_value(123);
254 ASSERT_EQ(future.get(), 123);
255}
std::future< T > get_future()
Definition: promise.h:36
void set_value(const T &value)
Definition: promise.h:38

◆ TEST() [36/377]

impeller::testing::TEST ( CapabilitiesGLES  ,
CanInitializeWithDefaults   
)

Definition at line 13 of file capabilities_unittests.cc.

13 {
14 auto mock_gles = MockGLES::Init();
15
16 auto capabilities = mock_gles->GetProcTable().GetCapabilities();
17
18 EXPECT_FALSE(capabilities->SupportsOffscreenMSAA());
19 EXPECT_FALSE(capabilities->SupportsSSBO());
20 EXPECT_FALSE(capabilities->SupportsTextureToTextureBlits());
21 EXPECT_FALSE(capabilities->SupportsFramebufferFetch());
22 EXPECT_FALSE(capabilities->SupportsCompute());
23 EXPECT_FALSE(capabilities->SupportsComputeSubgroups());
24 EXPECT_FALSE(capabilities->SupportsReadFromResolve());
25 EXPECT_FALSE(capabilities->SupportsDecalSamplerAddressMode());
26 EXPECT_FALSE(capabilities->SupportsDeviceTransientTextures());
27
28 EXPECT_EQ(capabilities->GetDefaultColorFormat(),
29 PixelFormat::kR8G8B8A8UNormInt);
30 EXPECT_EQ(capabilities->GetDefaultStencilFormat(), PixelFormat::kS8UInt);
31 EXPECT_EQ(capabilities->GetDefaultDepthStencilFormat(),
32 PixelFormat::kD24UnormS8Uint);
33}
void Init()

◆ TEST() [37/377]

impeller::testing::TEST ( CapabilitiesGLES  ,
SupportsDecalSamplerAddressMode   
)

Definition at line 35 of file capabilities_unittests.cc.

35 {
36 auto const extensions = std::vector<const unsigned char*>{
37 reinterpret_cast<const unsigned char*>("GL_KHR_debug"), //
38 reinterpret_cast<const unsigned char*>("GL_EXT_texture_border_clamp"), //
39 };
40 auto mock_gles = MockGLES::Init(extensions);
41 auto capabilities = mock_gles->GetProcTable().GetCapabilities();
42 EXPECT_TRUE(capabilities->SupportsDecalSamplerAddressMode());
43}
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678

◆ TEST() [38/377]

impeller::testing::TEST ( CapabilitiesGLES  ,
SupportsDecalSamplerAddressModeNotOES   
)

Definition at line 45 of file capabilities_unittests.cc.

45 {
46 auto const extensions = std::vector<const unsigned char*>{
47 reinterpret_cast<const unsigned char*>("GL_KHR_debug"), //
48 reinterpret_cast<const unsigned char*>("GL_OES_texture_border_clamp"), //
49 };
50 auto mock_gles = MockGLES::Init(extensions);
51 auto capabilities = mock_gles->GetProcTable().GetCapabilities();
52 EXPECT_FALSE(capabilities->SupportsDecalSamplerAddressMode());
53}

◆ TEST() [39/377]

impeller::testing::TEST ( CapabilitiesGLES  ,
SupportsFramebufferFetch   
)

Definition at line 55 of file capabilities_unittests.cc.

55 {
56 auto const extensions = std::vector<const unsigned char*>{
57 reinterpret_cast<const unsigned char*>("GL_KHR_debug"), //
58 reinterpret_cast<const unsigned char*>(
59 "GL_EXT_shader_framebuffer_fetch"), //
60 };
61 auto mock_gles = MockGLES::Init(extensions);
62 auto capabilities = mock_gles->GetProcTable().GetCapabilities();
63 EXPECT_TRUE(capabilities->SupportsFramebufferFetch());
64}

◆ TEST() [40/377]

impeller::testing::TEST ( CapabilitiesTest  ,
DefaultColorFormat   
)

Definition at line 31 of file capabilities_unittests.cc.

31 {
32 auto defaults = CapabilitiesBuilder().Build();
33 EXPECT_EQ(defaults->GetDefaultColorFormat(), PixelFormat::kUnknown);
34 auto mutated = CapabilitiesBuilder()
35 .SetDefaultColorFormat(PixelFormat::kB10G10R10A10XR)
36 .Build();
37 EXPECT_EQ(mutated->GetDefaultColorFormat(), PixelFormat::kB10G10R10A10XR);
38}
CapabilitiesBuilder & SetDefaultColorFormat(PixelFormat value)
std::unique_ptr< Capabilities > Build()

◆ TEST() [41/377]

impeller::testing::TEST ( CapabilitiesTest  ,
DefaultDepthStencilFormat   
)

Definition at line 49 of file capabilities_unittests.cc.

49 {
50 auto defaults = CapabilitiesBuilder().Build();
51 EXPECT_EQ(defaults->GetDefaultDepthStencilFormat(), PixelFormat::kUnknown);
52 auto mutated = CapabilitiesBuilder()
53 .SetDefaultDepthStencilFormat(PixelFormat::kD32FloatS8UInt)
54 .Build();
55 EXPECT_EQ(mutated->GetDefaultDepthStencilFormat(),
56 PixelFormat::kD32FloatS8UInt);
57}
CapabilitiesBuilder & SetDefaultDepthStencilFormat(PixelFormat value)

◆ TEST() [42/377]

impeller::testing::TEST ( CapabilitiesTest  ,
DefaultGlyphAtlasFormat   
)

Definition at line 59 of file capabilities_unittests.cc.

59 {
60 auto defaults = CapabilitiesBuilder().Build();
61 EXPECT_EQ(defaults->GetDefaultGlyphAtlasFormat(), PixelFormat::kUnknown);
62 auto mutated = CapabilitiesBuilder()
63 .SetDefaultGlyphAtlasFormat(PixelFormat::kA8UNormInt)
64 .Build();
65 EXPECT_EQ(mutated->GetDefaultGlyphAtlasFormat(), PixelFormat::kA8UNormInt);
66}
CapabilitiesBuilder & SetDefaultGlyphAtlasFormat(PixelFormat value)

◆ TEST() [43/377]

impeller::testing::TEST ( CapabilitiesTest  ,
DefaultStencilFormat   
)

Definition at line 40 of file capabilities_unittests.cc.

40 {
41 auto defaults = CapabilitiesBuilder().Build();
42 EXPECT_EQ(defaults->GetDefaultStencilFormat(), PixelFormat::kUnknown);
43 auto mutated = CapabilitiesBuilder()
44 .SetDefaultStencilFormat(PixelFormat::kS8UInt)
45 .Build();
46 EXPECT_EQ(mutated->GetDefaultStencilFormat(), PixelFormat::kS8UInt);
47}
CapabilitiesBuilder & SetDefaultStencilFormat(PixelFormat value)

◆ TEST() [44/377]

impeller::testing::TEST ( CapabilitiesVKTest  ,
ContextFailsInitializationForNoCombinedDepthStencilFormat   
)

Definition at line 195 of file context_vk_unittests.cc.

196 {
197 ScopedValidationDisable disable_validation;
198 const std::shared_ptr<ContextVK> context =
201 [](VkPhysicalDevice physicalDevice, VkFormat format,
202 VkFormatProperties* pFormatProperties) {
204 pFormatProperties->optimalTilingFeatures =
205 static_cast<VkFormatFeatureFlags>(
206 vk::FormatFeatureFlagBits::eColorAttachment);
207 }
208 // Ignore combined depth-stencil formats.
209 })
210 .Build();
211 ASSERT_EQ(context, nullptr);
212}
MockVulkanContextBuilder & SetPhysicalDeviceFormatPropertiesCallback(std::function< void(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties)> format_properties_callback)
Definition: mock_vulkan.h:94
uint32_t uint32_t * format
def Build(configs, env, options)
Definition: build.py:232
VkFormatFeatureFlags optimalTilingFeatures
Definition: vulkan_core.h:3014
VkFlags VkFormatFeatureFlags
Definition: vulkan_core.h:2307
VkFormat
Definition: vulkan_core.h:1458
@ VK_FORMAT_R8G8B8A8_UNORM
Definition: vulkan_core.h:1496

◆ TEST() [45/377]

impeller::testing::TEST ( CapabilitiesVKTest  ,
ContextInitializesWithNoStencilFormat   
)

Definition at line 164 of file context_vk_unittests.cc.

164 {
165 const std::shared_ptr<ContextVK> context =
168 [](VkPhysicalDevice physicalDevice, VkFormat format,
169 VkFormatProperties* pFormatProperties) {
171 pFormatProperties->optimalTilingFeatures =
172 static_cast<VkFormatFeatureFlags>(
173 vk::FormatFeatureFlagBits::eColorAttachment);
174 } else if (format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
175 pFormatProperties->optimalTilingFeatures =
176 static_cast<VkFormatFeatureFlags>(
177 vk::FormatFeatureFlagBits::eDepthStencilAttachment);
178 }
179 // Ignore just the stencil format.
180 })
181 .Build();
182 ASSERT_NE(context, nullptr);
183 const CapabilitiesVK* capabilites_vk =
184 reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
185 ASSERT_EQ(capabilites_vk->GetDefaultDepthStencilFormat(),
186 PixelFormat::kD32FloatS8UInt);
187 ASSERT_EQ(capabilites_vk->GetDefaultStencilFormat(),
188 PixelFormat::kD32FloatS8UInt);
189}
@ VK_FORMAT_D32_SFLOAT_S8_UINT
Definition: vulkan_core.h:1589

◆ TEST() [46/377]

impeller::testing::TEST ( CommandEncoderVKTest  ,
CleanupAfterSubmit   
)

Definition at line 42 of file command_encoder_vk_unittests.cc.

42 {
43 // This tests deleting the TrackedObjects where the thread is killed before
44 // the fence waiter has disposed of them, making sure the command buffer and
45 // its pools are deleted in that order.
46 std::shared_ptr<std::vector<std::string>> called_functions;
47 {
48 fml::AutoResetWaitableEvent wait_for_submit;
49 fml::AutoResetWaitableEvent wait_for_thread_join;
50 auto context = MockVulkanContextBuilder().Build();
51 std::thread thread([&] {
52 auto buffer = context->CreateCommandBuffer();
53 context->GetCommandQueue()->Submit(
54 {buffer}, [&](CommandBuffer::Status status) {
55 ASSERT_EQ(status, CommandBuffer::Status::kCompleted);
56 wait_for_thread_join.Wait();
57 wait_for_submit.Signal();
58 });
59 });
60 thread.join();
61 wait_for_thread_join.Signal();
62 wait_for_submit.Wait();
63 called_functions = GetMockVulkanFunctions(context->GetDevice());
64 context->Shutdown();
65 }
66
67 auto destroy_pool =
68 std::find(called_functions->begin(), called_functions->end(),
69 "vkDestroyCommandPool");
70 auto free_buffers =
71 std::find(called_functions->begin(), called_functions->end(),
72 "vkFreeCommandBuffers");
73 EXPECT_TRUE(destroy_pool != called_functions->end());
74 EXPECT_TRUE(free_buffers != called_functions->end());
75 EXPECT_TRUE(free_buffers < destroy_pool);
76}
int find(T *array, int N, T item)
std::shared_ptr< ContextVK > Build()
Create a Vulkan context with Vulkan functions mocked. The caller is given a chance to tinker on the s...
Definition: mock_vulkan.cc:912
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 to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
std::shared_ptr< std::vector< std::string > > GetMockVulkanFunctions(VkDevice device)
Definition: mock_vulkan.cc:926

◆ TEST() [47/377]

impeller::testing::TEST ( CommandEncoderVKTest  ,
DeleteEncoderAfterThreadDies   
)

Definition at line 16 of file command_encoder_vk_unittests.cc.

16 {
17 // Tests that when a CommandEncoderVK is deleted that it will clean up its
18 // command buffers before it cleans up its command pool.
19 std::shared_ptr<std::vector<std::string>> called_functions;
20 {
21 auto context = MockVulkanContextBuilder().Build();
22 called_functions = GetMockVulkanFunctions(context->GetDevice());
23 std::shared_ptr<CommandEncoderVK> encoder;
24 std::thread thread([&] {
25 CommandEncoderFactoryVK factory(context);
26 encoder = factory.Create();
27 });
28 thread.join();
29 context->Shutdown();
30 }
31 auto destroy_pool =
32 std::find(called_functions->begin(), called_functions->end(),
33 "vkDestroyCommandPool");
34 auto free_buffers =
35 std::find(called_functions->begin(), called_functions->end(),
36 "vkFreeCommandBuffers");
37 EXPECT_TRUE(destroy_pool != called_functions->end());
38 EXPECT_TRUE(free_buffers != called_functions->end());
39 EXPECT_TRUE(free_buffers < destroy_pool);
40}

◆ TEST() [48/377]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
CommandBuffersAreRecycled   
)

Definition at line 115 of file command_pool_vk_unittests.cc.

115 {
116 auto const context = MockVulkanContextBuilder().Build();
117
118 {
119 // Fetch a pool (which will be created).
120 auto const recycler = context->GetCommandPoolRecycler();
121 auto pool = recycler->Get();
122
123 auto buffer = pool->CreateCommandBuffer();
124 pool->CollectCommandBuffer(std::move(buffer));
125
126 // This normally is called at the end of a frame.
127 recycler->Dispose();
128 }
129
130 // Wait for the pool to be reclaimed.
131 for (auto i = 0u; i < 2u; i++) {
132 auto waiter = fml::AutoResetWaitableEvent();
133 auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
134 {
135 UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
136 std::move(rattle));
137 }
138 waiter.Wait();
139 }
140
141 {
142 // Create a second pool and command buffer, which should reused the existing
143 // pool and cmd buffer.
144 auto const recycler = context->GetCommandPoolRecycler();
145 auto pool = recycler->Get();
146
147 auto buffer = pool->CreateCommandBuffer();
148 pool->CollectCommandBuffer(std::move(buffer));
149
150 // This normally is called at the end of a frame.
151 recycler->Dispose();
152 }
153
154 // Now check that we only ever created one pool and one command buffer.
155 auto const called = GetMockVulkanFunctions(context->GetDevice());
156 EXPECT_EQ(std::count(called->begin(), called->end(), "vkCreateCommandPool"),
157 1u);
158 EXPECT_EQ(
159 std::count(called->begin(), called->end(), "vkAllocateCommandBuffers"),
160 1u);
161
162 context->Shutdown();
163}
AutoreleasePool pool
int count
Definition: FontMgrTest.cpp:50
static SkString resource(SkPDFResourceType type, int index)

◆ TEST() [49/377]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
GetsACommandPoolPerThread   
)

Definition at line 14 of file command_pool_vk_unittests.cc.

14 {
15 auto const context = MockVulkanContextBuilder().Build();
16
17 {
18 // Record the memory location of each pointer to a command pool.
19 //
20 // These pools have to be held at this context, otherwise they will be
21 // dropped and recycled and potentially reused by another thread, causing
22 // flaky tests.
23 std::shared_ptr<CommandPoolVK> pool1;
24 std::shared_ptr<CommandPoolVK> pool2;
25
26 // Create a command pool in two threads and record the memory location.
27 std::thread thread1(
28 [&]() { pool1 = context->GetCommandPoolRecycler()->Get(); });
29
30 std::thread thread2(
31 [&]() { pool2 = context->GetCommandPoolRecycler()->Get(); });
32
33 thread1.join();
34 thread2.join();
35
36 // The two command pools should be different.
37 EXPECT_NE(pool1, pool2);
38 }
39
40 context->Shutdown();
41}
const GrXPFactory * Get(SkBlendMode mode)

◆ TEST() [50/377]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
GetsTheSameCommandPoolOnSameThread   
)

Definition at line 43 of file command_pool_vk_unittests.cc.

43 {
44 auto const context = MockVulkanContextBuilder().Build();
45
46 auto const pool1 = context->GetCommandPoolRecycler()->Get();
47 auto const pool2 = context->GetCommandPoolRecycler()->Get();
48
49 // The two command pools should be the same.
50 EXPECT_EQ(pool1.get(), pool2.get());
51
52 context->Shutdown();
53}

◆ TEST() [51/377]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
ReclaimMakesCommandPoolAvailable   
)

Definition at line 76 of file command_pool_vk_unittests.cc.

76 {
77 auto const context = MockVulkanContextBuilder().Build();
78
79 {
80 // Fetch a pool (which will be created).
81 auto const recycler = context->GetCommandPoolRecycler();
82 auto const pool = recycler->Get();
83
84 // This normally is called at the end of a frame.
85 recycler->Dispose();
86 }
87
88 // Add something to the resource manager and have it notify us when it's
89 // destroyed. That should give us a non-flaky signal that the pool has been
90 // reclaimed as well.
91 auto waiter = fml::AutoResetWaitableEvent();
92 auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
93 {
94 UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
95 std::move(rattle));
96 }
97 waiter.Wait();
98
99 // On another thread explicitly, request a new pool.
100 std::thread thread([&]() {
101 auto const pool = context->GetCommandPoolRecycler()->Get();
102 EXPECT_NE(pool.get(), nullptr);
103 });
104
105 thread.join();
106
107 // Now check that we only ever created one pool.
108 auto const called = GetMockVulkanFunctions(context->GetDevice());
109 EXPECT_EQ(std::count(called->begin(), called->end(), "vkCreateCommandPool"),
110 1u);
111
112 context->Shutdown();
113}

◆ TEST() [52/377]

impeller::testing::TEST ( ConditionVariableTest  ,
TestsCriticalSectionAfterWait   
)

Definition at line 205 of file base_unittests.cc.

205 {
206 std::vector<std::thread> threads;
207 const auto kThreadCount = 10u;
208
209 Mutex mtx;
211 size_t sum = 0u;
212
213 std::condition_variable start_cv;
214 std::mutex start_mtx;
215 bool start = false;
216 auto start_predicate = [&start]() { return start; };
217 auto thread_main = [&]() {
218 {
219 std::unique_lock start_lock(start_mtx);
220 start_cv.wait(start_lock, start_predicate);
221 }
222
223 mtx.Lock();
224 cv.Wait(mtx, []() { return true; });
225 auto old_val = sum;
226 std::this_thread::sleep_for(std::chrono::milliseconds{100u});
227 sum = old_val + 1u;
228 mtx.Unlock();
229 };
230 // Launch all threads. They will wait for the start CV to be signaled.
231 for (size_t i = 0; i < kThreadCount; i++) {
232 threads.emplace_back(thread_main);
233 }
234 // Notify all threads that the test may start.
235 {
236 {
237 std::scoped_lock start_lock(start_mtx);
238 start = true;
239 }
240 start_cv.notify_all();
241 }
242 // Join all threads.
243 ASSERT_EQ(threads.size(), kThreadCount);
244 for (size_t i = 0; i < kThreadCount; i++) {
245 threads[i].join();
246 }
247 ASSERT_EQ(sum, kThreadCount);
248}
A condition variable exactly similar to the one in libcxx with two major differences:
Definition: thread.h:144
void Wait(Mutex &mutex, const Predicate &should_stop_waiting) IPLR_REQUIRES(mutex)
Atomically unlocks the mutex and waits on the condition variable indefinitely till the predicate dete...
Definition: thread.h:258
static constexpr uint64_t kThreadCount

◆ TEST() [53/377]

impeller::testing::TEST ( ConditionVariableTest  ,
TestsCriticalSectionAfterWaitForUntil   
)

Definition at line 160 of file base_unittests.cc.

160 {
161 std::vector<std::thread> threads;
162 const auto kThreadCount = 10u;
163
164 Mutex mtx;
166 size_t sum = 0u;
167
168 std::condition_variable start_cv;
169 std::mutex start_mtx;
170 bool start = false;
171 auto start_predicate = [&start]() { return start; };
172 auto thread_main = [&]() {
173 {
174 std::unique_lock start_lock(start_mtx);
175 start_cv.wait(start_lock, start_predicate);
176 }
177
178 mtx.Lock();
179 cv.WaitFor(mtx, std::chrono::milliseconds{0u}, []() { return true; });
180 auto old_val = sum;
181 std::this_thread::sleep_for(std::chrono::milliseconds{100u});
182 sum = old_val + 1u;
183 mtx.Unlock();
184 };
185 // Launch all threads. They will wait for the start CV to be signaled.
186 for (size_t i = 0; i < kThreadCount; i++) {
187 threads.emplace_back(thread_main);
188 }
189 // Notify all threads that the test may start.
190 {
191 {
192 std::scoped_lock start_lock(start_mtx);
193 start = true;
194 }
195 start_cv.notify_all();
196 }
197 // Join all threads.
198 ASSERT_EQ(threads.size(), kThreadCount);
199 for (size_t i = 0; i < kThreadCount; i++) {
200 threads[i].join();
201 }
202 ASSERT_EQ(sum, kThreadCount);
203}
bool WaitFor(Mutex &mutex, const std::chrono::duration< Representation, Period > &duration, const Predicate &should_stop_waiting) IPLR_REQUIRES(mutex)
Atomically unlocks the mutex and waits on the condition variable for a designated duration....
Definition: thread.h:229

◆ TEST() [54/377]

impeller::testing::TEST ( ConditionVariableTest  ,
WaitFor   
)

Definition at line 122 of file base_unittests.cc.

122 {
123 CVTest test;
124 // test.rando_ivar = 12; // <--- Static analysis error
125 for (size_t i = 0; i < 2; ++i) {
126 test.mutex.Lock(); // <--- Static analysis error without this.
127 auto result = test.cv.WaitFor(
128 test.mutex, std::chrono::milliseconds{10},
129 [&]() IPLR_REQUIRES(test.mutex) {
130 test.rando_ivar = 12; // <-- Static analysics error without the
131 // IPLR_REQUIRES on the pred.
132 return false;
133 });
134 test.mutex.Unlock();
135 ASSERT_FALSE(result);
136 }
137 Lock lock(test.mutex); // <--- Static analysis error without this.
138 // The predicate never returns true. So return has to be due to a non-spurious
139 // wake.
140 ASSERT_EQ(test.rando_ivar, 12u);
141}
#define test(name)
#define IPLR_REQUIRES(...)
Definition: thread_safety.h:30

◆ TEST() [55/377]

impeller::testing::TEST ( ConditionVariableTest  ,
WaitForever   
)

Definition at line 143 of file base_unittests.cc.

143 {
144 CVTest test;
145 // test.rando_ivar = 12; // <--- Static analysis error
146 for (size_t i = 0; i < 2; ++i) {
147 test.mutex.Lock(); // <--- Static analysis error without this.
148 test.cv.Wait(test.mutex, [&]() IPLR_REQUIRES(test.mutex) {
149 test.rando_ivar = 12; // <-- Static analysics error without
150 // the IPLR_REQUIRES on the pred.
151 return true;
152 });
153 test.mutex.Unlock();
154 }
155 Lock lock(test.mutex); // <--- Static analysis error without this.
156 // The wake only happens when the predicate returns true.
157 ASSERT_EQ(test.rando_ivar, 12u);
158}

◆ TEST() [56/377]

impeller::testing::TEST ( ConditionVariableTest  ,
WaitUntil   
)

Definition at line 99 of file base_unittests.cc.

99 {
100 CVTest test;
101 // test.rando_ivar = 12; // <--- Static analysis error
102 for (size_t i = 0; i < 2; ++i) {
103 test.mutex.Lock(); // <--- Static analysis error without this.
104 auto result = test.cv.WaitUntil(
105 test.mutex,
106 std::chrono::high_resolution_clock::now() +
107 std::chrono::milliseconds{10},
108 [&]() IPLR_REQUIRES(test.mutex) {
109 test.rando_ivar = 12; // <-- Static analysics error without the
110 // IPLR_REQUIRES on the pred.
111 return false;
112 });
113 test.mutex.Unlock();
114 ASSERT_FALSE(result);
115 }
116 Lock lock(test.mutex); // <--- Static analysis error without this.
117 // The predicate never returns true. So return has to be due to a non-spurious
118 // wake.
119 ASSERT_EQ(test.rando_ivar, 12u);
120}

◆ TEST() [57/377]

impeller::testing::TEST ( ContextVKTest  ,
CanCreateContextInAbsenceOfValidationLayers   
)

Definition at line 132 of file context_vk_unittests.cc.

132 {
133 // The mocked methods don't report the presence of a validation layer but we
134 // explicitly ask for validation. Context creation should continue anyway.
135 auto context = MockVulkanContextBuilder()
136 .SetSettingsCallback([](auto& settings) {
137 settings.enable_validation = true;
138 })
139 .Build();
140 ASSERT_NE(context, nullptr);
141 const CapabilitiesVK* capabilites_vk =
142 reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
143 ASSERT_FALSE(capabilites_vk->AreValidationsEnabled());
144}
The Vulkan layers and extensions wrangler.
bool AreValidationsEnabled() const
MockVulkanContextBuilder & SetSettingsCallback(const std::function< void(ContextVK::Settings &)> &settings_callback)
Definition: mock_vulkan.h:74

◆ TEST() [58/377]

impeller::testing::TEST ( ContextVKTest  ,
CanCreateContextWithValidationLayers   
)

Definition at line 146 of file context_vk_unittests.cc.

146 {
147 auto context =
150 [](auto& settings) { settings.enable_validation = true; })
151 .SetInstanceExtensions(
152 {"VK_KHR_surface", "VK_MVK_macos_surface", "VK_EXT_debug_utils"})
153 .SetInstanceLayers({"VK_LAYER_KHRONOS_validation"})
154 .Build();
155 ASSERT_NE(context, nullptr);
156 const CapabilitiesVK* capabilites_vk =
157 reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
158 ASSERT_TRUE(capabilites_vk->AreValidationsEnabled());
159}

◆ TEST() [59/377]

impeller::testing::TEST ( ContextVKTest  ,
CommonHardwareConcurrencyConfigurations   
)

Definition at line 16 of file context_vk_unittests.cc.

16 {
17 EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(100u), 4u);
18 EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(9u), 4u);
19 EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(8u), 4u);
20 EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(7u), 3u);
21 EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(6u), 3u);
22 EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(5u), 2u);
23 EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(4u), 2u);
24 EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(3u), 1u);
25 EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(2u), 1u);
26 EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(1u), 1u);
27}

◆ TEST() [60/377]

impeller::testing::TEST ( ContextVKTest  ,
DeletePipelineAfterContext   
)

Definition at line 75 of file context_vk_unittests.cc.

75 {
76 std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline;
77 std::shared_ptr<std::vector<std::string>> functions;
78 {
79 std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
80 PipelineDescriptor pipeline_desc;
81 pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
83 context->GetPipelineLibrary()->GetPipeline(pipeline_desc);
84 pipeline = pipeline_future.Get();
85 ASSERT_TRUE(pipeline);
86 functions = GetMockVulkanFunctions(context->GetDevice());
87 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
88 "vkCreateGraphicsPipelines") != functions->end());
89 }
90 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
91 "vkDestroyDevice") != functions->end());
92}
PipelineDescriptor & SetVertexDescriptor(std::shared_ptr< VertexDescriptor > vertex_descriptor)
const std::shared_ptr< Pipeline< T > > Get() const
Definition: pipeline.h:29

◆ TEST() [61/377]

impeller::testing::TEST ( ContextVKTest  ,
DeletePipelineLibraryAfterContext   
)

Definition at line 116 of file context_vk_unittests.cc.

116 {
117 std::shared_ptr<PipelineLibrary> pipeline_library;
118 std::shared_ptr<std::vector<std::string>> functions;
119 {
120 std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
121 PipelineDescriptor pipeline_desc;
122 pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
123 pipeline_library = context->GetPipelineLibrary();
124 functions = GetMockVulkanFunctions(context->GetDevice());
125 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
126 "vkCreatePipelineCache") != functions->end());
127 }
128 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
129 "vkDestroyDevice") != functions->end());
130}

◆ TEST() [62/377]

impeller::testing::TEST ( ContextVKTest  ,
DeletesCommandPools   
)

Definition at line 29 of file context_vk_unittests.cc.

29 {
30 std::weak_ptr<ContextVK> weak_context;
31 std::weak_ptr<CommandPoolVK> weak_pool;
32 {
33 std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
34 auto const pool = context->GetCommandPoolRecycler()->Get();
35 weak_pool = pool;
36 weak_context = context;
37 ASSERT_TRUE(weak_pool.lock());
38 ASSERT_TRUE(weak_context.lock());
39 }
40 ASSERT_FALSE(weak_pool.lock());
41 ASSERT_FALSE(weak_context.lock());
42}

◆ TEST() [63/377]

impeller::testing::TEST ( ContextVKTest  ,
DeletesCommandPoolsOnAllThreads   
)

Definition at line 44 of file context_vk_unittests.cc.

44 {
45 std::weak_ptr<ContextVK> weak_context;
46 std::weak_ptr<CommandPoolVK> weak_pool_main;
47
48 std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
49 weak_pool_main = context->GetCommandPoolRecycler()->Get();
50 weak_context = context;
51 ASSERT_TRUE(weak_pool_main.lock());
52 ASSERT_TRUE(weak_context.lock());
53
54 // Start a second thread that obtains a command pool.
55 fml::AutoResetWaitableEvent latch1, latch2;
56 std::weak_ptr<CommandPoolVK> weak_pool_thread;
57 std::thread thread([&]() {
58 weak_pool_thread = context->GetCommandPoolRecycler()->Get();
59 latch1.Signal();
60 latch2.Wait();
61 });
62
63 // Delete the ContextVK on the main thread.
64 latch1.Wait();
65 context.reset();
66 ASSERT_FALSE(weak_pool_main.lock());
67 ASSERT_FALSE(weak_context.lock());
68
69 // Stop the second thread and check that its command pool has been deleted.
70 latch2.Signal();
71 thread.join();
72 ASSERT_FALSE(weak_pool_thread.lock());
73}

◆ TEST() [64/377]

impeller::testing::TEST ( ContextVKTest  ,
DeleteShaderFunctionAfterContext   
)

Definition at line 94 of file context_vk_unittests.cc.

94 {
95 std::shared_ptr<const ShaderFunction> shader_function;
96 std::shared_ptr<std::vector<std::string>> functions;
97 {
98 std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
99 PipelineDescriptor pipeline_desc;
100 pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
101 std::vector<uint8_t> data = {0x03, 0x02, 0x23, 0x07};
102 context->GetShaderLibrary()->RegisterFunction(
103 "foobar_fragment_main", ShaderStage::kFragment,
104 std::make_shared<fml::DataMapping>(data), [](bool) {});
105 shader_function = context->GetShaderLibrary()->GetFunction(
106 "foobar_fragment_main", ShaderStage::kFragment);
107 ASSERT_TRUE(shader_function);
108 functions = GetMockVulkanFunctions(context->GetDevice());
109 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
110 "vkCreateShaderModule") != functions->end());
111 }
112 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
113 "vkDestroyDevice") != functions->end());
114}

◆ TEST() [65/377]

impeller::testing::TEST ( ContextVKTest  ,
FatalMissingValidations   
)

Definition at line 225 of file context_vk_unittests.cc.

225 {
226 EXPECT_DEATH(const std::shared_ptr<ContextVK> context =
228 .SetSettingsCallback([](ContextVK::Settings& settings) {
229 settings.enable_validation = true;
230 settings.fatal_missing_validations = true;
231 })
232 .Build(),
233 "");
234}

◆ TEST() [66/377]

impeller::testing::TEST ( ContextVKTest  ,
HasDefaultColorFormat   
)

Definition at line 236 of file context_vk_unittests.cc.

236 {
237 std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
238
239 const CapabilitiesVK* capabilites_vk =
240 reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
241 ASSERT_NE(capabilites_vk->GetDefaultColorFormat(), PixelFormat::kUnknown);
242}
PixelFormat GetDefaultColorFormat() const override
Returns a supported PixelFormat for textures that store 4-channel colors (red/green/blue/alpha).

◆ TEST() [67/377]

impeller::testing::TEST ( ContextVKTest  ,
WarmUpFunctionCreatesRenderPass   
)

Definition at line 214 of file context_vk_unittests.cc.

214 {
215 const std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
216
217 context->SetOffscreenFormat(PixelFormat::kR8G8B8A8UNormInt);
218 context->InitializeCommonlyUsedShadersIfNeeded();
219
220 auto functions = GetMockVulkanFunctions(context->GetDevice());
221 ASSERT_TRUE(std::find(functions->begin(), functions->end(),
222 "vkCreateRenderPass") != functions->end());
223}

◆ TEST() [68/377]

impeller::testing::TEST ( DescriptorPoolRecyclerVKTest  ,
GetDescriptorPoolRecyclerCreatesNewPools   
)

Definition at line 15 of file descriptor_pool_vk_unittests.cc.

15 {
16 auto const context = MockVulkanContextBuilder().Build();
17
18 auto const pool1 = context->GetDescriptorPoolRecycler()->Get();
19 auto const pool2 = context->GetDescriptorPoolRecycler()->Get();
20
21 // The two descriptor pools should be different.
22 EXPECT_NE(pool1.get(), pool2.get());
23
24 context->Shutdown();
25}

◆ TEST() [69/377]

impeller::testing::TEST ( DescriptorPoolRecyclerVKTest  ,
ReclaimDropsDescriptorPoolIfSizeIsExceeded   
)

Definition at line 65 of file descriptor_pool_vk_unittests.cc.

65 {
66 auto const context = MockVulkanContextBuilder().Build();
67
68 // Create 33 pools
69 {
70 std::vector<std::unique_ptr<DescriptorPoolVK>> pools;
71 for (auto i = 0u; i < 33; i++) {
72 auto pool = std::make_unique<DescriptorPoolVK>(context);
73 pool->AllocateDescriptorSets({}, *context);
74 pools.push_back(std::move(pool));
75 }
76 }
77
78 // See note above.
79 for (auto i = 0u; i < 2; i++) {
80 auto waiter = fml::AutoResetWaitableEvent();
81 auto rattle = fml::ScopedCleanupClosure([&waiter]() { waiter.Signal(); });
82 {
83 UniqueResourceVKT<fml::ScopedCleanupClosure> resource(
84 context->GetResourceManager(), std::move(rattle));
85 }
86 waiter.Wait();
87 }
88
89 auto const called = GetMockVulkanFunctions(context->GetDevice());
90 EXPECT_EQ(
91 std::count(called->begin(), called->end(), "vkCreateDescriptorPool"),
92 33u);
93 EXPECT_EQ(std::count(called->begin(), called->end(), "vkResetDescriptorPool"),
94 33u);
95
96 // Now create 33 more descriptor pools and observe that only one more is
97 // allocated.
98 {
99 std::vector<std::unique_ptr<DescriptorPoolVK>> pools;
100 for (auto i = 0u; i < 33; i++) {
101 auto pool = std::make_unique<DescriptorPoolVK>(context);
102 pool->AllocateDescriptorSets({}, *context);
103 pools.push_back(std::move(pool));
104 }
105 }
106
107 for (auto i = 0u; i < 2; i++) {
108 auto waiter = fml::AutoResetWaitableEvent();
109 auto rattle = fml::ScopedCleanupClosure([&waiter]() { waiter.Signal(); });
110 {
111 UniqueResourceVKT<fml::ScopedCleanupClosure> resource(
112 context->GetResourceManager(), std::move(rattle));
113 }
114 waiter.Wait();
115 }
116
117 auto const called_twice = GetMockVulkanFunctions(context->GetDevice());
118 // 32 of the descriptor pools were recycled, so only one more is created.
119 EXPECT_EQ(
120 std::count(called->begin(), called->end(), "vkCreateDescriptorPool"),
121 34u);
122
123 context->Shutdown();
124}
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition: closure.h:32

◆ TEST() [70/377]

impeller::testing::TEST ( DescriptorPoolRecyclerVKTest  ,
ReclaimMakesDescriptorPoolAvailable   
)

Definition at line 27 of file descriptor_pool_vk_unittests.cc.

27 {
28 auto const context = MockVulkanContextBuilder().Build();
29
30 {
31 // Fetch a pool (which will be created).
32 auto pool = DescriptorPoolVK(context);
33 pool.AllocateDescriptorSets({}, *context);
34 }
35
36 // There is a chance that the first death rattle item below is destroyed in
37 // the same reclaim cycle as the pool allocation above. These items are placed
38 // into a std::vector and free'd, which may free in reverse order. That would
39 // imply that the death rattle and subsequent waitable event fires before the
40 // pool is reset. To work around this, we can either manually remove items
41 // from the vector or use two death rattles.
42 for (auto i = 0u; i < 2; i++) {
43 // Add something to the resource manager and have it notify us when it's
44 // destroyed. That should give us a non-flaky signal that the pool has been
45 // reclaimed as well.
46 auto waiter = fml::AutoResetWaitableEvent();
47 auto rattle = fml::ScopedCleanupClosure([&waiter]() { waiter.Signal(); });
48 {
49 UniqueResourceVKT<fml::ScopedCleanupClosure> resource(
50 context->GetResourceManager(), std::move(rattle));
51 }
52 waiter.Wait();
53 }
54
55 auto const pool = context->GetDescriptorPoolRecycler()->Get();
56
57 // Now check that we only ever created one pool.
58 auto const called = GetMockVulkanFunctions(context->GetDevice());
59 EXPECT_EQ(
60 std::count(called->begin(), called->end(), "vkCreateDescriptorPool"), 1u);
61
62 context->Shutdown();
63}
A per-frame descriptor pool. Descriptors from this pool don't need to be freed individually....

◆ TEST() [71/377]

impeller::testing::TEST ( DisplayListTest  ,
CircleBoundsComputation   
)

Definition at line 1584 of file dl_unittests.cc.

1584 {
1585 SkPath path = SkPath().addCircle(0, 0, 5);
1586
1589
1590 builder.DrawPath(path, paint);
1591 auto display_list = builder.Build();
1592
1593 DlDispatcher dispatcher;
1594 display_list->Dispatch(dispatcher);
1595 auto picture = dispatcher.EndRecordingAsPicture();
1596
1597 std::optional<Rect> coverage =
1598 GetCoverageOfFirstEntity<SolidColorContents>(picture);
1599
1600 ASSERT_TRUE(coverage.has_value());
1601 ASSERT_EQ(coverage.value_or(Rect::MakeMaximum()),
1602 Rect::MakeLTRB(-5, -5, 5, 5));
1603}
Definition: SkPath.h:59
SkPath & addCircle(SkScalar x, SkScalar y, SkScalar radius, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1213

◆ TEST() [72/377]

impeller::testing::TEST ( DisplayListTest  ,
RRectBoundsComputation   
)

Definition at line 1561 of file dl_unittests.cc.

1561 {
1562 SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 100, 100), 4, 4);
1564
1567
1568 builder.DrawPath(path, paint);
1569 auto display_list = builder.Build();
1570
1571 DlDispatcher dispatcher;
1572 display_list->Dispatch(dispatcher);
1573 auto picture = dispatcher.EndRecordingAsPicture();
1574
1575 std::optional<Rect> coverage =
1576 GetCoverageOfFirstEntity<SolidColorContents>(picture);
1577
1578 // Validate that the RRect coverage is _exactly_ the same as the input rect.
1579 ASSERT_TRUE(coverage.has_value());
1580 ASSERT_EQ(coverage.value_or(Rect::MakeMaximum()),
1581 Rect::MakeLTRB(0, 0, 100, 100));
1582}
SkPath & addRRect(const SkRRect &rrect, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1000
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.h:180
SkRRect rrect
Definition: SkRecords.h:232
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646

◆ TEST() [73/377]

impeller::testing::TEST ( EntityGeometryTest  ,
AlphaCoverageStrokePaths   
)

Definition at line 139 of file geometry_unittests.cc.

139 {
140 Entity entity;
141 entity.SetTransform(Matrix::MakeScale(Vector2{3.0, 3.0}));
142 EXPECT_EQ(Geometry::MakeStrokePath({}, 0.5)->ComputeAlphaCoverage(entity), 1);
143 EXPECT_EQ(Geometry::MakeStrokePath({}, 0.1)->ComputeAlphaCoverage(entity), 1);
144 EXPECT_EQ(Geometry::MakeStrokePath({}, 0.05)->ComputeAlphaCoverage(entity),
145 1);
146 EXPECT_NEAR(Geometry::MakeStrokePath({}, 0.01)->ComputeAlphaCoverage(entity),
147 0.6, 0.1);
148 EXPECT_NEAR(
149 Geometry::MakeStrokePath({}, 0.0000005)->ComputeAlphaCoverage(entity),
150 1e-05, 0.001);
151 EXPECT_EQ(Geometry::MakeStrokePath({}, 0)->ComputeAlphaCoverage(entity), 1);
152 EXPECT_EQ(Geometry::MakeStrokePath({}, 40)->ComputeAlphaCoverage(entity), 1);
153}
void SetTransform(const Matrix &transform)
Set the global transform matrix for this Entity.
Definition: entity.cc:62

◆ TEST() [74/377]

impeller::testing::TEST ( EntityGeometryTest  ,
FillPathGeometryCoversArea   
)

Definition at line 78 of file geometry_unittests.cc.

78 {
79 auto path = PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath();
80 auto geometry = Geometry::MakeFillPath(
81 path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
82 ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
83 ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
84 ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
85 ASSERT_TRUE(geometry->CoversArea({}, Rect()));
86}
Path TakePath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:22

◆ TEST() [75/377]

impeller::testing::TEST ( EntityGeometryTest  ,
FillPathGeometryCoversAreaNoInnerRect   
)

Definition at line 88 of file geometry_unittests.cc.

88 {
89 auto path = PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath();
90 auto geometry = Geometry::MakeFillPath(path);
91 ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
92 ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
93 ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
94 ASSERT_FALSE(geometry->CoversArea({}, Rect()));
95}

◆ TEST() [76/377]

impeller::testing::TEST ( EntityGeometryTest  ,
GeometryResultHasReasonableDefaults   
)

Definition at line 132 of file geometry_unittests.cc.

132 {
134 EXPECT_EQ(result.type, PrimitiveType::kTriangleStrip);
135 EXPECT_EQ(result.transform, Matrix());
136 EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
137}
A 4x4 matrix using column-major storage.
Definition: matrix.h:37

◆ TEST() [77/377]

impeller::testing::TEST ( EntityGeometryTest  ,
LineGeometryCoverage   
)

Definition at line 97 of file geometry_unittests.cc.

97 {
98 {
99 auto geometry = Geometry::MakeLine({10, 10}, {20, 10}, 2, Cap::kButt);
100 EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(10, 9, 20, 11));
101 EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(10, 9, 20, 11)));
102 }
103
104 {
105 auto geometry = Geometry::MakeLine({10, 10}, {20, 10}, 2, Cap::kSquare);
106 EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 9, 21, 11));
107 EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 9, 21, 11)));
108 }
109
110 {
111 auto geometry = Geometry::MakeLine({10, 10}, {10, 20}, 2, Cap::kButt);
112 EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 10, 11, 20));
113 EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 10, 11, 20)));
114 }
115
116 {
117 auto geometry = Geometry::MakeLine({10, 10}, {10, 20}, 2, Cap::kSquare);
118 EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 9, 11, 21));
119 EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 9, 11, 21)));
120 }
121}

◆ TEST() [78/377]

impeller::testing::TEST ( EntityGeometryTest  ,
RectGeometryCoversArea   
)

Definition at line 70 of file geometry_unittests.cc.

70 {
71 auto geometry = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 100, 100));
72 ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
73 ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
74 ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
75 ASSERT_TRUE(geometry->CoversArea({}, Rect()));
76}
GrOp::Owner MakeRect(GrRecordingContext *context, GrPaint &&paint, const SkRect &drawRect, const SkRect &localRect, const SkMatrix &localM)
Definition: TestOps.cpp:227

◆ TEST() [79/377]

impeller::testing::TEST ( EntityGeometryTest  ,
RoundRectGeometryCoversArea   
)

Definition at line 123 of file geometry_unittests.cc.

123 {
124 auto geometry =
125 Geometry::MakeRoundRect(Rect::MakeLTRB(0, 0, 100, 100), Size(20, 20));
126 EXPECT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(15, 15, 85, 85)));
127 EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(20, 20, 80, 80)));
128 EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(30, 1, 70, 99)));
129 EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 30, 99, 70)));
130}
TSize< Scalar > Size
Definition: size.h:137

◆ TEST() [80/377]

impeller::testing::TEST ( EntityPassClipStackTest  ,
AppendAndRestoreClipCoverage   
)

Definition at line 92 of file entity_pass_unittests.cc.

92 {
93 EntityPassClipStack recorder =
94 EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
95
96 ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
97
98 // Push a clip.
99 Entity entity;
102 .type = Contents::ClipCoverage::Type::kAppend,
103 .coverage = Rect::MakeLTRB(50, 50, 55, 55),
104 },
105 entity, 0, Point(0, 0));
106 EXPECT_TRUE(result.should_render);
107 EXPECT_TRUE(result.clip_did_change);
108
109 ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
110 EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
111 Rect::MakeLTRB(50, 50, 55, 55));
112 EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u);
113 EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
114
115 // Restore the clip.
116 auto restore_clip = std::make_shared<ClipRestoreContents>();
117 restore_clip->SetRestoreHeight(0);
118 entity.SetContents(std::move(restore_clip));
119 recorder.ApplyClipState(
121 .type = Contents::ClipCoverage::Type::kRestore,
122 .coverage = Rect::MakeLTRB(50, 50, 55, 55),
123 },
124 entity, 0, Point(0, 0));
125
126 ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
127 EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
128 Rect::MakeSize(Size::MakeWH(100, 100)));
129 EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
130 EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
131}
A class that tracks all clips that have been recorded in the current entity pass stencil.
const std::vector< ReplayResult > & GetReplayEntities() const
ClipStateResult ApplyClipState(Contents::ClipCoverage global_clip_coverage, Entity &entity, size_t clip_height_floor, Point global_pass_position)
Applies the current clip state to an Entity. If the given Entity is a clip operation,...
const std::vector< ClipCoverageLayer > GetClipCoverageLayers() const

◆ TEST() [81/377]

impeller::testing::TEST ( EntityPassClipStackTest  ,
AppendCoverageNoChange   
)

Definition at line 69 of file entity_pass_unittests.cc.

69 {
70 EntityPassClipStack recorder =
71 EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
72
73 EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
74 Rect::MakeSize(Size::MakeWH(100, 100)));
75 EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
76
77 Entity entity;
80 .type = Contents::ClipCoverage::Type::kNoChange,
81 .coverage = std::nullopt,
82 },
83 entity, 0, Point(0, 0));
84 EXPECT_TRUE(result.should_render);
85 EXPECT_FALSE(result.clip_did_change);
86
87 EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
88 Rect::MakeSize(Size::MakeWH(100, 100)));
89 EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
90}

◆ TEST() [82/377]

impeller::testing::TEST ( EntityPassClipStackTest  ,
CanAppendNoChange   
)

Definition at line 57 of file entity_pass_unittests.cc.

57 {
58 EntityPassClipStack recorder =
59 EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
60
61 EXPECT_TRUE(recorder.GetReplayEntities().empty());
62
63 Entity entity;
64 recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kNoChange,
65 Rect());
66 EXPECT_TRUE(recorder.GetReplayEntities().empty());
67}
void RecordEntity(const Entity &entity, Contents::ClipCoverage::Type type, std::optional< Rect > clip_coverage)
TRect< Scalar > Rect
Definition: rect.h:769

◆ TEST() [83/377]

impeller::testing::TEST ( EntityPassClipStackTest  ,
CanPopEntitiesSafely   
)

Definition at line 46 of file entity_pass_unittests.cc.

46 {
47 EntityPassClipStack recorder =
48 EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
49
50 EXPECT_TRUE(recorder.GetReplayEntities().empty());
51
52 Entity entity;
53 recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kRestore, Rect());
54 EXPECT_TRUE(recorder.GetReplayEntities().empty());
55}

◆ TEST() [84/377]

impeller::testing::TEST ( EntityPassClipStackTest  ,
CanPushAndPopEntities   
)

Definition at line 16 of file entity_pass_unittests.cc.

16 {
17 EntityPassClipStack recorder =
18 EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
19
20 EXPECT_TRUE(recorder.GetReplayEntities().empty());
21
22 Entity entity;
23 recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kAppend,
24 Rect::MakeLTRB(0, 0, 100, 100));
25 EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
26
27 recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kAppend,
28 Rect::MakeLTRB(0, 0, 50, 50));
29 EXPECT_EQ(recorder.GetReplayEntities().size(), 2u);
30 ASSERT_TRUE(recorder.GetReplayEntities()[0].clip_coverage.has_value());
31 ASSERT_TRUE(recorder.GetReplayEntities()[1].clip_coverage.has_value());
32 // NOLINTBEGIN(bugprone-unchecked-optional-access)
33 EXPECT_EQ(recorder.GetReplayEntities()[0].clip_coverage.value(),
34 Rect::MakeLTRB(0, 0, 100, 100));
35 EXPECT_EQ(recorder.GetReplayEntities()[1].clip_coverage.value(),
36 Rect::MakeLTRB(0, 0, 50, 50));
37 // NOLINTEND(bugprone-unchecked-optional-access)
38
39 recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kRestore, Rect());
40 EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
41
42 recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kRestore, Rect());
43 EXPECT_TRUE(recorder.GetReplayEntities().empty());
44}

◆ TEST() [85/377]

impeller::testing::TEST ( EntityPassClipStackTest  ,
ClipAndRestoreWithSubpasses   
)

Definition at line 160 of file entity_pass_unittests.cc.

160 {
161 EntityPassClipStack recorder =
162 EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
163
164 ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
165
166 // Push a clip.
167 Entity entity;
168 {
171 .type = Contents::ClipCoverage::Type::kAppend,
172 .coverage = Rect::MakeLTRB(50, 50, 55, 55),
173 },
174 entity, 0, Point(0, 0));
175 EXPECT_TRUE(result.should_render);
176 EXPECT_TRUE(result.clip_did_change);
177 }
178
179 ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
180 EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
181 Rect::MakeLTRB(50, 50, 55, 55));
182 EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u);
183 EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
184
185 // Begin a subpass.
186 recorder.PushSubpass(Rect::MakeLTRB(50, 50, 55, 55), 1);
187 ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
188 EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
189 Rect::MakeLTRB(50, 50, 55, 55));
190
191 {
192 EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
193 Contents::ClipCoverage{
194 .type = Contents::ClipCoverage::Type::kAppend,
195 .coverage = Rect::MakeLTRB(54, 54, 55, 55),
196 },
197 entity, 0, Point(0, 0));
198 EXPECT_TRUE(result.should_render);
199 EXPECT_TRUE(result.clip_did_change);
200 }
201
202 EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
203 Rect::MakeLTRB(54, 54, 55, 55));
204
205 // End subpass.
206 recorder.PopSubpass();
207
208 EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
209 Rect::MakeLTRB(50, 50, 55, 55));
210}
void PushSubpass(std::optional< Rect > subpass_coverage, size_t clip_height)

◆ TEST() [86/377]

impeller::testing::TEST ( EntityPassClipStackTest  ,
UnbalancedRestore   
)

Definition at line 133 of file entity_pass_unittests.cc.

133 {
134 EntityPassClipStack recorder =
135 EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
136
137 ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
138
139 // Restore the clip.
140 Entity entity;
141 auto restore_clip = std::make_shared<ClipRestoreContents>();
142 restore_clip->SetRestoreHeight(0);
143 entity.SetContents(std::move(restore_clip));
146 .type = Contents::ClipCoverage::Type::kRestore,
147 .coverage = Rect::MakeLTRB(50, 50, 55, 55),
148 },
149 entity, 0, Point(0, 0));
150 EXPECT_FALSE(result.should_render);
151 EXPECT_FALSE(result.clip_did_change);
152
153 ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
154 EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
155 Rect::MakeSize(Size::MakeWH(100, 100)));
156 EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
157 EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
158}

◆ TEST() [87/377]

impeller::testing::TEST ( FenceWaiterVKTest  ,
AddFenceDoesNothingIfTerminating   
)

Definition at line 86 of file fence_waiter_vk_unittests.cc.

86 {
87 auto signal = fml::ManualResetWaitableEvent();
88
89 {
90 auto const context = MockVulkanContextBuilder().Build();
91 auto const device = context->GetDevice();
92 auto const waiter = context->GetFenceWaiter();
93 waiter->Terminate();
94
95 auto fence = device.createFenceUnique({}).value;
96 waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
97 }
98
99 // Ensure the fence did _not_ signal.
100 EXPECT_TRUE(signal.WaitWithTimeout(fml::TimeDelta::FromMilliseconds(100)));
101}
static constexpr TimeDelta FromMilliseconds(int64_t millis)
Definition: time_delta.h:46

◆ TEST() [88/377]

impeller::testing::TEST ( FenceWaiterVKTest  ,
ExecutesFenceCallback   
)

Definition at line 28 of file fence_waiter_vk_unittests.cc.

28 {
29 auto const context = MockVulkanContextBuilder().Build();
30 auto const device = context->GetDevice();
31 auto const waiter = context->GetFenceWaiter();
32
33 auto signal = fml::ManualResetWaitableEvent();
34 auto fence = device.createFenceUnique({}).value;
35 waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
36
37 signal.Wait();
38}

◆ TEST() [89/377]

impeller::testing::TEST ( FenceWaiterVKTest  ,
ExecutesFenceCallbackX2   
)

Definition at line 40 of file fence_waiter_vk_unittests.cc.

40 {
41 auto const context = MockVulkanContextBuilder().Build();
42 auto const device = context->GetDevice();
43 auto const waiter = context->GetFenceWaiter();
44
45 auto signal = fml::ManualResetWaitableEvent();
46 auto fence = device.createFenceUnique({}).value;
47 waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
48
49 auto signal2 = fml::ManualResetWaitableEvent();
50 auto fence2 = device.createFenceUnique({}).value;
51 waiter->AddFence(std::move(fence2), [&signal2]() { signal2.Signal(); });
52
53 signal.Wait();
54 signal2.Wait();
55}

◆ TEST() [90/377]

impeller::testing::TEST ( FenceWaiterVKTest  ,
ExecutesNewFenceThenOldFence   
)

Definition at line 57 of file fence_waiter_vk_unittests.cc.

57 {
58 auto const context = MockVulkanContextBuilder().Build();
59 auto const device = context->GetDevice();
60 auto const waiter = context->GetFenceWaiter();
61
62 auto signal = fml::ManualResetWaitableEvent();
63 auto fence = device.createFenceUnique({}).value;
64 MockFence::SetStatus(fence, vk::Result::eNotReady);
65 auto raw_fence = MockFence::GetRawPointer(fence);
66 waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
67
68 // The easiest way to verify that the callback was _not_ called is to wait
69 // for a timeout, but that could introduce flakiness. Instead, we'll add a
70 // second fence that will signal immediately, and wait for that one instead.
71 {
72 auto signal2 = fml::ManualResetWaitableEvent();
73 auto fence2 = device.createFenceUnique({}).value;
74 MockFence::SetStatus(fence2, vk::Result::eSuccess);
75 waiter->AddFence(std::move(fence2), [&signal2]() { signal2.Signal(); });
76 signal2.Wait();
77 }
78
79 // Now, we'll signal the first fence, and wait for the callback to be called.
80 raw_fence->SetStatus(vk::Result::eSuccess);
81
82 // Now, we'll signal the first fence, and wait for the callback to be called.
83 signal.Wait();
84}

◆ TEST() [91/377]

impeller::testing::TEST ( FenceWaiterVKTest  ,
IgnoresNullCallback   
)

Definition at line 19 of file fence_waiter_vk_unittests.cc.

19 {
20 auto const context = MockVulkanContextBuilder().Build();
21 auto const device = context->GetDevice();
22 auto const waiter = context->GetFenceWaiter();
23
24 auto fence = device.createFenceUnique({}).value;
25 EXPECT_FALSE(waiter->AddFence(std::move(fence), nullptr));
26}

◆ TEST() [92/377]

impeller::testing::TEST ( FenceWaiterVKTest  ,
IgnoresNullFence   
)

Definition at line 13 of file fence_waiter_vk_unittests.cc.

13 {
14 auto const context = MockVulkanContextBuilder().Build();
15 auto const waiter = context->GetFenceWaiter();
16 EXPECT_FALSE(waiter->AddFence(vk::UniqueFence(), []() {}));
17}

◆ TEST() [93/377]

impeller::testing::TEST ( FenceWaiterVKTest  ,
InProgressFencesStillWaitIfTerminated   
)

Definition at line 103 of file fence_waiter_vk_unittests.cc.

103 {
104 MockFence* raw_fence = nullptr;
105 auto signal = fml::ManualResetWaitableEvent();
106
107 auto const context = MockVulkanContextBuilder().Build();
108 auto const device = context->GetDevice();
109 auto const waiter = context->GetFenceWaiter();
110
111 // Add a fence that isn't signalled yet.
112 auto fence = device.createFenceUnique({}).value;
113
114 // Even if the fence is eSuccess, it's not guaranteed to be called in time.
115 MockFence::SetStatus(fence, vk::Result::eNotReady);
116 raw_fence = MockFence::GetRawPointer(fence);
117 waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
118
119 // Terminate the waiter.
120 waiter->Terminate();
121
122 // Signal the fence.
123 raw_fence->SetStatus(vk::Result::eSuccess);
124
125 // This will hang if the fence was not signalled.
126 signal.Wait();
127}
void SetStatus(vk::Result result)
Definition: mock_vulkan.h:33

◆ TEST() [94/377]

impeller::testing::TEST ( FilterInputTest  ,
CanSetLocalTransformForTexture   
)

Definition at line 17 of file filter_input_unittests.cc.

17 {
18 std::shared_ptr<Texture> texture = nullptr;
19 auto input =
20 FilterInput::Make(texture, Matrix::MakeTranslation({1.0, 0.0, 0.0}));
21 Entity e;
22 e.SetTransform(Matrix::MakeTranslation({0.0, 2.0, 0.0}));
23
24 ASSERT_MATRIX_NEAR(input->GetLocalTransform(e),
25 Matrix::MakeTranslation({1.0, 0.0, 0.0}));
26 ASSERT_MATRIX_NEAR(input->GetTransform(e),
27 Matrix::MakeTranslation({1.0, 2.0, 0.0}));
28}
#define ASSERT_MATRIX_NEAR(a, b)
FlTexture * texture

◆ TEST() [95/377]

impeller::testing::TEST ( FilterInputTest  ,
IsLeaf   
)

Definition at line 30 of file filter_input_unittests.cc.

30 {
31 std::shared_ptr<FilterContents> leaf =
32 ColorFilterContents::MakeBlend(BlendMode::kSource, {});
33 ASSERT_TRUE(leaf->IsLeaf());
34
35 auto base = ColorFilterContents::MakeMatrixFilter(FilterInput::Make(leaf),
36 Matrix(), {});
37
38 ASSERT_TRUE(leaf->IsLeaf());
39 ASSERT_FALSE(base->IsLeaf());
40}
SK_API sk_sp< PrecompileColorFilter > Matrix()

◆ TEST() [96/377]

impeller::testing::TEST ( FilterInputTest  ,
SetCoverageInputs   
)

Definition at line 42 of file filter_input_unittests.cc.

42 {
43 std::shared_ptr<FilterContents> leaf =
44 ColorFilterContents::MakeBlend(BlendMode::kSource, {});
45 ASSERT_TRUE(leaf->IsLeaf());
46
47 auto base = ColorFilterContents::MakeMatrixFilter(FilterInput::Make(leaf),
48 Matrix(), {});
49
50 {
51 auto result = base->GetCoverage({});
52 ASSERT_FALSE(result.has_value());
53 }
54
55 auto coverage_rect = Rect::MakeLTRB(100, 100, 200, 200);
56 base->SetLeafInputs(FilterInput::Make({coverage_rect}));
57
58 {
59 auto result = base->GetCoverage({});
60 ASSERT_TRUE(result.has_value());
61 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
62 ASSERT_RECT_NEAR(result.value(), coverage_rect);
63 }
64}
#define ASSERT_RECT_NEAR(a, b)

◆ TEST() [97/377]

impeller::testing::TEST ( FormatsGLES  ,
CanFormatFramebufferErrorMessage   
)

Definition at line 12 of file formats_gles_unittests.cc.

12 {
13 ASSERT_EQ(DebugToFramebufferError(GL_FRAMEBUFFER_UNDEFINED),
14 "GL_FRAMEBUFFER_UNDEFINED");
15 ASSERT_EQ(DebugToFramebufferError(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
16 "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
17 ASSERT_EQ(
18 DebugToFramebufferError(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
19 "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
20 ASSERT_EQ(DebugToFramebufferError(GL_FRAMEBUFFER_UNSUPPORTED),
21 "GL_FRAMEBUFFER_UNSUPPORTED");
22 ASSERT_EQ(DebugToFramebufferError(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE),
23 "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE");
24 ASSERT_EQ(DebugToFramebufferError(0), "Unknown error code: 0");
25}
std::string DebugToFramebufferError(int status)
Definition: formats_gles.cc:9

◆ TEST() [98/377]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CalculateSigmaForBlurRadius   
)

Definition at line 449 of file gaussian_blur_filter_contents_unittests.cc.

449 {
450 Scalar sigma = 1.0;
451 Scalar radius = GaussianBlurFilterContents::CalculateBlurRadius(
452 GaussianBlurFilterContents::ScaleSigma(sigma));
453 fml::StatusOr<Scalar> derived_sigma =
454 CalculateSigmaForBlurRadius(radius, Matrix());
455 ASSERT_TRUE(derived_sigma.ok());
456 EXPECT_NEAR(sigma, derived_sigma.value(), 0.01f);
457}
const T & value() const
Definition: status_or.h:77
bool ok() const
Definition: status_or.h:75

◆ TEST() [99/377]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CalculateSigmaValues   
)

Definition at line 216 of file gaussian_blur_filter_contents_unittests.cc.

216 {
217 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(1.0f), 1);
218 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(2.0f), 1);
219 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(3.0f), 1);
220 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(4.0f), 1);
221 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(16.0f), 0.25);
222 // Hang on to 1/8 as long as possible.
223 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(95.0f), 0.125);
224 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(96.0f), 0.0625);
225 // Downsample clamped to 1/16th.
226 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(1024.0f), 0.0625);
227}

◆ TEST() [100/377]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
Coefficients   
)

Definition at line 459 of file gaussian_blur_filter_contents_unittests.cc.

459 {
460 BlurParameters parameters = {.blur_uv_offset = Point(1, 0),
461 .blur_sigma = 1,
462 .blur_radius = 5,
463 .step_size = 1};
464 GaussianBlurPipeline::FragmentShader::KernelSamples samples =
465 GenerateBlurInfo(parameters);
466 EXPECT_EQ(samples.sample_count, 9);
467
468 // Coefficients should add up to 1.
469 Scalar tally = 0;
470 for (int i = 0; i < samples.sample_count; ++i) {
471 tally += samples.samples[i].coefficient;
472 }
473 EXPECT_FLOAT_EQ(tally, 1.0f);
474
475 // Verify the shape of the curve.
476 for (int i = 0; i < 4; ++i) {
477 EXPECT_FLOAT_EQ(samples.samples[i].coefficient,
478 samples.samples[8 - i].coefficient);
479 EXPECT_TRUE(samples.samples[i + 1].coefficient >
480 samples.samples[i].coefficient);
481 }
482}
GaussianBlurPipeline::FragmentShader::KernelSamples GenerateBlurInfo(BlurParameters parameters)

◆ TEST() [101/377]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CoverageEmpty   
)

Definition at line 112 of file gaussian_blur_filter_contents_unittests.cc.

112 {
114 /*sigma_x=*/0.0, /*sigma_y=*/0.0, Entity::TileMode::kDecal,
115 FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
117 Entity entity;
118 std::optional<Rect> coverage =
119 contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
120 ASSERT_FALSE(coverage.has_value());
121}
std::vector< FilterInput::Ref > Vector
Definition: filter_input.h:33

◆ TEST() [102/377]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CoverageSimple   
)

Definition at line 123 of file gaussian_blur_filter_contents_unittests.cc.

123 {
125 /*sigma_x=*/0.0, /*sigma_y=*/0.0, Entity::TileMode::kDecal,
126 FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
128 FilterInput::Make(Rect::MakeLTRB(10, 10, 110, 110))};
129 Entity entity;
130 std::optional<Rect> coverage =
131 contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
132
133 ASSERT_EQ(coverage, Rect::MakeLTRB(10, 10, 110, 110));
134}

◆ TEST() [103/377]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CoverageWithSigma   
)

Definition at line 136 of file gaussian_blur_filter_contents_unittests.cc.

136 {
137 fml::StatusOr<Scalar> sigma_radius_1 =
138 CalculateSigmaForBlurRadius(1.0, Matrix());
139 ASSERT_TRUE(sigma_radius_1.ok());
141 /*sigma_x=*/sigma_radius_1.value(),
142 /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
143 FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
145 FilterInput::Make(Rect::MakeLTRB(100, 100, 200, 200))};
146 Entity entity;
147 std::optional<Rect> coverage =
148 contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
149
150 EXPECT_TRUE(coverage.has_value());
151 if (coverage.has_value()) {
152 EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
153 }
154}
#define EXPECT_RECT_NEAR(a, b)

◆ TEST() [104/377]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
Create   
)

Definition at line 104 of file gaussian_blur_filter_contents_unittests.cc.

104 {
106 /*sigma_x=*/0.0, /*sigma_y=*/0.0, Entity::TileMode::kDecal,
107 FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
108 EXPECT_EQ(contents.GetSigmaX(), 0.0);
109 EXPECT_EQ(contents.GetSigmaY(), 0.0);
110}

◆ TEST() [105/377]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
FilterSourceCoverage   
)

Definition at line 199 of file gaussian_blur_filter_contents_unittests.cc.

199 {
200 fml::StatusOr<Scalar> sigma_radius_1 =
201 CalculateSigmaForBlurRadius(1.0, Matrix());
202 ASSERT_TRUE(sigma_radius_1.ok());
203 auto contents = std::make_unique<GaussianBlurFilterContents>(
204 sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
205 FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
206 std::optional<Rect> coverage = contents->GetFilterSourceCoverage(
207 /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}),
208 /*output_limit=*/Rect::MakeLTRB(100, 100, 200, 200));
209 EXPECT_TRUE(coverage.has_value());
210 if (coverage.has_value()) {
212 Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2));
213 }
214}

◆ TEST() [106/377]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
LerpHackKernelSamplesComplex   
)

Definition at line 562 of file gaussian_blur_filter_contents_unittests.cc.

562 {
563 Scalar sigma = 10.0f;
564 int32_t blur_radius = static_cast<int32_t>(
565 std::ceil(GaussianBlurFilterContents::CalculateBlurRadius(sigma)));
566 BlurParameters parameters = {.blur_uv_offset = Point(1, 0),
567 .blur_sigma = sigma,
568 .blur_radius = blur_radius,
569 .step_size = 1};
570 GaussianBlurPipeline::FragmentShader::KernelSamples kernel_samples =
571 GenerateBlurInfo(parameters);
572 EXPECT_EQ(kernel_samples.sample_count, 33);
573 GaussianBlurPipeline::FragmentShader::KernelSamples fast_kernel_samples =
574 LerpHackKernelSamples(kernel_samples);
575 EXPECT_EQ(fast_kernel_samples.sample_count, 17);
576 float data[33];
577 srand(0);
578 for (int i = 0; i < 33; i++) {
579 data[i] = 255.0 * static_cast<double>(IMPELLER_RAND()) / RAND_MAX;
580 }
581
582 auto sampler = [data](Point point) -> Scalar {
583 FML_CHECK(point.y == 0.0f);
584 FML_CHECK(point.x >= -16);
585 FML_CHECK(point.x <= 16);
586 Scalar fint_part;
587 Scalar fract = fabsf(modf(point.x, &fint_part));
588 if (fract == 0) {
589 int32_t int_part = static_cast<int32_t>(fint_part) + 16;
590 return data[int_part];
591 } else {
592 int32_t left = static_cast<int32_t>(floor(point.x)) + 16;
593 int32_t right = static_cast<int32_t>(ceil(point.x)) + 16;
594 if (point.x < 0) {
595 return fract * data[left] + (1.0 - fract) * data[right];
596 } else {
597 return (1.0 - fract) * data[left] + fract * data[right];
598 }
599 }
600 };
601
602 Scalar output = 0.0;
603 for (int i = 0; i < kernel_samples.sample_count; ++i) {
604 auto sample = kernel_samples.samples[i];
605 output += sample.coefficient * sampler(sample.uv_offset);
606 }
607
608 Scalar fast_output = 0.0;
609 for (int i = 0; i < fast_kernel_samples.sample_count; ++i) {
610 auto sample = fast_kernel_samples.samples[i];
611 fast_output += sample.coefficient * sampler(sample.uv_offset);
612 }
613
614 EXPECT_NEAR(output, fast_output, 0.1);
615}
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define FML_CHECK(condition)
Definition: logging.h:85
GaussianBlurPipeline::FragmentShader::KernelSamples LerpHackKernelSamples(GaussianBlurPipeline::FragmentShader::KernelSamples parameters)
SIN Vec< N, float > fract(const Vec< N, float > &x)
Definition: SkVx.h:744
SIN Vec< N, float > floor(const Vec< N, float > &x)
Definition: SkVx.h:703
SIN Vec< N, float > ceil(const Vec< N, float > &x)
Definition: SkVx.h:702

◆ TEST() [107/377]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
LerpHackKernelSamplesSimple   
)

Definition at line 484 of file gaussian_blur_filter_contents_unittests.cc.

484 {
485 GaussianBlurPipeline::FragmentShader::KernelSamples kernel_samples = {
486 .sample_count = 5,
487 .samples =
488 {
489 {
490 .uv_offset = Vector2(-2, 0),
491 .coefficient = 0.1f,
492 },
493 {
494 .uv_offset = Vector2(-1, 0),
495 .coefficient = 0.2f,
496 },
497 {
498 .uv_offset = Vector2(0, 0),
499 .coefficient = 0.4f,
500 },
501 {
502 .uv_offset = Vector2(1, 0),
503 .coefficient = 0.2f,
504 },
505 {
506 .uv_offset = Vector2(2, 0),
507 .coefficient = 0.1f,
508 },
509 },
510 };
511
512 GaussianBlurPipeline::FragmentShader::KernelSamples fast_kernel_samples =
513 LerpHackKernelSamples(kernel_samples);
514 EXPECT_EQ(fast_kernel_samples.sample_count, 3);
515
516 GaussianBlurPipeline::FragmentShader::KernelSample* samples =
517 kernel_samples.samples;
518 GaussianBlurPipeline::FragmentShader::KernelSample* fast_samples =
519 fast_kernel_samples.samples;
520
521 //////////////////////////////////////////////////////////////////////////////
522 // Check output kernel.
523
524 EXPECT_FLOAT_EQ(fast_samples[0].uv_offset.x, -1.3333333);
525 EXPECT_FLOAT_EQ(fast_samples[0].uv_offset.y, 0);
526 EXPECT_FLOAT_EQ(fast_samples[0].coefficient, 0.3);
527 EXPECT_FLOAT_EQ(fast_samples[1].uv_offset.x, 0);
528 EXPECT_FLOAT_EQ(fast_samples[1].uv_offset.y, 0);
529 EXPECT_FLOAT_EQ(fast_samples[1].coefficient, 0.4);
530 EXPECT_FLOAT_EQ(fast_samples[2].uv_offset.x, 1.3333333);
531 EXPECT_FLOAT_EQ(fast_samples[2].uv_offset.y, 0);
532 EXPECT_FLOAT_EQ(fast_samples[2].coefficient, 0.3);
533
534 //////////////////////////////////////////////////////////////////////////////
535 // Check output of fast kernel versus original kernel.
536
537 Scalar data[5] = {0.25, 0.5, 0.5, 1.0, 0.2};
538 Scalar original_output =
539 samples[0].coefficient * data[0] + samples[1].coefficient * data[1] +
540 samples[2].coefficient * data[2] + samples[3].coefficient * data[3] +
541 samples[4].coefficient * data[4];
542
543 auto lerp = [](const Point& point, Scalar left, Scalar right) {
544 Scalar int_part;
545 Scalar fract = fabsf(modf(point.x, &int_part));
546 if (point.x < 0) {
547 return left * fract + right * (1.0 - fract);
548 } else {
549 return left * (1.0 - fract) + right * fract;
550 }
551 };
552 Scalar fast_output =
553 /*1st*/ lerp(fast_samples[0].uv_offset, data[0], data[1]) *
554 fast_samples[0].coefficient +
555 /*2nd*/ data[2] * fast_samples[1].coefficient +
556 /*3rd*/ lerp(fast_samples[2].uv_offset, data[3], data[4]) *
557 fast_samples[2].coefficient;
558
559 EXPECT_NEAR(original_output, fast_output, 0.01);
560}
SkPoint lerp(const SkPoint &a, const SkPoint &b, float t)

◆ TEST() [108/377]

impeller::testing::TEST ( GeometryTest  ,
BlendModeToString   
)

Definition at line 1678 of file geometry_unittests.cc.

1678 {
1679 using BlendT = std::underlying_type_t<BlendMode>;
1680 for (BlendT i = 0; i <= static_cast<BlendT>(BlendMode::kLast); i++) {
1681 auto mode = static_cast<BlendMode>(i);
1684 }
1685}
#define _BLEND_MODE_NAME_CHECK(blend_mode)
static std::string BlendModeToString(DlBlendMode mode)
BlendMode
Definition: color.h:59

◆ TEST() [109/377]

impeller::testing::TEST ( GeometryTest  ,
CanConvertBetweenDegressAndRadians   
)

Definition at line 1687 of file geometry_unittests.cc.

1687 {
1688 {
1689 auto deg = Degrees{90.0};
1690 Radians rad = deg;
1691 ASSERT_FLOAT_EQ(rad.radians, kPiOver2);
1692 }
1693}
constexpr float kPiOver2
Definition: math.h:30
Scalar radians
Definition: scalar.h:39

◆ TEST() [110/377]

impeller::testing::TEST ( GeometryTest  ,
CanConvertTTypesExplicitly   
)

Definition at line 608 of file geometry_unittests.cc.

608 {
609 {
610 Point p1(1.0, 2.0);
611 IPoint p2 = static_cast<IPoint>(p1);
612 ASSERT_EQ(p2.x, 1u);
613 ASSERT_EQ(p2.y, 2u);
614 }
615
616 {
617 Size s1(1.0, 2.0);
618 ISize s2 = static_cast<ISize>(s1);
619 ASSERT_EQ(s2.width, 1u);
620 ASSERT_EQ(s2.height, 2u);
621 }
622
623 {
624 Size s1(1.0, 2.0);
625 Point p1 = static_cast<Point>(s1);
626 ASSERT_EQ(p1.x, 1u);
627 ASSERT_EQ(p1.y, 2u);
628 }
629}
Type height
Definition: size.h:23
Type width
Definition: size.h:22

◆ TEST() [111/377]

impeller::testing::TEST ( GeometryTest  ,
CanGenerateMipCounts   
)

Definition at line 595 of file geometry_unittests.cc.

595 {
596 ASSERT_EQ((Size{128, 128}.MipCount()), 7u);
597 ASSERT_EQ((Size{128, 256}.MipCount()), 8u);
598 ASSERT_EQ((Size{128, 130}.MipCount()), 8u);
599 ASSERT_EQ((Size{128, 257}.MipCount()), 9u);
600 ASSERT_EQ((Size{257, 128}.MipCount()), 9u);
601 ASSERT_EQ((Size{128, 0}.MipCount()), 1u);
602 ASSERT_EQ((Size{128, -25}.MipCount()), 1u);
603 ASSERT_EQ((Size{-128, 25}.MipCount()), 1u);
604 ASSERT_EQ((Size{1, 1}.MipCount()), 1u);
605 ASSERT_EQ((Size{0, 0}.MipCount()), 1u);
606}
constexpr size_t MipCount() const
Definition: size.h:115

◆ TEST() [112/377]

impeller::testing::TEST ( GeometryTest  ,
CanPerformAlgebraicPointOps   
)

Definition at line 631 of file geometry_unittests.cc.

631 {
632 {
633 IPoint p1(1, 2);
634 IPoint p2 = p1 + IPoint(1, 2);
635 ASSERT_EQ(p2.x, 2u);
636 ASSERT_EQ(p2.y, 4u);
637 }
638
639 {
640 IPoint p1(3, 6);
641 IPoint p2 = p1 - IPoint(1, 2);
642 ASSERT_EQ(p2.x, 2u);
643 ASSERT_EQ(p2.y, 4u);
644 }
645
646 {
647 IPoint p1(1, 2);
648 IPoint p2 = p1 * IPoint(2, 3);
649 ASSERT_EQ(p2.x, 2u);
650 ASSERT_EQ(p2.y, 6u);
651 }
652
653 {
654 IPoint p1(2, 6);
655 IPoint p2 = p1 / IPoint(2, 3);
656 ASSERT_EQ(p2.x, 1u);
657 ASSERT_EQ(p2.y, 2u);
658 }
659}
TPoint< int64_t > IPoint
Definition: point.h:323

◆ TEST() [113/377]

impeller::testing::TEST ( GeometryTest  ,
CanPerformAlgebraicPointOpsWithArithmeticTypes   
)

Definition at line 661 of file geometry_unittests.cc.

661 {
662 // LHS
663 {
664 IPoint p1(1, 2);
665 IPoint p2 = p1 * 2.0f;
666 ASSERT_EQ(p2.x, 2u);
667 ASSERT_EQ(p2.y, 4u);
668 }
669
670 {
671 IPoint p1(2, 6);
672 IPoint p2 = p1 / 2.0f;
673 ASSERT_EQ(p2.x, 1u);
674 ASSERT_EQ(p2.y, 3u);
675 }
676
677 // RHS
678 {
679 IPoint p1(1, 2);
680 IPoint p2 = 2.0f * p1;
681 ASSERT_EQ(p2.x, 2u);
682 ASSERT_EQ(p2.y, 4u);
683 }
684
685 {
686 IPoint p1(2, 6);
687 IPoint p2 = 12.0f / p1;
688 ASSERT_EQ(p2.x, 6u);
689 ASSERT_EQ(p2.y, 2u);
690 }
691}

◆ TEST() [114/377]

impeller::testing::TEST ( GeometryTest  ,
CanPerformAlgebraicVector3Ops   
)

Definition at line 1245 of file geometry_unittests.cc.

1245 {
1246 {
1247 Vector3 p1(1, 2, 3);
1248 Vector3 p2 = p1 + Vector3(1, 2, 3);
1249 ASSERT_EQ(p2.x, 2u);
1250 ASSERT_EQ(p2.y, 4u);
1251 ASSERT_EQ(p2.z, 6u);
1252 }
1253
1254 {
1255 Vector3 p1(3, 6, 9);
1256 Vector3 p2 = p1 - Vector3(1, 2, 3);
1257 ASSERT_EQ(p2.x, 2u);
1258 ASSERT_EQ(p2.y, 4u);
1259 ASSERT_EQ(p2.z, 6u);
1260 }
1261
1262 {
1263 Vector3 p1(1, 2, 3);
1264 Vector3 p2 = p1 * Vector3(2, 3, 4);
1265 ASSERT_EQ(p2.x, 2u);
1266 ASSERT_EQ(p2.y, 6u);
1267 ASSERT_EQ(p2.z, 12u);
1268 }
1269
1270 {
1271 Vector3 p1(2, 6, 12);
1272 Vector3 p2 = p1 / Vector3(2, 3, 4);
1273 ASSERT_EQ(p2.x, 1u);
1274 ASSERT_EQ(p2.y, 2u);
1275 ASSERT_EQ(p2.z, 3u);
1276 }
1277}

◆ TEST() [115/377]

impeller::testing::TEST ( GeometryTest  ,
CanPerformAlgebraicVector3OpsWithArithmeticTypes   
)

Definition at line 1279 of file geometry_unittests.cc.

1279 {
1280 // LHS
1281 {
1282 Vector3 p1(1, 2, 3);
1283 Vector3 p2 = p1 + 2.0f;
1284 ASSERT_EQ(p2.x, 3);
1285 ASSERT_EQ(p2.y, 4);
1286 ASSERT_EQ(p2.z, 5);
1287 }
1288
1289 {
1290 Vector3 p1(1, 2, 3);
1291 Vector3 p2 = p1 - 2.0f;
1292 ASSERT_EQ(p2.x, -1);
1293 ASSERT_EQ(p2.y, 0);
1294 ASSERT_EQ(p2.z, 1);
1295 }
1296
1297 {
1298 Vector3 p1(1, 2, 3);
1299 Vector3 p2 = p1 * 2.0f;
1300 ASSERT_EQ(p2.x, 2);
1301 ASSERT_EQ(p2.y, 4);
1302 ASSERT_EQ(p2.z, 6);
1303 }
1304
1305 {
1306 Vector3 p1(2, 6, 12);
1307 Vector3 p2 = p1 / 2.0f;
1308 ASSERT_EQ(p2.x, 1);
1309 ASSERT_EQ(p2.y, 3);
1310 ASSERT_EQ(p2.z, 6);
1311 }
1312
1313 // RHS
1314 {
1315 Vector3 p1(1, 2, 3);
1316 Vector3 p2 = 2.0f + p1;
1317 ASSERT_EQ(p2.x, 3);
1318 ASSERT_EQ(p2.y, 4);
1319 ASSERT_EQ(p2.z, 5);
1320 }
1321
1322 {
1323 Vector3 p1(1, 2, 3);
1324 Vector3 p2 = 2.0f - p1;
1325 ASSERT_EQ(p2.x, 1);
1326 ASSERT_EQ(p2.y, 0);
1327 ASSERT_EQ(p2.z, -1);
1328 }
1329
1330 {
1331 Vector3 p1(1, 2, 3);
1332 Vector3 p2 = 2.0f * p1;
1333 ASSERT_EQ(p2.x, 2);
1334 ASSERT_EQ(p2.y, 4);
1335 ASSERT_EQ(p2.z, 6);
1336 }
1337
1338 {
1339 Vector3 p1(2, 6, 12);
1340 Vector3 p2 = 12.0f / p1;
1341 ASSERT_EQ(p2.x, 6);
1342 ASSERT_EQ(p2.y, 2);
1343 ASSERT_EQ(p2.z, 1);
1344 }
1345}

◆ TEST() [116/377]

impeller::testing::TEST ( GeometryTest  ,
CanUsePointAssignmentOperators   
)

Definition at line 813 of file geometry_unittests.cc.

813 {
814 // Point on RHS
815 {
816 IPoint p(1, 2);
817 p += IPoint(1, 2);
818 ASSERT_EQ(p.x, 2u);
819 ASSERT_EQ(p.y, 4u);
820 }
821
822 {
823 IPoint p(3, 6);
824 p -= IPoint(1, 2);
825 ASSERT_EQ(p.x, 2u);
826 ASSERT_EQ(p.y, 4u);
827 }
828
829 {
830 IPoint p(1, 2);
831 p *= IPoint(2, 3);
832 ASSERT_EQ(p.x, 2u);
833 ASSERT_EQ(p.y, 6u);
834 }
835
836 {
837 IPoint p(2, 6);
838 p /= IPoint(2, 3);
839 ASSERT_EQ(p.x, 1u);
840 ASSERT_EQ(p.y, 2u);
841 }
842
843 // Size on RHS
844 {
845 IPoint p(1, 2);
846 p += ISize(1, 2);
847 ASSERT_EQ(p.x, 2u);
848 ASSERT_EQ(p.y, 4u);
849 }
850
851 {
852 IPoint p(3, 6);
853 p -= ISize(1, 2);
854 ASSERT_EQ(p.x, 2u);
855 ASSERT_EQ(p.y, 4u);
856 }
857
858 {
859 IPoint p(1, 2);
860 p *= ISize(2, 3);
861 ASSERT_EQ(p.x, 2u);
862 ASSERT_EQ(p.y, 6u);
863 }
864
865 {
866 IPoint p(2, 6);
867 p /= ISize(2, 3);
868 ASSERT_EQ(p.x, 1u);
869 ASSERT_EQ(p.y, 2u);
870 }
871
872 // Arithmetic type on RHS
873 {
874 IPoint p(1, 2);
875 p *= 3;
876 ASSERT_EQ(p.x, 3u);
877 ASSERT_EQ(p.y, 6u);
878 }
879
880 {
881 IPoint p(3, 6);
882 p /= 3;
883 ASSERT_EQ(p.x, 1u);
884 ASSERT_EQ(p.y, 2u);
885 }
886}

◆ TEST() [117/377]

impeller::testing::TEST ( GeometryTest  ,
CanUseVector3AssignmentOperators   
)

Definition at line 1195 of file geometry_unittests.cc.

1195 {
1196 {
1197 Vector3 p(1, 2, 4);
1198 p += Vector3(1, 2, 4);
1199 ASSERT_EQ(p.x, 2u);
1200 ASSERT_EQ(p.y, 4u);
1201 ASSERT_EQ(p.z, 8u);
1202 }
1203
1204 {
1205 Vector3 p(3, 6, 8);
1206 p -= Vector3(1, 2, 3);
1207 ASSERT_EQ(p.x, 2u);
1208 ASSERT_EQ(p.y, 4u);
1209 ASSERT_EQ(p.z, 5u);
1210 }
1211
1212 {
1213 Vector3 p(1, 2, 3);
1214 p *= Vector3(2, 3, 4);
1215 ASSERT_EQ(p.x, 2u);
1216 ASSERT_EQ(p.y, 6u);
1217 ASSERT_EQ(p.z, 12u);
1218 }
1219
1220 {
1221 Vector3 p(1, 2, 3);
1222 p *= 2;
1223 ASSERT_EQ(p.x, 2u);
1224 ASSERT_EQ(p.y, 4u);
1225 ASSERT_EQ(p.z, 6u);
1226 }
1227
1228 {
1229 Vector3 p(2, 6, 12);
1230 p /= Vector3(2, 3, 4);
1231 ASSERT_EQ(p.x, 1u);
1232 ASSERT_EQ(p.y, 2u);
1233 ASSERT_EQ(p.z, 3u);
1234 }
1235
1236 {
1237 Vector3 p(2, 6, 12);
1238 p /= 2;
1239 ASSERT_EQ(p.x, 1u);
1240 ASSERT_EQ(p.y, 3u);
1241 ASSERT_EQ(p.z, 6u);
1242 }
1243}

◆ TEST() [118/377]

impeller::testing::TEST ( GeometryTest  ,
ColorApplyColorMatrix   
)

Definition at line 1452 of file geometry_unittests.cc.

1452 {
1453 {
1454 ColorMatrix color_matrix = {
1455 1, 1, 1, 1, 1, //
1456 1, 1, 1, 1, 1, //
1457 1, 1, 1, 1, 1, //
1458 1, 1, 1, 1, 1, //
1459 };
1460 auto result = Color::White().ApplyColorMatrix(color_matrix);
1461 auto expected = Color(1, 1, 1, 1);
1462 ASSERT_COLOR_NEAR(result, expected);
1463 }
1464
1465 {
1466 ColorMatrix color_matrix = {
1467 0.1, 0, 0, 0, 0.01, //
1468 0, 0.2, 0, 0, 0.02, //
1469 0, 0, 0.3, 0, 0.03, //
1470 0, 0, 0, 0.4, 0.04, //
1471 };
1472 auto result = Color::White().ApplyColorMatrix(color_matrix);
1473 auto expected = Color(0.11, 0.22, 0.33, 0.44);
1474 ASSERT_COLOR_NEAR(result, expected);
1475 }
1476}
#define ASSERT_COLOR_NEAR(a, b)
SK_API sk_sp< SkShader > Color(SkColor)

◆ TEST() [119/377]

impeller::testing::TEST ( GeometryTest  ,
ColorBlendReturnsExpectedResults   
)

Definition at line 1661 of file geometry_unittests.cc.

1661 {
1662 Color dst = ColorBlendTestData::kDestinationColor;
1663 for (size_t source_i = 0;
1664 source_i < sizeof(ColorBlendTestData::kSourceColors) / sizeof(Color);
1665 source_i++) {
1666 Color src = ColorBlendTestData::kSourceColors[source_i];
1667
1668 Color expected;
1670 }
1671}
#define _BLEND_MODE_RESULT_CHECK(blend_mode)
dst
Definition: cp.py:12

◆ TEST() [120/377]

impeller::testing::TEST ( GeometryTest  ,
ColorClamp01   
)

Definition at line 1412 of file geometry_unittests.cc.

1412 {
1413 {
1414 Color result = Color(0.5, 0.5, 0.5, 0.5).Clamp01();
1415 Color expected = Color(0.5, 0.5, 0.5, 0.5);
1416 ASSERT_COLOR_NEAR(result, expected);
1417 }
1418
1419 {
1420 Color result = Color(-1, -1, -1, -1).Clamp01();
1421 Color expected = Color(0, 0, 0, 0);
1422 ASSERT_COLOR_NEAR(result, expected);
1423 }
1424
1425 {
1426 Color result = Color(2, 2, 2, 2).Clamp01();
1427 Color expected = Color(1, 1, 1, 1);
1428 ASSERT_COLOR_NEAR(result, expected);
1429 }
1430}

◆ TEST() [121/377]

impeller::testing::TEST ( GeometryTest  ,
ColorLerp   
)

Definition at line 1390 of file geometry_unittests.cc.

1390 {
1391 {
1392 Color a(0.0, 0.0, 0.0, 0.0);
1393 Color b(1.0, 1.0, 1.0, 1.0);
1394
1395 ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.5), Color(0.5, 0.5, 0.5, 0.5));
1398 ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.2), Color(0.2, 0.2, 0.2, 0.2));
1399 }
1400
1401 {
1402 Color a(0.2, 0.4, 1.0, 0.5);
1403 Color b(0.4, 1.0, 0.2, 0.3);
1404
1405 ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.5), Color(0.3, 0.7, 0.6, 0.4));
1408 ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.2), Color(0.24, 0.52, 0.84, 0.46));
1409 }
1410}
struct MyStruct a[10]
SK_API sk_sp< PrecompileColorFilter > Lerp(SkSpan< const sk_sp< PrecompileColorFilter > > dstOptions, SkSpan< const sk_sp< PrecompileColorFilter > > srcOptions)

◆ TEST() [122/377]

impeller::testing::TEST ( GeometryTest  ,
ColorLinearToSRGB   
)

Definition at line 1478 of file geometry_unittests.cc.

1478 {
1479 {
1480 auto result = Color::White().LinearToSRGB();
1481 auto expected = Color(1, 1, 1, 1);
1482 ASSERT_COLOR_NEAR(result, expected);
1483 }
1484
1485 {
1486 auto result = Color::BlackTransparent().LinearToSRGB();
1487 auto expected = Color(0, 0, 0, 0);
1488 ASSERT_COLOR_NEAR(result, expected);
1489 }
1490
1491 {
1492 auto result = Color(0.2, 0.4, 0.6, 0.8).LinearToSRGB();
1493 auto expected = Color(0.484529, 0.665185, 0.797738, 0.8);
1494 ASSERT_COLOR_NEAR(result, expected);
1495 }
1496}

◆ TEST() [123/377]

impeller::testing::TEST ( GeometryTest  ,
ColorMakeRGBA8   
)

Definition at line 1432 of file geometry_unittests.cc.

1432 {
1433 {
1434 Color a = Color::MakeRGBA8(0, 0, 0, 0);
1435 Color b = Color::BlackTransparent();
1437 }
1438
1439 {
1440 Color a = Color::MakeRGBA8(255, 255, 255, 255);
1441 Color b = Color::White();
1443 }
1444
1445 {
1446 Color a = Color::MakeRGBA8(63, 127, 191, 127);
1447 Color b(0.247059, 0.498039, 0.74902, 0.498039);
1449 }
1450}

◆ TEST() [124/377]

impeller::testing::TEST ( GeometryTest  ,
ColorPremultiply   
)

Definition at line 1347 of file geometry_unittests.cc.

1347 {
1348 {
1349 Color a(1.0, 0.5, 0.2, 0.5);
1350 Color premultiplied = a.Premultiply();
1351 Color expected = Color(0.5, 0.25, 0.1, 0.5);
1352 ASSERT_COLOR_NEAR(premultiplied, expected);
1353 }
1354
1355 {
1356 Color a(0.5, 0.25, 0.1, 0.5);
1357 Color unpremultiplied = a.Unpremultiply();
1358 Color expected = Color(1.0, 0.5, 0.2, 0.5);
1359 ASSERT_COLOR_NEAR(unpremultiplied, expected);
1360 }
1361
1362 {
1363 Color a(0.5, 0.25, 0.1, 0.0);
1364 Color unpremultiplied = a.Unpremultiply();
1365 Color expected = Color(0.0, 0.0, 0.0, 0.0);
1366 ASSERT_COLOR_NEAR(unpremultiplied, expected);
1367 }
1368}

◆ TEST() [125/377]

impeller::testing::TEST ( GeometryTest  ,
ColorPrinting   
)

Definition at line 1770 of file geometry_unittests.cc.

1770 {
1771 {
1772 std::stringstream stream;
1773 Color m;
1774 stream << m;
1775 ASSERT_EQ(stream.str(), "(0, 0, 0, 0)");
1776 }
1777
1778 {
1779 std::stringstream stream;
1780 Color m(1, 2, 3, 4);
1781 stream << m;
1782 ASSERT_EQ(stream.str(), "(1, 2, 3, 4)");
1783 }
1784}

◆ TEST() [126/377]

impeller::testing::TEST ( GeometryTest  ,
ColorR8G8B8A8   
)

Definition at line 1370 of file geometry_unittests.cc.

1370 {
1371 {
1372 Color a(1.0, 0.5, 0.2, 0.5);
1373 std::array<uint8_t, 4> expected = {255, 128, 51, 128};
1374 ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1375 }
1376
1377 {
1378 Color a(0.0, 0.0, 0.0, 0.0);
1379 std::array<uint8_t, 4> expected = {0, 0, 0, 0};
1380 ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1381 }
1382
1383 {
1384 Color a(1.0, 1.0, 1.0, 1.0);
1385 std::array<uint8_t, 4> expected = {255, 255, 255, 255};
1386 ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1387 }
1388}
#define ASSERT_ARRAY_4_NEAR(a, b)

◆ TEST() [127/377]

impeller::testing::TEST ( GeometryTest  ,
ColorSRGBToLinear   
)

Definition at line 1498 of file geometry_unittests.cc.

1498 {
1499 {
1500 auto result = Color::White().SRGBToLinear();
1501 auto expected = Color(1, 1, 1, 1);
1502 ASSERT_COLOR_NEAR(result, expected);
1503 }
1504
1505 {
1506 auto result = Color::BlackTransparent().SRGBToLinear();
1507 auto expected = Color(0, 0, 0, 0);
1508 ASSERT_COLOR_NEAR(result, expected);
1509 }
1510
1511 {
1512 auto result = Color(0.2, 0.4, 0.6, 0.8).SRGBToLinear();
1513 auto expected = Color(0.0331048, 0.132868, 0.318547, 0.8);
1514 ASSERT_COLOR_NEAR(result, expected);
1515 }
1516}

◆ TEST() [128/377]

impeller::testing::TEST ( GeometryTest  ,
DeterminantTest   
)

Definition at line 121 of file geometry_unittests.cc.

121 {
122 auto matrix = Matrix{3, 4, 14, 155, 2, 1, 3, 4, 2, 3, 2, 1, 1, 2, 4, 2};
123 ASSERT_EQ(matrix.GetDeterminant(), -1889);
124}
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258

◆ TEST() [129/377]

impeller::testing::TEST ( GeometryTest  ,
Gradient   
)

Definition at line 1792 of file geometry_unittests.cc.

1792 {
1793 {
1794 // Simple 2 color gradient produces color buffer containing exactly those
1795 // values.
1796 std::vector<Color> colors = {Color::Red(), Color::Blue()};
1797 std::vector<Scalar> stops = {0.0, 1.0};
1798
1799 auto gradient = CreateGradientBuffer(colors, stops);
1800
1801 ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, colors);
1802 ASSERT_EQ(gradient.texture_size, 2u);
1803 }
1804
1805 {
1806 // Gradient with duplicate stops does not create an empty texture.
1807 std::vector<Color> colors = {Color::Red(), Color::Yellow(), Color::Black(),
1808 Color::Blue()};
1809 std::vector<Scalar> stops = {0.0, 0.25, 0.25, 1.0};
1810
1811 auto gradient = CreateGradientBuffer(colors, stops);
1812 ASSERT_EQ(gradient.texture_size, 5u);
1813 }
1814
1815 {
1816 // Simple N color gradient produces color buffer containing exactly those
1817 // values.
1818 std::vector<Color> colors = {Color::Red(), Color::Blue(), Color::Green(),
1819 Color::White()};
1820 std::vector<Scalar> stops = {0.0, 0.33, 0.66, 1.0};
1821
1822 auto gradient = CreateGradientBuffer(colors, stops);
1823
1824 ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, colors);
1825 ASSERT_EQ(gradient.texture_size, 4u);
1826 }
1827
1828 {
1829 // Gradient with color stops will lerp and scale buffer.
1830 std::vector<Color> colors = {Color::Red(), Color::Blue(), Color::Green()};
1831 std::vector<Scalar> stops = {0.0, 0.25, 1.0};
1832
1833 auto gradient = CreateGradientBuffer(colors, stops);
1834
1835 std::vector<Color> lerped_colors = {
1836 Color::Red(),
1837 Color::Blue(),
1838 Color::Lerp(Color::Blue(), Color::Green(), 0.3333),
1839 Color::Lerp(Color::Blue(), Color::Green(), 0.6666),
1840 Color::Green(),
1841 };
1842 ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, lerped_colors);
1843 ASSERT_EQ(gradient.texture_size, 5u);
1844 }
1845
1846 {
1847 // Gradient size is capped at 1024.
1848 std::vector<Color> colors = {};
1849 std::vector<Scalar> stops = {};
1850 for (auto i = 0u; i < 1025; i++) {
1851 colors.push_back(Color::Blue());
1852 stops.push_back(i / 1025.0);
1853 }
1854
1855 auto gradient = CreateGradientBuffer(colors, stops);
1856
1857 ASSERT_EQ(gradient.texture_size, 1024u);
1858 ASSERT_EQ(gradient.color_bytes.size(), 1024u * 4);
1859 }
1860}
#define ASSERT_COLOR_BUFFER_NEAR(a, b)
GradientData CreateGradientBuffer(const std::vector< Color > &colors, const std::vector< Scalar > &stops)
Populate a vector with the interpolated color bytes for the linear gradient described by colors and s...
Definition: gradient.cc:20

◆ TEST() [130/377]

impeller::testing::TEST ( GeometryTest  ,
HalfConversions   
)

Definition at line 1862 of file geometry_unittests.cc.

1862 {
1863#if defined(FML_OS_MACOSX) || defined(FML_OS_IOS) || \
1864 defined(FML_OS_IOS_SIMULATOR)
1865 ASSERT_EQ(ScalarToHalf(0.0), 0.0f16);
1866 ASSERT_EQ(ScalarToHalf(0.05), 0.05f16);
1867 ASSERT_EQ(ScalarToHalf(2.43), 2.43f16);
1868 ASSERT_EQ(ScalarToHalf(-1.45), -1.45f16);
1869
1870 // 65504 is the largest possible half.
1871 ASSERT_EQ(ScalarToHalf(65504.0f), 65504.0f16);
1872 ASSERT_EQ(ScalarToHalf(65504.0f + 1), 65504.0f16);
1873
1874 // Colors
1875 ASSERT_EQ(HalfVector4(Color::Red()),
1876 HalfVector4(1.0f16, 0.0f16, 0.0f16, 1.0f16));
1877 ASSERT_EQ(HalfVector4(Color::Green()),
1878 HalfVector4(0.0f16, 1.0f16, 0.0f16, 1.0f16));
1879 ASSERT_EQ(HalfVector4(Color::Blue()),
1880 HalfVector4(0.0f16, 0.0f16, 1.0f16, 1.0f16));
1881 ASSERT_EQ(HalfVector4(Color::Black().WithAlpha(0)),
1882 HalfVector4(0.0f16, 0.0f16, 0.0f16, 0.0f16));
1883
1884 ASSERT_EQ(HalfVector3(Vector3(4.0, 6.0, -1.0)),
1885 HalfVector3(4.0f16, 6.0f16, -1.0f16));
1886 ASSERT_EQ(HalfVector2(Vector2(4.0, 6.0)), HalfVector2(4.0f16, 6.0f16));
1887
1888 ASSERT_EQ(Half(0.5f), Half(0.5f16));
1889 ASSERT_EQ(Half(0.5), Half(0.5f16));
1890 ASSERT_EQ(Half(5), Half(5.0f16));
1891#else
1892 GTEST_SKIP() << "Half-precision floats (IEEE 754) are not portable and "
1893 "only used on Apple platforms.";
1894#endif // FML_OS_MACOSX || FML_OS_IOS || FML_OS_IOS_SIMULATOR
1895}
constexpr InternalHalf ScalarToHalf(Scalar f)
Convert a scalar to a half precision float.
Definition: half.h:32
A storage only class for half precision floating point vector 2.
Definition: half.h:129
A storage only class for half precision floating point vector 3.
Definition: half.h:101
A storage only class for half precision floating point vector 4.
Definition: half.h:60
A storage only class for half precision floating point.
Definition: half.h:41

◆ TEST() [131/377]

impeller::testing::TEST ( GeometryTest  ,
InvertMatrix   
)

Definition at line 126 of file geometry_unittests.cc.

126 {
127 auto inverted = Matrix{10, -9, -12, 8, //
128 7, -12, 11, 22, //
129 -10, 10, 3, 6, //
130 -2, 22, 2, 1}
131 .Invert();
132
133 auto result = Matrix{
134 438.0 / 85123.0, 1751.0 / 85123.0, -7783.0 / 85123.0, 4672.0 / 85123.0,
135 393.0 / 85123.0, -178.0 / 85123.0, -570.0 / 85123.0, 4192 / 85123.0,
136 -5230.0 / 85123.0, 2802.0 / 85123.0, -3461.0 / 85123.0, 962.0 / 85123.0,
137 2690.0 / 85123.0, 1814.0 / 85123.0, 3896.0 / 85123.0, 319.0 / 85123.0};
138
139 ASSERT_MATRIX_NEAR(inverted, result);
140}
Matrix Invert() const
Definition: matrix.cc:97

◆ TEST() [132/377]

impeller::testing::TEST ( GeometryTest  ,
InvertMultMatrix   
)

Definition at line 79 of file geometry_unittests.cc.

79 {
80 {
81 auto rotation = Matrix::MakeRotationZ(Radians{kPiOver4});
82 auto invert = rotation.Invert();
83 // clang-format off
84 auto expect = Matrix{k1OverSqrt2, -k1OverSqrt2, 0, 0,
86 0, 0, 1, 0,
87 0, 0, 0, 1};
88 // clang-format on
90 }
91 {
92 auto scale = Matrix::MakeScale(Vector2{2, 4});
93 auto invert = scale.Invert();
94 auto expect = Matrix{0.5, 0, 0, 0, //
95 0, 0.25, 0, 0, //
96 0, 0, 1, 0, //
97 0, 0, 0, 1};
99 }
100}
gboolean invert
constexpr float kPiOver4
Definition: math.h:33
constexpr float k1OverSqrt2
Definition: math.h:48

◆ TEST() [133/377]

impeller::testing::TEST ( GeometryTest  ,
MakeColumn   
)

Definition at line 40 of file geometry_unittests.cc.

40 {
41 auto matrix = Matrix::MakeColumn(1, 2, 3, 4, //
42 5, 6, 7, 8, //
43 9, 10, 11, 12, //
44 13, 14, 15, 16);
45
46 auto expect = Matrix{1, 2, 3, 4, //
47 5, 6, 7, 8, //
48 9, 10, 11, 12, //
49 13, 14, 15, 16};
50
51 ASSERT_TRUE(matrix == expect);
52}

◆ TEST() [134/377]

impeller::testing::TEST ( GeometryTest  ,
MakeRow   
)

Definition at line 54 of file geometry_unittests.cc.

54 {
55 auto matrix = Matrix::MakeRow(1, 2, 3, 4, //
56 5, 6, 7, 8, //
57 9, 10, 11, 12, //
58 13, 14, 15, 16);
59
60 auto expect = Matrix{1, 5, 9, 13, //
61 2, 6, 10, 14, //
62 3, 7, 11, 15, //
63 4, 8, 12, 16};
64
65 ASSERT_TRUE(matrix == expect);
66}

◆ TEST() [135/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixBasis   
)

Definition at line 102 of file geometry_unittests.cc.

102 {
103 auto matrix = Matrix{1, 2, 3, 4, //
104 5, 6, 7, 8, //
105 9, 10, 11, 12, //
106 13, 14, 15, 16};
107 auto basis = matrix.Basis();
108 auto expect = Matrix{1, 2, 3, 0, //
109 5, 6, 7, 0, //
110 9, 10, 11, 0, //
111 0, 0, 0, 1};
112 ASSERT_MATRIX_NEAR(basis, expect);
113}

◆ TEST() [136/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixGetBasisVectors   
)

Definition at line 423 of file geometry_unittests.cc.

423 {
424 {
425 auto m = Matrix();
426 Vector3 x = m.GetBasisX();
427 Vector3 y = m.GetBasisY();
428 Vector3 z = m.GetBasisZ();
429 ASSERT_VECTOR3_NEAR(x, Vector3(1, 0, 0));
430 ASSERT_VECTOR3_NEAR(y, Vector3(0, 1, 0));
431 ASSERT_VECTOR3_NEAR(z, Vector3(0, 0, 1));
432 }
433
434 {
435 auto m = Matrix::MakeRotationZ(Radians{kPiOver2}) *
436 Matrix::MakeRotationX(Radians{kPiOver2}) *
437 Matrix::MakeScale(Vector3(2, 3, 4));
438 Vector3 x = m.GetBasisX();
439 Vector3 y = m.GetBasisY();
440 Vector3 z = m.GetBasisZ();
441 ASSERT_VECTOR3_NEAR(x, Vector3(0, 2, 0));
442 ASSERT_VECTOR3_NEAR(y, Vector3(0, 0, 3));
443 ASSERT_VECTOR3_NEAR(z, Vector3(4, 0, 0));
444 }
445}
#define ASSERT_VECTOR3_NEAR(a, b)

◆ TEST() [137/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixGetDirectionScale   
)

Definition at line 447 of file geometry_unittests.cc.

447 {
448 {
449 auto m = Matrix();
450 Scalar result = m.GetDirectionScale(Vector3{1, 0, 0});
451 ASSERT_FLOAT_EQ(result, 1);
452 }
453
454 {
455 auto m = Matrix::MakeRotationX(Degrees{10}) *
456 Matrix::MakeRotationY(Degrees{83}) *
457 Matrix::MakeRotationZ(Degrees{172});
458 Scalar result = m.GetDirectionScale(Vector3{0, 1, 0});
459 ASSERT_FLOAT_EQ(result, 1);
460 }
461
462 {
463 auto m = Matrix::MakeRotationZ(Radians{kPiOver2}) *
464 Matrix::MakeScale(Vector3(3, 4, 5));
465 Scalar result = m.GetDirectionScale(Vector3{2, 0, 0});
466 ASSERT_FLOAT_EQ(result, 8);
467 }
468}

◆ TEST() [138/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixGetMaxBasisLength   
)

Definition at line 333 of file geometry_unittests.cc.

333 {
334 {
335 auto m = Matrix::MakeScale({3, 1, 1});
336 ASSERT_EQ(m.GetMaxBasisLength(), 3);
337
338 m = m * Matrix::MakeSkew(0, 4);
339 ASSERT_EQ(m.GetMaxBasisLength(), 5);
340 }
341
342 {
343 auto m = Matrix::MakeScale({-3, 4, 2});
344 ASSERT_EQ(m.GetMaxBasisLength(), 4);
345 }
346}

◆ TEST() [139/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixGetMaxBasisLengthXY   
)

Definition at line 348 of file geometry_unittests.cc.

348 {
349 {
350 auto m = Matrix::MakeScale({3, 1, 1});
351 ASSERT_EQ(m.GetMaxBasisLengthXY(), 3);
352
353 m = m * Matrix::MakeSkew(0, 4);
354 ASSERT_EQ(m.GetMaxBasisLengthXY(), 5);
355 }
356
357 {
358 auto m = Matrix::MakeScale({-3, 4, 7});
359 ASSERT_EQ(m.GetMaxBasisLengthXY(), 4);
360 }
361
362 {
363 // clang-format off
364 auto m = Matrix::MakeColumn(
365 1.0f, 0.0f, 0.0f, 0.0f,
366 0.0f, 1.0f, 0.0f, 0.0f,
367 4.0f, 0.0f, 1.0f, 0.0f,
368 0.0f, 0.0f, 0.0f, 1.0f
369 );
370 // clang-format on
371 ASSERT_EQ(m.GetMaxBasisLengthXY(), 1.0f);
372 }
373}

◆ TEST() [140/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixLookAt   
)

Definition at line 496 of file geometry_unittests.cc.

496 {
497 {
498 auto m = Matrix::MakeLookAt(Vector3(0, 0, -1), Vector3(0, 0, 1),
499 Vector3(0, 1, 0));
500 auto expected = Matrix{
501 1, 0, 0, 0, //
502 0, 1, 0, 0, //
503 0, 0, 1, 0, //
504 0, 0, 1, 1, //
505 };
506 ASSERT_MATRIX_NEAR(m, expected);
507 }
508
509 // Sideways tilt.
510 {
511 auto m = Matrix::MakeLookAt(Vector3(0, 0, -1), Vector3(0, 0, 1),
512 Vector3(1, 1, 0).Normalize());
513
514 // clang-format off
515 auto expected = Matrix{
517 -k1OverSqrt2, k1OverSqrt2, 0, 0,
518 0, 0, 1, 0,
519 0, 0, 1, 1,
520 };
521 // clang-format on
522 ASSERT_MATRIX_NEAR(m, expected);
523 }
524
525 // Half way between +x and -y, yaw 90
526 {
527 auto m =
528 Matrix::MakeLookAt(Vector3(), Vector3(10, -10, 0), Vector3(0, 0, -1));
529
530 // clang-format off
531 auto expected = Matrix{
532 -k1OverSqrt2, 0, k1OverSqrt2, 0,
533 -k1OverSqrt2, 0, -k1OverSqrt2, 0,
534 0, -1, 0, 0,
535 0, 0, 0, 1,
536 };
537 // clang-format on
538 ASSERT_MATRIX_NEAR(m, expected);
539 }
540}
static void Normalize(char *s)
Definition: flags.cc:296

◆ TEST() [141/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixMakeOrthographic   
)

Definition at line 375 of file geometry_unittests.cc.

375 {
376 {
377 auto m = Matrix::MakeOrthographic(Size(100, 200));
378 auto expect = Matrix{
379 0.02, 0, 0, 0, //
380 0, -0.01, 0, 0, //
381 0, 0, 0, 0, //
382 -1, 1, 0.5, 1, //
383 };
384 ASSERT_MATRIX_NEAR(m, expect);
385 }
386
387 {
388 auto m = Matrix::MakeOrthographic(Size(400, 100));
389 auto expect = Matrix{
390 0.005, 0, 0, 0, //
391 0, -0.02, 0, 0, //
392 0, 0, 0, 0, //
393 -1, 1, 0.5, 1, //
394 };
395 ASSERT_MATRIX_NEAR(m, expect);
396 }
397}

◆ TEST() [142/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixMakePerspective   
)

Definition at line 399 of file geometry_unittests.cc.

399 {
400 {
401 auto m = Matrix::MakePerspective(Degrees(60), Size(100, 200), 1, 10);
402 auto expect = Matrix{
403 3.4641, 0, 0, 0, //
404 0, 1.73205, 0, 0, //
405 0, 0, 1.11111, 1, //
406 0, 0, -1.11111, 0, //
407 };
408 ASSERT_MATRIX_NEAR(m, expect);
409 }
410
411 {
412 auto m = Matrix::MakePerspective(Radians(1), 2, 10, 20);
413 auto expect = Matrix{
414 0.915244, 0, 0, 0, //
415 0, 1.83049, 0, 0, //
416 0, 0, 2, 1, //
417 0, 0, -20, 0, //
418 };
419 ASSERT_MATRIX_NEAR(m, expect);
420 }
421}

◆ TEST() [143/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixMakeRotationFromQuaternion   
)

Definition at line 278 of file geometry_unittests.cc.

278 {
279 {
280 auto matrix = Matrix::MakeRotation(Quaternion({1, 0, 0}, kPiOver2));
281 auto expected = Matrix::MakeRotationX(Radians(kPiOver2));
282 ASSERT_MATRIX_NEAR(matrix, expected);
283 }
284
285 {
286 auto matrix = Matrix::MakeRotation(Quaternion({0, 1, 0}, kPiOver2));
287 auto expected = Matrix::MakeRotationY(Radians(kPiOver2));
288 ASSERT_MATRIX_NEAR(matrix, expected);
289 }
290
291 {
292 auto matrix = Matrix::MakeRotation(Quaternion({0, 0, 1}, kPiOver2));
293 auto expected = Matrix::MakeRotationZ(Radians(kPiOver2));
294 ASSERT_MATRIX_NEAR(matrix, expected);
295 }
296}

◆ TEST() [144/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixPrinting   
)

Definition at line 1695 of file geometry_unittests.cc.

1695 {
1696 {
1697 std::stringstream stream;
1698 Matrix m;
1699 stream << m;
1700 ASSERT_EQ(stream.str(), R"((
1701 1.000000, 0.000000, 0.000000, 0.000000,
1702 0.000000, 1.000000, 0.000000, 0.000000,
1703 0.000000, 0.000000, 1.000000, 0.000000,
1704 0.000000, 0.000000, 0.000000, 1.000000,
1705))");
1706 }
1707
1708 {
1709 std::stringstream stream;
1710 Matrix m = Matrix::MakeTranslation(Vector3(10, 20, 30));
1711 stream << m;
1712
1713 ASSERT_EQ(stream.str(), R"((
1714 1.000000, 0.000000, 0.000000, 10.000000,
1715 0.000000, 1.000000, 0.000000, 20.000000,
1716 0.000000, 0.000000, 1.000000, 30.000000,
1717 0.000000, 0.000000, 0.000000, 1.000000,
1718))");
1719 }
1720}

◆ TEST() [145/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixTransformDirection   
)

Definition at line 298 of file geometry_unittests.cc.

298 {
299 {
300 auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
301 Matrix::MakeRotationZ(Radians{kPiOver2}) *
302 Matrix::MakeScale({2.0, 2.0, 2.0});
303 auto vector = Vector4(10, 20, 30, 2);
304
305 Vector4 result = matrix.TransformDirection(vector);
306 auto expected = Vector4(-40, 20, 60, 2);
307 ASSERT_VECTOR4_NEAR(result, expected);
308 }
309
310 {
311 auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
312 Matrix::MakeRotationZ(Radians{kPiOver2}) *
313 Matrix::MakeScale({2.0, 2.0, 2.0});
314 auto vector = Vector3(10, 20, 30);
315
316 Vector3 result = matrix.TransformDirection(vector);
317 auto expected = Vector3(-40, 20, 60);
318 ASSERT_VECTOR3_NEAR(result, expected);
319 }
320
321 {
322 auto matrix = Matrix::MakeTranslation({0, -0.4, 100}) *
323 Matrix::MakeRotationZ(Radians{kPiOver2}) *
324 Matrix::MakeScale({2.0, 2.0, 2.0});
325 auto vector = Point(10, 20);
326
327 Point result = matrix.TransformDirection(vector);
328 auto expected = Point(-40, 20);
329 ASSERT_POINT_NEAR(result, expected);
330 }
331}
#define ASSERT_VECTOR4_NEAR(a, b)
#define ASSERT_POINT_NEAR(a, b)

◆ TEST() [146/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixTranslationScaleOnly   
)

Definition at line 470 of file geometry_unittests.cc.

470 {
471 {
472 auto m = Matrix();
473 bool result = m.IsTranslationScaleOnly();
474 ASSERT_TRUE(result);
475 }
476
477 {
478 auto m = Matrix::MakeScale(Vector3(2, 3, 4));
479 bool result = m.IsTranslationScaleOnly();
480 ASSERT_TRUE(result);
481 }
482
483 {
484 auto m = Matrix::MakeTranslation(Vector3(2, 3, 4));
485 bool result = m.IsTranslationScaleOnly();
486 ASSERT_TRUE(result);
487 }
488
489 {
490 auto m = Matrix::MakeRotationZ(Degrees(10));
491 bool result = m.IsTranslationScaleOnly();
492 ASSERT_FALSE(result);
493 }
494}

◆ TEST() [147/377]

impeller::testing::TEST ( GeometryTest  ,
MatrixVectorMultiplication   
)

Definition at line 213 of file geometry_unittests.cc.

213 {
214 {
215 auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
216 Matrix::MakeRotationZ(Radians{kPiOver2}) *
217 Matrix::MakeScale({2.0, 2.0, 2.0});
218 auto vector = Vector4(10, 20, 30, 2);
219
220 Vector4 result = matrix * vector;
221 auto expected = Vector4(160, 220, 260, 2);
222 ASSERT_VECTOR4_NEAR(result, expected);
223 }
224
225 {
226 auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
227 Matrix::MakeRotationZ(Radians{kPiOver2}) *
228 Matrix::MakeScale({2.0, 2.0, 2.0});
229 auto vector = Vector3(10, 20, 30);
230
231 Vector3 result = matrix * vector;
232 auto expected = Vector3(60, 120, 160);
233 ASSERT_VECTOR3_NEAR(result, expected);
234 }
235
236 {
237 auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
238 Matrix::MakeRotationZ(Radians{kPiOver2}) *
239 Matrix::MakeScale({2.0, 2.0, 2.0});
240 auto vector = Point(10, 20);
241
242 Point result = matrix * vector;
243 auto expected = Point(60, 120);
244 ASSERT_POINT_NEAR(result, expected);
245 }
246
247 // Matrix Vector ops should respect perspective transforms.
248 {
249 auto matrix = Matrix::MakePerspective(Radians(kPiOver2), 1, 1, 100);
250 auto vector = Vector3(3, 3, -3);
251
252 Vector3 result = matrix * vector;
253 auto expected = Vector3(-1, -1, 1.3468);
254 ASSERT_VECTOR3_NEAR(result, expected);
255 }
256
257 {
258 auto matrix = Matrix::MakePerspective(Radians(kPiOver2), 1, 1, 100) *
259 Matrix::MakeTranslation(Vector3(0, 0, -3));
260 auto point = Point(3, 3);
261
262 Point result = matrix * point;
263 auto expected = Point(-1, -1);
264 ASSERT_POINT_NEAR(result, expected);
265 }
266
267 // Resolves to 0 on perspective singularity.
268 {
269 auto matrix = Matrix::MakePerspective(Radians(kPiOver2), 1, 1, 100);
270 auto point = Point(3, 3);
271
272 Point result = matrix * point;
273 auto expected = Point(0, 0);
274 ASSERT_POINT_NEAR(result, expected);
275 }
276}

◆ TEST() [148/377]

impeller::testing::TEST ( GeometryTest  ,
MutliplicationMatrix   
)

Definition at line 115 of file geometry_unittests.cc.

115 {
116 auto rotation = Matrix::MakeRotationZ(Radians{kPiOver4});
117 auto invert = rotation.Invert();
118 ASSERT_MATRIX_NEAR(rotation * invert, Matrix{});
119}

◆ TEST() [149/377]

impeller::testing::TEST ( GeometryTest  ,
PointAbs   
)

Definition at line 953 of file geometry_unittests.cc.

953 {
954 Point a(-1, -2);
955 auto a_abs = a.Abs();
956 auto expected = Point(1, 2);
957 ASSERT_POINT_NEAR(a_abs, expected);
958}

◆ TEST() [150/377]

impeller::testing::TEST ( GeometryTest  ,
PointAngleTo   
)

Definition at line 990 of file geometry_unittests.cc.

990 {
991 // Negative result in the CCW (with up = -Y) direction.
992 {
993 Point a(1, 1);
994 Point b(1, -1);
995 Radians actual = a.AngleTo(b);
996 Radians expected = Radians{-kPi / 2};
997 ASSERT_FLOAT_EQ(actual.radians, expected.radians);
998 }
999
1000 // Check the other direction to ensure the result is signed correctly.
1001 {
1002 Point a(1, -1);
1003 Point b(1, 1);
1004 Radians actual = a.AngleTo(b);
1005 Radians expected = Radians{kPi / 2};
1006 ASSERT_FLOAT_EQ(actual.radians, expected.radians);
1007 }
1008
1009 // Differences in magnitude should have no impact on the result.
1010 {
1011 Point a(100, -100);
1012 Point b(0.01, 0.01);
1013 Radians actual = a.AngleTo(b);
1014 Radians expected = Radians{kPi / 2};
1015 ASSERT_FLOAT_EQ(actual.radians, expected.radians);
1016 }
1017}

◆ TEST() [151/377]

impeller::testing::TEST ( GeometryTest  ,
PointCeil   
)

Definition at line 1082 of file geometry_unittests.cc.

1082 {
1083 Point p(1.5, 2.3);
1084 Point result = p.Ceil();
1085 Point expected(2, 3);
1086 ASSERT_POINT_NEAR(result, expected);
1087}

◆ TEST() [152/377]

impeller::testing::TEST ( GeometryTest  ,
PointCrossProduct   
)

Definition at line 908 of file geometry_unittests.cc.

908 {
909 {
910 Point p(1, 0);
911 Scalar s = p.Cross(Point(-1, 0));
912 ASSERT_FLOAT_EQ(s, 0);
913 }
914
915 {
916 Point p(0, -1);
917 Scalar s = p.Cross(Point(-1, 0));
918 ASSERT_FLOAT_EQ(s, -1);
919 }
920
921 {
922 Point p(1, 2);
923 Scalar s = p.Cross(Point(3, -4));
924 ASSERT_FLOAT_EQ(s, -10);
925 }
926}
struct MyStruct s

◆ TEST() [153/377]

impeller::testing::TEST ( GeometryTest  ,
PointDotProduct   
)

Definition at line 888 of file geometry_unittests.cc.

888 {
889 {
890 Point p(1, 0);
891 Scalar s = p.Dot(Point(-1, 0));
892 ASSERT_FLOAT_EQ(s, -1);
893 }
894
895 {
896 Point p(0, -1);
897 Scalar s = p.Dot(Point(-1, 0));
898 ASSERT_FLOAT_EQ(s, 0);
899 }
900
901 {
902 Point p(1, 2);
903 Scalar s = p.Dot(Point(3, -4));
904 ASSERT_FLOAT_EQ(s, -5);
905 }
906}

◆ TEST() [154/377]

impeller::testing::TEST ( GeometryTest  ,
PointFloor   
)

Definition at line 1061 of file geometry_unittests.cc.

1061 {
1062 Point p(1.5, 2.3);
1063 Point result = p.Floor();
1064 Point expected(1, 2);
1065 ASSERT_POINT_NEAR(result, expected);
1066}

◆ TEST() [155/377]

impeller::testing::TEST ( GeometryTest  ,
PointIntegerCoercesToFloat   
)

Definition at line 693 of file geometry_unittests.cc.

693 {
694 // Integer on LHS, float on RHS
695 {
696 IPoint p1(1, 2);
697 Point p2 = p1 + Point(1, 2);
698 ASSERT_FLOAT_EQ(p2.x, 2u);
699 ASSERT_FLOAT_EQ(p2.y, 4u);
700 }
701
702 {
703 IPoint p1(3, 6);
704 Point p2 = p1 - Point(1, 2);
705 ASSERT_FLOAT_EQ(p2.x, 2u);
706 ASSERT_FLOAT_EQ(p2.y, 4u);
707 }
708
709 {
710 IPoint p1(1, 2);
711 Point p2 = p1 * Point(2, 3);
712 ASSERT_FLOAT_EQ(p2.x, 2u);
713 ASSERT_FLOAT_EQ(p2.y, 6u);
714 }
715
716 {
717 IPoint p1(2, 6);
718 Point p2 = p1 / Point(2, 3);
719 ASSERT_FLOAT_EQ(p2.x, 1u);
720 ASSERT_FLOAT_EQ(p2.y, 2u);
721 }
722
723 // Float on LHS, integer on RHS
724 {
725 Point p1(1, 2);
726 Point p2 = p1 + IPoint(1, 2);
727 ASSERT_FLOAT_EQ(p2.x, 2u);
728 ASSERT_FLOAT_EQ(p2.y, 4u);
729 }
730
731 {
732 Point p1(3, 6);
733 Point p2 = p1 - IPoint(1, 2);
734 ASSERT_FLOAT_EQ(p2.x, 2u);
735 ASSERT_FLOAT_EQ(p2.y, 4u);
736 }
737
738 {
739 Point p1(1, 2);
740 Point p2 = p1 * IPoint(2, 3);
741 ASSERT_FLOAT_EQ(p2.x, 2u);
742 ASSERT_FLOAT_EQ(p2.y, 6u);
743 }
744
745 {
746 Point p1(2, 6);
747 Point p2 = p1 / IPoint(2, 3);
748 ASSERT_FLOAT_EQ(p2.x, 1u);
749 ASSERT_FLOAT_EQ(p2.y, 2u);
750 }
751}

◆ TEST() [156/377]

impeller::testing::TEST ( GeometryTest  ,
PointLerp   
)

Definition at line 1124 of file geometry_unittests.cc.

1124 {
1125 Point p(1, 2);
1126 Point result = p.Lerp({5, 10}, 0.75);
1127 Point expected(4, 8);
1128 ASSERT_POINT_NEAR(result, expected);
1129}

◆ TEST() [157/377]

impeller::testing::TEST ( GeometryTest  ,
PointMax   
)

Definition at line 1040 of file geometry_unittests.cc.

1040 {
1041 Point p(1, 2);
1042 Point result = p.Max({0, 10});
1043 Point expected(1, 10);
1044 ASSERT_POINT_NEAR(result, expected);
1045}

◆ TEST() [158/377]

impeller::testing::TEST ( GeometryTest  ,
PointMin   
)

Definition at line 1019 of file geometry_unittests.cc.

1019 {
1020 Point p(1, 2);
1021 Point result = p.Min({0, 10});
1022 Point expected(0, 2);
1023 ASSERT_POINT_NEAR(result, expected);
1024}

◆ TEST() [159/377]

impeller::testing::TEST ( GeometryTest  ,
PointPrinting   
)

Definition at line 1722 of file geometry_unittests.cc.

1722 {
1723 {
1724 std::stringstream stream;
1725 Point m;
1726 stream << m;
1727 ASSERT_EQ(stream.str(), "(0, 0)");
1728 }
1729
1730 {
1731 std::stringstream stream;
1732 Point m(13, 37);
1733 stream << m;
1734 ASSERT_EQ(stream.str(), "(13, 37)");
1735 }
1736}

◆ TEST() [160/377]

impeller::testing::TEST ( GeometryTest  ,
PointReflect   
)

Definition at line 928 of file geometry_unittests.cc.

928 {
929 {
930 Point axis = Point(0, 1);
931 Point a(2, 3);
932 auto reflected = a.Reflect(axis);
933 auto expected = Point(2, -3);
934 ASSERT_POINT_NEAR(reflected, expected);
935 }
936
937 {
938 Point axis = Point(1, 1).Normalize();
939 Point a(1, 0);
940 auto reflected = a.Reflect(axis);
941 auto expected = Point(0, -1);
942 ASSERT_POINT_NEAR(reflected, expected);
943 }
944
945 {
946 Point axis = Point(1, 1).Normalize();
947 Point a(-1, -1);
948 auto reflected = a.Reflect(axis);
949 ASSERT_POINT_NEAR(reflected, -a);
950 }
951}
constexpr TPoint Normalize() const
Definition: point.h:208

◆ TEST() [161/377]

impeller::testing::TEST ( GeometryTest  ,
PointRotate   
)

Definition at line 960 of file geometry_unittests.cc.

960 {
961 {
962 Point a(1, 0);
963 auto rotated = a.Rotate(Radians{kPiOver2});
964 auto expected = Point(0, 1);
965 ASSERT_POINT_NEAR(rotated, expected);
966 }
967
968 {
969 Point a(1, 0);
970 auto rotated = a.Rotate(Radians{-kPiOver2});
971 auto expected = Point(0, -1);
972 ASSERT_POINT_NEAR(rotated, expected);
973 }
974
975 {
976 Point a(1, 0);
977 auto rotated = a.Rotate(Radians{kPi});
978 auto expected = Point(-1, 0);
979 ASSERT_POINT_NEAR(rotated, expected);
980 }
981
982 {
983 Point a(1, 0);
984 auto rotated = a.Rotate(Radians{kPi * 1.5});
985 auto expected = Point(0, -1);
986 ASSERT_POINT_NEAR(rotated, expected);
987 }
988}

◆ TEST() [162/377]

impeller::testing::TEST ( GeometryTest  ,
PointRound   
)

Definition at line 1103 of file geometry_unittests.cc.

1103 {
1104 Point p(1.5, 2.3);
1105 Point result = p.Round();
1106 Point expected(2, 2);
1107 ASSERT_POINT_NEAR(result, expected);
1108}

◆ TEST() [163/377]

impeller::testing::TEST ( GeometryTest  ,
QuaternionLerp   
)

Definition at line 542 of file geometry_unittests.cc.

542 {
543 auto q1 = Quaternion{{0.0, 0.0, 1.0}, 0.0};
544 auto q2 = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
545
546 auto q3 = q1.Slerp(q2, 0.5);
547
548 auto expected = Quaternion{{0.0, 0.0, 1.0}, kPiOver4 / 2.0};
549
550 ASSERT_QUATERNION_NEAR(q3, expected);
551}
#define ASSERT_QUATERNION_NEAR(a, b)

◆ TEST() [164/377]

impeller::testing::TEST ( GeometryTest  ,
QuaternionVectorMultiply   
)

Definition at line 553 of file geometry_unittests.cc.

553 {
554 {
555 Quaternion q({0, 0, 1}, 0);
556 Vector3 v(0, 1, 0);
557
558 Vector3 result = q * v;
559 Vector3 expected(0, 1, 0);
560
561 ASSERT_VECTOR3_NEAR(result, expected);
562 }
563
564 {
565 Quaternion q({0, 0, 1}, k2Pi);
566 Vector3 v(1, 0, 0);
567
568 Vector3 result = q * v;
569 Vector3 expected(1, 0, 0);
570
571 ASSERT_VECTOR3_NEAR(result, expected);
572 }
573
574 {
575 Quaternion q({0, 0, 1}, kPiOver4);
576 Vector3 v(0, 1, 0);
577
578 Vector3 result = q * v;
579 Vector3 expected(-k1OverSqrt2, k1OverSqrt2, 0);
580
581 ASSERT_VECTOR3_NEAR(result, expected);
582 }
583
584 {
585 Quaternion q(Vector3(1, 0, 1).Normalize(), kPi);
586 Vector3 v(0, 0, -1);
587
588 Vector3 result = q * v;
589 Vector3 expected(-1, 0, 0);
590
591 ASSERT_VECTOR3_NEAR(result, expected);
592 }
593}
constexpr float k2Pi
Definition: constants.h:29

◆ TEST() [165/377]

impeller::testing::TEST ( GeometryTest  ,
RotationMatrix   
)

Definition at line 68 of file geometry_unittests.cc.

68 {
69 auto rotation = Matrix::MakeRotationZ(Radians{kPiOver4});
70 // clang-format off
71 auto expect = Matrix{k1OverSqrt2, k1OverSqrt2, 0, 0,
73 0, 0, 1, 0,
74 0, 0, 0, 1};
75 // clang-format on
76 ASSERT_MATRIX_NEAR(rotation, expect);
77}

◆ TEST() [166/377]

impeller::testing::TEST ( GeometryTest  ,
ScalarNearlyEqual   
)

Definition at line 31 of file geometry_unittests.cc.

31 {
32 ASSERT_FALSE(ScalarNearlyEqual(0.0021f, 0.001f));
33 ASSERT_TRUE(ScalarNearlyEqual(0.0019f, 0.001f));
34 ASSERT_TRUE(ScalarNearlyEqual(0.002f, 0.001f, 0.0011f));
35 ASSERT_FALSE(ScalarNearlyEqual(0.002f, 0.001f, 0.0009f));
36 ASSERT_TRUE(ScalarNearlyEqual(
37 1.0f, 1.0f + std::numeric_limits<float>::epsilon() * 4));
38}
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:30

◆ TEST() [167/377]

impeller::testing::TEST ( GeometryTest  ,
SeparatedVector2AngleTo   
)

Definition at line 1179 of file geometry_unittests.cc.

1179 {
1180 {
1181 SeparatedVector2 v(Vector2(10, 0));
1182 Radians actual = v.AngleTo(SeparatedVector2(Vector2(5, 0)));
1183 Radians expected = Radians{0};
1184 ASSERT_NEAR(actual.radians, expected.radians, kEhCloseEnough);
1185 }
1186
1187 {
1188 SeparatedVector2 v(Vector2(10, 0));
1189 Radians actual = v.AngleTo(SeparatedVector2(Vector2(0, -5)));
1190 Radians expected = Radians{-kPi / 2};
1191 ASSERT_NEAR(actual.radians, expected.radians, kEhCloseEnough);
1192 }
1193}
constexpr float kEhCloseEnough
Definition: constants.h:56
A Vector2, broken down as a separate magnitude and direction. Assumes that the direction given is nor...

◆ TEST() [168/377]

impeller::testing::TEST ( GeometryTest  ,
SeparatedVector2GetAlignment   
)

Definition at line 1156 of file geometry_unittests.cc.

1156 {
1157 // Parallel
1158 {
1159 SeparatedVector2 v(Vector2(10, 0));
1160 Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(5, 0)));
1161 ASSERT_NEAR(actual, 1, kEhCloseEnough);
1162 }
1163
1164 // Perpendicular
1165 {
1166 SeparatedVector2 v(Vector2(10, 0));
1167 Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(0, 5)));
1168 ASSERT_NEAR(actual, 0, kEhCloseEnough);
1169 }
1170
1171 // Opposite parallel
1172 {
1173 SeparatedVector2 v(Vector2(0, 10));
1174 Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(0, -5)));
1175 ASSERT_NEAR(actual, -1, kEhCloseEnough);
1176 }
1177}

◆ TEST() [169/377]

impeller::testing::TEST ( GeometryTest  ,
SeparatedVector2GetVector   
)

Definition at line 1151 of file geometry_unittests.cc.

1151 {
1152 SeparatedVector2 v(Vector2(10, 0));
1153 ASSERT_POINT_NEAR(v.GetVector(), Vector2(10, 0));
1154}

◆ TEST() [170/377]

impeller::testing::TEST ( GeometryTest  ,
SeparatedVector2NormalizesWithConstructor   
)

Definition at line 1145 of file geometry_unittests.cc.

1145 {
1146 SeparatedVector2 v(Vector2(10, 0));
1147 ASSERT_POINT_NEAR(v.direction, Vector2(1, 0));
1148 ASSERT_NEAR(v.magnitude, 10, kEhCloseEnough);
1149}

◆ TEST() [171/377]

impeller::testing::TEST ( GeometryTest  ,
SizeCoercesToPoint   
)

Definition at line 753 of file geometry_unittests.cc.

753 {
754 // Point on LHS, Size on RHS
755 {
756 IPoint p1(1, 2);
757 IPoint p2 = p1 + ISize(1, 2);
758 ASSERT_EQ(p2.x, 2u);
759 ASSERT_EQ(p2.y, 4u);
760 }
761
762 {
763 IPoint p1(3, 6);
764 IPoint p2 = p1 - ISize(1, 2);
765 ASSERT_EQ(p2.x, 2u);
766 ASSERT_EQ(p2.y, 4u);
767 }
768
769 {
770 IPoint p1(1, 2);
771 IPoint p2 = p1 * ISize(2, 3);
772 ASSERT_EQ(p2.x, 2u);
773 ASSERT_EQ(p2.y, 6u);
774 }
775
776 {
777 IPoint p1(2, 6);
778 IPoint p2 = p1 / ISize(2, 3);
779 ASSERT_EQ(p2.x, 1u);
780 ASSERT_EQ(p2.y, 2u);
781 }
782
783 // Size on LHS, Point on RHS
784 {
785 ISize p1(1, 2);
786 IPoint p2 = p1 + IPoint(1, 2);
787 ASSERT_EQ(p2.x, 2u);
788 ASSERT_EQ(p2.y, 4u);
789 }
790
791 {
792 ISize p1(3, 6);
793 IPoint p2 = p1 - IPoint(1, 2);
794 ASSERT_EQ(p2.x, 2u);
795 ASSERT_EQ(p2.y, 4u);
796 }
797
798 {
799 ISize p1(1, 2);
800 IPoint p2 = p1 * IPoint(2, 3);
801 ASSERT_EQ(p2.x, 2u);
802 ASSERT_EQ(p2.y, 6u);
803 }
804
805 {
806 ISize p1(2, 6);
807 IPoint p2 = p1 / IPoint(2, 3);
808 ASSERT_EQ(p2.x, 1u);
809 ASSERT_EQ(p2.y, 2u);
810 }
811}

◆ TEST() [172/377]

impeller::testing::TEST ( GeometryTest  ,
TestDecomposition   
)

Definition at line 142 of file geometry_unittests.cc.

142 {
143 auto rotated = Matrix::MakeRotationZ(Radians{kPiOver4});
144
145 auto result = rotated.Decompose();
146
147 ASSERT_TRUE(result.has_value());
148
149 MatrixDecomposition res = result.value();
150
151 auto quaternion = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
152 ASSERT_QUATERNION_NEAR(res.rotation, quaternion);
153}

◆ TEST() [173/377]

impeller::testing::TEST ( GeometryTest  ,
TestDecomposition2   
)

Definition at line 155 of file geometry_unittests.cc.

155 {
156 auto rotated = Matrix::MakeRotationZ(Radians{kPiOver4});
157 auto scaled = Matrix::MakeScale({2.0, 3.0, 1.0});
158 auto translated = Matrix::MakeTranslation({-200, 750, 20});
159
160 auto result = (translated * rotated * scaled).Decompose();
161
162 ASSERT_TRUE(result.has_value());
163
164 MatrixDecomposition res = result.value();
165
166 auto quaternion = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
167
168 ASSERT_QUATERNION_NEAR(res.rotation, quaternion);
169
170 ASSERT_FLOAT_EQ(res.translation.x, -200);
171 ASSERT_FLOAT_EQ(res.translation.y, 750);
172 ASSERT_FLOAT_EQ(res.translation.z, 20);
173
174 ASSERT_FLOAT_EQ(res.scale.x, 2);
175 ASSERT_FLOAT_EQ(res.scale.y, 3);
176 ASSERT_FLOAT_EQ(res.scale.z, 1);
177}

◆ TEST() [174/377]

impeller::testing::TEST ( GeometryTest  ,
TestRecomposition   
)

Definition at line 179 of file geometry_unittests.cc.

179 {
180 /*
181 * Decomposition.
182 */
183 auto rotated = Matrix::MakeRotationZ(Radians{kPiOver4});
184
185 auto result = rotated.Decompose();
186
187 ASSERT_TRUE(result.has_value());
188
189 MatrixDecomposition res = result.value();
190
191 auto quaternion = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
192
193 ASSERT_QUATERNION_NEAR(res.rotation, quaternion);
194
195 /*
196 * Recomposition.
197 */
198 ASSERT_MATRIX_NEAR(rotated, Matrix{res});
199}

◆ TEST() [175/377]

impeller::testing::TEST ( GeometryTest  ,
TestRecomposition2   
)

Definition at line 201 of file geometry_unittests.cc.

201 {
202 auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
203 Matrix::MakeRotationZ(Radians{kPiOver4}) *
204 Matrix::MakeScale({2.0, 2.0, 2.0});
205
206 auto result = matrix.Decompose();
207
208 ASSERT_TRUE(result.has_value());
209
211}

◆ TEST() [176/377]

impeller::testing::TEST ( GeometryTest  ,
ToIColor   
)

Definition at line 1786 of file geometry_unittests.cc.

1786 {
1787 ASSERT_EQ(Color::ToIColor(Color(0, 0, 0, 0)), 0u);
1788 ASSERT_EQ(Color::ToIColor(Color(1.0, 1.0, 1.0, 1.0)), 0xFFFFFFFF);
1789 ASSERT_EQ(Color::ToIColor(Color(0.5, 0.5, 1.0, 1.0)), 0xFF8080FF);
1790}

◆ TEST() [177/377]

impeller::testing::TEST ( GeometryTest  ,
Vector3Ceil   
)

Definition at line 1089 of file geometry_unittests.cc.

1089 {
1090 Vector3 p(1.5, 2.3, 3.9);
1091 Vector3 result = p.Ceil();
1092 Vector3 expected(2, 3, 4);
1093 ASSERT_VECTOR3_NEAR(result, expected);
1094}

◆ TEST() [178/377]

impeller::testing::TEST ( GeometryTest  ,
Vector3Floor   
)

Definition at line 1068 of file geometry_unittests.cc.

1068 {
1069 Vector3 p(1.5, 2.3, 3.9);
1070 Vector3 result = p.Floor();
1071 Vector3 expected(1, 2, 3);
1072 ASSERT_VECTOR3_NEAR(result, expected);
1073}

◆ TEST() [179/377]

impeller::testing::TEST ( GeometryTest  ,
Vector3Lerp   
)

Definition at line 1131 of file geometry_unittests.cc.

1131 {
1132 Vector3 p(1, 2, 3);
1133 Vector3 result = p.Lerp({5, 10, 15}, 0.75);
1134 Vector3 expected(4, 8, 12);
1135 ASSERT_VECTOR3_NEAR(result, expected);
1136}

◆ TEST() [180/377]

impeller::testing::TEST ( GeometryTest  ,
Vector3Max   
)

Definition at line 1047 of file geometry_unittests.cc.

1047 {
1048 Vector3 p(1, 2, 3);
1049 Vector3 result = p.Max({0, 10, 2});
1050 Vector3 expected(1, 10, 3);
1051 ASSERT_VECTOR3_NEAR(result, expected);
1052}

◆ TEST() [181/377]

impeller::testing::TEST ( GeometryTest  ,
Vector3Min   
)

Definition at line 1026 of file geometry_unittests.cc.

1026 {
1027 Vector3 p(1, 2, 3);
1028 Vector3 result = p.Min({0, 10, 2});
1029 Vector3 expected(0, 2, 2);
1030 ASSERT_VECTOR3_NEAR(result, expected);
1031}

◆ TEST() [182/377]

impeller::testing::TEST ( GeometryTest  ,
Vector3Printing   
)

Definition at line 1738 of file geometry_unittests.cc.

1738 {
1739 {
1740 std::stringstream stream;
1741 Vector3 m;
1742 stream << m;
1743 ASSERT_EQ(stream.str(), "(0, 0, 0)");
1744 }
1745
1746 {
1747 std::stringstream stream;
1748 Vector3 m(1, 2, 3);
1749 stream << m;
1750 ASSERT_EQ(stream.str(), "(1, 2, 3)");
1751 }
1752}

◆ TEST() [183/377]

impeller::testing::TEST ( GeometryTest  ,
Vector3Round   
)

Definition at line 1110 of file geometry_unittests.cc.

1110 {
1111 Vector3 p(1.5, 2.3, 3.9);
1112 Vector3 result = p.Round();
1113 Vector3 expected(2, 2, 4);
1114 ASSERT_VECTOR3_NEAR(result, expected);
1115}

◆ TEST() [184/377]

impeller::testing::TEST ( GeometryTest  ,
Vector4Ceil   
)

Definition at line 1096 of file geometry_unittests.cc.

1096 {
1097 Vector4 p(1.5, 2.3, 3.9, 4.0);
1098 Vector4 result = p.Ceil();
1099 Vector4 expected(2, 3, 4, 4);
1100 ASSERT_VECTOR4_NEAR(result, expected);
1101}

◆ TEST() [185/377]

impeller::testing::TEST ( GeometryTest  ,
Vector4Floor   
)

Definition at line 1075 of file geometry_unittests.cc.

1075 {
1076 Vector4 p(1.5, 2.3, 3.9, 4.0);
1077 Vector4 result = p.Floor();
1078 Vector4 expected(1, 2, 3, 4);
1079 ASSERT_VECTOR4_NEAR(result, expected);
1080}

◆ TEST() [186/377]

impeller::testing::TEST ( GeometryTest  ,
Vector4Lerp   
)

Definition at line 1138 of file geometry_unittests.cc.

1138 {
1139 Vector4 p(1, 2, 3, 4);
1140 Vector4 result = p.Lerp({5, 10, 15, 20}, 0.75);
1141 Vector4 expected(4, 8, 12, 16);
1142 ASSERT_VECTOR4_NEAR(result, expected);
1143}

◆ TEST() [187/377]

impeller::testing::TEST ( GeometryTest  ,
Vector4Max   
)

Definition at line 1054 of file geometry_unittests.cc.

1054 {
1055 Vector4 p(1, 2, 3, 4);
1056 Vector4 result = p.Max({0, 10, 2, 1});
1057 Vector4 expected(1, 10, 3, 4);
1058 ASSERT_VECTOR4_NEAR(result, expected);
1059}

◆ TEST() [188/377]

impeller::testing::TEST ( GeometryTest  ,
Vector4Min   
)

Definition at line 1033 of file geometry_unittests.cc.

1033 {
1034 Vector4 p(1, 2, 3, 4);
1035 Vector4 result = p.Min({0, 10, 2, 1});
1036 Vector4 expected(0, 2, 2, 1);
1037 ASSERT_VECTOR4_NEAR(result, expected);
1038}

◆ TEST() [189/377]

impeller::testing::TEST ( GeometryTest  ,
Vector4Printing   
)

Definition at line 1754 of file geometry_unittests.cc.

1754 {
1755 {
1756 std::stringstream stream;
1757 Vector4 m;
1758 stream << m;
1759 ASSERT_EQ(stream.str(), "(0, 0, 0, 1)");
1760 }
1761
1762 {
1763 std::stringstream stream;
1764 Vector4 m(1, 2, 3, 4);
1765 stream << m;
1766 ASSERT_EQ(stream.str(), "(1, 2, 3, 4)");
1767 }
1768}

◆ TEST() [190/377]

impeller::testing::TEST ( GeometryTest  ,
Vector4Round   
)

Definition at line 1117 of file geometry_unittests.cc.

1117 {
1118 Vector4 p(1.5, 2.3, 3.9, 4.0);
1119 Vector4 result = p.Round();
1120 Vector4 expected(2, 2, 4, 4);
1121 ASSERT_VECTOR4_NEAR(result, expected);
1122}

◆ TEST() [191/377]

impeller::testing::TEST ( MatrixFilterContentsTest  ,
Coverage2x   
)

Definition at line 70 of file matrix_filter_contents_unittests.cc.

70 {
71 MatrixFilterContents contents;
72 contents.SetMatrix(Matrix::MakeScale({2.0, 2.0, 1.0}));
74 FilterInput::Make(Rect::MakeXYWH(10, 10, 100, 100))};
75 Entity entity;
76 std::optional<Rect> coverage =
77 contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
78
79 ASSERT_EQ(coverage, Rect::MakeXYWH(20, 20, 200, 200));
80}
std::optional< Rect > GetFilterCoverage(const FilterInput::Vector &inputs, const Entity &entity, const Matrix &effect_transform) const override
Internal utility method for |GetLocalCoverage| that computes the output coverage of this filter acros...

◆ TEST() [192/377]

impeller::testing::TEST ( MatrixFilterContentsTest  ,
Coverage2xEffect   
)

Definition at line 82 of file matrix_filter_contents_unittests.cc.

82 {
83 MatrixFilterContents contents;
85 FilterInput::Make(Rect::MakeXYWH(10, 10, 100, 100))};
86 Entity entity;
87 std::optional<Rect> coverage = contents.GetFilterCoverage(
88 inputs, entity, /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}));
89
90 ASSERT_EQ(coverage, Rect::MakeXYWH(10, 10, 100, 100));
91}

◆ TEST() [193/377]

impeller::testing::TEST ( MatrixFilterContentsTest  ,
CoverageEmpty   
)

Definition at line 50 of file matrix_filter_contents_unittests.cc.

50 {
51 MatrixFilterContents contents;
53 Entity entity;
54 std::optional<Rect> coverage =
55 contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
56 ASSERT_FALSE(coverage.has_value());
57}

◆ TEST() [194/377]

impeller::testing::TEST ( MatrixFilterContentsTest  ,
CoverageSimple   
)

Definition at line 59 of file matrix_filter_contents_unittests.cc.

59 {
60 MatrixFilterContents contents;
62 FilterInput::Make(Rect::MakeLTRB(10, 10, 110, 110))};
63 Entity entity;
64 std::optional<Rect> coverage =
65 contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
66
67 ASSERT_EQ(coverage, Rect::MakeLTRB(10, 10, 110, 110));
68}

◆ TEST() [195/377]

impeller::testing::TEST ( MatrixFilterContentsTest  ,
Create   
)

Definition at line 45 of file matrix_filter_contents_unittests.cc.

45 {
46 MatrixFilterContents contents;
48}
bool IsTranslationOnly() const override
Returns true if this filter graph doesn't perform any basis transforms to the filtered content....

◆ TEST() [196/377]

impeller::testing::TEST ( MatrixTest  ,
HasPerspective   
)

Definition at line 45 of file matrix_unittests.cc.

45 {
46 EXPECT_FALSE(Matrix().HasPerspective());
47
48 auto test = [](int index, bool expect) {
50 EXPECT_FALSE(matrix.HasPerspective());
51 matrix.m[index] = 0.5f;
52 EXPECT_EQ(matrix.HasPerspective(), expect) << "index: " << index;
53 };
54
55 // clang-format off
56 test( 0, false); test( 1, false); test( 2, false); test( 3, true);
57 test( 4, false); test( 5, false); test( 6, false); test( 7, true);
58 test( 8, false); test( 9, false); test(10, false); test(11, true);
59 test(12, false); test(13, false); test(14, false); test(15, true);
60 // clang-format on
61}

◆ TEST() [197/377]

impeller::testing::TEST ( MatrixTest  ,
HasPerspective2D   
)

Definition at line 27 of file matrix_unittests.cc.

27 {
28 EXPECT_FALSE(Matrix().HasPerspective2D());
29
30 auto test = [](int index, bool expect) {
32 EXPECT_FALSE(matrix.HasPerspective2D());
33 matrix.m[index] = 0.5f;
34 EXPECT_EQ(matrix.HasPerspective2D(), expect) << "index: " << index;
35 };
36
37 // clang-format off
38 test( 0, false); test( 1, false); test( 2, false); test( 3, true);
39 test( 4, false); test( 5, false); test( 6, false); test( 7, true);
40 test( 8, false); test( 9, false); test(10, false); test(11, false);
41 test(12, false); test(13, false); test(14, false); test(15, true);
42 // clang-format on
43}

◆ TEST() [198/377]

impeller::testing::TEST ( MatrixTest  ,
HasTranslation   
)

Definition at line 63 of file matrix_unittests.cc.

63 {
64 EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).HasTranslation());
65 EXPECT_TRUE(Matrix::MakeTranslation({0, 100, 0}).HasTranslation());
66 EXPECT_TRUE(Matrix::MakeTranslation({100, 0, 0}).HasTranslation());
67 EXPECT_FALSE(Matrix().HasTranslation());
68}

◆ TEST() [199/377]

impeller::testing::TEST ( MatrixTest  ,
IsAligned   
)

Definition at line 103 of file matrix_unittests.cc.

103 {
104 EXPECT_TRUE(Matrix().IsAligned());
105 EXPECT_TRUE(Matrix::MakeScale({1.0f, 1.0f, 2.0f}).IsAligned());
106
107 // Begin Legacy tests transferred over from geometry_unittests.cc
108 {
109 auto m = Matrix::MakeTranslation({1, 2, 3});
110 bool result = m.IsAligned();
111 ASSERT_TRUE(result);
112 }
113
114 {
115 auto m = Matrix::MakeRotationZ(Degrees{123});
116 bool result = m.IsAligned();
117 ASSERT_FALSE(result);
118 }
119 // End Legacy tests transferred over from geometry_unittests.cc
120
121 auto test = [](int index, bool expect) {
123 EXPECT_TRUE(matrix.IsAligned());
124 matrix.m[index] = 0.5f;
125 EXPECT_EQ(matrix.IsAligned(), expect) << "index: " << index;
126 };
127
128 // clang-format off
129 test( 0, true); test( 1, false); test( 2, false); test( 3, false);
130 test( 4, false); test( 5, true); test( 6, false); test( 7, false);
131 test( 8, false); test( 9, false); test(10, true); test(11, false);
132 test(12, true); test(13, true); test(14, true); test(15, false);
133 // clang-format on
134
135 // True for quadrant rotations from -250 to +250 full circles
136 for (int i = -1000; i < 1000; i++) {
137 Degrees d = Degrees(i * 90);
138 Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
139 EXPECT_TRUE(matrix.IsAligned()) << "degrees: " << d.degrees;
140 }
141
142 // False for half degree rotations from -999.5 to +1000.5 degrees
143 for (int i = -1000; i < 1000; i++) {
144 Degrees d = Degrees(i + 0.5f);
145 Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
146 EXPECT_FALSE(matrix.IsAligned()) << "degrees: " << d.degrees;
147 }
148}
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19

◆ TEST() [200/377]

impeller::testing::TEST ( MatrixTest  ,
IsAligned2D   
)

Definition at line 70 of file matrix_unittests.cc.

70 {
71 EXPECT_TRUE(Matrix().IsAligned2D());
72 EXPECT_TRUE(Matrix::MakeScale({1.0f, 1.0f, 2.0f}).IsAligned2D());
73
74 auto test = [](int index, bool expect) {
76 EXPECT_TRUE(matrix.IsAligned2D());
77 matrix.m[index] = 0.5f;
78 EXPECT_EQ(matrix.IsAligned2D(), expect) << "index: " << index;
79 };
80
81 // clang-format off
82 test( 0, true); test( 1, false); test( 2, true); test( 3, false);
83 test( 4, false); test( 5, true); test( 6, true); test( 7, false);
84 test( 8, true); test( 9, true); test(10, true); test(11, true);
85 test(12, true); test(13, true); test(14, true); test(15, false);
86 // clang-format on
87
88 // True for quadrant rotations from -250 to +250 full circles
89 for (int i = -1000; i < 1000; i++) {
90 Degrees d = Degrees(i * 90);
91 Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
92 EXPECT_TRUE(matrix.IsAligned2D()) << "degrees: " << d.degrees;
93 }
94
95 // False for half degree rotations from -999.5 to +1000.5 degrees
96 for (int i = -1000; i < 1000; i++) {
97 Degrees d = Degrees(i + 0.5f);
98 Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
99 EXPECT_FALSE(matrix.IsAligned2D()) << "degrees: " << d.degrees;
100 }
101}

◆ TEST() [201/377]

impeller::testing::TEST ( MatrixTest  ,
Multiply   
)

Definition at line 14 of file matrix_unittests.cc.

14 {
15 Matrix x(0.0, 0.0, 0.0, 1.0, //
16 1.0, 0.0, 0.0, 1.0, //
17 0.0, 1.0, 0.0, 1.0, //
18 1.0, 1.0, 0.0, 1.0);
19 Matrix translate = Matrix::MakeTranslation({10, 20, 0});
20 Matrix result = translate * x;
21 EXPECT_TRUE(MatrixNear(result, Matrix(10.0, 20.0, 0.0, 1.0, //
22 11.0, 20.0, 0.0, 1.0, //
23 10.0, 21.0, 0.0, 1.0, //
24 11.0, 21.0, 0.0, 1.0)));
25}
inline ::testing::AssertionResult MatrixNear(impeller::Matrix a, impeller::Matrix b)

◆ TEST() [202/377]

impeller::testing::TEST ( MatrixTest  ,
TransformHomogenous   
)

Definition at line 150 of file matrix_unittests.cc.

150 {
151 Matrix matrix = Matrix::MakeColumn(
152 // clang-format off
153 2.0f, 3.0f, 5.0f, 7.0f,
154 11.0f, 13.0f, 17.0f, 19.0f,
155 23.0f, 29.0f, 31.0f, 37.0f,
156 41.0f, 43.0f, 47.0f, 53.0f
157 // clang-format on
158 );
159 EXPECT_EQ(matrix.TransformHomogenous({1.0f, -1.0f}),
160 Vector3(32.0f, 33.0f, 41.0f));
161}

◆ TEST() [203/377]

impeller::testing::TEST ( MockGLES  ,
CanCallUnmockedFunction   
)

Definition at line 38 of file mock_gles_unittests.cc.

38 {
39 auto mock_gles = MockGLES::Init();
40
41 auto& gl = mock_gles->GetProcTable();
42 gl.DeleteFramebuffers(1, nullptr);
43
44 // Test should still complete.
45 // If we end up mocking DeleteFramebuffers, delete this test.
46}
gl
Definition: malisc.py:41

◆ TEST() [204/377]

impeller::testing::TEST ( MockGLES  ,
CanInitialize   
)

Definition at line 16 of file mock_gles_unittests.cc.

16 {
17 auto mock_gles = MockGLES::Init();
18
19 std::string_view vendor(reinterpret_cast<const char*>(
20 mock_gles->GetProcTable().GetString(GL_VENDOR)));
21 EXPECT_EQ(vendor, "MockGLES");
22}

◆ TEST() [205/377]

impeller::testing::TEST ( MockGLES  ,
CapturesPushAndPopDebugGroup   
)

Definition at line 25 of file mock_gles_unittests.cc.

25 {
26 auto mock_gles = MockGLES::Init();
27
28 auto& gl = mock_gles->GetProcTable();
29 gl.PushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION_KHR, 0, -1, "test");
30 gl.PopDebugGroupKHR();
31
32 auto calls = mock_gles->GetCapturedCalls();
33 EXPECT_EQ(calls, std::vector<std::string>(
34 {"PushDebugGroupKHR", "PopDebugGroupKHR"}));
35}

◆ TEST() [206/377]

impeller::testing::TEST ( MockVulkanContextTest  ,
DefaultFenceAlwaysReportsSuccess   
)

Definition at line 36 of file mock_vulkan_unittests.cc.

36 {
37 auto const context = MockVulkanContextBuilder().Build();
38 auto const device = context->GetDevice();
39
40 auto fence = device.createFenceUnique({}).value;
41 EXPECT_EQ(vk::Result::eSuccess, device.getFenceStatus(*fence));
42}

◆ TEST() [207/377]

impeller::testing::TEST ( MockVulkanContextTest  ,
IsThreadSafe   
)

Definition at line 13 of file mock_vulkan_unittests.cc.

13 {
14 // In a typical app, there is a single ContextVK per app, shared b/w threads.
15 //
16 // This test ensures that the (mock) ContextVK is thread-safe.
17 auto const context = MockVulkanContextBuilder().Build();
18
19 // Spawn two threads, and have them create a CommandPoolVK each.
20 std::thread thread1([&context]() {
21 auto const pool = context->GetCommandPoolRecycler()->Get();
23 });
24
25 std::thread thread2([&context]() {
26 auto const pool = context->GetCommandPoolRecycler()->Get();
28 });
29
30 thread1.join();
31 thread2.join();
32
33 context->Shutdown();
34}

◆ TEST() [208/377]

impeller::testing::TEST ( MockVulkanContextTest  ,
MockedFenceReportsStatus   
)

Definition at line 44 of file mock_vulkan_unittests.cc.

44 {
45 auto const context = MockVulkanContextBuilder().Build();
46
47 auto const device = context->GetDevice();
48 auto fence = device.createFenceUnique({}).value;
49 MockFence::SetStatus(fence, vk::Result::eNotReady);
50
51 EXPECT_EQ(vk::Result::eNotReady, device.getFenceStatus(fence.get()));
52
53 MockFence::SetStatus(fence, vk::Result::eSuccess);
54 EXPECT_EQ(vk::Result::eSuccess, device.getFenceStatus(*fence));
55}

◆ TEST() [209/377]

impeller::testing::TEST ( PathTest  ,
BoundingBoxCubic   
)

Definition at line 339 of file path_unittests.cc.

339 {
341 auto path =
342 builder.AddCubicCurve({120, 160}, {25, 200}, {220, 260}, {220, 40})
343 .TakePath();
344 auto box = path.GetBoundingBox();
345 Rect expected = Rect::MakeXYWH(93.9101, 40, 126.09, 158.862);
346 ASSERT_TRUE(box.has_value());
347 ASSERT_RECT_NEAR(box.value_or(Rect::MakeMaximum()), expected);
348}

◆ TEST() [210/377]

impeller::testing::TEST ( PathTest  ,
BoundingBoxOfCompositePathIsCorrect   
)

Definition at line 350 of file path_unittests.cc.

350 {
352 builder.AddRoundedRect(Rect::MakeXYWH(10, 10, 300, 300), {50, 50, 50, 50});
353 auto path = builder.TakePath();
354 auto actual = path.GetBoundingBox();
355 Rect expected = Rect::MakeXYWH(10, 10, 300, 300);
356
357 ASSERT_TRUE(actual.has_value());
358 ASSERT_RECT_NEAR(actual.value_or(Rect::MakeMaximum()), expected);
359}

◆ TEST() [211/377]

impeller::testing::TEST ( PathTest  ,
CanBeCloned   
)

Definition at line 501 of file path_unittests.cc.

501 {
503 builder.MoveTo({10, 10});
504 builder.LineTo({20, 20});
505 builder.SetBounds(Rect::MakeLTRB(0, 0, 100, 100));
506 builder.SetConvexity(Convexity::kConvex);
507
508 auto path_a = builder.TakePath(FillType::kOdd);
509 // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
510 auto path_b = path_a;
511
512 EXPECT_EQ(path_a.GetBoundingBox(), path_b.GetBoundingBox());
513 EXPECT_EQ(path_a.GetFillType(), path_b.GetFillType());
514 EXPECT_EQ(path_a.IsConvex(), path_b.IsConvex());
515
516 auto poly_a = path_a.CreatePolyline(1.0);
517 auto poly_b = path_b.CreatePolyline(1.0);
518
519 ASSERT_EQ(poly_a.points->size(), poly_b.points->size());
520 ASSERT_EQ(poly_a.contours.size(), poly_b.contours.size());
521
522 for (auto i = 0u; i < poly_a.points->size(); i++) {
523 EXPECT_EQ((*poly_a.points)[i], (*poly_b.points)[i]);
524 }
525
526 for (auto i = 0u; i < poly_a.contours.size(); i++) {
527 EXPECT_EQ(poly_a.contours[i].start_index, poly_b.contours[i].start_index);
528 EXPECT_EQ(poly_a.contours[i].start_direction,
529 poly_b.contours[i].start_direction);
530 }
531}

◆ TEST() [212/377]

impeller::testing::TEST ( PathTest  ,
CloseAfterMoveDoesNotAddNewLines   
)

Definition at line 471 of file path_unittests.cc.

471 {
473 auto path = builder.LineTo({0, 10})
474 .LineTo({10, 10})
475 .MoveTo({30, 30}) // Moves to (30, 30)
476 .Close() // No Op
477 .Close() // Still No op
478 .TakePath();
479
480 EXPECT_EQ(path.GetComponentCount(), 4u);
481 EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 2u);
482 EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 2u);
483}
static constexpr skcms_TransferFunction kLinear
Definition: SkColorSpace.h:51
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:20

◆ TEST() [213/377]

impeller::testing::TEST ( PathTest  ,
CloseAtOriginDoesNotAddNewLineSegment   
)

Definition at line 485 of file path_unittests.cc.

485 {
487 // Create a path that has a current position at the origin when close is
488 // called. This should not insert a new line segment
489 auto path = builder.LineTo({10, 0})
490 .LineTo({10, 10})
491 .LineTo({0, 10})
492 .LineTo({0, 0})
493 .Close()
494 .TakePath();
495
496 EXPECT_EQ(path.GetComponentCount(), 6u);
497 EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 4u);
498 EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 2u);
499}

◆ TEST() [214/377]

impeller::testing::TEST ( PathTest  ,
CubicPath   
)

Definition at line 324 of file path_unittests.cc.

324 {
326 auto path =
327 builder.CubicCurveTo(Point(10, 10), Point(-10, -10), Point(20, 20))
328 .TakePath();
329
331 path.GetCubicComponentAtIndex(1, cubic);
332
333 EXPECT_EQ(cubic.p1, Point(0, 0));
334 EXPECT_EQ(cubic.cp1, Point(10, 10));
335 EXPECT_EQ(cubic.cp2, Point(-10, -10));
336 EXPECT_EQ(cubic.p2, Point(20, 20));
337}
AI float cubic(float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:195

◆ TEST() [215/377]

impeller::testing::TEST ( PathTest  ,
CubicPathComponentPolylineDoesNotIncludePointOne   
)

Definition at line 15 of file path_unittests.cc.

15 {
16 CubicPathComponent component({10, 10}, {20, 35}, {35, 20}, {40, 40});
17 std::vector<Point> polyline;
18 component.AppendPolylinePoints(1.0f, polyline);
19 ASSERT_NE(polyline.front().x, 10);
20 ASSERT_NE(polyline.front().y, 10);
21 ASSERT_EQ(polyline.back().x, 40);
22 ASSERT_EQ(polyline.back().y, 40);
23}
const Path::Polyline & polyline

◆ TEST() [216/377]

impeller::testing::TEST ( PathTest  ,
EmptyPath   
)

Definition at line 384 of file path_unittests.cc.

384 {
385 auto path = PathBuilder{}.TakePath();
386 ASSERT_EQ(path.GetComponentCount(), 1u);
387
389 path.GetContourComponentAtIndex(0, c);
391
392 Path::Polyline polyline = path.CreatePolyline(1.0f);
393 ASSERT_TRUE(polyline.points->empty());
394 ASSERT_TRUE(polyline.contours.empty());
395}

◆ TEST() [217/377]

impeller::testing::TEST ( PathTest  ,
ExtremaOfCubicPathComponentIsCorrect   
)

Definition at line 361 of file path_unittests.cc.

361 {
362 CubicPathComponent cubic{{11.769268, 252.883148},
363 {-6.2857933, 204.356461},
364 {-4.53997231, 156.552902},
365 {17.0067291, 109.472488}};
366 auto points = cubic.Extrema();
367
368 ASSERT_EQ(points.size(), static_cast<size_t>(3));
369 ASSERT_POINT_NEAR(points[2], cubic.Solve(0.455916));
370}
static const int points[]

◆ TEST() [218/377]

impeller::testing::TEST ( PathTest  ,
PathAddRectPolylineHasCorrectContourData   
)

Definition at line 160 of file path_unittests.cc.

160 {
162 .AddRect(Rect::MakeLTRB(50, 60, 70, 80))
163 .TakePath()
164 .CreatePolyline(1.0f);
165 ASSERT_EQ(polyline.contours.size(), 1u);
166 ASSERT_TRUE(polyline.contours[0].is_closed);
167 ASSERT_EQ(polyline.contours[0].start_index, 0u);
168 ASSERT_EQ(polyline.points->size(), 5u);
169 ASSERT_EQ(polyline.GetPoint(0), Point(50, 60));
170 ASSERT_EQ(polyline.GetPoint(1), Point(70, 60));
171 ASSERT_EQ(polyline.GetPoint(2), Point(70, 80));
172 ASSERT_EQ(polyline.GetPoint(3), Point(50, 80));
173 ASSERT_EQ(polyline.GetPoint(4), Point(50, 60));
174}
Polyline CreatePolyline(Scalar scale, Polyline::PointBufferPtr point_buffer=std::make_unique< std::vector< Point > >(), Polyline::ReclaimPointBufferCallback reclaim=nullptr) const
Definition: path.cc:264

◆ TEST() [219/377]

impeller::testing::TEST ( PathTest  ,
PathBuilderDoesNotMutateCopiedPaths   
)

Definition at line 533 of file path_unittests.cc.

533 {
534 auto test_isolation =
535 [](const std::function<void(PathBuilder & builder)>& mutator,
536 bool will_close, Point mutation_offset, const std::string& label) {
538 builder.MoveTo({10, 10});
539 builder.LineTo({20, 20});
540 builder.LineTo({20, 10});
541
542 auto verify_path = [](const Path& path, bool is_mutated, bool is_closed,
543 Point offset, const std::string& label) {
544 if (is_mutated) {
545 // We can only test the initial state before the mutator did
546 // its work. We have >= 3 components and the first 3 components
547 // will match what we saw before the mutation.
548 EXPECT_GE(path.GetComponentCount(), 3u) << label;
549 } else {
550 EXPECT_EQ(path.GetComponentCount(), 3u) << label;
551 }
552 {
553 ContourComponent contour;
554 EXPECT_TRUE(path.GetContourComponentAtIndex(0, contour)) << label;
555 EXPECT_EQ(contour.destination, offset + Point(10, 10)) << label;
556 EXPECT_EQ(contour.is_closed, is_closed) << label;
557 }
558 {
559 LinearPathComponent line;
560 EXPECT_TRUE(path.GetLinearComponentAtIndex(1, line)) << label;
561 EXPECT_EQ(line.p1, offset + Point(10, 10)) << label;
562 EXPECT_EQ(line.p2, offset + Point(20, 20)) << label;
563 }
564 {
565 LinearPathComponent line;
566 EXPECT_TRUE(path.GetLinearComponentAtIndex(2, line)) << label;
567 EXPECT_EQ(line.p1, offset + Point(20, 20)) << label;
568 EXPECT_EQ(line.p2, offset + Point(20, 10)) << label;
569 }
570 };
571
572 auto path1 = builder.CopyPath();
573 verify_path(path1, false, false, {},
574 "Initial Path1 state before " + label);
575
576 for (int i = 0; i < 10; i++) {
577 auto path = builder.CopyPath();
578 verify_path(
579 path, false, false, {},
580 "Extra CopyPath #" + std::to_string(i + 1) + " for " + label);
581 }
582 mutator(builder);
583 verify_path(path1, false, false, {},
584 "Path1 state after subsequent " + label);
585
586 auto path2 = builder.CopyPath();
587 verify_path(path1, false, false, {},
588 "Path1 state after subsequent " + label + " and CopyPath");
589 verify_path(path2, true, will_close, mutation_offset,
590 "Initial Path2 state with subsequent " + label);
591 };
592
593 test_isolation(
594 [](PathBuilder& builder) { //
595 builder.SetConvexity(Convexity::kConvex);
596 },
597 false, {}, "SetConvex");
598
599 test_isolation(
600 [](PathBuilder& builder) { //
601 builder.SetConvexity(Convexity::kUnknown);
602 },
603 false, {}, "SetUnknownConvex");
604
605 test_isolation(
606 [](PathBuilder& builder) { //
607 builder.Close();
608 },
609 true, {}, "Close");
610
611 test_isolation(
612 [](PathBuilder& builder) {
613 builder.MoveTo({20, 30}, false);
614 },
615 false, {}, "Absolute MoveTo");
616
617 test_isolation(
618 [](PathBuilder& builder) {
619 builder.MoveTo({20, 30}, true);
620 },
621 false, {}, "Relative MoveTo");
622
623 test_isolation(
624 [](PathBuilder& builder) {
625 builder.LineTo({20, 30}, false);
626 },
627 false, {}, "Absolute LineTo");
628
629 test_isolation(
630 [](PathBuilder& builder) {
631 builder.LineTo({20, 30}, true);
632 },
633 false, {}, "Relative LineTo");
634
635 test_isolation(
636 [](PathBuilder& builder) { //
637 builder.HorizontalLineTo(100, false);
638 },
639 false, {}, "Absolute HorizontalLineTo");
640
641 test_isolation(
642 [](PathBuilder& builder) { //
643 builder.HorizontalLineTo(100, true);
644 },
645 false, {}, "Relative HorizontalLineTo");
646
647 test_isolation(
648 [](PathBuilder& builder) { //
649 builder.VerticalLineTo(100, false);
650 },
651 false, {}, "Absolute VerticalLineTo");
652
653 test_isolation(
654 [](PathBuilder& builder) { //
655 builder.VerticalLineTo(100, true);
656 },
657 false, {}, "Relative VerticalLineTo");
658
659 test_isolation(
660 [](PathBuilder& builder) {
661 builder.QuadraticCurveTo({20, 30}, {30, 20}, false);
662 },
663 false, {}, "Absolute QuadraticCurveTo");
664
665 test_isolation(
666 [](PathBuilder& builder) {
667 builder.QuadraticCurveTo({20, 30}, {30, 20}, true);
668 },
669 false, {}, "Relative QuadraticCurveTo");
670
671 test_isolation(
672 [](PathBuilder& builder) {
673 builder.CubicCurveTo({20, 30}, {30, 20}, {30, 30}, false);
674 },
675 false, {}, "Absolute CubicCurveTo");
676
677 test_isolation(
678 [](PathBuilder& builder) {
679 builder.CubicCurveTo({20, 30}, {30, 20}, {30, 30}, true);
680 },
681 false, {}, "Relative CubicCurveTo");
682
683 test_isolation(
684 [](PathBuilder& builder) {
685 builder.AddLine({100, 100}, {150, 100});
686 },
687 false, {}, "AddLine");
688
689 test_isolation(
690 [](PathBuilder& builder) {
691 builder.AddRect(Rect::MakeLTRB(100, 100, 120, 120));
692 },
693 false, {}, "AddRect");
694
695 test_isolation(
696 [](PathBuilder& builder) {
697 builder.AddOval(Rect::MakeLTRB(100, 100, 120, 120));
698 },
699 false, {}, "AddOval");
700
701 test_isolation(
702 [](PathBuilder& builder) {
703 builder.AddCircle({100, 100}, 20);
704 },
705 false, {}, "AddCircle");
706
707 test_isolation(
708 [](PathBuilder& builder) {
709 builder.AddArc(Rect::MakeLTRB(100, 100, 120, 120), Degrees(10),
710 Degrees(170));
711 },
712 false, {}, "AddArc");
713
714 test_isolation(
715 [](PathBuilder& builder) {
716 builder.AddQuadraticCurve({100, 100}, {150, 100}, {150, 150});
717 },
718 false, {}, "AddQuadraticCurve");
719
720 test_isolation(
721 [](PathBuilder& builder) {
722 builder.AddCubicCurve({100, 100}, {150, 100}, {100, 150}, {150, 150});
723 },
724 false, {}, "AddCubicCurve");
725
726 test_isolation(
727 [](PathBuilder& builder) {
728 builder.Shift({23, 42});
729 },
730 false, {23, 42}, "Shift");
731}
static SkPath path1()
static SkPath path2()
Dart_NativeFunction function
Definition: fuchsia.cc:51
CanvasPath Path
Definition: dart_ui.cc:58
static SkString to_string(int n)
Definition: nanobench.cpp:119

◆ TEST() [220/377]

impeller::testing::TEST ( PathTest  ,
PathBuilderSetsCorrectContourPropertiesForAddCommands   
)

Definition at line 44 of file path_unittests.cc.

44 {
45 // Closed shapes.
46 {
47 Path path = PathBuilder{}.AddCircle({100, 100}, 50).TakePath();
48 ContourComponent contour;
49 path.GetContourComponentAtIndex(0, contour);
50 EXPECT_POINT_NEAR(contour.destination, Point(100, 50));
51 EXPECT_TRUE(contour.is_closed);
52 }
53
54 {
55 Path path =
56 PathBuilder{}.AddOval(Rect::MakeXYWH(100, 100, 100, 100)).TakePath();
57 ContourComponent contour;
58 path.GetContourComponentAtIndex(0, contour);
59 EXPECT_POINT_NEAR(contour.destination, Point(150, 100));
60 EXPECT_TRUE(contour.is_closed);
61 }
62
63 {
64 Path path =
65 PathBuilder{}.AddRect(Rect::MakeXYWH(100, 100, 100, 100)).TakePath();
66 ContourComponent contour;
67 path.GetContourComponentAtIndex(0, contour);
68 EXPECT_POINT_NEAR(contour.destination, Point(100, 100));
69 EXPECT_TRUE(contour.is_closed);
70 }
71
72 {
73 Path path = PathBuilder{}
74 .AddRoundedRect(Rect::MakeXYWH(100, 100, 100, 100), 10)
75 .TakePath();
76 ContourComponent contour;
77 path.GetContourComponentAtIndex(0, contour);
78 EXPECT_POINT_NEAR(contour.destination, Point(110, 100));
79 EXPECT_TRUE(contour.is_closed);
80 }
81
82 {
83 Path path =
84 PathBuilder{}
85 .AddRoundedRect(Rect::MakeXYWH(100, 100, 100, 100), Size(10, 20))
86 .TakePath();
87 ContourComponent contour;
88 path.GetContourComponentAtIndex(0, contour);
89 EXPECT_POINT_NEAR(contour.destination, Point(110, 100));
90 EXPECT_TRUE(contour.is_closed);
91 }
92
93 // Open shapes.
94 {
95 Point p(100, 100);
96 Path path = PathBuilder{}.AddLine(p, {200, 100}).TakePath();
97 ContourComponent contour;
98 path.GetContourComponentAtIndex(0, contour);
99 ASSERT_POINT_NEAR(contour.destination, p);
100 ASSERT_FALSE(contour.is_closed);
101 }
102
103 {
104 Path path =
105 PathBuilder{}
106 .AddCubicCurve({100, 100}, {100, 50}, {100, 150}, {200, 100})
107 .TakePath();
108 ContourComponent contour;
109 path.GetContourComponentAtIndex(0, contour);
110 ASSERT_POINT_NEAR(contour.destination, Point(100, 100));
111 ASSERT_FALSE(contour.is_closed);
112 }
113
114 {
115 Path path = PathBuilder{}
116 .AddQuadraticCurve({100, 100}, {100, 50}, {200, 100})
117 .TakePath();
118 ContourComponent contour;
119 path.GetContourComponentAtIndex(0, contour);
120 ASSERT_POINT_NEAR(contour.destination, Point(100, 100));
121 ASSERT_FALSE(contour.is_closed);
122 }
123}
PathBuilder & AddCircle(const Point &center, Scalar radius)
#define EXPECT_POINT_NEAR(a, b)

◆ TEST() [221/377]

impeller::testing::TEST ( PathTest  ,
PathBuilderWillComputeBounds   
)

Definition at line 268 of file path_unittests.cc.

268 {
270 auto path_1 = builder.AddLine({0, 0}, {1, 1}).TakePath();
271
272 ASSERT_EQ(path_1.GetBoundingBox().value_or(Rect::MakeMaximum()),
273 Rect::MakeLTRB(0, 0, 1, 1));
274
275 auto path_2 = builder.AddLine({-1, -1}, {1, 1}).TakePath();
276
277 // Verify that PathBuilder recomputes the bounds.
278 ASSERT_EQ(path_2.GetBoundingBox().value_or(Rect::MakeMaximum()),
279 Rect::MakeLTRB(-1, -1, 1, 1));
280
281 // PathBuilder can set the bounds to whatever it wants
282 auto path_3 = builder.AddLine({0, 0}, {1, 1})
283 .SetBounds(Rect::MakeLTRB(0, 0, 100, 100))
284 .TakePath();
285
286 ASSERT_EQ(path_3.GetBoundingBox().value_or(Rect::MakeMaximum()),
287 Rect::MakeLTRB(0, 0, 100, 100));
288}

◆ TEST() [222/377]

impeller::testing::TEST ( PathTest  ,
PathCreatePolyLineDoesNotDuplicatePoints   
)

Definition at line 25 of file path_unittests.cc.

25 {
27 builder.MoveTo({10, 10});
28 builder.LineTo({20, 20});
29 builder.LineTo({30, 30});
30 builder.MoveTo({40, 40});
31 builder.LineTo({50, 50});
32
33 auto polyline = builder.TakePath().CreatePolyline(1.0f);
34
35 ASSERT_EQ(polyline.contours.size(), 2u);
36 ASSERT_EQ(polyline.points->size(), 5u);
37 ASSERT_EQ(polyline.GetPoint(0).x, 10);
38 ASSERT_EQ(polyline.GetPoint(1).x, 20);
39 ASSERT_EQ(polyline.GetPoint(2).x, 30);
40 ASSERT_EQ(polyline.GetPoint(3).x, 40);
41 ASSERT_EQ(polyline.GetPoint(4).x, 50);
42}

◆ TEST() [223/377]

impeller::testing::TEST ( PathTest  ,
PathCreatePolylineGeneratesCorrectContourData   
)

Definition at line 125 of file path_unittests.cc.

125 {
127 .AddLine({100, 100}, {200, 100})
128 .MoveTo({100, 200})
129 .LineTo({150, 250})
130 .LineTo({200, 200})
131 .Close()
132 .TakePath()
133 .CreatePolyline(1.0f);
134 ASSERT_EQ(polyline.points->size(), 6u);
135 ASSERT_EQ(polyline.contours.size(), 2u);
136 ASSERT_EQ(polyline.contours[0].is_closed, false);
137 ASSERT_EQ(polyline.contours[0].start_index, 0u);
138 ASSERT_EQ(polyline.contours[1].is_closed, true);
139 ASSERT_EQ(polyline.contours[1].start_index, 2u);
140}
PathBuilder & AddLine(const Point &p1, const Point &p2)
Move to point p1, then insert a line from p1 to p2.

◆ TEST() [224/377]

impeller::testing::TEST ( PathTest  ,
PathGetBoundingBoxForCubicWithNoDerivativeRootsIsCorrect   
)

Definition at line 372 of file path_unittests.cc.

372 {
374 // Straight diagonal line.
375 builder.AddCubicCurve({0, 1}, {2, 3}, {4, 5}, {6, 7});
376 auto path = builder.TakePath();
377 auto actual = path.GetBoundingBox();
378 auto expected = Rect::MakeLTRB(0, 1, 6, 7);
379
380 ASSERT_TRUE(actual.has_value());
381 ASSERT_RECT_NEAR(actual.value_or(Rect::MakeMaximum()), expected);
382}

◆ TEST() [225/377]

impeller::testing::TEST ( PathTest  ,
PathHorizontalLine   
)

Definition at line 290 of file path_unittests.cc.

290 {
292 auto path = builder.HorizontalLineTo(10).TakePath();
293
295 path.GetLinearComponentAtIndex(1, linear);
296
297 EXPECT_EQ(linear.p1, Point(0, 0));
298 EXPECT_EQ(linear.p2, Point(10, 0));
299}
static sk_sp< SkShader > linear(sk_sp< SkShader > shader)

◆ TEST() [226/377]

impeller::testing::TEST ( PathTest  ,
PathPolylineDuplicatesAreRemovedForSameContour   
)

Definition at line 176 of file path_unittests.cc.

176 {
179 .MoveTo({50, 50})
180 .LineTo({50, 50}) // Insert duplicate at beginning of contour.
181 .LineTo({100, 50})
182 .LineTo({100, 50}) // Insert duplicate at contour join.
183 .LineTo({100, 100})
184 .Close() // Implicitly insert duplicate {50, 50} across contours.
185 .LineTo({0, 50})
186 .LineTo({0, 100})
187 .LineTo({0, 100}) // Insert duplicate at end of contour.
188 .TakePath()
189 .CreatePolyline(1.0f);
190 ASSERT_EQ(polyline.contours.size(), 2u);
191 ASSERT_EQ(polyline.contours[0].start_index, 0u);
192 ASSERT_TRUE(polyline.contours[0].is_closed);
193 ASSERT_EQ(polyline.contours[1].start_index, 4u);
194 ASSERT_FALSE(polyline.contours[1].is_closed);
195 ASSERT_EQ(polyline.points->size(), 7u);
196 ASSERT_EQ(polyline.GetPoint(0), Point(50, 50));
197 ASSERT_EQ(polyline.GetPoint(1), Point(100, 50));
198 ASSERT_EQ(polyline.GetPoint(2), Point(100, 100));
199 ASSERT_EQ(polyline.GetPoint(3), Point(50, 50));
200 ASSERT_EQ(polyline.GetPoint(4), Point(50, 50));
201 ASSERT_EQ(polyline.GetPoint(5), Point(0, 50));
202 ASSERT_EQ(polyline.GetPoint(6), Point(0, 100));
203}
PathBuilder & MoveTo(Point point, bool relative=false)
Definition: path_builder.cc:33

◆ TEST() [227/377]

impeller::testing::TEST ( PathTest  ,
PathShifting   
)

Definition at line 232 of file path_unittests.cc.

232 {
234 auto path =
235 builder.AddLine(Point(0, 0), Point(10, 10))
236 .AddQuadraticCurve(Point(10, 10), Point(15, 15), Point(20, 20))
237 .AddCubicCurve(Point(20, 20), Point(25, 25), Point(-5, -5),
238 Point(30, 30))
239 .Close()
240 .Shift(Point(1, 1))
241 .TakePath();
242
247
248 ASSERT_TRUE(path.GetContourComponentAtIndex(0, contour));
249 ASSERT_TRUE(path.GetLinearComponentAtIndex(1, linear));
250 ASSERT_TRUE(path.GetQuadraticComponentAtIndex(3, quad));
251 ASSERT_TRUE(path.GetCubicComponentAtIndex(5, cubic));
252
253 EXPECT_EQ(contour.destination, Point(1, 1));
254
255 EXPECT_EQ(linear.p1, Point(1, 1));
256 EXPECT_EQ(linear.p2, Point(11, 11));
257
258 EXPECT_EQ(quad.cp, Point(16, 16));
259 EXPECT_EQ(quad.p1, Point(11, 11));
260 EXPECT_EQ(quad.p2, Point(21, 21));
261
262 EXPECT_EQ(cubic.cp1, Point(26, 26));
263 EXPECT_EQ(cubic.cp2, Point(-4, -4));
264 EXPECT_EQ(cubic.p1, Point(21, 21));
265 EXPECT_EQ(cubic.p2, Point(31, 31));
266}

◆ TEST() [228/377]

impeller::testing::TEST ( PathTest  ,
PathVerticalLine   
)

Definition at line 301 of file path_unittests.cc.

301 {
303 auto path = builder.VerticalLineTo(10).TakePath();
304
306 path.GetLinearComponentAtIndex(1, linear);
307
308 EXPECT_EQ(linear.p1, Point(0, 0));
309 EXPECT_EQ(linear.p2, Point(0, 10));
310}

◆ TEST() [229/377]

impeller::testing::TEST ( PathTest  ,
PolylineBufferReuse   
)

Definition at line 205 of file path_unittests.cc.

205 {
206 auto point_buffer = std::make_unique<std::vector<Point>>();
207 auto point_buffer_address = reinterpret_cast<uintptr_t>(point_buffer.get());
210 .MoveTo({50, 50})
211 .LineTo({100, 100})
212 .TakePath()
213 .CreatePolyline(
214 1.0f, std::move(point_buffer),
215 [point_buffer_address](
216 Path::Polyline::PointBufferPtr point_buffer) {
217 ASSERT_EQ(point_buffer->size(), 0u);
218 ASSERT_EQ(point_buffer_address,
219 reinterpret_cast<uintptr_t>(point_buffer.get()));
220 });
221}

◆ TEST() [230/377]

impeller::testing::TEST ( PathTest  ,
PolylineFailsWithNullptrBuffer   
)

Definition at line 223 of file path_unittests.cc.

223 {
224 EXPECT_DEATH_IF_SUPPORTED(PathBuilder{}
225 .MoveTo({50, 50})
226 .LineTo({100, 100})
227 .TakePath()
228 .CreatePolyline(1.0f, nullptr),
229 "");
230}

◆ TEST() [231/377]

impeller::testing::TEST ( PathTest  ,
PolylineGetContourPointBoundsReturnsCorrectRanges   
)

Definition at line 142 of file path_unittests.cc.

142 {
144 .AddLine({100, 100}, {200, 100})
145 .MoveTo({100, 200})
146 .LineTo({150, 250})
147 .LineTo({200, 200})
148 .Close()
149 .TakePath()
150 .CreatePolyline(1.0f);
151 size_t a1, a2, b1, b2;
152 std::tie(a1, a2) = polyline.GetContourPointBounds(0);
153 std::tie(b1, b2) = polyline.GetContourPointBounds(1);
154 ASSERT_EQ(a1, 0u);
155 ASSERT_EQ(a2, 2u);
156 ASSERT_EQ(b1, 2u);
157 ASSERT_EQ(b2, 6u);
158}

◆ TEST() [232/377]

impeller::testing::TEST ( PathTest  ,
QuadradicPath   
)

Definition at line 312 of file path_unittests.cc.

312 {
314 auto path = builder.QuadraticCurveTo(Point(10, 10), Point(20, 20)).TakePath();
315
317 path.GetQuadraticComponentAtIndex(1, quad);
318
319 EXPECT_EQ(quad.p1, Point(0, 0));
320 EXPECT_EQ(quad.cp, Point(10, 10));
321 EXPECT_EQ(quad.p2, Point(20, 20));
322}

◆ TEST() [233/377]

impeller::testing::TEST ( PathTest  ,
RepeatCloseDoesNotAddNewLines   
)

Definition at line 457 of file path_unittests.cc.

457 {
459 auto path = builder.LineTo({0, 10})
460 .LineTo({10, 10})
461 .Close() // Returns to (0, 0)
462 .Close() // No Op
463 .Close() // Still No op
464 .TakePath();
465
466 EXPECT_EQ(path.GetComponentCount(), 5u);
467 EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 3u);
468 EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 2u);
469}

◆ TEST() [234/377]

impeller::testing::TEST ( PathTest  ,
SimplePath   
)

Definition at line 397 of file path_unittests.cc.

397 {
399
400 auto path = builder.AddLine({0, 0}, {100, 100})
401 .AddQuadraticCurve({100, 100}, {200, 200}, {300, 300})
402 .AddCubicCurve({300, 300}, {400, 400}, {500, 500}, {600, 600})
403 .TakePath();
404
405 ASSERT_EQ(path.GetComponentCount(), 6u);
406 ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 1u);
407 ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kQuadratic), 1u);
408 ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kCubic), 1u);
409 ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 3u);
410
411 path.EnumerateComponents(
412 [](size_t index, const LinearPathComponent& linear) {
413 Point p1(0, 0);
414 Point p2(100, 100);
415 ASSERT_EQ(index, 1u);
416 ASSERT_EQ(linear.p1, p1);
417 ASSERT_EQ(linear.p2, p2);
418 },
419 [](size_t index, const QuadraticPathComponent& quad) {
420 Point p1(100, 100);
421 Point cp(200, 200);
422 Point p2(300, 300);
423 ASSERT_EQ(index, 3u);
424 ASSERT_EQ(quad.p1, p1);
425 ASSERT_EQ(quad.cp, cp);
426 ASSERT_EQ(quad.p2, p2);
427 },
428 [](size_t index, const CubicPathComponent& cubic) {
429 Point p1(300, 300);
430 Point cp1(400, 400);
431 Point cp2(500, 500);
432 Point p2(600, 600);
433 ASSERT_EQ(index, 5u);
434 ASSERT_EQ(cubic.p1, p1);
435 ASSERT_EQ(cubic.cp1, cp1);
436 ASSERT_EQ(cubic.cp2, cp2);
437 ASSERT_EQ(cubic.p2, p2);
438 },
439 [](size_t index, const ContourComponent& contour) {
440 // There is an initial countour added for each curve.
441 if (index == 0u) {
442 Point p1(0, 0);
443 ASSERT_EQ(contour.destination, p1);
444 } else if (index == 2u) {
445 Point p1(100, 100);
446 ASSERT_EQ(contour.destination, p1);
447 } else if (index == 4u) {
448 Point p1(300, 300);
449 ASSERT_EQ(contour.destination, p1);
450 } else {
451 ASSERT_FALSE(true);
452 }
453 ASSERT_FALSE(contour.is_closed);
454 });
455}

◆ TEST() [235/377]

impeller::testing::TEST ( PipelineDescriptorTest  ,
PrimitiveTypeHashEquality   
)

Definition at line 13 of file pipeline_descriptor_unittests.cc.

13 {
16
17 ASSERT_TRUE(descA.IsEqual(descB));
18 ASSERT_EQ(descA.GetHash(), descB.GetHash());
19
20 descA.SetPrimitiveType(PrimitiveType::kTriangleStrip);
21
22 ASSERT_FALSE(descA.IsEqual(descB));
23 ASSERT_NE(descA.GetHash(), descB.GetHash());
24}
std::size_t GetHash() const override
bool IsEqual(const PipelineDescriptor &other) const override
void SetPrimitiveType(PrimitiveType type)

◆ TEST() [236/377]

impeller::testing::TEST ( PoolTest  ,
Overload   
)

Definition at line 47 of file pool_unittests.cc.

47 {
48 Pool<Foobar> pool(1'000);
49 {
50 std::vector<std::shared_ptr<Foobar>> values;
51 values.reserve(20);
52 for (int i = 0; i < 20; i++) {
53 values.push_back(pool.Grab());
54 }
55 for (const auto& value : values) {
56 value->SetSize(100);
57 pool.Recycle(value);
58 }
59 }
60 EXPECT_EQ(pool.GetSize(), 1'000u);
61}
A thread-safe pool with a limited byte size.
Definition: pool.h:17

◆ TEST() [237/377]

impeller::testing::TEST ( PoolTest  ,
Simple   
)

Definition at line 33 of file pool_unittests.cc.

33 {
34 Pool<Foobar> pool(1'000);
35 {
36 auto grabbed = pool.Grab();
37 grabbed->SetSize(123);
38 pool.Recycle(grabbed);
39 EXPECT_EQ(pool.GetSize(), 123u);
40 }
41 auto grabbed = pool.Grab();
42 EXPECT_EQ(grabbed->GetSize(), 123u);
43 EXPECT_TRUE(grabbed->GetIsReset());
44 EXPECT_EQ(pool.GetSize(), 0u);
45}

◆ TEST() [238/377]

impeller::testing::TEST ( ProcTableGLES  ,
ResolvesCorrectClearDepthProcOnDesktopGL   
)

Definition at line 28 of file proc_table_gles_unittests.cc.

28 {
29 auto mock_gles = MockGLES::Init(std::nullopt, "OpenGL 4.0");
30 EXPECT_FALSE(mock_gles->GetProcTable().GetDescription()->IsES());
31
34}
#define FOR_EACH_IMPELLER_DESKTOP_ONLY_PROC(PROC)
#define FOR_EACH_IMPELLER_ES_ONLY_PROC(PROC)
#define EXPECT_AVAILABLE(proc_ivar)
#define EXPECT_UNAVAILABLE(proc_ivar)

◆ TEST() [239/377]

impeller::testing::TEST ( ProcTableGLES  ,
ResolvesCorrectClearDepthProcOnES   
)

Definition at line 20 of file proc_table_gles_unittests.cc.

20 {
21 auto mock_gles = MockGLES::Init(std::nullopt, "OpenGL ES 3.0");
22 EXPECT_TRUE(mock_gles->GetProcTable().GetDescription()->IsES());
23
26}

◆ TEST() [240/377]

impeller::testing::TEST ( RectTest  ,
ContainsFloatingPoint   
)

Definition at line 1271 of file rect_unittests.cc.

1271 {
1272 auto rect1 =
1273 Rect::MakeXYWH(472.599945f, 440.999969f, 1102.80005f, 654.000061f);
1274 auto rect2 = Rect::MakeXYWH(724.f, 618.f, 600.f, 300.f);
1275 EXPECT_TRUE(rect1.Contains(rect2));
1276}

◆ TEST() [241/377]

impeller::testing::TEST ( RectTest  ,
EmptyIRectDoesNotIntersect   
)

Definition at line 854 of file rect_unittests.cc.

854 {
855 IRect rect = IRect::MakeLTRB(50, 50, 100, 100);
856
857 auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t b,
858 const std::string& label) {
859 EXPECT_FALSE(IRect::MakeLTRB(l, b, r, t).IntersectsWithRect(rect))
860 << label << " with Top/Bottom swapped";
861 EXPECT_FALSE(IRect::MakeLTRB(r, b, l, t).IntersectsWithRect(rect))
862 << label << " with Left/Right swapped";
863 EXPECT_FALSE(IRect::MakeLTRB(r, t, l, b).IntersectsWithRect(rect))
864 << label << " with all sides swapped";
865 };
866
867 test(20, 20, 30, 30, "Above and Left");
868 test(70, 20, 80, 30, "Above");
869 test(120, 20, 130, 30, "Above and Right");
870 test(120, 70, 130, 80, "Right");
871 test(120, 120, 130, 130, "Below and Right");
872 test(70, 120, 80, 130, "Below");
873 test(20, 120, 30, 130, "Below and Left");
874 test(20, 70, 30, 80, "Left");
875
876 test(70, 70, 80, 80, "Inside");
877
878 test(40, 70, 60, 80, "Straddling Left");
879 test(70, 40, 80, 60, "Straddling Top");
880 test(90, 70, 110, 80, "Straddling Right");
881 test(70, 90, 80, 110, "Straddling Bottom");
882}

◆ TEST() [242/377]

impeller::testing::TEST ( RectTest  ,
EmptyRectDoesNotIntersect   
)

Definition at line 824 of file rect_unittests.cc.

824 {
825 Rect rect = Rect::MakeLTRB(50, 50, 100, 100);
826
827 auto test = [&rect](Scalar l, Scalar t, Scalar r, Scalar b,
828 const std::string& label) {
829 EXPECT_FALSE(Rect::MakeLTRB(l, b, r, t).IntersectsWithRect(rect))
830 << label << " with Top/Bottom swapped";
831 EXPECT_FALSE(Rect::MakeLTRB(r, b, l, t).IntersectsWithRect(rect))
832 << label << " with Left/Right swapped";
833 EXPECT_FALSE(Rect::MakeLTRB(r, t, l, b).IntersectsWithRect(rect))
834 << label << " with all sides swapped";
835 };
836
837 test(20, 20, 30, 30, "Above and Left");
838 test(70, 20, 80, 30, "Above");
839 test(120, 20, 130, 30, "Above and Right");
840 test(120, 70, 130, 80, "Right");
841 test(120, 120, 130, 130, "Below and Right");
842 test(70, 120, 80, 130, "Below");
843 test(20, 120, 30, 130, "Below and Left");
844 test(20, 70, 30, 80, "Left");
845
846 test(70, 70, 80, 80, "Inside");
847
848 test(40, 70, 60, 80, "Straddling Left");
849 test(70, 40, 80, 60, "Straddling Top");
850 test(90, 70, 110, 80, "Straddling Right");
851 test(70, 90, 80, 110, "Straddling Bottom");
852}

◆ TEST() [243/377]

impeller::testing::TEST ( RectTest  ,
GetCenter   
)

Definition at line 1194 of file rect_unittests.cc.

1194 {
1195 EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
1196 EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
1197 EXPECT_EQ(Rect::MakeMaximum().GetCenter(), Point(0, 0));
1198
1199 // Note that we expect a Point as the answer from an IRect
1200 EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
1201 EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
1202 EXPECT_EQ(IRect::MakeMaximum().GetCenter(), Point(0, 0));
1203}

◆ TEST() [244/377]

impeller::testing::TEST ( RectTest  ,
IRectArea   
)

Definition at line 980 of file rect_unittests.cc.

980 {
981 EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
982 EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
983 EXPECT_EQ(IRect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
984 EXPECT_EQ(IRect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
985 EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
986 EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
987}

◆ TEST() [245/377]

impeller::testing::TEST ( RectTest  ,
IRectContainsInclusiveIPoint   
)

Definition at line 2355 of file rect_unittests.cc.

2355 {
2356 auto check_empty_flips = [](const IRect& rect, const IPoint& point,
2357 const std::string& label) {
2358 ASSERT_FALSE(rect.IsEmpty());
2359
2360 EXPECT_FALSE(flip_lr(rect).ContainsInclusive(point)) << label;
2361 EXPECT_FALSE(flip_tb(rect).ContainsInclusive(point)) << label;
2362 EXPECT_FALSE(flip_lrtb(rect).ContainsInclusive(point)) << label;
2363 };
2364
2365 auto test_inside = [&check_empty_flips](const IRect& rect,
2366 const IPoint& point) {
2367 ASSERT_FALSE(rect.IsEmpty()) << rect;
2368
2369 std::stringstream stream;
2370 stream << rect << " contains " << point;
2371 auto label = stream.str();
2372
2373 EXPECT_TRUE(rect.ContainsInclusive(point)) << label;
2374 check_empty_flips(rect, point, label);
2375 };
2376
2377 auto test_outside = [&check_empty_flips](const IRect& rect,
2378 const IPoint& point) {
2379 ASSERT_FALSE(rect.IsEmpty()) << rect;
2380
2381 std::stringstream stream;
2382 stream << rect << " contains " << point;
2383 auto label = stream.str();
2384
2385 EXPECT_FALSE(rect.ContainsInclusive(point)) << label;
2386 check_empty_flips(rect, point, label);
2387 };
2388
2389 {
2390 // Origin is inclusive
2391 auto r = IRect::MakeXYWH(100, 100, 100, 100);
2392 auto p = IPoint(100, 100);
2393
2394 test_inside(r, p);
2395 }
2396 {
2397 // Size is inclusive
2398 auto r = IRect::MakeXYWH(100, 100, 100, 100);
2399 auto p = IPoint(200, 200);
2400
2401 test_inside(r, p);
2402 }
2403 {
2404 // Size + "epsilon" is exclusive
2405 auto r = IRect::MakeXYWH(100, 100, 100, 100);
2406 auto p = IPoint(201, 201);
2407
2408 test_outside(r, p);
2409 }
2410 {
2411 auto r = IRect::MakeXYWH(100, 100, 100, 100);
2412 auto p = IPoint(99, 99);
2413
2414 test_outside(r, p);
2415 }
2416 {
2417 auto r = IRect::MakeXYWH(100, 100, 100, 100);
2418 auto p = IPoint(199, 199);
2419
2420 test_inside(r, p);
2421 }
2422
2423 {
2424 auto r = IRect::MakeMaximum();
2425 auto p = IPoint(199, 199);
2426
2427 test_inside(r, p);
2428 }
2429}
static constexpr R flip_lrtb(R rect)
IRect64 IRect
Definition: rect.h:772

◆ TEST() [246/377]

impeller::testing::TEST ( RectTest  ,
IRectContainsIPoint   
)

Definition at line 2193 of file rect_unittests.cc.

2193 {
2194 auto check_empty_flips = [](const IRect& rect, const IPoint& point,
2195 const std::string& label) {
2196 ASSERT_FALSE(rect.IsEmpty());
2197
2198 EXPECT_FALSE(flip_lr(rect).Contains(point)) << label;
2199 EXPECT_FALSE(flip_tb(rect).Contains(point)) << label;
2200 EXPECT_FALSE(flip_lrtb(rect).Contains(point)) << label;
2201 };
2202
2203 auto test_inside = [&check_empty_flips](const IRect& rect,
2204 const IPoint& point) {
2205 ASSERT_FALSE(rect.IsEmpty()) << rect;
2206
2207 std::stringstream stream;
2208 stream << rect << " contains " << point;
2209 auto label = stream.str();
2210
2211 EXPECT_TRUE(rect.Contains(point)) << label;
2212 check_empty_flips(rect, point, label);
2213 };
2214
2215 auto test_outside = [&check_empty_flips](const IRect& rect,
2216 const IPoint& point) {
2217 ASSERT_FALSE(rect.IsEmpty()) << rect;
2218
2219 std::stringstream stream;
2220 stream << rect << " contains " << point;
2221 auto label = stream.str();
2222
2223 EXPECT_FALSE(rect.Contains(point)) << label;
2224 check_empty_flips(rect, point, label);
2225 };
2226
2227 {
2228 // Origin is inclusive
2229 auto r = IRect::MakeXYWH(100, 100, 100, 100);
2230 auto p = IPoint(100, 100);
2231
2232 test_inside(r, p);
2233 }
2234 {
2235 // Size is exclusive
2236 auto r = IRect::MakeXYWH(100, 100, 100, 100);
2237 auto p = IPoint(200, 200);
2238
2239 test_outside(r, p);
2240 }
2241 {
2242 auto r = IRect::MakeXYWH(100, 100, 100, 100);
2243 auto p = IPoint(99, 99);
2244
2245 test_outside(r, p);
2246 }
2247 {
2248 auto r = IRect::MakeXYWH(100, 100, 100, 100);
2249 auto p = IPoint(199, 199);
2250
2251 test_inside(r, p);
2252 }
2253
2254 {
2255 auto r = IRect::MakeMaximum();
2256 auto p = IPoint(199, 199);
2257
2258 test_inside(r, p);
2259 }
2260}
bool Contains(const Container &container, const Value &value)

◆ TEST() [247/377]

impeller::testing::TEST ( RectTest  ,
IRectContainsIRect   
)

Definition at line 2546 of file rect_unittests.cc.

2546 {
2547 auto check_empty_flips = [](const IRect& a, const IRect& b,
2548 const std::string& label) {
2549 ASSERT_FALSE(a.IsEmpty());
2550 // test b rects are allowed to have 0 w/h, but not be backwards
2551 ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2552
2553 // unflipped a vs flipped (empty) b yields true
2554 EXPECT_TRUE(a.Contains(flip_lr(b))) << label;
2555 EXPECT_TRUE(a.Contains(flip_tb(b))) << label;
2556 EXPECT_TRUE(a.Contains(flip_lrtb(b))) << label;
2557
2558 // flipped (empty) a vs unflipped b yields false
2559 EXPECT_FALSE(flip_lr(a).Contains(b)) << label;
2560 EXPECT_FALSE(flip_tb(a).Contains(b)) << label;
2561 EXPECT_FALSE(flip_lrtb(a).Contains(b)) << label;
2562
2563 // flipped (empty) a vs flipped (empty) b yields empty
2564 EXPECT_FALSE(flip_lr(a).Contains(flip_lr(b))) << label;
2565 EXPECT_FALSE(flip_tb(a).Contains(flip_tb(b))) << label;
2566 EXPECT_FALSE(flip_lrtb(a).Contains(flip_lrtb(b))) << label;
2567 };
2568
2569 auto test_inside = [&check_empty_flips](const IRect& a, const IRect& b) {
2570 ASSERT_FALSE(a.IsEmpty()) << a;
2571 // test b rects are allowed to have 0 w/h, but not be backwards
2572 ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2573
2574 std::stringstream stream;
2575 stream << a << " contains " << b;
2576 auto label = stream.str();
2577
2578 EXPECT_TRUE(a.Contains(b)) << label;
2579 check_empty_flips(a, b, label);
2580 };
2581
2582 auto test_not_inside = [&check_empty_flips](const IRect& a, const IRect& b) {
2583 ASSERT_FALSE(a.IsEmpty()) << a;
2584 // If b was empty, it would be contained and should not be tested with
2585 // this function - use |test_inside| instead.
2586 ASSERT_FALSE(b.IsEmpty()) << b;
2587
2588 std::stringstream stream;
2589 stream << a << " contains " << b;
2590 auto label = stream.str();
2591
2592 EXPECT_FALSE(a.Contains(b)) << label;
2593 check_empty_flips(a, b, label);
2594 };
2595
2596 {
2597 auto a = IRect::MakeXYWH(100, 100, 100, 100);
2598
2599 test_inside(a, a);
2600 }
2601 {
2602 auto a = IRect::MakeXYWH(100, 100, 100, 100);
2603 auto b = IRect::MakeXYWH(0, 0, 0, 0);
2604
2605 test_inside(a, b);
2606 }
2607 {
2608 auto a = IRect::MakeXYWH(100, 100, 100, 100);
2609 auto b = IRect::MakeXYWH(150, 150, 20, 20);
2610
2611 test_inside(a, b);
2612 }
2613 {
2614 auto a = IRect::MakeXYWH(100, 100, 100, 100);
2615 auto b = IRect::MakeXYWH(150, 150, 100, 100);
2616
2617 test_not_inside(a, b);
2618 }
2619 {
2620 auto a = IRect::MakeXYWH(100, 100, 100, 100);
2621 auto b = IRect::MakeXYWH(50, 50, 100, 100);
2622
2623 test_not_inside(a, b);
2624 }
2625 {
2626 auto a = IRect::MakeXYWH(100, 100, 100, 100);
2627 auto b = IRect::MakeXYWH(0, 0, 300, 300);
2628
2629 test_not_inside(a, b);
2630 }
2631 {
2632 auto a = IRect::MakeMaximum();
2633 auto b = IRect::MakeXYWH(0, 0, 300, 300);
2634
2635 test_inside(a, b);
2636 }
2637}

◆ TEST() [248/377]

impeller::testing::TEST ( RectTest  ,
IRectCopy   
)

Definition at line 641 of file rect_unittests.cc.

641 {
642 IRect rect = IRect::MakeLTRB(5, 10, 20, 25);
643 IRect copy = rect;
644
645 EXPECT_EQ(rect, copy);
646 EXPECT_EQ(copy.GetLeft(), 5);
647 EXPECT_EQ(copy.GetTop(), 10);
648 EXPECT_EQ(copy.GetRight(), 20);
649 EXPECT_EQ(copy.GetBottom(), 25);
650 EXPECT_EQ(copy.GetX(), 5);
651 EXPECT_EQ(copy.GetY(), 10);
652 EXPECT_EQ(copy.GetWidth(), 15);
653 EXPECT_EQ(copy.GetHeight(), 15);
654 EXPECT_FALSE(copy.IsEmpty());
655}
Definition: copy.py:1

◆ TEST() [249/377]

impeller::testing::TEST ( RectTest  ,
IRectCutOut   
)

Definition at line 2791 of file rect_unittests.cc.

2791 {
2792 IRect cull_rect = IRect::MakeLTRB(20, 20, 40, 40);
2793
2794 auto check_empty_flips = [&cull_rect](const IRect& diff_rect,
2795 const std::string& label) {
2796 EXPECT_FALSE(diff_rect.IsEmpty());
2797 EXPECT_FALSE(cull_rect.IsEmpty());
2798
2799 // unflipped cull_rect vs flipped(empty) diff_rect
2800 // == cull_rect
2801 EXPECT_TRUE(cull_rect.Cutout(flip_lr(diff_rect)).has_value()) << label;
2802 EXPECT_EQ(cull_rect.Cutout(flip_lr(diff_rect)), cull_rect) << label;
2803 EXPECT_TRUE(cull_rect.Cutout(flip_tb(diff_rect)).has_value()) << label;
2804 EXPECT_EQ(cull_rect.Cutout(flip_tb(diff_rect)), cull_rect) << label;
2805 EXPECT_TRUE(cull_rect.Cutout(flip_lrtb(diff_rect)).has_value()) << label;
2806 EXPECT_EQ(cull_rect.Cutout(flip_lrtb(diff_rect)), cull_rect) << label;
2807
2808 // flipped(empty) cull_rect vs flipped(empty) diff_rect
2809 // == empty
2810 EXPECT_FALSE(flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2811 EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2812 EXPECT_FALSE(flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2813 EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2814 EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2815 EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2816
2817 // flipped(empty) cull_rect vs unflipped diff_rect
2818 // == empty
2819 EXPECT_FALSE(flip_lr(cull_rect).Cutout(flip_lr(diff_rect)).has_value())
2820 << label;
2821 EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(flip_lr(diff_rect)), IRect())
2822 << label;
2823 EXPECT_FALSE(flip_tb(cull_rect).Cutout(flip_tb(diff_rect)).has_value())
2824 << label;
2825 EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(flip_tb(diff_rect)), IRect())
2826 << label;
2827 EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(flip_lrtb(diff_rect)).has_value())
2828 << label;
2829 EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(flip_lrtb(diff_rect)), IRect())
2830 << label;
2831 };
2832
2833 auto non_reducing = [&cull_rect, &check_empty_flips](
2834 const IRect& diff_rect, const std::string& label) {
2835 EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2836 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2837 check_empty_flips(diff_rect, label);
2838 };
2839
2840 auto reducing = [&cull_rect, &check_empty_flips](const IRect& diff_rect,
2841 const IRect& result_rect,
2842 const std::string& label) {
2843 EXPECT_TRUE(!result_rect.IsEmpty());
2844 EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2845 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2846 check_empty_flips(diff_rect, label);
2847 };
2848
2849 auto emptying = [&cull_rect, &check_empty_flips](const IRect& diff_rect,
2850 const std::string& label) {
2851 EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2852 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), IRect()) << label;
2853 check_empty_flips(diff_rect, label);
2854 };
2855
2856 // Skim the corners and edge
2857 non_reducing(IRect::MakeLTRB(10, 10, 20, 20), "outside UL corner");
2858 non_reducing(IRect::MakeLTRB(20, 10, 40, 20), "Above");
2859 non_reducing(IRect::MakeLTRB(40, 10, 50, 20), "outside UR corner");
2860 non_reducing(IRect::MakeLTRB(40, 20, 50, 40), "Right");
2861 non_reducing(IRect::MakeLTRB(40, 40, 50, 50), "outside LR corner");
2862 non_reducing(IRect::MakeLTRB(20, 40, 40, 50), "Below");
2863 non_reducing(IRect::MakeLTRB(10, 40, 20, 50), "outside LR corner");
2864 non_reducing(IRect::MakeLTRB(10, 20, 20, 40), "Left");
2865
2866 // Overlap corners
2867 non_reducing(IRect::MakeLTRB(15, 15, 25, 25), "covering UL corner");
2868 non_reducing(IRect::MakeLTRB(35, 15, 45, 25), "covering UR corner");
2869 non_reducing(IRect::MakeLTRB(35, 35, 45, 45), "covering LR corner");
2870 non_reducing(IRect::MakeLTRB(15, 35, 25, 45), "covering LL corner");
2871
2872 // Overlap edges, but not across an entire side
2873 non_reducing(IRect::MakeLTRB(20, 15, 39, 25), "Top edge left-biased");
2874 non_reducing(IRect::MakeLTRB(21, 15, 40, 25), "Top edge, right biased");
2875 non_reducing(IRect::MakeLTRB(35, 20, 45, 39), "Right edge, top-biased");
2876 non_reducing(IRect::MakeLTRB(35, 21, 45, 40), "Right edge, bottom-biased");
2877 non_reducing(IRect::MakeLTRB(20, 35, 39, 45), "Bottom edge, left-biased");
2878 non_reducing(IRect::MakeLTRB(21, 35, 40, 45), "Bottom edge, right-biased");
2879 non_reducing(IRect::MakeLTRB(15, 20, 25, 39), "Left edge, top-biased");
2880 non_reducing(IRect::MakeLTRB(15, 21, 25, 40), "Left edge, bottom-biased");
2881
2882 // Slice all the way through the middle
2883 non_reducing(IRect::MakeLTRB(25, 15, 35, 45), "Vertical interior slice");
2884 non_reducing(IRect::MakeLTRB(15, 25, 45, 35), "Horizontal interior slice");
2885
2886 // Slice off each edge
2887 reducing(IRect::MakeLTRB(20, 15, 40, 25), //
2888 IRect::MakeLTRB(20, 25, 40, 40), //
2889 "Slice off top");
2890 reducing(IRect::MakeLTRB(35, 20, 45, 40), //
2891 IRect::MakeLTRB(20, 20, 35, 40), //
2892 "Slice off right");
2893 reducing(IRect::MakeLTRB(20, 35, 40, 45), //
2894 IRect::MakeLTRB(20, 20, 40, 35), //
2895 "Slice off bottom");
2896 reducing(IRect::MakeLTRB(15, 20, 25, 40), //
2897 IRect::MakeLTRB(25, 20, 40, 40), //
2898 "Slice off left");
2899
2900 // cull rect contains diff rect
2901 non_reducing(IRect::MakeLTRB(21, 21, 39, 39), "Contained, non-covering");
2902
2903 // cull rect equals diff rect
2904 emptying(cull_rect, "Perfectly covering");
2905
2906 // diff rect contains cull rect
2907 emptying(IRect::MakeLTRB(15, 15, 45, 45), "Smothering");
2908}
constexpr std::optional< TRect< T > > Cutout(const TRect &o) const
Returns the new boundary rectangle that would result from this rectangle being cut out by the specifi...
Definition: rect.h:544
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: rect.h:287
constexpr TRect CutoutOrEmpty(const TRect &o) const
Definition: rect.h:584

◆ TEST() [250/377]

impeller::testing::TEST ( RectTest  ,
IRectDefaultConstructor   
)

Definition at line 59 of file rect_unittests.cc.

59 {
60 IRect rect = IRect();
61
62 EXPECT_EQ(rect.GetLeft(), 0);
63 EXPECT_EQ(rect.GetTop(), 0);
64 EXPECT_EQ(rect.GetRight(), 0);
65 EXPECT_EQ(rect.GetBottom(), 0);
66 EXPECT_EQ(rect.GetX(), 0);
67 EXPECT_EQ(rect.GetY(), 0);
68 EXPECT_EQ(rect.GetWidth(), 0);
69 EXPECT_EQ(rect.GetHeight(), 0);
70 EXPECT_TRUE(rect.IsEmpty());
71}

◆ TEST() [251/377]

impeller::testing::TEST ( RectTest  ,
IRectDoesNotIntersectEmpty   
)

Definition at line 794 of file rect_unittests.cc.

794 {
795 IRect rect = IRect::MakeLTRB(50, 50, 100, 100);
796
797 auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t b,
798 const std::string& label) {
799 EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(l, b, r, t)))
800 << label << " with Top/Bottom swapped";
801 EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(r, b, l, t)))
802 << label << " with Left/Right swapped";
803 EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(r, t, l, b)))
804 << label << " with all sides swapped";
805 };
806
807 test(20, 20, 30, 30, "Above and Left");
808 test(70, 20, 80, 30, "Above");
809 test(120, 20, 130, 30, "Above and Right");
810 test(120, 70, 130, 80, "Right");
811 test(120, 120, 130, 130, "Below and Right");
812 test(70, 120, 80, 130, "Below");
813 test(20, 120, 30, 130, "Below and Left");
814 test(20, 70, 30, 80, "Left");
815
816 test(70, 70, 80, 80, "Inside");
817
818 test(40, 70, 60, 80, "Straddling Left");
819 test(70, 40, 80, 60, "Straddling Top");
820 test(90, 70, 110, 80, "Straddling Right");
821 test(70, 90, 80, 110, "Straddling Bottom");
822}

◆ TEST() [252/377]

impeller::testing::TEST ( RectTest  ,
IRectEmptyDeclaration   
)

Definition at line 29 of file rect_unittests.cc.

29 {
30 IRect rect;
31
32 EXPECT_EQ(rect.GetLeft(), 0);
33 EXPECT_EQ(rect.GetTop(), 0);
34 EXPECT_EQ(rect.GetRight(), 0);
35 EXPECT_EQ(rect.GetBottom(), 0);
36 EXPECT_EQ(rect.GetX(), 0);
37 EXPECT_EQ(rect.GetY(), 0);
38 EXPECT_EQ(rect.GetWidth(), 0);
39 EXPECT_EQ(rect.GetHeight(), 0);
40 EXPECT_TRUE(rect.IsEmpty());
41 // EXPECT_TRUE(rect.IsFinite()); // should fail to compile
42}

◆ TEST() [253/377]

impeller::testing::TEST ( RectTest  ,
IRectExpand   
)

Definition at line 1238 of file rect_unittests.cc.

1238 {
1239 auto rect = IRect::MakeLTRB(100, 100, 200, 200);
1240
1241 // Expand(T amount)
1242 EXPECT_EQ(rect.Expand(10), IRect::MakeLTRB(90, 90, 210, 210));
1243 EXPECT_EQ(rect.Expand(-10), IRect::MakeLTRB(110, 110, 190, 190));
1244
1245 // Expand(amount, amount)
1246 EXPECT_EQ(rect.Expand(10, 10), IRect::MakeLTRB(90, 90, 210, 210));
1247 EXPECT_EQ(rect.Expand(10, -10), IRect::MakeLTRB(90, 110, 210, 190));
1248 EXPECT_EQ(rect.Expand(-10, 10), IRect::MakeLTRB(110, 90, 190, 210));
1249 EXPECT_EQ(rect.Expand(-10, -10), IRect::MakeLTRB(110, 110, 190, 190));
1250
1251 // Expand(amount, amount, amount, amount)
1252 EXPECT_EQ(rect.Expand(10, 20, 30, 40), IRect::MakeLTRB(90, 80, 230, 240));
1253 EXPECT_EQ(rect.Expand(-10, 20, 30, 40), IRect::MakeLTRB(110, 80, 230, 240));
1254 EXPECT_EQ(rect.Expand(10, -20, 30, 40), IRect::MakeLTRB(90, 120, 230, 240));
1255 EXPECT_EQ(rect.Expand(10, 20, -30, 40), IRect::MakeLTRB(90, 80, 170, 240));
1256 EXPECT_EQ(rect.Expand(10, 20, 30, -40), IRect::MakeLTRB(90, 80, 230, 160));
1257
1258 // Expand(IPoint amount)
1259 EXPECT_EQ(rect.Expand(IPoint{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
1260 EXPECT_EQ(rect.Expand(IPoint{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
1261 EXPECT_EQ(rect.Expand(IPoint{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
1262 EXPECT_EQ(rect.Expand(IPoint{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
1263
1264 // Expand(ISize amount)
1265 EXPECT_EQ(rect.Expand(ISize{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
1266 EXPECT_EQ(rect.Expand(ISize{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
1267 EXPECT_EQ(rect.Expand(ISize{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
1268 EXPECT_EQ(rect.Expand(ISize{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
1269}

◆ TEST() [254/377]

impeller::testing::TEST ( RectTest  ,
IRectFromIRect   
)

Definition at line 616 of file rect_unittests.cc.

616 {
617 EXPECT_EQ(IRect(IRect::MakeXYWH(2, 3, 7, 15)), //
618 IRect::MakeXYWH(2, 3, 7, 15));
619 EXPECT_EQ(IRect(IRect::MakeLTRB(2, 3, 7, 15)), //
620 IRect::MakeLTRB(2, 3, 7, 15));
621}

◆ TEST() [255/377]

impeller::testing::TEST ( RectTest  ,
IRectGetNormalizingTransform   
)

Definition at line 1077 of file rect_unittests.cc.

1077 {
1078 {
1079 // Checks for expected matrix values
1080
1081 auto r = IRect::MakeXYWH(100, 200, 200, 400);
1082
1083 EXPECT_EQ(r.GetNormalizingTransform(),
1084 Matrix::MakeScale({0.005, 0.0025, 1.0}) *
1085 Matrix::MakeTranslation({-100, -200}));
1086 }
1087
1088 {
1089 // Checks for expected transform of points relative to the rect
1090
1091 auto r = IRect::MakeLTRB(300, 500, 400, 700);
1092 auto m = r.GetNormalizingTransform();
1093
1094 // The 4 corners of the rect => (0, 0) to (1, 1)
1095 EXPECT_EQ(m * Point(300, 500), Point(0, 0));
1096 EXPECT_EQ(m * Point(400, 500), Point(1, 0));
1097 EXPECT_EQ(m * Point(400, 700), Point(1, 1));
1098 EXPECT_EQ(m * Point(300, 700), Point(0, 1));
1099
1100 // The center => (0.5, 0.5)
1101 EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
1102
1103 // Outside the 4 corners => (-1, -1) to (2, 2)
1104 EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
1105 EXPECT_EQ(m * Point(500, 300), Point(2, -1));
1106 EXPECT_EQ(m * Point(500, 900), Point(2, 2));
1107 EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
1108 }
1109
1110 {
1111 // Checks for behavior with empty rects
1112
1113 auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
1114
1115 // Empty for width and/or height == 0
1116 EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1117 EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1118 EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1119
1120 // Empty for width and/or height < 0
1121 EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1122 EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1123 EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1124 }
1125}

◆ TEST() [256/377]

impeller::testing::TEST ( RectTest  ,
IRectIntersection   
)

Definition at line 1751 of file rect_unittests.cc.

1751 {
1752 auto check_empty_flips = [](const IRect& a, const IRect& b,
1753 const std::string& label) {
1754 ASSERT_FALSE(a.IsEmpty());
1755 // b is allowed to be empty
1756
1757 // unflipped a vs flipped (empty) b yields a
1758 EXPECT_FALSE(a.Intersection(flip_lr(b)).has_value()) << label;
1759 EXPECT_FALSE(a.Intersection(flip_tb(b)).has_value()) << label;
1760 EXPECT_FALSE(a.Intersection(flip_lrtb(b)).has_value()) << label;
1761
1762 // flipped (empty) a vs unflipped b yields b
1763 EXPECT_FALSE(flip_lr(a).Intersection(b).has_value()) << label;
1764 EXPECT_FALSE(flip_tb(a).Intersection(b).has_value()) << label;
1765 EXPECT_FALSE(flip_lrtb(a).Intersection(b).has_value()) << label;
1766
1767 // flipped (empty) a vs flipped (empty) b yields empty
1768 EXPECT_FALSE(flip_lr(a).Intersection(flip_lr(b)).has_value()) << label;
1769 EXPECT_FALSE(flip_tb(a).Intersection(flip_tb(b)).has_value()) << label;
1770 EXPECT_FALSE(flip_lrtb(a).Intersection(flip_lrtb(b)).has_value()) << label;
1771 };
1772
1773 auto test_non_empty = [&check_empty_flips](const IRect& a, const IRect& b,
1774 const IRect& result) {
1775 ASSERT_FALSE(a.IsEmpty()) << a;
1776 // b is allowed to be empty
1777
1778 std::stringstream stream;
1779 stream << a << " union " << b;
1780 auto label = stream.str();
1781
1782 EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1783 EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1784 EXPECT_EQ(a.Intersection(b), result) << label;
1785 EXPECT_EQ(b.Intersection(a), result) << label;
1786 check_empty_flips(a, b, label);
1787 };
1788
1789 auto test_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
1790 ASSERT_FALSE(a.IsEmpty()) << a;
1791 // b is allowed to be empty
1792
1793 std::stringstream stream;
1794 stream << a << " union " << b;
1795 auto label = stream.str();
1796
1797 EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1798 EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1799 check_empty_flips(a, b, label);
1800 };
1801
1802 {
1803 auto a = IRect::MakeXYWH(100, 100, 100, 100);
1804 auto b = IRect::MakeXYWH(0, 0, 0, 0);
1805
1806 test_empty(a, b);
1807 }
1808
1809 {
1810 auto a = IRect::MakeXYWH(100, 100, 100, 100);
1811 auto b = IRect::MakeXYWH(10, 10, 0, 0);
1812
1813 test_empty(a, b);
1814 }
1815
1816 {
1817 auto a = IRect::MakeXYWH(0, 0, 100, 100);
1818 auto b = IRect::MakeXYWH(10, 10, 100, 100);
1819 auto expected = IRect::MakeXYWH(10, 10, 90, 90);
1820
1821 test_non_empty(a, b, expected);
1822 }
1823
1824 {
1825 auto a = IRect::MakeXYWH(0, 0, 100, 100);
1826 auto b = IRect::MakeXYWH(100, 100, 100, 100);
1827
1828 test_empty(a, b);
1829 }
1830
1831 {
1832 auto a = IRect::MakeMaximum();
1833 auto b = IRect::MakeXYWH(10, 10, 300, 300);
1834
1835 test_non_empty(a, b, b);
1836 }
1837
1838 {
1839 auto a = IRect::MakeMaximum();
1840 auto b = IRect::MakeMaximum();
1841
1842 test_non_empty(a, b, IRect::MakeMaximum());
1843 }
1844}
static void test_empty(skiatest::Reporter *reporter)
Definition: AAClipTest.cpp:233

◆ TEST() [257/377]

impeller::testing::TEST ( RectTest  ,
IRectIntersectsWithRect   
)

Definition at line 2016 of file rect_unittests.cc.

2016 {
2017 auto check_empty_flips = [](const IRect& a, const IRect& b,
2018 const std::string& label) {
2019 ASSERT_FALSE(a.IsEmpty());
2020 // b is allowed to be empty
2021
2022 // unflipped a vs flipped (empty) b yields a
2023 EXPECT_FALSE(a.IntersectsWithRect(flip_lr(b))) << label;
2024 EXPECT_FALSE(a.IntersectsWithRect(flip_tb(b))) << label;
2025 EXPECT_FALSE(a.IntersectsWithRect(flip_lrtb(b))) << label;
2026
2027 // flipped (empty) a vs unflipped b yields b
2028 EXPECT_FALSE(flip_lr(a).IntersectsWithRect(b)) << label;
2029 EXPECT_FALSE(flip_tb(a).IntersectsWithRect(b)) << label;
2030 EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(b)) << label;
2031
2032 // flipped (empty) a vs flipped (empty) b yields empty
2033 EXPECT_FALSE(flip_lr(a).IntersectsWithRect(flip_lr(b))) << label;
2034 EXPECT_FALSE(flip_tb(a).IntersectsWithRect(flip_tb(b))) << label;
2035 EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(flip_lrtb(b))) << label;
2036 };
2037
2038 auto test_non_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
2039 ASSERT_FALSE(a.IsEmpty()) << a;
2040 // b is allowed to be empty
2041
2042 std::stringstream stream;
2043 stream << a << " union " << b;
2044 auto label = stream.str();
2045
2046 EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
2047 EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
2048 check_empty_flips(a, b, label);
2049 };
2050
2051 auto test_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
2052 ASSERT_FALSE(a.IsEmpty()) << a;
2053 // b is allowed to be empty
2054
2055 std::stringstream stream;
2056 stream << a << " union " << b;
2057 auto label = stream.str();
2058
2059 EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
2060 EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
2061 check_empty_flips(a, b, label);
2062 };
2063
2064 {
2065 auto a = IRect::MakeXYWH(100, 100, 100, 100);
2066 auto b = IRect::MakeXYWH(0, 0, 0, 0);
2067
2068 test_empty(a, b);
2069 }
2070
2071 {
2072 auto a = IRect::MakeXYWH(100, 100, 100, 100);
2073 auto b = IRect::MakeXYWH(10, 10, 0, 0);
2074
2075 test_empty(a, b);
2076 }
2077
2078 {
2079 auto a = IRect::MakeXYWH(0, 0, 100, 100);
2080 auto b = IRect::MakeXYWH(10, 10, 100, 100);
2081
2082 test_non_empty(a, b);
2083 }
2084
2085 {
2086 auto a = IRect::MakeXYWH(0, 0, 100, 100);
2087 auto b = IRect::MakeXYWH(100, 100, 100, 100);
2088
2089 test_empty(a, b);
2090 }
2091
2092 {
2093 auto a = IRect::MakeMaximum();
2094 auto b = IRect::MakeXYWH(10, 10, 100, 100);
2095
2096 test_non_empty(a, b);
2097 }
2098
2099 {
2100 auto a = IRect::MakeMaximum();
2101 auto b = IRect::MakeMaximum();
2102
2103 test_non_empty(a, b);
2104 }
2105}

◆ TEST() [258/377]

impeller::testing::TEST ( RectTest  ,
IRectMakeMaximum   
)

Definition at line 593 of file rect_unittests.cc.

593 {
594 IRect rect = IRect::MakeMaximum();
597
598 EXPECT_EQ(rect.GetLeft(), min);
599 EXPECT_EQ(rect.GetTop(), min);
600 EXPECT_EQ(rect.GetRight(), max);
601 EXPECT_EQ(rect.GetBottom(), max);
602 EXPECT_EQ(rect.GetX(), min);
603 EXPECT_EQ(rect.GetY(), min);
604 EXPECT_EQ(rect.GetWidth(), max);
605 EXPECT_EQ(rect.GetHeight(), max);
606 EXPECT_FALSE(rect.IsEmpty());
607}
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

◆ TEST() [259/377]

impeller::testing::TEST ( RectTest  ,
IRectOriginSizeXYWHGetters   
)

Definition at line 683 of file rect_unittests.cc.

683 {
684 {
685 IRect r = IRect::MakeOriginSize({10, 20}, {50, 40});
686 EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
687 EXPECT_EQ(r.GetSize(), ISize(50, 40));
688 EXPECT_EQ(r.GetX(), 10);
689 EXPECT_EQ(r.GetY(), 20);
690 EXPECT_EQ(r.GetWidth(), 50);
691 EXPECT_EQ(r.GetHeight(), 40);
692 auto expected_array = std::array<int64_t, 4>{10, 20, 50, 40};
693 EXPECT_EQ(r.GetXYWH(), expected_array);
694 }
695
696 {
697 IRect r = IRect::MakeLTRB(10, 20, 50, 40);
698 EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
699 EXPECT_EQ(r.GetSize(), ISize(40, 20));
700 EXPECT_EQ(r.GetX(), 10);
701 EXPECT_EQ(r.GetY(), 20);
702 EXPECT_EQ(r.GetWidth(), 40);
703 EXPECT_EQ(r.GetHeight(), 20);
704 auto expected_array = std::array<int64_t, 4>{10, 20, 40, 20};
705 EXPECT_EQ(r.GetXYWH(), expected_array);
706 }
707}
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition: rect.h:327
constexpr TSize< Type > GetSize() const
Returns the size of the rectangle which may be negative in either width or height and may have been c...
Definition: rect.h:317
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition: rect.h:337
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition: rect.h:323
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition: rect.h:331
constexpr std::array< T, 4 > GetXYWH() const
Get the x, y coordinates of the origin and the width and height of the rectangle in an array.
Definition: rect.h:384
constexpr TPoint< Type > GetOrigin() const
Returns the upper left corner of the rectangle as specified by the left/top or x/y values when it was...
Definition: rect.h:310

◆ TEST() [260/377]

impeller::testing::TEST ( RectTest  ,
IRectOverflowLTRB   
)

Definition at line 478 of file rect_unittests.cc.

478 {
481
482 // 4 cases
483 // negative l, r near max takes width past max
484 // positive l, r near min takes width below min
485 // negative t, b near max takes width past max
486 // positive t, b near min takes width below min
487
488 {
489 IRect rect = IRect::MakeLTRB(-10, 10, max - 5, 26);
490
491 EXPECT_EQ(rect.GetLeft(), -10);
492 EXPECT_EQ(rect.GetTop(), 10);
493 EXPECT_EQ(rect.GetRight(), max - 5);
494 EXPECT_EQ(rect.GetBottom(), 26);
495 EXPECT_EQ(rect.GetX(), -10);
496 EXPECT_EQ(rect.GetY(), 10);
497 EXPECT_EQ(rect.GetWidth(), max);
498 EXPECT_EQ(rect.GetHeight(), 16);
499 EXPECT_FALSE(rect.IsEmpty());
500 }
501
502 {
503 IRect rect = IRect::MakeLTRB(10, 10, min + 5, 26);
504
505 EXPECT_EQ(rect.GetLeft(), 10);
506 EXPECT_EQ(rect.GetTop(), 10);
507 EXPECT_EQ(rect.GetRight(), min + 5);
508 EXPECT_EQ(rect.GetBottom(), 26);
509 EXPECT_EQ(rect.GetX(), 10);
510 EXPECT_EQ(rect.GetY(), 10);
511 EXPECT_EQ(rect.GetWidth(), min);
512 EXPECT_EQ(rect.GetHeight(), 16);
513 EXPECT_TRUE(rect.IsEmpty());
514 }
515
516 {
517 IRect rect = IRect::MakeLTRB(5, -10, 15, max - 5);
518
519 EXPECT_EQ(rect.GetLeft(), 5);
520 EXPECT_EQ(rect.GetTop(), -10);
521 EXPECT_EQ(rect.GetRight(), 15);
522 EXPECT_EQ(rect.GetBottom(), max - 5);
523 EXPECT_EQ(rect.GetX(), 5);
524 EXPECT_EQ(rect.GetY(), -10);
525 EXPECT_EQ(rect.GetWidth(), 10);
526 EXPECT_EQ(rect.GetHeight(), max);
527 EXPECT_FALSE(rect.IsEmpty());
528 }
529
530 {
531 IRect rect = IRect::MakeLTRB(5, 10, 15, min + 5);
532
533 EXPECT_EQ(rect.GetLeft(), 5);
534 EXPECT_EQ(rect.GetTop(), 10);
535 EXPECT_EQ(rect.GetRight(), 15);
536 EXPECT_EQ(rect.GetBottom(), min + 5);
537 EXPECT_EQ(rect.GetX(), 5);
538 EXPECT_EQ(rect.GetY(), 10);
539 EXPECT_EQ(rect.GetWidth(), 10);
540 EXPECT_EQ(rect.GetHeight(), min);
541 EXPECT_TRUE(rect.IsEmpty());
542 }
543}

◆ TEST() [261/377]

impeller::testing::TEST ( RectTest  ,
IRectOverflowXYWH   
)

Definition at line 272 of file rect_unittests.cc.

272 {
275
276 // 4 cases
277 // x near max, positive w takes it past max
278 // x near min, negative w takes it below min
279 // y near max, positive h takes it past max
280 // y near min, negative h takes it below min
281
282 {
283 IRect rect = IRect::MakeXYWH(max - 5, 10, 10, 16);
284
285 EXPECT_EQ(rect.GetLeft(), max - 5);
286 EXPECT_EQ(rect.GetTop(), 10);
287 EXPECT_EQ(rect.GetRight(), max);
288 EXPECT_EQ(rect.GetBottom(), 26);
289 EXPECT_EQ(rect.GetX(), max - 5);
290 EXPECT_EQ(rect.GetY(), 10);
291 EXPECT_EQ(rect.GetWidth(), 5);
292 EXPECT_EQ(rect.GetHeight(), 16);
293 EXPECT_FALSE(rect.IsEmpty());
294 }
295
296 {
297 IRect rect = IRect::MakeXYWH(min + 5, 10, -10, 16);
298
299 EXPECT_EQ(rect.GetLeft(), min + 5);
300 EXPECT_EQ(rect.GetTop(), 10);
301 EXPECT_EQ(rect.GetRight(), min);
302 EXPECT_EQ(rect.GetBottom(), 26);
303 EXPECT_EQ(rect.GetX(), min + 5);
304 EXPECT_EQ(rect.GetY(), 10);
305 EXPECT_EQ(rect.GetWidth(), -5);
306 EXPECT_EQ(rect.GetHeight(), 16);
307 EXPECT_TRUE(rect.IsEmpty());
308 }
309
310 {
311 IRect rect = IRect::MakeXYWH(5, max - 10, 10, 16);
312
313 EXPECT_EQ(rect.GetLeft(), 5);
314 EXPECT_EQ(rect.GetTop(), max - 10);
315 EXPECT_EQ(rect.GetRight(), 15);
316 EXPECT_EQ(rect.GetBottom(), max);
317 EXPECT_EQ(rect.GetX(), 5);
318 EXPECT_EQ(rect.GetY(), max - 10);
319 EXPECT_EQ(rect.GetWidth(), 10);
320 EXPECT_EQ(rect.GetHeight(), 10);
321 EXPECT_FALSE(rect.IsEmpty());
322 }
323
324 {
325 IRect rect = IRect::MakeXYWH(5, min + 10, 10, -16);
326
327 EXPECT_EQ(rect.GetLeft(), 5);
328 EXPECT_EQ(rect.GetTop(), min + 10);
329 EXPECT_EQ(rect.GetRight(), 15);
330 EXPECT_EQ(rect.GetBottom(), min);
331 EXPECT_EQ(rect.GetX(), 5);
332 EXPECT_EQ(rect.GetY(), min + 10);
333 EXPECT_EQ(rect.GetWidth(), 10);
334 EXPECT_EQ(rect.GetHeight(), -10);
335 EXPECT_TRUE(rect.IsEmpty());
336 }
337}

◆ TEST() [262/377]

impeller::testing::TEST ( RectTest  ,
IRectRound   
)

Definition at line 3049 of file rect_unittests.cc.

3049 {
3050 {
3051 auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3052 auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3053 EXPECT_EQ(IRect::Round(r), ir);
3054 }
3055 {
3056 auto r = Rect::MakeLTRB(-100.4, -200.4, 300.4, 400.4);
3057 auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3058 EXPECT_EQ(IRect::Round(r), ir);
3059 }
3060 {
3061 auto r = Rect::MakeLTRB(-100.5, -200.5, 300.5, 400.5);
3062 auto ir = IRect::MakeLTRB(-101, -201, 301, 401);
3063 EXPECT_EQ(IRect::Round(r), ir);
3064 }
3065}

◆ TEST() [263/377]

impeller::testing::TEST ( RectTest  ,
IRectRoundOut   
)

Definition at line 3021 of file rect_unittests.cc.

3021 {
3022 {
3023 auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3024 auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3025 EXPECT_EQ(IRect::RoundOut(r), ir);
3026 }
3027 {
3028 auto r = Rect::MakeLTRB(-100.1, -200.1, 300.1, 400.1);
3029 auto ir = IRect::MakeLTRB(-101, -201, 301, 401);
3030 EXPECT_EQ(IRect::RoundOut(r), ir);
3031 }
3032}
SkIRect RoundOut(SkRect r)

◆ TEST() [264/377]

impeller::testing::TEST ( RectTest  ,
IRectScale   
)

Definition at line 929 of file rect_unittests.cc.

929 {
930 auto test1 = [](IRect rect, int64_t scale) {
931 IRect expected = IRect::MakeXYWH(rect.GetX() * scale, //
932 rect.GetY() * scale, //
933 rect.GetWidth() * scale, //
934 rect.GetHeight() * scale);
935
936 EXPECT_EQ(rect.Scale(scale), expected) //
937 << rect << " * " << scale;
938 EXPECT_EQ(rect.Scale(scale, scale), expected) //
939 << rect << " * " << scale;
940 EXPECT_EQ(rect.Scale(IPoint(scale, scale)), expected) //
941 << rect << " * " << scale;
942 EXPECT_EQ(rect.Scale(ISize(scale, scale)), expected) //
943 << rect << " * " << scale;
944 };
945
946 auto test2 = [&test1](IRect rect, int64_t scale_x, int64_t scale_y) {
947 IRect expected = IRect::MakeXYWH(rect.GetX() * scale_x, //
948 rect.GetY() * scale_y, //
949 rect.GetWidth() * scale_x, //
950 rect.GetHeight() * scale_y);
951
952 EXPECT_EQ(rect.Scale(scale_x, scale_y), expected) //
953 << rect << " * " << scale_x << ", " << scale_y;
954 EXPECT_EQ(rect.Scale(IPoint(scale_x, scale_y)), expected) //
955 << rect << " * " << scale_x << ", " << scale_y;
956 EXPECT_EQ(rect.Scale(ISize(scale_x, scale_y)), expected) //
957 << rect << " * " << scale_x << ", " << scale_y;
958
959 test1(rect, scale_x);
960 test1(rect, scale_y);
961 };
962
963 test2(IRect::MakeLTRB(10, 15, 100, 150), 2, 3);
964 test2(IRect::MakeLTRB(10, 15, 100, 150), 3, 2);
965 test2(IRect::MakeLTRB(10, 15, -100, 150), 2, 3);
966 test2(IRect::MakeLTRB(10, 15, 100, -150), 2, 3);
967 test2(IRect::MakeLTRB(10, 15, 100, 150), -2, 3);
968 test2(IRect::MakeLTRB(10, 15, 100, 150), 2, -3);
969}
static void test1(skiatest::Reporter *reporter, SkWriter32 *writer)

◆ TEST() [265/377]

impeller::testing::TEST ( RectTest  ,
IRectSimpleLTRB   
)

Definition at line 89 of file rect_unittests.cc.

89 {
90 IRect rect = IRect::MakeLTRB(5, 10, 20, 25);
91
92 EXPECT_EQ(rect.GetLeft(), 5);
93 EXPECT_EQ(rect.GetTop(), 10);
94 EXPECT_EQ(rect.GetRight(), 20);
95 EXPECT_EQ(rect.GetBottom(), 25);
96 EXPECT_EQ(rect.GetX(), 5);
97 EXPECT_EQ(rect.GetY(), 10);
98 EXPECT_EQ(rect.GetWidth(), 15);
99 EXPECT_EQ(rect.GetHeight(), 15);
100 EXPECT_FALSE(rect.IsEmpty());
101}

◆ TEST() [266/377]

impeller::testing::TEST ( RectTest  ,
IRectSimpleXYWH   
)

Definition at line 119 of file rect_unittests.cc.

119 {
120 IRect rect = IRect::MakeXYWH(5, 10, 15, 16);
121
122 EXPECT_EQ(rect.GetLeft(), 5);
123 EXPECT_EQ(rect.GetTop(), 10);
124 EXPECT_EQ(rect.GetRight(), 20);
125 EXPECT_EQ(rect.GetBottom(), 26);
126 EXPECT_EQ(rect.GetX(), 5);
127 EXPECT_EQ(rect.GetY(), 10);
128 EXPECT_EQ(rect.GetWidth(), 15);
129 EXPECT_EQ(rect.GetHeight(), 16);
130 EXPECT_FALSE(rect.IsEmpty());
131}

◆ TEST() [267/377]

impeller::testing::TEST ( RectTest  ,
IRectUnion   
)

Definition at line 1456 of file rect_unittests.cc.

1456 {
1457 auto check_empty_flips = [](const IRect& a, const IRect& b,
1458 const std::string& label) {
1459 ASSERT_FALSE(a.IsEmpty());
1460 // b is allowed to be empty
1461
1462 // unflipped a vs flipped (empty) b yields a
1463 EXPECT_EQ(a.Union(flip_lr(b)), a) << label;
1464 EXPECT_EQ(a.Union(flip_tb(b)), a) << label;
1465 EXPECT_EQ(a.Union(flip_lrtb(b)), a) << label;
1466
1467 // flipped (empty) a vs unflipped b yields b
1468 EXPECT_EQ(flip_lr(a).Union(b), b) << label;
1469 EXPECT_EQ(flip_tb(a).Union(b), b) << label;
1470 EXPECT_EQ(flip_lrtb(a).Union(b), b) << label;
1471
1472 // flipped (empty) a vs flipped (empty) b yields empty
1473 EXPECT_TRUE(flip_lr(a).Union(flip_lr(b)).IsEmpty()) << label;
1474 EXPECT_TRUE(flip_tb(a).Union(flip_tb(b)).IsEmpty()) << label;
1476 };
1477
1478 auto test = [&check_empty_flips](const IRect& a, const IRect& b,
1479 const IRect& result) {
1480 ASSERT_FALSE(a.IsEmpty()) << a;
1481 // b is allowed to be empty
1482
1483 std::stringstream stream;
1484 stream << a << " union " << b;
1485 auto label = stream.str();
1486
1487 EXPECT_EQ(a.Union(b), result) << label;
1488 EXPECT_EQ(b.Union(a), result) << label;
1489 check_empty_flips(a, b, label);
1490 };
1491
1492 {
1493 auto a = IRect::MakeXYWH(100, 100, 100, 100);
1494 auto b = IRect::MakeXYWH(0, 0, 0, 0);
1495 auto expected = IRect::MakeXYWH(100, 100, 100, 100);
1496 test(a, b, expected);
1497 }
1498
1499 {
1500 auto a = IRect::MakeXYWH(100, 100, 100, 100);
1501 auto b = IRect::MakeXYWH(0, 0, 1, 1);
1502 auto expected = IRect::MakeXYWH(0, 0, 200, 200);
1503 test(a, b, expected);
1504 }
1505
1506 {
1507 auto a = IRect::MakeXYWH(100, 100, 100, 100);
1508 auto b = IRect::MakeXYWH(10, 10, 1, 1);
1509 auto expected = IRect::MakeXYWH(10, 10, 190, 190);
1510 test(a, b, expected);
1511 }
1512
1513 {
1514 auto a = IRect::MakeXYWH(0, 0, 100, 100);
1515 auto b = IRect::MakeXYWH(10, 10, 100, 100);
1516 auto expected = IRect::MakeXYWH(0, 0, 110, 110);
1517 test(a, b, expected);
1518 }
1519
1520 {
1521 auto a = IRect::MakeXYWH(0, 0, 100, 100);
1522 auto b = IRect::MakeXYWH(100, 100, 100, 100);
1523 auto expected = IRect::MakeXYWH(0, 0, 200, 200);
1524 test(a, b, expected);
1525 }
1526}
static void Union(SkRegion *rgn, const SkIRect &rect)
Definition: RegionTest.cpp:27
bool EMSCRIPTEN_KEEPALIVE IsEmpty(const SkPath &path)

◆ TEST() [268/377]

impeller::testing::TEST ( RectTest  ,
IRectXYWHIsEmpty   
)

Definition at line 1151 of file rect_unittests.cc.

1151 {
1152 // Non-empty
1153 EXPECT_FALSE(IRect::MakeXYWH(1, 2, 10, 7).IsEmpty());
1154
1155 // Empty both width and height both 0 or negative, in all combinations
1156 EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 0).IsEmpty());
1157 EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, -1).IsEmpty());
1158 EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 0).IsEmpty());
1159 EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, -1).IsEmpty());
1160
1161 // Empty for 0 or negative width or height (but not both at the same time)
1162 EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, 0).IsEmpty());
1163 EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, -1).IsEmpty());
1164 EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 7).IsEmpty());
1165 EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 7).IsEmpty());
1166}

◆ TEST() [269/377]

impeller::testing::TEST ( RectTest  ,
IsSquare   
)

Definition at line 1182 of file rect_unittests.cc.

1182 {
1183 EXPECT_TRUE(Rect::MakeXYWH(10, 30, 20, 20).IsSquare());
1184 EXPECT_FALSE(Rect::MakeXYWH(10, 30, 20, 19).IsSquare());
1185 EXPECT_FALSE(Rect::MakeXYWH(10, 30, 19, 20).IsSquare());
1186 EXPECT_TRUE(Rect::MakeMaximum().IsSquare());
1187
1188 EXPECT_TRUE(IRect::MakeXYWH(10, 30, 20, 20).IsSquare());
1189 EXPECT_FALSE(IRect::MakeXYWH(10, 30, 20, 19).IsSquare());
1190 EXPECT_FALSE(IRect::MakeXYWH(10, 30, 19, 20).IsSquare());
1191 EXPECT_TRUE(IRect::MakeMaximum().IsSquare());
1192}

◆ TEST() [270/377]

impeller::testing::TEST ( RectTest  ,
MakePointBoundsQuad   
)

Definition at line 1168 of file rect_unittests.cc.

1168 {
1169 Quad quad = {
1170 Point(10, 10),
1171 Point(20, 10),
1172 Point(10, 20),
1173 Point(20, 20),
1174 };
1175 std::optional<Rect> bounds = Rect::MakePointBounds(quad);
1176 EXPECT_TRUE(bounds.has_value());
1177 if (bounds.has_value()) {
1178 EXPECT_TRUE(RectNear(bounds.value(), Rect::MakeLTRB(10, 10, 20, 20)));
1179 }
1180}
inline ::testing::AssertionResult RectNear(impeller::Rect a, impeller::Rect b)
Optional< SkRect > bounds
Definition: SkRecords.h:189
std::array< Point, 4 > Quad
Definition: point.h:327

◆ TEST() [271/377]

impeller::testing::TEST ( RectTest  ,
OptIRectIntersection   
)

Definition at line 1846 of file rect_unittests.cc.

1846 {
1847 auto a = IRect::MakeLTRB(0, 0, 110, 110);
1848 auto b = IRect::MakeLTRB(100, 100, 200, 200);
1849 auto c = IRect::MakeLTRB(100, 0, 200, 110);
1850
1851 // NullOpt, NullOpt
1852 EXPECT_FALSE(IRect::Intersection(std::nullopt, std::nullopt).has_value());
1853 EXPECT_EQ(IRect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1854
1855 auto test1 = [](const IRect& r) {
1856 // Rect, NullOpt
1857 EXPECT_TRUE(IRect::Intersection(r, std::nullopt).has_value());
1858 EXPECT_EQ(IRect::Intersection(r, std::nullopt).value(), r);
1859
1860 // OptRect, NullOpt
1862 IRect::Intersection(std::optional(r), std::nullopt).has_value());
1863 EXPECT_EQ(IRect::Intersection(std::optional(r), std::nullopt).value(), r);
1864
1865 // NullOpt, Rect
1866 EXPECT_TRUE(IRect::Intersection(std::nullopt, r).has_value());
1867 EXPECT_EQ(IRect::Intersection(std::nullopt, r).value(), r);
1868
1869 // NullOpt, OptRect
1871 IRect::Intersection(std::nullopt, std::optional(r)).has_value());
1872 EXPECT_EQ(IRect::Intersection(std::nullopt, std::optional(r)).value(), r);
1873 };
1874
1875 test1(a);
1876 test1(b);
1877 test1(c);
1878
1879 auto test2 = [](const IRect& a, const IRect& b, const IRect& i) {
1880 ASSERT_EQ(a.Intersection(b), i);
1881
1882 // Rect, OptRect
1883 EXPECT_TRUE(IRect::Intersection(a, std::optional(b)).has_value());
1884 EXPECT_EQ(IRect::Intersection(a, std::optional(b)).value(), i);
1885
1886 // OptRect, Rect
1887 EXPECT_TRUE(IRect::Intersection(std::optional(a), b).has_value());
1888 EXPECT_EQ(IRect::Intersection(std::optional(a), b).value(), i);
1889
1890 // OptRect, OptRect
1892 IRect::Intersection(std::optional(a), std::optional(b)).has_value());
1893 EXPECT_EQ(IRect::Intersection(std::optional(a), std::optional(b)).value(),
1894 i);
1895 };
1896
1897 test2(a, b, IRect::MakeLTRB(100, 100, 110, 110));
1898 test2(a, c, IRect::MakeLTRB(100, 0, 110, 110));
1899 test2(b, c, IRect::MakeLTRB(100, 100, 200, 110));
1900}

◆ TEST() [272/377]

impeller::testing::TEST ( RectTest  ,
OptIRectUnion   
)

Definition at line 1528 of file rect_unittests.cc.

1528 {
1529 auto a = IRect::MakeLTRB(0, 0, 100, 100);
1530 auto b = IRect::MakeLTRB(100, 100, 200, 200);
1531 auto c = IRect::MakeLTRB(100, 0, 200, 100);
1532
1533 // NullOpt, NullOpt
1534 EXPECT_FALSE(IRect::Union(std::nullopt, std::nullopt).has_value());
1535 EXPECT_EQ(IRect::Union(std::nullopt, std::nullopt), std::nullopt);
1536
1537 auto test1 = [](const IRect& r) {
1538 // Rect, NullOpt
1539 EXPECT_TRUE(IRect::Union(r, std::nullopt).has_value());
1540 EXPECT_EQ(IRect::Union(r, std::nullopt).value(), r);
1541
1542 // OptRect, NullOpt
1543 EXPECT_TRUE(IRect::Union(std::optional(r), std::nullopt).has_value());
1544 EXPECT_EQ(IRect::Union(std::optional(r), std::nullopt).value(), r);
1545
1546 // NullOpt, Rect
1547 EXPECT_TRUE(IRect::Union(std::nullopt, r).has_value());
1548 EXPECT_EQ(IRect::Union(std::nullopt, r).value(), r);
1549
1550 // NullOpt, OptRect
1551 EXPECT_TRUE(IRect::Union(std::nullopt, std::optional(r)).has_value());
1552 EXPECT_EQ(IRect::Union(std::nullopt, std::optional(r)).value(), r);
1553 };
1554
1555 test1(a);
1556 test1(b);
1557 test1(c);
1558
1559 auto test2 = [](const IRect& a, const IRect& b, const IRect& u) {
1560 ASSERT_EQ(a.Union(b), u);
1561
1562 // Rect, OptRect
1563 EXPECT_TRUE(IRect::Union(a, std::optional(b)).has_value());
1564 EXPECT_EQ(IRect::Union(a, std::optional(b)).value(), u);
1565
1566 // OptRect, Rect
1567 EXPECT_TRUE(IRect::Union(std::optional(a), b).has_value());
1568 EXPECT_EQ(IRect::Union(std::optional(a), b).value(), u);
1569
1570 // OptRect, OptRect
1571 EXPECT_TRUE(IRect::Union(std::optional(a), std::optional(b)).has_value());
1572 EXPECT_EQ(IRect::Union(std::optional(a), std::optional(b)).value(), u);
1573 };
1574
1575 test2(a, b, IRect::MakeLTRB(0, 0, 200, 200));
1576 test2(a, c, IRect::MakeLTRB(0, 0, 200, 100));
1577 test2(b, c, IRect::MakeLTRB(100, 0, 200, 200));
1578}

◆ TEST() [273/377]

impeller::testing::TEST ( RectTest  ,
OptRectIntersection   
)

Definition at line 1697 of file rect_unittests.cc.

1697 {
1698 auto a = Rect::MakeLTRB(0, 0, 110, 110);
1699 auto b = Rect::MakeLTRB(100, 100, 200, 200);
1700 auto c = Rect::MakeLTRB(100, 0, 200, 110);
1701
1702 // NullOpt, NullOpt
1703 EXPECT_FALSE(Rect::Intersection(std::nullopt, std::nullopt).has_value());
1704 EXPECT_EQ(Rect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1705
1706 auto test1 = [](const Rect& r) {
1707 // Rect, NullOpt
1708 EXPECT_TRUE(Rect::Intersection(r, std::nullopt).has_value());
1709 EXPECT_EQ(Rect::Intersection(r, std::nullopt).value(), r);
1710
1711 // OptRect, NullOpt
1712 EXPECT_TRUE(Rect::Intersection(std::optional(r), std::nullopt).has_value());
1713 EXPECT_EQ(Rect::Intersection(std::optional(r), std::nullopt).value(), r);
1714
1715 // NullOpt, Rect
1716 EXPECT_TRUE(Rect::Intersection(std::nullopt, r).has_value());
1717 EXPECT_EQ(Rect::Intersection(std::nullopt, r).value(), r);
1718
1719 // NullOpt, OptRect
1720 EXPECT_TRUE(Rect::Intersection(std::nullopt, std::optional(r)).has_value());
1721 EXPECT_EQ(Rect::Intersection(std::nullopt, std::optional(r)).value(), r);
1722 };
1723
1724 test1(a);
1725 test1(b);
1726 test1(c);
1727
1728 auto test2 = [](const Rect& a, const Rect& b, const Rect& i) {
1729 ASSERT_EQ(a.Intersection(b), i);
1730
1731 // Rect, OptRect
1732 EXPECT_TRUE(Rect::Intersection(a, std::optional(b)).has_value());
1733 EXPECT_EQ(Rect::Intersection(a, std::optional(b)).value(), i);
1734
1735 // OptRect, Rect
1736 EXPECT_TRUE(Rect::Intersection(std::optional(a), b).has_value());
1737 EXPECT_EQ(Rect::Intersection(std::optional(a), b).value(), i);
1738
1739 // OptRect, OptRect
1741 Rect::Intersection(std::optional(a), std::optional(b)).has_value());
1742 EXPECT_EQ(Rect::Intersection(std::optional(a), std::optional(b)).value(),
1743 i);
1744 };
1745
1746 test2(a, b, Rect::MakeLTRB(100, 100, 110, 110));
1747 test2(a, c, Rect::MakeLTRB(100, 0, 110, 110));
1748 test2(b, c, Rect::MakeLTRB(100, 100, 200, 110));
1749}

◆ TEST() [274/377]

impeller::testing::TEST ( RectTest  ,
OptRectUnion   
)

Definition at line 1404 of file rect_unittests.cc.

1404 {
1405 auto a = Rect::MakeLTRB(0, 0, 100, 100);
1406 auto b = Rect::MakeLTRB(100, 100, 200, 200);
1407 auto c = Rect::MakeLTRB(100, 0, 200, 100);
1408
1409 // NullOpt, NullOpt
1410 EXPECT_FALSE(Rect::Union(std::nullopt, std::nullopt).has_value());
1411 EXPECT_EQ(Rect::Union(std::nullopt, std::nullopt), std::nullopt);
1412
1413 auto test1 = [](const Rect& r) {
1414 // Rect, NullOpt
1415 EXPECT_TRUE(Rect::Union(r, std::nullopt).has_value());
1416 EXPECT_EQ(Rect::Union(r, std::nullopt).value(), r);
1417
1418 // OptRect, NullOpt
1419 EXPECT_TRUE(Rect::Union(std::optional(r), std::nullopt).has_value());
1420 EXPECT_EQ(Rect::Union(std::optional(r), std::nullopt).value(), r);
1421
1422 // NullOpt, Rect
1423 EXPECT_TRUE(Rect::Union(std::nullopt, r).has_value());
1424 EXPECT_EQ(Rect::Union(std::nullopt, r).value(), r);
1425
1426 // NullOpt, OptRect
1427 EXPECT_TRUE(Rect::Union(std::nullopt, std::optional(r)).has_value());
1428 EXPECT_EQ(Rect::Union(std::nullopt, std::optional(r)).value(), r);
1429 };
1430
1431 test1(a);
1432 test1(b);
1433 test1(c);
1434
1435 auto test2 = [](const Rect& a, const Rect& b, const Rect& u) {
1436 ASSERT_EQ(a.Union(b), u);
1437
1438 // Rect, OptRect
1439 EXPECT_TRUE(Rect::Union(a, std::optional(b)).has_value());
1440 EXPECT_EQ(Rect::Union(a, std::optional(b)).value(), u);
1441
1442 // OptRect, Rect
1443 EXPECT_TRUE(Rect::Union(std::optional(a), b).has_value());
1444 EXPECT_EQ(Rect::Union(std::optional(a), b).value(), u);
1445
1446 // OptRect, OptRect
1447 EXPECT_TRUE(Rect::Union(std::optional(a), std::optional(b)).has_value());
1448 EXPECT_EQ(Rect::Union(std::optional(a), std::optional(b)).value(), u);
1449 };
1450
1451 test2(a, b, Rect::MakeLTRB(0, 0, 200, 200));
1452 test2(a, c, Rect::MakeLTRB(0, 0, 200, 100));
1453 test2(b, c, Rect::MakeLTRB(100, 0, 200, 200));
1454}

◆ TEST() [275/377]

impeller::testing::TEST ( RectTest  ,
RectArea   
)

Definition at line 971 of file rect_unittests.cc.

971 {
972 EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
973 EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
974 EXPECT_EQ(Rect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
975 EXPECT_EQ(Rect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
976 EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
977 EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
978}

◆ TEST() [276/377]

impeller::testing::TEST ( RectTest  ,
RectContainsInclusivePoint   
)

Definition at line 2262 of file rect_unittests.cc.

2262 {
2263 auto check_nans = [](const Rect& rect, const Point& point,
2264 const std::string& label) {
2265 ASSERT_TRUE(rect.IsFinite()) << label;
2266 ASSERT_TRUE(point.IsFinite()) << label;
2267
2268 for (int i = 1; i < 16; i++) {
2269 EXPECT_FALSE(swap_nan(rect, i).ContainsInclusive(point))
2270 << label << ", index = " << i;
2271 for (int j = 1; j < 4; j++) {
2272 EXPECT_FALSE(swap_nan(rect, i).ContainsInclusive(swap_nan(point, j)))
2273 << label << ", indices = " << i << ", " << j;
2274 }
2275 }
2276 };
2277
2278 auto check_empty_flips = [](const Rect& rect, const Point& point,
2279 const std::string& label) {
2280 ASSERT_FALSE(rect.IsEmpty());
2281
2282 EXPECT_FALSE(flip_lr(rect).ContainsInclusive(point)) << label;
2283 EXPECT_FALSE(flip_tb(rect).ContainsInclusive(point)) << label;
2284 EXPECT_FALSE(flip_lrtb(rect).ContainsInclusive(point)) << label;
2285 };
2286
2287 auto test_inside = [&check_nans, &check_empty_flips](const Rect& rect,
2288 const Point& point) {
2289 ASSERT_FALSE(rect.IsEmpty()) << rect;
2290
2291 std::stringstream stream;
2292 stream << rect << " contains " << point;
2293 auto label = stream.str();
2294
2295 EXPECT_TRUE(rect.ContainsInclusive(point)) << label;
2296 check_empty_flips(rect, point, label);
2297 check_nans(rect, point, label);
2298 };
2299
2300 auto test_outside = [&check_nans, &check_empty_flips](const Rect& rect,
2301 const Point& point) {
2302 ASSERT_FALSE(rect.IsEmpty()) << rect;
2303
2304 std::stringstream stream;
2305 stream << rect << " contains " << point;
2306 auto label = stream.str();
2307
2308 EXPECT_FALSE(rect.ContainsInclusive(point)) << label;
2309 check_empty_flips(rect, point, label);
2310 check_nans(rect, point, label);
2311 };
2312
2313 {
2314 // Origin is inclusive
2315 auto r = Rect::MakeXYWH(100, 100, 100, 100);
2316 auto p = Point(100, 100);
2317
2318 test_inside(r, p);
2319 }
2320 {
2321 // Size is inclusive
2322 auto r = Rect::MakeXYWH(100, 100, 100, 100);
2323 auto p = Point(200, 200);
2324
2325 test_inside(r, p);
2326 }
2327 {
2328 // Size + epsilon is exclusive
2329 auto r = Rect::MakeXYWH(100, 100, 100, 100);
2330 auto p = Point(200 + kEhCloseEnough, 200 + kEhCloseEnough);
2331
2332 test_outside(r, p);
2333 }
2334 {
2335 auto r = Rect::MakeXYWH(100, 100, 100, 100);
2336 auto p = Point(99, 99);
2337
2338 test_outside(r, p);
2339 }
2340 {
2341 auto r = Rect::MakeXYWH(100, 100, 100, 100);
2342 auto p = Point(199, 199);
2343
2344 test_inside(r, p);
2345 }
2346
2347 {
2348 auto r = Rect::MakeMaximum();
2349 auto p = Point(199, 199);
2350
2351 test_inside(r, p);
2352 }
2353}
static constexpr Point swap_nan(const Point &point, int index)

◆ TEST() [277/377]

impeller::testing::TEST ( RectTest  ,
RectContainsPoint   
)

Definition at line 2107 of file rect_unittests.cc.

2107 {
2108 auto check_nans = [](const Rect& rect, const Point& point,
2109 const std::string& label) {
2110 ASSERT_TRUE(rect.IsFinite()) << label;
2111 ASSERT_TRUE(point.IsFinite()) << label;
2112
2113 for (int i = 1; i < 16; i++) {
2114 EXPECT_FALSE(swap_nan(rect, i).Contains(point))
2115 << label << ", index = " << i;
2116 for (int j = 1; j < 4; j++) {
2117 EXPECT_FALSE(swap_nan(rect, i).Contains(swap_nan(point, j)))
2118 << label << ", indices = " << i << ", " << j;
2119 }
2120 }
2121 };
2122
2123 auto check_empty_flips = [](const Rect& rect, const Point& point,
2124 const std::string& label) {
2125 ASSERT_FALSE(rect.IsEmpty());
2126
2127 EXPECT_FALSE(flip_lr(rect).Contains(point)) << label;
2128 EXPECT_FALSE(flip_tb(rect).Contains(point)) << label;
2129 EXPECT_FALSE(flip_lrtb(rect).Contains(point)) << label;
2130 };
2131
2132 auto test_inside = [&check_nans, &check_empty_flips](const Rect& rect,
2133 const Point& point) {
2134 ASSERT_FALSE(rect.IsEmpty()) << rect;
2135
2136 std::stringstream stream;
2137 stream << rect << " contains " << point;
2138 auto label = stream.str();
2139
2140 EXPECT_TRUE(rect.Contains(point)) << label;
2141 check_empty_flips(rect, point, label);
2142 check_nans(rect, point, label);
2143 };
2144
2145 auto test_outside = [&check_nans, &check_empty_flips](const Rect& rect,
2146 const Point& point) {
2147 ASSERT_FALSE(rect.IsEmpty()) << rect;
2148
2149 std::stringstream stream;
2150 stream << rect << " contains " << point;
2151 auto label = stream.str();
2152
2153 EXPECT_FALSE(rect.Contains(point)) << label;
2154 check_empty_flips(rect, point, label);
2155 check_nans(rect, point, label);
2156 };
2157
2158 {
2159 // Origin is inclusive
2160 auto r = Rect::MakeXYWH(100, 100, 100, 100);
2161 auto p = Point(100, 100);
2162
2163 test_inside(r, p);
2164 }
2165 {
2166 // Size is exclusive
2167 auto r = Rect::MakeXYWH(100, 100, 100, 100);
2168 auto p = Point(200, 200);
2169
2170 test_outside(r, p);
2171 }
2172 {
2173 auto r = Rect::MakeXYWH(100, 100, 100, 100);
2174 auto p = Point(99, 99);
2175
2176 test_outside(r, p);
2177 }
2178 {
2179 auto r = Rect::MakeXYWH(100, 100, 100, 100);
2180 auto p = Point(199, 199);
2181
2182 test_inside(r, p);
2183 }
2184
2185 {
2186 auto r = Rect::MakeMaximum();
2187 auto p = Point(199, 199);
2188
2189 test_inside(r, p);
2190 }
2191}

◆ TEST() [278/377]

impeller::testing::TEST ( RectTest  ,
RectContainsRect   
)

Definition at line 2431 of file rect_unittests.cc.

2431 {
2432 auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
2433 ASSERT_TRUE(a.IsFinite()) << label;
2434 ASSERT_TRUE(b.IsFinite()) << label;
2435 ASSERT_FALSE(a.IsEmpty());
2436
2437 for (int i = 1; i < 16; i++) {
2438 // NaN in a produces false
2439 EXPECT_FALSE(swap_nan(a, i).Contains(b)) << label << ", index = " << i;
2440 // NaN in b produces false
2441 EXPECT_TRUE(a.Contains(swap_nan(b, i))) << label << ", index = " << i;
2442 // NaN in both is false
2443 for (int j = 1; j < 16; j++) {
2444 EXPECT_FALSE(swap_nan(a, i).Contains(swap_nan(b, j)))
2445 << label << ", indices = " << i << ", " << j;
2446 }
2447 }
2448 };
2449
2450 auto check_empty_flips = [](const Rect& a, const Rect& b,
2451 const std::string& label) {
2452 ASSERT_FALSE(a.IsEmpty());
2453 // test b rects are allowed to have 0 w/h, but not be backwards
2454 ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2455
2456 // unflipped a vs flipped (empty) b yields false
2457 EXPECT_TRUE(a.Contains(flip_lr(b))) << label;
2458 EXPECT_TRUE(a.Contains(flip_tb(b))) << label;
2459 EXPECT_TRUE(a.Contains(flip_lrtb(b))) << label;
2460
2461 // flipped (empty) a vs unflipped b yields false
2462 EXPECT_FALSE(flip_lr(a).Contains(b)) << label;
2463 EXPECT_FALSE(flip_tb(a).Contains(b)) << label;
2464 EXPECT_FALSE(flip_lrtb(a).Contains(b)) << label;
2465
2466 // flipped (empty) a vs flipped (empty) b yields empty
2467 EXPECT_FALSE(flip_lr(a).Contains(flip_lr(b))) << label;
2468 EXPECT_FALSE(flip_tb(a).Contains(flip_tb(b))) << label;
2469 EXPECT_FALSE(flip_lrtb(a).Contains(flip_lrtb(b))) << label;
2470 };
2471
2472 auto test_inside = [&check_nans, &check_empty_flips](const Rect& a,
2473 const Rect& b) {
2474 ASSERT_FALSE(a.IsEmpty()) << a;
2475 // test b rects are allowed to have 0 w/h, but not be backwards
2476 ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2477
2478 std::stringstream stream;
2479 stream << a << " contains " << b;
2480 auto label = stream.str();
2481
2482 EXPECT_TRUE(a.Contains(b)) << label;
2483 check_empty_flips(a, b, label);
2484 check_nans(a, b, label);
2485 };
2486
2487 auto test_not_inside = [&check_nans, &check_empty_flips](const Rect& a,
2488 const Rect& b) {
2489 ASSERT_FALSE(a.IsEmpty()) << a;
2490 // If b was empty, it would be contained and should not be tested with
2491 // this function - use |test_inside| instead.
2492 ASSERT_FALSE(b.IsEmpty()) << b;
2493
2494 std::stringstream stream;
2495 stream << a << " contains " << b;
2496 auto label = stream.str();
2497
2498 EXPECT_FALSE(a.Contains(b)) << label;
2499 check_empty_flips(a, b, label);
2500 check_nans(a, b, label);
2501 };
2502
2503 {
2504 auto a = Rect::MakeXYWH(100, 100, 100, 100);
2505
2506 test_inside(a, a);
2507 }
2508 {
2509 auto a = Rect::MakeXYWH(100, 100, 100, 100);
2510 auto b = Rect::MakeXYWH(0, 0, 0, 0);
2511
2512 test_inside(a, b);
2513 }
2514 {
2515 auto a = Rect::MakeXYWH(100, 100, 100, 100);
2516 auto b = Rect::MakeXYWH(150, 150, 20, 20);
2517
2518 test_inside(a, b);
2519 }
2520 {
2521 auto a = Rect::MakeXYWH(100, 100, 100, 100);
2522 auto b = Rect::MakeXYWH(150, 150, 100, 100);
2523
2524 test_not_inside(a, b);
2525 }
2526 {
2527 auto a = Rect::MakeXYWH(100, 100, 100, 100);
2528 auto b = Rect::MakeXYWH(50, 50, 100, 100);
2529
2530 test_not_inside(a, b);
2531 }
2532 {
2533 auto a = Rect::MakeXYWH(100, 100, 100, 100);
2534 auto b = Rect::MakeXYWH(0, 0, 300, 300);
2535
2536 test_not_inside(a, b);
2537 }
2538 {
2539 auto a = Rect::MakeMaximum();
2540 auto b = Rect::MakeXYWH(0, 0, 300, 300);
2541
2542 test_inside(a, b);
2543 }
2544}

◆ TEST() [279/377]

impeller::testing::TEST ( RectTest  ,
RectCopy   
)

Definition at line 623 of file rect_unittests.cc.

623 {
624 // Using fractional-power-of-2 friendly values for equality tests
625 Rect rect = Rect::MakeLTRB(5.125f, 10.25f, 20.625f, 25.375f);
626 Rect copy = rect;
627
628 EXPECT_EQ(rect, copy);
629 EXPECT_EQ(copy.GetLeft(), 5.125f);
630 EXPECT_EQ(copy.GetTop(), 10.25f);
631 EXPECT_EQ(copy.GetRight(), 20.625f);
632 EXPECT_EQ(copy.GetBottom(), 25.375f);
633 EXPECT_EQ(copy.GetX(), 5.125f);
634 EXPECT_EQ(copy.GetY(), 10.25f);
635 EXPECT_EQ(copy.GetWidth(), 15.5f);
636 EXPECT_EQ(copy.GetHeight(), 15.125f);
637 EXPECT_FALSE(copy.IsEmpty());
638 EXPECT_TRUE(copy.IsFinite());
639}

◆ TEST() [280/377]

impeller::testing::TEST ( RectTest  ,
RectCutOut   
)

Definition at line 2639 of file rect_unittests.cc.

2639 {
2640 Rect cull_rect = Rect::MakeLTRB(20, 20, 40, 40);
2641
2642 auto check_nans = [&cull_rect](const Rect& diff_rect,
2643 const std::string& label) {
2644 EXPECT_TRUE(cull_rect.IsFinite()) << label;
2645 EXPECT_TRUE(diff_rect.IsFinite()) << label;
2646
2647 for (int i = 1; i < 16; i++) {
2648 // NaN in cull_rect produces empty
2649 EXPECT_FALSE(swap_nan(cull_rect, i).Cutout(diff_rect).has_value())
2650 << label << ", index " << i;
2651 EXPECT_EQ(swap_nan(cull_rect, i).CutoutOrEmpty(diff_rect), Rect())
2652 << label << ", index " << i;
2653
2654 // NaN in diff_rect is nop
2655 EXPECT_TRUE(cull_rect.Cutout(swap_nan(diff_rect, i)).has_value())
2656 << label << ", index " << i;
2657 EXPECT_EQ(cull_rect.CutoutOrEmpty(swap_nan(diff_rect, i)), cull_rect)
2658 << label << ", index " << i;
2659
2660 for (int j = 1; j < 16; j++) {
2661 // NaN in both is also empty
2662 EXPECT_FALSE(
2663 swap_nan(cull_rect, i).Cutout(swap_nan(diff_rect, j)).has_value())
2664 << label << ", indices " << i << ", " << j;
2665 EXPECT_EQ(swap_nan(cull_rect, i).CutoutOrEmpty(swap_nan(diff_rect, j)),
2666 Rect())
2667 << label << ", indices " << i << ", " << j;
2668 }
2669 }
2670 };
2671
2672 auto check_empty_flips = [&cull_rect](const Rect& diff_rect,
2673 const std::string& label) {
2674 EXPECT_FALSE(cull_rect.IsEmpty()) << label;
2675 EXPECT_FALSE(diff_rect.IsEmpty()) << label;
2676
2677 // unflipped cull_rect vs flipped(empty) diff_rect
2678 // == cull_rect
2679 EXPECT_TRUE(cull_rect.Cutout(flip_lr(diff_rect)).has_value()) << label;
2680 EXPECT_EQ(cull_rect.Cutout(flip_lr(diff_rect)), cull_rect) << label;
2681 EXPECT_TRUE(cull_rect.Cutout(flip_tb(diff_rect)).has_value()) << label;
2682 EXPECT_EQ(cull_rect.Cutout(flip_tb(diff_rect)), cull_rect) << label;
2683 EXPECT_TRUE(cull_rect.Cutout(flip_lrtb(diff_rect)).has_value()) << label;
2684 EXPECT_EQ(cull_rect.Cutout(flip_lrtb(diff_rect)), cull_rect) << label;
2685
2686 // flipped(empty) cull_rect vs unflipped diff_rect
2687 // == empty
2688 EXPECT_FALSE(flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2689 EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2690 EXPECT_FALSE(flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2691 EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2692 EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2693 EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2694
2695 // flipped(empty) cull_rect vs flipped(empty) diff_rect
2696 // == empty
2697 EXPECT_FALSE(flip_lr(cull_rect).Cutout(flip_lr(diff_rect)).has_value())
2698 << label;
2699 EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(flip_lr(diff_rect)), Rect())
2700 << label;
2701 EXPECT_FALSE(flip_tb(cull_rect).Cutout(flip_tb(diff_rect)).has_value())
2702 << label;
2703 EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(flip_tb(diff_rect)), Rect())
2704 << label;
2705 EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(flip_lrtb(diff_rect)).has_value())
2706 << label;
2707 EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(flip_lrtb(diff_rect)), Rect())
2708 << label;
2709 };
2710
2711 auto non_reducing = [&cull_rect, &check_empty_flips, &check_nans](
2712 const Rect& diff_rect, const std::string& label) {
2713 EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2714 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2715 check_empty_flips(diff_rect, label);
2716 check_nans(diff_rect, label);
2717 };
2718
2719 auto reducing = [&cull_rect, &check_empty_flips, &check_nans](
2720 const Rect& diff_rect, const Rect& result_rect,
2721 const std::string& label) {
2722 EXPECT_TRUE(!result_rect.IsEmpty());
2723 EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2724 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2725 check_empty_flips(diff_rect, label);
2726 check_nans(diff_rect, label);
2727 };
2728
2729 auto emptying = [&cull_rect, &check_empty_flips, &check_nans](
2730 const Rect& diff_rect, const std::string& label) {
2731 EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2732 EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), Rect()) << label;
2733 check_empty_flips(diff_rect, label);
2734 check_nans(diff_rect, label);
2735 };
2736
2737 // Skim the corners and edge
2738 non_reducing(Rect::MakeLTRB(10, 10, 20, 20), "outside UL corner");
2739 non_reducing(Rect::MakeLTRB(20, 10, 40, 20), "Above");
2740 non_reducing(Rect::MakeLTRB(40, 10, 50, 20), "outside UR corner");
2741 non_reducing(Rect::MakeLTRB(40, 20, 50, 40), "Right");
2742 non_reducing(Rect::MakeLTRB(40, 40, 50, 50), "outside LR corner");
2743 non_reducing(Rect::MakeLTRB(20, 40, 40, 50), "Below");
2744 non_reducing(Rect::MakeLTRB(10, 40, 20, 50), "outside LR corner");
2745 non_reducing(Rect::MakeLTRB(10, 20, 20, 40), "Left");
2746
2747 // Overlap corners
2748 non_reducing(Rect::MakeLTRB(15, 15, 25, 25), "covering UL corner");
2749 non_reducing(Rect::MakeLTRB(35, 15, 45, 25), "covering UR corner");
2750 non_reducing(Rect::MakeLTRB(35, 35, 45, 45), "covering LR corner");
2751 non_reducing(Rect::MakeLTRB(15, 35, 25, 45), "covering LL corner");
2752
2753 // Overlap edges, but not across an entire side
2754 non_reducing(Rect::MakeLTRB(20, 15, 39, 25), "Top edge left-biased");
2755 non_reducing(Rect::MakeLTRB(21, 15, 40, 25), "Top edge, right biased");
2756 non_reducing(Rect::MakeLTRB(35, 20, 45, 39), "Right edge, top-biased");
2757 non_reducing(Rect::MakeLTRB(35, 21, 45, 40), "Right edge, bottom-biased");
2758 non_reducing(Rect::MakeLTRB(20, 35, 39, 45), "Bottom edge, left-biased");
2759 non_reducing(Rect::MakeLTRB(21, 35, 40, 45), "Bottom edge, right-biased");
2760 non_reducing(Rect::MakeLTRB(15, 20, 25, 39), "Left edge, top-biased");
2761 non_reducing(Rect::MakeLTRB(15, 21, 25, 40), "Left edge, bottom-biased");
2762
2763 // Slice all the way through the middle
2764 non_reducing(Rect::MakeLTRB(25, 15, 35, 45), "Vertical interior slice");
2765 non_reducing(Rect::MakeLTRB(15, 25, 45, 35), "Horizontal interior slice");
2766
2767 // Slice off each edge
2768 reducing(Rect::MakeLTRB(20, 15, 40, 25), //
2769 Rect::MakeLTRB(20, 25, 40, 40), //
2770 "Slice off top");
2771 reducing(Rect::MakeLTRB(35, 20, 45, 40), //
2772 Rect::MakeLTRB(20, 20, 35, 40), //
2773 "Slice off right");
2774 reducing(Rect::MakeLTRB(20, 35, 40, 45), //
2775 Rect::MakeLTRB(20, 20, 40, 35), //
2776 "Slice off bottom");
2777 reducing(Rect::MakeLTRB(15, 20, 25, 40), //
2778 Rect::MakeLTRB(25, 20, 40, 40), //
2779 "Slice off left");
2780
2781 // cull rect contains diff rect
2782 non_reducing(Rect::MakeLTRB(21, 21, 39, 39), "Contained, non-covering");
2783
2784 // cull rect equals diff rect
2785 emptying(cull_rect, "Perfectly covering");
2786
2787 // diff rect contains cull rect
2788 emptying(Rect::MakeLTRB(15, 15, 45, 45), "Smothering");
2789}

◆ TEST() [281/377]

impeller::testing::TEST ( RectTest  ,
RectDefaultConstructor   
)

Definition at line 44 of file rect_unittests.cc.

44 {
45 Rect rect = Rect();
46
47 EXPECT_EQ(rect.GetLeft(), 0.0f);
48 EXPECT_EQ(rect.GetTop(), 0.0f);
49 EXPECT_EQ(rect.GetRight(), 0.0f);
50 EXPECT_EQ(rect.GetBottom(), 0.0f);
51 EXPECT_EQ(rect.GetX(), 0.0f);
52 EXPECT_EQ(rect.GetY(), 0.0f);
53 EXPECT_EQ(rect.GetWidth(), 0.0f);
54 EXPECT_EQ(rect.GetHeight(), 0.0f);
55 EXPECT_TRUE(rect.IsEmpty());
56 EXPECT_TRUE(rect.IsFinite());
57}

◆ TEST() [282/377]

impeller::testing::TEST ( RectTest  ,
RectDirections   
)

Definition at line 2981 of file rect_unittests.cc.

2981 {
2982 auto r = Rect::MakeLTRB(1, 2, 3, 4);
2983
2984 EXPECT_EQ(r.GetLeft(), 1);
2985 EXPECT_EQ(r.GetTop(), 2);
2986 EXPECT_EQ(r.GetRight(), 3);
2987 EXPECT_EQ(r.GetBottom(), 4);
2988
2989 EXPECT_POINT_NEAR(r.GetLeftTop(), Point(1, 2));
2990 EXPECT_POINT_NEAR(r.GetRightTop(), Point(3, 2));
2991 EXPECT_POINT_NEAR(r.GetLeftBottom(), Point(1, 4));
2992 EXPECT_POINT_NEAR(r.GetRightBottom(), Point(3, 4));
2993}

◆ TEST() [283/377]

impeller::testing::TEST ( RectTest  ,
RectDoesNotIntersectEmpty   
)

Definition at line 764 of file rect_unittests.cc.

764 {
765 Rect rect = Rect::MakeLTRB(50, 50, 100, 100);
766
767 auto test = [&rect](Scalar l, Scalar t, Scalar r, Scalar b,
768 const std::string& label) {
769 EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(l, b, r, t)))
770 << label << " with Top/Bottom swapped";
771 EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(r, b, l, t)))
772 << label << " with Left/Right swapped";
773 EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(r, t, l, b)))
774 << label << " with all sides swapped";
775 };
776
777 test(20, 20, 30, 30, "Above and Left");
778 test(70, 20, 80, 30, "Above");
779 test(120, 20, 130, 30, "Above and Right");
780 test(120, 70, 130, 80, "Right");
781 test(120, 120, 130, 130, "Below and Right");
782 test(70, 120, 80, 130, "Below");
783 test(20, 120, 30, 130, "Below and Left");
784 test(20, 70, 30, 80, "Left");
785
786 test(70, 70, 80, 80, "Inside");
787
788 test(40, 70, 60, 80, "Straddling Left");
789 test(70, 40, 80, 60, "Straddling Top");
790 test(90, 70, 110, 80, "Straddling Right");
791 test(70, 90, 80, 110, "Straddling Bottom");
792}

◆ TEST() [284/377]

impeller::testing::TEST ( RectTest  ,
RectEmptyDeclaration   
)

Definition at line 14 of file rect_unittests.cc.

14 {
15 Rect rect;
16
17 EXPECT_EQ(rect.GetLeft(), 0.0f);
18 EXPECT_EQ(rect.GetTop(), 0.0f);
19 EXPECT_EQ(rect.GetRight(), 0.0f);
20 EXPECT_EQ(rect.GetBottom(), 0.0f);
21 EXPECT_EQ(rect.GetX(), 0.0f);
22 EXPECT_EQ(rect.GetY(), 0.0f);
23 EXPECT_EQ(rect.GetWidth(), 0.0f);
24 EXPECT_EQ(rect.GetHeight(), 0.0f);
25 EXPECT_TRUE(rect.IsEmpty());
26 EXPECT_TRUE(rect.IsFinite());
27}

◆ TEST() [285/377]

impeller::testing::TEST ( RectTest  ,
RectExpand   
)

Definition at line 1205 of file rect_unittests.cc.

1205 {
1206 auto rect = Rect::MakeLTRB(100, 100, 200, 200);
1207
1208 // Expand(T amount)
1209 EXPECT_EQ(rect.Expand(10), Rect::MakeLTRB(90, 90, 210, 210));
1210 EXPECT_EQ(rect.Expand(-10), Rect::MakeLTRB(110, 110, 190, 190));
1211
1212 // Expand(amount, amount)
1213 EXPECT_EQ(rect.Expand(10, 10), Rect::MakeLTRB(90, 90, 210, 210));
1214 EXPECT_EQ(rect.Expand(10, -10), Rect::MakeLTRB(90, 110, 210, 190));
1215 EXPECT_EQ(rect.Expand(-10, 10), Rect::MakeLTRB(110, 90, 190, 210));
1216 EXPECT_EQ(rect.Expand(-10, -10), Rect::MakeLTRB(110, 110, 190, 190));
1217
1218 // Expand(amount, amount, amount, amount)
1219 EXPECT_EQ(rect.Expand(10, 20, 30, 40), Rect::MakeLTRB(90, 80, 230, 240));
1220 EXPECT_EQ(rect.Expand(-10, 20, 30, 40), Rect::MakeLTRB(110, 80, 230, 240));
1221 EXPECT_EQ(rect.Expand(10, -20, 30, 40), Rect::MakeLTRB(90, 120, 230, 240));
1222 EXPECT_EQ(rect.Expand(10, 20, -30, 40), Rect::MakeLTRB(90, 80, 170, 240));
1223 EXPECT_EQ(rect.Expand(10, 20, 30, -40), Rect::MakeLTRB(90, 80, 230, 160));
1224
1225 // Expand(Point amount)
1226 EXPECT_EQ(rect.Expand(Point{10, 10}), Rect::MakeLTRB(90, 90, 210, 210));
1227 EXPECT_EQ(rect.Expand(Point{10, -10}), Rect::MakeLTRB(90, 110, 210, 190));
1228 EXPECT_EQ(rect.Expand(Point{-10, 10}), Rect::MakeLTRB(110, 90, 190, 210));
1229 EXPECT_EQ(rect.Expand(Point{-10, -10}), Rect::MakeLTRB(110, 110, 190, 190));
1230
1231 // Expand(Size amount)
1232 EXPECT_EQ(rect.Expand(Size{10, 10}), Rect::MakeLTRB(90, 90, 210, 210));
1233 EXPECT_EQ(rect.Expand(Size{10, -10}), Rect::MakeLTRB(90, 110, 210, 190));
1234 EXPECT_EQ(rect.Expand(Size{-10, 10}), Rect::MakeLTRB(110, 90, 190, 210));
1235 EXPECT_EQ(rect.Expand(Size{-10, -10}), Rect::MakeLTRB(110, 110, 190, 190));
1236}

◆ TEST() [286/377]

impeller::testing::TEST ( RectTest  ,
RectFromRect   
)

Definition at line 609 of file rect_unittests.cc.

609 {
610 EXPECT_EQ(Rect(Rect::MakeXYWH(2, 3, 7, 15)),
611 Rect::MakeXYWH(2.0, 3.0, 7.0, 15.0));
612 EXPECT_EQ(Rect(Rect::MakeLTRB(2, 3, 7, 15)),
613 Rect::MakeLTRB(2.0, 3.0, 7.0, 15.0));
614}

◆ TEST() [287/377]

impeller::testing::TEST ( RectTest  ,
RectGetNormalizingTransform   
)

Definition at line 989 of file rect_unittests.cc.

989 {
990 {
991 // Checks for expected matrix values
992
993 auto r = Rect::MakeXYWH(100, 200, 200, 400);
994
995 EXPECT_EQ(r.GetNormalizingTransform(),
996 Matrix::MakeScale({0.005, 0.0025, 1.0}) *
997 Matrix::MakeTranslation({-100, -200}));
998 }
999
1000 {
1001 // Checks for expected transform of points relative to the rect
1002
1003 auto r = Rect::MakeLTRB(300, 500, 400, 700);
1004 auto m = r.GetNormalizingTransform();
1005
1006 // The 4 corners of the rect => (0, 0) to (1, 1)
1007 EXPECT_EQ(m * Point(300, 500), Point(0, 0));
1008 EXPECT_EQ(m * Point(400, 500), Point(1, 0));
1009 EXPECT_EQ(m * Point(400, 700), Point(1, 1));
1010 EXPECT_EQ(m * Point(300, 700), Point(0, 1));
1011
1012 // The center => (0.5, 0.5)
1013 EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
1014
1015 // Outside the 4 corners => (-1, -1) to (2, 2)
1016 EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
1017 EXPECT_EQ(m * Point(500, 300), Point(2, -1));
1018 EXPECT_EQ(m * Point(500, 900), Point(2, 2));
1019 EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
1020 }
1021
1022 {
1023 // Checks for behavior with empty rects
1024
1025 auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
1026
1027 // Empty for width and/or height == 0
1028 EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1029 EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1030 EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1031
1032 // Empty for width and/or height < 0
1033 EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1034 EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1035 EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1036 }
1037
1038 {
1039 // Checks for behavior with non-finite rects
1040
1041 auto z = Matrix::MakeScale({0.0, 0.0, 1.0});
1042 auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1043 auto inf = std::numeric_limits<Scalar>::infinity();
1044
1045 // Non-finite for width and/or height == nan
1046 EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, 10).GetNormalizingTransform(), z);
1047 EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, nan).GetNormalizingTransform(), z);
1048 EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, nan).GetNormalizingTransform(), z);
1049
1050 // Non-finite for width and/or height == inf
1051 EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, 10).GetNormalizingTransform(), z);
1052 EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, inf).GetNormalizingTransform(), z);
1053 EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, inf).GetNormalizingTransform(), z);
1054
1055 // Non-finite for width and/or height == -inf
1056 EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, 10).GetNormalizingTransform(), z);
1057 EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -inf).GetNormalizingTransform(), z);
1058 EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, -inf).GetNormalizingTransform(), z);
1059
1060 // Non-finite for origin X and/or Y == nan
1061 EXPECT_EQ(Rect::MakeXYWH(nan, 10, 10, 10).GetNormalizingTransform(), z);
1062 EXPECT_EQ(Rect::MakeXYWH(10, nan, 10, 10).GetNormalizingTransform(), z);
1063 EXPECT_EQ(Rect::MakeXYWH(nan, nan, 10, 10).GetNormalizingTransform(), z);
1064
1065 // Non-finite for origin X and/or Y == inf
1066 EXPECT_EQ(Rect::MakeXYWH(inf, 10, 10, 10).GetNormalizingTransform(), z);
1067 EXPECT_EQ(Rect::MakeXYWH(10, inf, 10, 10).GetNormalizingTransform(), z);
1068 EXPECT_EQ(Rect::MakeXYWH(inf, inf, 10, 10).GetNormalizingTransform(), z);
1069
1070 // Non-finite for origin X and/or Y == -inf
1071 EXPECT_EQ(Rect::MakeXYWH(-inf, 10, 10, 10).GetNormalizingTransform(), z);
1072 EXPECT_EQ(Rect::MakeXYWH(10, -inf, 10, 10).GetNormalizingTransform(), z);
1073 EXPECT_EQ(Rect::MakeXYWH(-inf, -inf, 10, 10).GetNormalizingTransform(), z);
1074 }
1075}

◆ TEST() [288/377]

impeller::testing::TEST ( RectTest  ,
RectGetPoints   
)

Definition at line 2910 of file rect_unittests.cc.

2910 {
2911 {
2912 Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2913 auto points = r.GetPoints();
2914 EXPECT_POINT_NEAR(points[0], Point(100, 200));
2915 EXPECT_POINT_NEAR(points[1], Point(400, 200));
2916 EXPECT_POINT_NEAR(points[2], Point(100, 600));
2917 EXPECT_POINT_NEAR(points[3], Point(400, 600));
2918 }
2919
2920 {
2921 Rect r = Rect::MakeMaximum();
2922 auto points = r.GetPoints();
2923 EXPECT_EQ(points[0], Point(std::numeric_limits<float>::lowest(),
2924 std::numeric_limits<float>::lowest()));
2926 std::numeric_limits<float>::lowest()));
2927 EXPECT_EQ(points[2], Point(std::numeric_limits<float>::lowest(),
2931 }
2932}
constexpr std::array< TPoint< T >, 4 > GetPoints() const
Get the points that represent the 4 corners of this rectangle in a Z order that is compatible with tr...
Definition: rect.h:405

◆ TEST() [289/377]

impeller::testing::TEST ( RectTest  ,
RectGetPositive   
)

Definition at line 2967 of file rect_unittests.cc.

2967 {
2968 {
2969 Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2970 auto actual = r.GetPositive();
2971 EXPECT_RECT_NEAR(r, actual);
2972 }
2973 {
2974 Rect r = Rect::MakeXYWH(100, 200, -100, -100);
2975 auto actual = r.GetPositive();
2976 Rect expected = Rect::MakeXYWH(0, 100, 100, 100);
2977 EXPECT_RECT_NEAR(expected, actual);
2978 }
2979}
constexpr TRect GetPositive() const
Get a version of this rectangle that has a non-negative size.
Definition: rect.h:389

◆ TEST() [290/377]

impeller::testing::TEST ( RectTest  ,
RectGetTransformedPoints   
)

Definition at line 2941 of file rect_unittests.cc.

2941 {
2942 Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2943 auto points = r.GetTransformedPoints(Matrix::MakeTranslation({10, 20}));
2944 EXPECT_POINT_NEAR(points[0], Point(110, 220));
2945 EXPECT_POINT_NEAR(points[1], Point(410, 220));
2946 EXPECT_POINT_NEAR(points[2], Point(110, 620));
2947 EXPECT_POINT_NEAR(points[3], Point(410, 620));
2948}

◆ TEST() [291/377]

impeller::testing::TEST ( RectTest  ,
RectIntersection   
)

Definition at line 1580 of file rect_unittests.cc.

1580 {
1581 auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1582 ASSERT_TRUE(a.IsFinite()) << label;
1583 ASSERT_TRUE(b.IsFinite()) << label;
1584
1585 for (int i = 1; i < 16; i++) {
1586 // NaN in a produces empty
1587 EXPECT_FALSE(swap_nan(a, i).Intersection(b).has_value())
1588 << label << ", index = " << i;
1589 // NaN in b produces empty
1590 EXPECT_FALSE(a.Intersection(swap_nan(b, i)).has_value())
1591 << label << ", index = " << i;
1592 // NaN in both is empty
1593 for (int j = 1; j < 16; j++) {
1594 EXPECT_FALSE(swap_nan(a, i).Intersection(swap_nan(b, j)).has_value())
1595 << label << ", indices = " << i << ", " << j;
1596 }
1597 }
1598 };
1599
1600 auto check_empty_flips = [](const Rect& a, const Rect& b,
1601 const std::string& label) {
1602 ASSERT_FALSE(a.IsEmpty());
1603 // b is allowed to be empty
1604
1605 // unflipped a vs flipped (empty) b yields a
1606 EXPECT_FALSE(a.Intersection(flip_lr(b)).has_value()) << label;
1607 EXPECT_FALSE(a.Intersection(flip_tb(b)).has_value()) << label;
1608 EXPECT_FALSE(a.Intersection(flip_lrtb(b)).has_value()) << label;
1609
1610 // flipped (empty) a vs unflipped b yields b
1611 EXPECT_FALSE(flip_lr(a).Intersection(b).has_value()) << label;
1612 EXPECT_FALSE(flip_tb(a).Intersection(b).has_value()) << label;
1613 EXPECT_FALSE(flip_lrtb(a).Intersection(b).has_value()) << label;
1614
1615 // flipped (empty) a vs flipped (empty) b yields empty
1616 EXPECT_FALSE(flip_lr(a).Intersection(flip_lr(b)).has_value()) << label;
1617 EXPECT_FALSE(flip_tb(a).Intersection(flip_tb(b)).has_value()) << label;
1618 EXPECT_FALSE(flip_lrtb(a).Intersection(flip_lrtb(b)).has_value()) << label;
1619 };
1620
1621 auto test_non_empty = [&check_nans, &check_empty_flips](
1622 const Rect& a, const Rect& b, const Rect& result) {
1623 ASSERT_FALSE(a.IsEmpty()) << a;
1624 // b is allowed to be empty
1625
1626 std::stringstream stream;
1627 stream << a << " union " << b;
1628 auto label = stream.str();
1629
1630 EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1631 EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1632 EXPECT_EQ(a.Intersection(b), result) << label;
1633 EXPECT_EQ(b.Intersection(a), result) << label;
1634 check_empty_flips(a, b, label);
1635 check_nans(a, b, label);
1636 };
1637
1638 auto test_empty = [&check_nans, &check_empty_flips](const Rect& a,
1639 const Rect& b) {
1640 ASSERT_FALSE(a.IsEmpty()) << a;
1641 // b is allowed to be empty
1642
1643 std::stringstream stream;
1644 stream << a << " union " << b;
1645 auto label = stream.str();
1646
1647 EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1648 EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1649 check_empty_flips(a, b, label);
1650 check_nans(a, b, label);
1651 };
1652
1653 {
1654 auto a = Rect::MakeXYWH(100, 100, 100, 100);
1655 auto b = Rect::MakeXYWH(0, 0, 0, 0);
1656
1657 test_empty(a, b);
1658 }
1659
1660 {
1661 auto a = Rect::MakeXYWH(100, 100, 100, 100);
1662 auto b = Rect::MakeXYWH(10, 10, 0, 0);
1663
1664 test_empty(a, b);
1665 }
1666
1667 {
1668 auto a = Rect::MakeXYWH(0, 0, 100, 100);
1669 auto b = Rect::MakeXYWH(10, 10, 100, 100);
1670 auto expected = Rect::MakeXYWH(10, 10, 90, 90);
1671
1672 test_non_empty(a, b, expected);
1673 }
1674
1675 {
1676 auto a = Rect::MakeXYWH(0, 0, 100, 100);
1677 auto b = Rect::MakeXYWH(100, 100, 100, 100);
1678
1679 test_empty(a, b);
1680 }
1681
1682 {
1683 auto a = Rect::MakeMaximum();
1684 auto b = Rect::MakeXYWH(10, 10, 300, 300);
1685
1686 test_non_empty(a, b, b);
1687 }
1688
1689 {
1690 auto a = Rect::MakeMaximum();
1691 auto b = Rect::MakeMaximum();
1692
1693 test_non_empty(a, b, Rect::MakeMaximum());
1694 }
1695}

◆ TEST() [292/377]

impeller::testing::TEST ( RectTest  ,
RectIntersectsWithRect   
)

Definition at line 1902 of file rect_unittests.cc.

1902 {
1903 auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1904 ASSERT_TRUE(a.IsFinite()) << label;
1905 ASSERT_TRUE(b.IsFinite()) << label;
1906
1907 for (int i = 1; i < 16; i++) {
1908 // NaN in a produces b
1909 EXPECT_FALSE(swap_nan(a, i).IntersectsWithRect(b))
1910 << label << ", index = " << i;
1911 // NaN in b produces a
1912 EXPECT_FALSE(a.IntersectsWithRect(swap_nan(b, i)))
1913 << label << ", index = " << i;
1914 // NaN in both is empty
1915 for (int j = 1; j < 16; j++) {
1916 EXPECT_FALSE(swap_nan(a, i).IntersectsWithRect(swap_nan(b, j)))
1917 << label << ", indices = " << i << ", " << j;
1918 }
1919 }
1920 };
1921
1922 auto check_empty_flips = [](const Rect& a, const Rect& b,
1923 const std::string& label) {
1924 ASSERT_FALSE(a.IsEmpty());
1925 // b is allowed to be empty
1926
1927 // unflipped a vs flipped (empty) b yields a
1928 EXPECT_FALSE(a.IntersectsWithRect(flip_lr(b))) << label;
1929 EXPECT_FALSE(a.IntersectsWithRect(flip_tb(b))) << label;
1930 EXPECT_FALSE(a.IntersectsWithRect(flip_lrtb(b))) << label;
1931
1932 // flipped (empty) a vs unflipped b yields b
1933 EXPECT_FALSE(flip_lr(a).IntersectsWithRect(b)) << label;
1934 EXPECT_FALSE(flip_tb(a).IntersectsWithRect(b)) << label;
1935 EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(b)) << label;
1936
1937 // flipped (empty) a vs flipped (empty) b yields empty
1938 EXPECT_FALSE(flip_lr(a).IntersectsWithRect(flip_lr(b))) << label;
1939 EXPECT_FALSE(flip_tb(a).IntersectsWithRect(flip_tb(b))) << label;
1940 EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(flip_lrtb(b))) << label;
1941 };
1942
1943 auto test_non_empty = [&check_nans, &check_empty_flips](const Rect& a,
1944 const Rect& b) {
1945 ASSERT_FALSE(a.IsEmpty()) << a;
1946 // b is allowed to be empty
1947
1948 std::stringstream stream;
1949 stream << a << " union " << b;
1950 auto label = stream.str();
1951
1952 EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
1953 EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
1954 check_empty_flips(a, b, label);
1955 check_nans(a, b, label);
1956 };
1957
1958 auto test_empty = [&check_nans, &check_empty_flips](const Rect& a,
1959 const Rect& b) {
1960 ASSERT_FALSE(a.IsEmpty()) << a;
1961 // b is allowed to be empty
1962
1963 std::stringstream stream;
1964 stream << a << " union " << b;
1965 auto label = stream.str();
1966
1967 EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
1968 EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
1969 check_empty_flips(a, b, label);
1970 check_nans(a, b, label);
1971 };
1972
1973 {
1974 auto a = Rect::MakeXYWH(100, 100, 100, 100);
1975 auto b = Rect::MakeXYWH(0, 0, 0, 0);
1976
1977 test_empty(a, b);
1978 }
1979
1980 {
1981 auto a = Rect::MakeXYWH(100, 100, 100, 100);
1982 auto b = Rect::MakeXYWH(10, 10, 0, 0);
1983
1984 test_empty(a, b);
1985 }
1986
1987 {
1988 auto a = Rect::MakeXYWH(0, 0, 100, 100);
1989 auto b = Rect::MakeXYWH(10, 10, 100, 100);
1990
1991 test_non_empty(a, b);
1992 }
1993
1994 {
1995 auto a = Rect::MakeXYWH(0, 0, 100, 100);
1996 auto b = Rect::MakeXYWH(100, 100, 100, 100);
1997
1998 test_empty(a, b);
1999 }
2000
2001 {
2002 auto a = Rect::MakeMaximum();
2003 auto b = Rect::MakeXYWH(10, 10, 100, 100);
2004
2005 test_non_empty(a, b);
2006 }
2007
2008 {
2009 auto a = Rect::MakeMaximum();
2010 auto b = Rect::MakeMaximum();
2011
2012 test_non_empty(a, b);
2013 }
2014}

◆ TEST() [293/377]

impeller::testing::TEST ( RectTest  ,
RectMakeMaximum   
)

Definition at line 575 of file rect_unittests.cc.

575 {
576 Rect rect = Rect::MakeMaximum();
577 auto inf = std::numeric_limits<Scalar>::infinity();
578 auto min = std::numeric_limits<Scalar>::lowest();
580
581 EXPECT_EQ(rect.GetLeft(), min);
582 EXPECT_EQ(rect.GetTop(), min);
583 EXPECT_EQ(rect.GetRight(), max);
584 EXPECT_EQ(rect.GetBottom(), max);
585 EXPECT_EQ(rect.GetX(), min);
586 EXPECT_EQ(rect.GetY(), min);
587 EXPECT_EQ(rect.GetWidth(), inf);
588 EXPECT_EQ(rect.GetHeight(), inf);
589 EXPECT_FALSE(rect.IsEmpty());
590 EXPECT_TRUE(rect.IsFinite());
591}

◆ TEST() [294/377]

impeller::testing::TEST ( RectTest  ,
RectMakePointBounds   
)

Definition at line 2950 of file rect_unittests.cc.

2950 {
2951 {
2952 std::vector<Point> points{{1, 5}, {4, -1}, {0, 6}};
2953 auto r = Rect::MakePointBounds(points.begin(), points.end());
2954 auto expected = Rect::MakeXYWH(0, -1, 4, 7);
2955 EXPECT_TRUE(r.has_value());
2956 if (r.has_value()) {
2957 EXPECT_RECT_NEAR(r.value(), expected);
2958 }
2959 }
2960 {
2961 std::vector<Point> points;
2962 std::optional<Rect> r = Rect::MakePointBounds(points.begin(), points.end());
2963 EXPECT_FALSE(r.has_value());
2964 }
2965}

◆ TEST() [295/377]

impeller::testing::TEST ( RectTest  ,
RectMakeSize   
)

Definition at line 545 of file rect_unittests.cc.

545 {
546 {
547 Size s(100, 200);
548 Rect r = Rect::MakeSize(s);
549 Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
550 EXPECT_RECT_NEAR(r, expected);
551 }
552
553 {
554 ISize s(100, 200);
555 Rect r = Rect::MakeSize(s);
556 Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
557 EXPECT_RECT_NEAR(r, expected);
558 }
559
560 {
561 Size s(100, 200);
562 IRect r = IRect::MakeSize(s);
563 IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
564 EXPECT_EQ(r, expected);
565 }
566
567 {
568 ISize s(100, 200);
569 IRect r = IRect::MakeSize(s);
570 IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
571 EXPECT_EQ(r, expected);
572 }
573}

◆ TEST() [296/377]

impeller::testing::TEST ( RectTest  ,
RectOriginSizeXYWHGetters   
)

Definition at line 657 of file rect_unittests.cc.

657 {
658 {
659 Rect r = Rect::MakeOriginSize({10, 20}, {50, 40});
660 EXPECT_EQ(r.GetOrigin(), Point(10, 20));
661 EXPECT_EQ(r.GetSize(), Size(50, 40));
662 EXPECT_EQ(r.GetX(), 10);
663 EXPECT_EQ(r.GetY(), 20);
664 EXPECT_EQ(r.GetWidth(), 50);
665 EXPECT_EQ(r.GetHeight(), 40);
666 auto expected_array = std::array<Scalar, 4>{10, 20, 50, 40};
667 EXPECT_EQ(r.GetXYWH(), expected_array);
668 }
669
670 {
671 Rect r = Rect::MakeLTRB(10, 20, 50, 40);
672 EXPECT_EQ(r.GetOrigin(), Point(10, 20));
673 EXPECT_EQ(r.GetSize(), Size(40, 20));
674 EXPECT_EQ(r.GetX(), 10);
675 EXPECT_EQ(r.GetY(), 20);
676 EXPECT_EQ(r.GetWidth(), 40);
677 EXPECT_EQ(r.GetHeight(), 20);
678 auto expected_array = std::array<Scalar, 4>{10, 20, 40, 20};
679 EXPECT_EQ(r.GetXYWH(), expected_array);
680 }
681}

◆ TEST() [297/377]

impeller::testing::TEST ( RectTest  ,
RectOverflowLTRB   
)

Definition at line 339 of file rect_unittests.cc.

339 {
340 auto min = std::numeric_limits<Scalar>::lowest();
342 auto inf = std::numeric_limits<Scalar>::infinity();
343
344 // 8 cases:
345 // finite negative X, max W
346 // ~min X, ~max W
347 // finite negative Y, max H
348 // ~min Y, ~max H
349 // finite positive X, min W
350 // ~min X, ~min W
351 // finite positive Y, min H
352 // ~min Y, ~min H
353
354 // a small finite value subtracted from a max value will remain max
355 // a very large finite value (like min) subtracted from max will go to inf
356
357 {
358 Rect rect = Rect::MakeLTRB(-5.0f, 10.0f, max, 25.0f);
359
360 EXPECT_EQ(rect.GetLeft(), -5.0f);
361 EXPECT_EQ(rect.GetTop(), 10.0f);
362 EXPECT_EQ(rect.GetRight(), max);
363 EXPECT_EQ(rect.GetBottom(), 25.0f);
364 EXPECT_EQ(rect.GetX(), -5.0f);
365 EXPECT_EQ(rect.GetY(), 10.0f);
366 EXPECT_EQ(rect.GetWidth(), max);
367 EXPECT_EQ(rect.GetHeight(), 15.0f);
368 EXPECT_FALSE(rect.IsEmpty());
369 EXPECT_TRUE(rect.IsFinite());
370 }
371
372 {
373 Rect rect = Rect::MakeLTRB(min + 5.0f, 10.0f, max - 5.0f, 25.0f);
374
375 EXPECT_EQ(rect.GetLeft(), min + 5.0f);
376 EXPECT_EQ(rect.GetTop(), 10.0f);
377 EXPECT_EQ(rect.GetRight(), max - 5.0f);
378 EXPECT_EQ(rect.GetBottom(), 25.0f);
379 EXPECT_EQ(rect.GetX(), min + 5.0f);
380 EXPECT_EQ(rect.GetY(), 10.0f);
381 EXPECT_EQ(rect.GetWidth(), inf);
382 EXPECT_EQ(rect.GetHeight(), 15.0f);
383 EXPECT_FALSE(rect.IsEmpty());
384 EXPECT_TRUE(rect.IsFinite());
385 }
386
387 {
388 Rect rect = Rect::MakeLTRB(5.0f, -10.0f, 20.0f, max);
389
390 EXPECT_EQ(rect.GetLeft(), 5.0f);
391 EXPECT_EQ(rect.GetTop(), -10.0f);
392 EXPECT_EQ(rect.GetRight(), 20.0f);
393 EXPECT_EQ(rect.GetBottom(), max);
394 EXPECT_EQ(rect.GetX(), 5.0f);
395 EXPECT_EQ(rect.GetY(), -10.0f);
396 EXPECT_EQ(rect.GetWidth(), 15.0f);
397 EXPECT_EQ(rect.GetHeight(), max);
398 EXPECT_FALSE(rect.IsEmpty());
399 EXPECT_TRUE(rect.IsFinite());
400 }
401
402 {
403 Rect rect = Rect::MakeLTRB(5.0f, min + 10.0f, 20.0f, max - 15.0f);
404
405 EXPECT_EQ(rect.GetLeft(), 5.0f);
406 EXPECT_EQ(rect.GetTop(), min + 10.0f);
407 EXPECT_EQ(rect.GetRight(), 20.0f);
408 EXPECT_EQ(rect.GetBottom(), max - 15.0f);
409 EXPECT_EQ(rect.GetX(), 5.0f);
410 EXPECT_EQ(rect.GetY(), min + 10.0f);
411 EXPECT_EQ(rect.GetWidth(), 15.0f);
412 EXPECT_EQ(rect.GetHeight(), inf);
413 EXPECT_FALSE(rect.IsEmpty());
414 EXPECT_TRUE(rect.IsFinite());
415 }
416
417 {
418 Rect rect = Rect::MakeLTRB(5.0f, 10.0f, min, 25.0f);
419
420 EXPECT_EQ(rect.GetLeft(), 5.0f);
421 EXPECT_EQ(rect.GetTop(), 10.0f);
422 EXPECT_EQ(rect.GetRight(), min);
423 EXPECT_EQ(rect.GetBottom(), 25.0f);
424 EXPECT_EQ(rect.GetX(), 5.0f);
425 EXPECT_EQ(rect.GetY(), 10.0f);
426 EXPECT_EQ(rect.GetWidth(), min);
427 EXPECT_EQ(rect.GetHeight(), 15.0f);
428 EXPECT_TRUE(rect.IsEmpty());
429 EXPECT_TRUE(rect.IsFinite());
430 }
431
432 {
433 Rect rect = Rect::MakeLTRB(max - 5.0f, 10.0f, min + 10.0f, 25.0f);
434
435 EXPECT_EQ(rect.GetLeft(), max - 5.0f);
436 EXPECT_EQ(rect.GetTop(), 10.0f);
437 EXPECT_EQ(rect.GetRight(), min + 10.0f);
438 EXPECT_EQ(rect.GetBottom(), 25.0f);
439 EXPECT_EQ(rect.GetX(), max - 5.0f);
440 EXPECT_EQ(rect.GetY(), 10.0f);
441 EXPECT_EQ(rect.GetWidth(), -inf);
442 EXPECT_EQ(rect.GetHeight(), 15.0f);
443 EXPECT_TRUE(rect.IsEmpty());
444 EXPECT_TRUE(rect.IsFinite());
445 }
446
447 {
448 Rect rect = Rect::MakeLTRB(5.0f, 10.0f, 20.0f, min);
449
450 EXPECT_EQ(rect.GetLeft(), 5.0f);
451 EXPECT_EQ(rect.GetTop(), 10.0f);
452 EXPECT_EQ(rect.GetRight(), 20.0f);
453 EXPECT_EQ(rect.GetBottom(), min);
454 EXPECT_EQ(rect.GetX(), 5.0f);
455 EXPECT_EQ(rect.GetY(), 10.0f);
456 EXPECT_EQ(rect.GetWidth(), 15.0f);
457 EXPECT_EQ(rect.GetHeight(), min);
458 EXPECT_TRUE(rect.IsEmpty());
459 EXPECT_TRUE(rect.IsFinite());
460 }
461
462 {
463 Rect rect = Rect::MakeLTRB(5.0f, max - 5.0f, 20.0f, min + 10.0f);
464
465 EXPECT_EQ(rect.GetLeft(), 5.0f);
466 EXPECT_EQ(rect.GetTop(), max - 5.0f);
467 EXPECT_EQ(rect.GetRight(), 20.0f);
468 EXPECT_EQ(rect.GetBottom(), min + 10.0f);
469 EXPECT_EQ(rect.GetX(), 5.0f);
470 EXPECT_EQ(rect.GetY(), max - 5.0f);
471 EXPECT_EQ(rect.GetWidth(), 15.0f);
472 EXPECT_EQ(rect.GetHeight(), -inf);
473 EXPECT_TRUE(rect.IsEmpty());
474 EXPECT_TRUE(rect.IsFinite());
475 }
476}

◆ TEST() [298/377]

impeller::testing::TEST ( RectTest  ,
RectOverflowXYWH   
)

Definition at line 133 of file rect_unittests.cc.

133 {
134 auto min = std::numeric_limits<Scalar>::lowest();
136 auto inf = std::numeric_limits<Scalar>::infinity();
137
138 // 8 cases:
139 // finite X, max W
140 // max X, max W
141 // finite Y, max H
142 // max Y, max H
143 // finite X, min W
144 // min X, min W
145 // finite Y, min H
146 // min Y, min H
147
148 // a small finite value added to a max value will remain max
149 // a very large finite value (like max) added to max will go to infinity
150
151 {
152 Rect rect = Rect::MakeXYWH(5.0, 10.0f, max, 15.0f);
153
154 EXPECT_EQ(rect.GetLeft(), 5.0f);
155 EXPECT_EQ(rect.GetTop(), 10.0f);
156 EXPECT_EQ(rect.GetRight(), max);
157 EXPECT_EQ(rect.GetBottom(), 25.0f);
158 EXPECT_EQ(rect.GetX(), 5.0f);
159 EXPECT_EQ(rect.GetY(), 10.0f);
160 EXPECT_EQ(rect.GetWidth(), max);
161 EXPECT_EQ(rect.GetHeight(), 15.0f);
162 EXPECT_FALSE(rect.IsEmpty());
163 EXPECT_TRUE(rect.IsFinite());
164 }
165
166 {
167 Rect rect = Rect::MakeXYWH(max, 10.0f, max, 15.0f);
168
169 EXPECT_EQ(rect.GetLeft(), max);
170 EXPECT_EQ(rect.GetTop(), 10.0f);
171 EXPECT_EQ(rect.GetRight(), inf);
172 EXPECT_EQ(rect.GetBottom(), 25.0f);
173 EXPECT_EQ(rect.GetX(), max);
174 EXPECT_EQ(rect.GetY(), 10.0f);
175 EXPECT_EQ(rect.GetWidth(), inf);
176 EXPECT_EQ(rect.GetHeight(), 15.0f);
177 EXPECT_FALSE(rect.IsEmpty());
178 EXPECT_FALSE(rect.IsFinite());
179 }
180
181 {
182 Rect rect = Rect::MakeXYWH(5.0f, 10.0f, 20.0f, max);
183
184 EXPECT_EQ(rect.GetLeft(), 5.0f);
185 EXPECT_EQ(rect.GetTop(), 10.0f);
186 EXPECT_EQ(rect.GetRight(), 25.0f);
187 EXPECT_EQ(rect.GetBottom(), max);
188 EXPECT_EQ(rect.GetX(), 5.0f);
189 EXPECT_EQ(rect.GetY(), 10.0f);
190 EXPECT_EQ(rect.GetWidth(), 20.0f);
191 EXPECT_EQ(rect.GetHeight(), max);
192 EXPECT_FALSE(rect.IsEmpty());
193 EXPECT_TRUE(rect.IsFinite());
194 }
195
196 {
197 Rect rect = Rect::MakeXYWH(5.0f, max, 20.0f, max);
198
199 EXPECT_EQ(rect.GetLeft(), 5.0f);
200 EXPECT_EQ(rect.GetTop(), max);
201 EXPECT_EQ(rect.GetRight(), 25.0f);
202 EXPECT_EQ(rect.GetBottom(), inf);
203 EXPECT_EQ(rect.GetX(), 5.0f);
204 EXPECT_EQ(rect.GetY(), max);
205 EXPECT_EQ(rect.GetWidth(), 20.0f);
206 EXPECT_EQ(rect.GetHeight(), inf);
207 EXPECT_FALSE(rect.IsEmpty());
208 EXPECT_FALSE(rect.IsFinite());
209 }
210
211 {
212 Rect rect = Rect::MakeXYWH(5.0, 10.0f, min, 15.0f);
213
214 EXPECT_EQ(rect.GetLeft(), 5.0f);
215 EXPECT_EQ(rect.GetTop(), 10.0f);
216 EXPECT_EQ(rect.GetRight(), min);
217 EXPECT_EQ(rect.GetBottom(), 25.0f);
218 EXPECT_EQ(rect.GetX(), 5.0f);
219 EXPECT_EQ(rect.GetY(), 10.0f);
220 EXPECT_EQ(rect.GetWidth(), min);
221 EXPECT_EQ(rect.GetHeight(), 15.0f);
222 EXPECT_TRUE(rect.IsEmpty());
223 EXPECT_TRUE(rect.IsFinite());
224 }
225
226 {
227 Rect rect = Rect::MakeXYWH(min, 10.0f, min, 15.0f);
228
229 EXPECT_EQ(rect.GetLeft(), min);
230 EXPECT_EQ(rect.GetTop(), 10.0f);
231 EXPECT_EQ(rect.GetRight(), -inf);
232 EXPECT_EQ(rect.GetBottom(), 25.0f);
233 EXPECT_EQ(rect.GetX(), min);
234 EXPECT_EQ(rect.GetY(), 10.0f);
235 EXPECT_EQ(rect.GetWidth(), -inf);
236 EXPECT_EQ(rect.GetHeight(), 15.0f);
237 EXPECT_TRUE(rect.IsEmpty());
238 EXPECT_FALSE(rect.IsFinite());
239 }
240
241 {
242 Rect rect = Rect::MakeXYWH(5.0f, 10.0f, 20.0f, min);
243
244 EXPECT_EQ(rect.GetLeft(), 5.0f);
245 EXPECT_EQ(rect.GetTop(), 10.0f);
246 EXPECT_EQ(rect.GetRight(), 25.0f);
247 EXPECT_EQ(rect.GetBottom(), min);
248 EXPECT_EQ(rect.GetX(), 5.0f);
249 EXPECT_EQ(rect.GetY(), 10.0f);
250 EXPECT_EQ(rect.GetWidth(), 20.0f);
251 EXPECT_EQ(rect.GetHeight(), min);
252 EXPECT_TRUE(rect.IsEmpty());
253 EXPECT_TRUE(rect.IsFinite());
254 }
255
256 {
257 Rect rect = Rect::MakeXYWH(5.0f, min, 20.0f, min);
258
259 EXPECT_EQ(rect.GetLeft(), 5.0f);
260 EXPECT_EQ(rect.GetTop(), min);
261 EXPECT_EQ(rect.GetRight(), 25.0f);
262 EXPECT_EQ(rect.GetBottom(), -inf);
263 EXPECT_EQ(rect.GetX(), 5.0f);
264 EXPECT_EQ(rect.GetY(), min);
265 EXPECT_EQ(rect.GetWidth(), 20.0f);
266 EXPECT_EQ(rect.GetHeight(), -inf);
267 EXPECT_TRUE(rect.IsEmpty());
268 EXPECT_FALSE(rect.IsFinite());
269 }
270}

◆ TEST() [299/377]

impeller::testing::TEST ( RectTest  ,
RectProject   
)

Definition at line 2995 of file rect_unittests.cc.

2995 {
2996 {
2997 auto r = Rect::MakeLTRB(-100, -100, 100, 100);
2998 auto actual = r.Project(r);
2999 auto expected = Rect::MakeLTRB(0, 0, 1, 1);
3000 EXPECT_RECT_NEAR(expected, actual);
3001 }
3002 {
3003 auto r = Rect::MakeLTRB(-100, -100, 100, 100);
3004 auto actual = r.Project(Rect::MakeLTRB(0, 0, 100, 100));
3005 auto expected = Rect::MakeLTRB(0.5, 0.5, 1, 1);
3006 EXPECT_RECT_NEAR(expected, actual);
3007 }
3008}

◆ TEST() [300/377]

impeller::testing::TEST ( RectTest  ,
RectRound   
)

Definition at line 3034 of file rect_unittests.cc.

3034 {
3035 {
3036 auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3037 EXPECT_EQ(Rect::Round(r), r);
3038 }
3039 {
3040 auto r = Rect::MakeLTRB(-100.4, -200.4, 300.4, 400.4);
3041 EXPECT_EQ(Rect::Round(r), Rect::MakeLTRB(-100, -200, 300, 400));
3042 }
3043 {
3044 auto r = Rect::MakeLTRB(-100.5, -200.5, 300.5, 400.5);
3045 EXPECT_EQ(Rect::Round(r), Rect::MakeLTRB(-101, -201, 301, 401));
3046 }
3047}

◆ TEST() [301/377]

impeller::testing::TEST ( RectTest  ,
RectRoundOut   
)

Definition at line 3010 of file rect_unittests.cc.

3010 {
3011 {
3012 auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3013 EXPECT_EQ(Rect::RoundOut(r), r);
3014 }
3015 {
3016 auto r = Rect::MakeLTRB(-100.1, -200.1, 300.1, 400.1);
3017 EXPECT_EQ(Rect::RoundOut(r), Rect::MakeLTRB(-101, -201, 301, 401));
3018 }
3019}

◆ TEST() [302/377]

impeller::testing::TEST ( RectTest  ,
RectRoundOutEmpty   
)

Definition at line 709 of file rect_unittests.cc.

709 {
710 Rect rect;
711
712 EXPECT_EQ(Rect::RoundOut(rect), Rect());
713
714 EXPECT_EQ(IRect::RoundOut(rect), IRect());
715}

◆ TEST() [303/377]

impeller::testing::TEST ( RectTest  ,
RectRoundOutSimple   
)

Definition at line 717 of file rect_unittests.cc.

717 {
718 Rect rect = Rect::MakeLTRB(5.125f, 10.75f, 20.625f, 25.375f);
719
720 EXPECT_EQ(Rect::RoundOut(rect), Rect::MakeLTRB(5.0f, 10.0f, 21.0f, 26.0f));
721
722 EXPECT_EQ(IRect::RoundOut(rect), IRect::MakeLTRB(5, 10, 21, 26));
723}

◆ TEST() [304/377]

impeller::testing::TEST ( RectTest  ,
RectRoundOutToIRectHuge   
)

Definition at line 725 of file rect_unittests.cc.

725 {
726 auto test = [](int corners) {
727 EXPECT_TRUE(corners >= 0 && corners <= 0xf);
728 Scalar l, t, r, b;
729 int64_t il, it, ir, ib;
730 l = il = 50;
731 t = it = 50;
732 r = ir = 80;
733 b = ib = 80;
734 if ((corners & (1 << 0)) != 0) {
735 l = -1E20;
737 }
738 if ((corners & (1 << 1)) != 0) {
739 t = -1E20;
741 }
742 if ((corners & (1 << 2)) != 0) {
743 r = +1E20;
745 }
746 if ((corners & (1 << 3)) != 0) {
747 b = +1E20;
749 }
750
751 Rect rect = Rect::MakeLTRB(l, t, r, b);
752 IRect irect = IRect::RoundOut(rect);
753 EXPECT_EQ(irect.GetLeft(), il) << corners;
754 EXPECT_EQ(irect.GetTop(), it) << corners;
755 EXPECT_EQ(irect.GetRight(), ir) << corners;
756 EXPECT_EQ(irect.GetBottom(), ib) << corners;
757 };
758
759 for (int corners = 0; corners <= 15; corners++) {
760 test(corners);
761 }
762}

◆ TEST() [305/377]

impeller::testing::TEST ( RectTest  ,
RectScale   
)

Definition at line 884 of file rect_unittests.cc.

884 {
885 auto test1 = [](Rect rect, Scalar scale) {
886 Rect expected = Rect::MakeXYWH(rect.GetX() * scale, //
887 rect.GetY() * scale, //
888 rect.GetWidth() * scale, //
889 rect.GetHeight() * scale);
890
891 EXPECT_RECT_NEAR(rect.Scale(scale), expected) //
892 << rect << " * " << scale;
893 EXPECT_RECT_NEAR(rect.Scale(scale, scale), expected) //
894 << rect << " * " << scale;
895 EXPECT_RECT_NEAR(rect.Scale(Point(scale, scale)), expected) //
896 << rect << " * " << scale;
897 EXPECT_RECT_NEAR(rect.Scale(Size(scale, scale)), expected) //
898 << rect << " * " << scale;
899 };
900
901 auto test2 = [&test1](Rect rect, Scalar scale_x, Scalar scale_y) {
902 Rect expected = Rect::MakeXYWH(rect.GetX() * scale_x, //
903 rect.GetY() * scale_y, //
904 rect.GetWidth() * scale_x, //
905 rect.GetHeight() * scale_y);
906
907 EXPECT_RECT_NEAR(rect.Scale(scale_x, scale_y), expected) //
908 << rect << " * " << scale_x << ", " << scale_y;
909 EXPECT_RECT_NEAR(rect.Scale(Point(scale_x, scale_y)), expected) //
910 << rect << " * " << scale_x << ", " << scale_y;
911 EXPECT_RECT_NEAR(rect.Scale(Size(scale_x, scale_y)), expected) //
912 << rect << " * " << scale_x << ", " << scale_y;
913
914 test1(rect, scale_x);
915 test1(rect, scale_y);
916 };
917
918 test2(Rect::MakeLTRB(10, 15, 100, 150), 1.0, 0.0);
919 test2(Rect::MakeLTRB(10, 15, 100, 150), 0.0, 1.0);
920 test2(Rect::MakeLTRB(10, 15, 100, 150), 0.0, 0.0);
921 test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, 3.5);
922 test2(Rect::MakeLTRB(10, 15, 100, 150), 3.5, 2.5);
923 test2(Rect::MakeLTRB(10, 15, -100, 150), 2.5, 3.5);
924 test2(Rect::MakeLTRB(10, 15, 100, -150), 2.5, 3.5);
925 test2(Rect::MakeLTRB(10, 15, 100, 150), -2.5, 3.5);
926 test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, -3.5);
927}

◆ TEST() [306/377]

impeller::testing::TEST ( RectTest  ,
RectShift   
)

Definition at line 2934 of file rect_unittests.cc.

2934 {
2935 auto r = Rect::MakeLTRB(0, 0, 100, 100);
2936
2937 EXPECT_EQ(r.Shift(Point(10, 5)), Rect::MakeLTRB(10, 5, 110, 105));
2938 EXPECT_EQ(r.Shift(Point(-10, -5)), Rect::MakeLTRB(-10, -5, 90, 95));
2939}

◆ TEST() [307/377]

impeller::testing::TEST ( RectTest  ,
RectSimpleLTRB   
)

Definition at line 73 of file rect_unittests.cc.

73 {
74 // Using fractional-power-of-2 friendly values for equality tests
75 Rect rect = Rect::MakeLTRB(5.125f, 10.25f, 20.625f, 25.375f);
76
77 EXPECT_EQ(rect.GetLeft(), 5.125f);
78 EXPECT_EQ(rect.GetTop(), 10.25f);
79 EXPECT_EQ(rect.GetRight(), 20.625f);
80 EXPECT_EQ(rect.GetBottom(), 25.375f);
81 EXPECT_EQ(rect.GetX(), 5.125f);
82 EXPECT_EQ(rect.GetY(), 10.25f);
83 EXPECT_EQ(rect.GetWidth(), 15.5f);
84 EXPECT_EQ(rect.GetHeight(), 15.125f);
85 EXPECT_FALSE(rect.IsEmpty());
86 EXPECT_TRUE(rect.IsFinite());
87}

◆ TEST() [308/377]

impeller::testing::TEST ( RectTest  ,
RectSimpleXYWH   
)

Definition at line 103 of file rect_unittests.cc.

103 {
104 // Using fractional-power-of-2 friendly values for equality tests
105 Rect rect = Rect::MakeXYWH(5.125f, 10.25f, 15.5f, 15.125f);
106
107 EXPECT_EQ(rect.GetLeft(), 5.125f);
108 EXPECT_EQ(rect.GetTop(), 10.25f);
109 EXPECT_EQ(rect.GetRight(), 20.625f);
110 EXPECT_EQ(rect.GetBottom(), 25.375f);
111 EXPECT_EQ(rect.GetX(), 5.125f);
112 EXPECT_EQ(rect.GetY(), 10.25f);
113 EXPECT_EQ(rect.GetWidth(), 15.5f);
114 EXPECT_EQ(rect.GetHeight(), 15.125f);
115 EXPECT_FALSE(rect.IsEmpty());
116 EXPECT_TRUE(rect.IsFinite());
117}

◆ TEST() [309/377]

impeller::testing::TEST ( RectTest  ,
RectUnion   
)

Definition at line 1313 of file rect_unittests.cc.

1313 {
1314 auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1315 ASSERT_TRUE(a.IsFinite()) << label;
1316 ASSERT_TRUE(b.IsFinite()) << label;
1317 ASSERT_FALSE(a.Union(b).IsEmpty());
1318
1319 for (int i = 1; i < 16; i++) {
1320 // NaN in a produces b
1321 EXPECT_EQ(swap_nan(a, i).Union(b), b) << label << ", index = " << i;
1322 // NaN in b produces a
1323 EXPECT_EQ(a.Union(swap_nan(b, i)), a) << label << ", index = " << i;
1324 // NaN in both is empty
1325 for (int j = 1; j < 16; j++) {
1327 << label << ", indices = " << i << ", " << j;
1328 }
1329 }
1330 };
1331
1332 auto check_empty_flips = [](const Rect& a, const Rect& b,
1333 const std::string& label) {
1334 ASSERT_FALSE(a.IsEmpty());
1335 // b is allowed to be empty
1336
1337 // unflipped a vs flipped (empty) b yields a
1338 EXPECT_EQ(a.Union(flip_lr(b)), a) << label;
1339 EXPECT_EQ(a.Union(flip_tb(b)), a) << label;
1340 EXPECT_EQ(a.Union(flip_lrtb(b)), a) << label;
1341
1342 // flipped (empty) a vs unflipped b yields b
1343 EXPECT_EQ(flip_lr(a).Union(b), b) << label;
1344 EXPECT_EQ(flip_tb(a).Union(b), b) << label;
1345 EXPECT_EQ(flip_lrtb(a).Union(b), b) << label;
1346
1347 // flipped (empty) a vs flipped (empty) b yields empty
1348 EXPECT_TRUE(flip_lr(a).Union(flip_lr(b)).IsEmpty()) << label;
1349 EXPECT_TRUE(flip_tb(a).Union(flip_tb(b)).IsEmpty()) << label;
1351 };
1352
1353 auto test = [&check_nans, &check_empty_flips](const Rect& a, const Rect& b,
1354 const Rect& result) {
1355 ASSERT_FALSE(a.IsEmpty()) << a;
1356 // b is allowed to be empty
1357
1358 std::stringstream stream;
1359 stream << a << " union " << b;
1360 auto label = stream.str();
1361
1362 EXPECT_EQ(a.Union(b), result) << label;
1363 EXPECT_EQ(b.Union(a), result) << label;
1364 check_empty_flips(a, b, label);
1365 check_nans(a, b, label);
1366 };
1367
1368 {
1369 auto a = Rect::MakeXYWH(100, 100, 100, 100);
1370 auto b = Rect::MakeXYWH(0, 0, 0, 0);
1371 auto expected = Rect::MakeXYWH(100, 100, 100, 100);
1372 test(a, b, expected);
1373 }
1374
1375 {
1376 auto a = Rect::MakeXYWH(100, 100, 100, 100);
1377 auto b = Rect::MakeXYWH(0, 0, 1, 1);
1378 auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1379 test(a, b, expected);
1380 }
1381
1382 {
1383 auto a = Rect::MakeXYWH(100, 100, 100, 100);
1384 auto b = Rect::MakeXYWH(10, 10, 1, 1);
1385 auto expected = Rect::MakeXYWH(10, 10, 190, 190);
1386 test(a, b, expected);
1387 }
1388
1389 {
1390 auto a = Rect::MakeXYWH(0, 0, 100, 100);
1391 auto b = Rect::MakeXYWH(10, 10, 100, 100);
1392 auto expected = Rect::MakeXYWH(0, 0, 110, 110);
1393 test(a, b, expected);
1394 }
1395
1396 {
1397 auto a = Rect::MakeXYWH(0, 0, 100, 100);
1398 auto b = Rect::MakeXYWH(100, 100, 100, 100);
1399 auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1400 test(a, b, expected);
1401 }
1402}

◆ TEST() [310/377]

impeller::testing::TEST ( RectTest  ,
RectXYWHIsEmpty   
)

Definition at line 1127 of file rect_unittests.cc.

1127 {
1128 auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1129
1130 // Non-empty
1131 EXPECT_FALSE(Rect::MakeXYWH(1.5, 2.3, 10.5, 7.2).IsEmpty());
1132
1133 // Empty both width and height both 0 or negative, in all combinations
1134 EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 0.0).IsEmpty());
1135 EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, -1.0).IsEmpty());
1136 EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, -1.0).IsEmpty());
1137 EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 0.0).IsEmpty());
1138
1139 // Empty for 0 or negative width or height (but not both at the same time)
1140 EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, 0.0).IsEmpty());
1141 EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, -1.0).IsEmpty());
1142 EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 7.2).IsEmpty());
1143 EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 7.2).IsEmpty());
1144
1145 // Empty for NaN in width or height or both
1146 EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, nan).IsEmpty());
1147 EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, 7.2).IsEmpty());
1148 EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, nan).IsEmpty());
1149}

◆ TEST() [311/377]

impeller::testing::TEST ( RectTest  ,
TransformAndClipBounds   
)

Definition at line 3067 of file rect_unittests.cc.

3067 {
3068 {
3069 // This matrix should clip no corners.
3071 // clang-format off
3072 2.0f, 0.0f, 0.0f, 0.0f,
3073 0.0f, 4.0f, 0.0f, 0.0f,
3074 0.0f, 0.0f, 1.0f, 0.0f,
3075 0.0f, 0.0f, 0.0f, 8.0f
3076 // clang-format on
3077 );
3078 Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3079 // None of these should have a W<0
3080 EXPECT_EQ(matrix.TransformHomogenous(src.GetLeftTop()),
3081 Vector3(200.0f, 400.0f, 8.0f));
3082 EXPECT_EQ(matrix.TransformHomogenous(src.GetRightTop()),
3083 Vector3(400.0f, 400.0f, 8.0f));
3084 EXPECT_EQ(matrix.TransformHomogenous(src.GetLeftBottom()),
3085 Vector3(200.0f, 800.0f, 8.0f));
3086 EXPECT_EQ(matrix.TransformHomogenous(src.GetRightBottom()),
3087 Vector3(400.0f, 800.0f, 8.0f));
3088
3089 Rect expect = Rect::MakeLTRB(25.0f, 50.0f, 50.0f, 100.0f);
3090 EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3091 EXPECT_EQ(src.TransformAndClipBounds(matrix), expect);
3092 }
3093
3094 {
3095 // This matrix should clip one corner.
3097 // clang-format off
3098 2.0f, 0.0f, 0.0f, -0.01f,
3099 0.0f, 2.0f, 0.0f, -0.006f,
3100 0.0f, 0.0f, 1.0f, 0.0f,
3101 0.0f, 0.0f, 0.0f, 3.0f
3102 // clang-format on
3103 );
3104 Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3105 // Exactly one of these should have a W<0
3106 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3107 Vector3(200.0f, 200.0f, 1.4f));
3108 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3109 Vector3(400.0f, 200.0f, 0.4f));
3110 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3111 Vector3(200.0f, 400.0f, 0.8f));
3112 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3113 Vector3(400.0f, 400.0f, -0.2f));
3114
3115 Rect expect = Rect::MakeLTRB(142.85715f, 142.85715f, 6553600.f, 6553600.f);
3116 EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3117 EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3118 }
3119
3120 {
3121 // This matrix should clip two corners.
3123 // clang-format off
3124 2.0f, 0.0f, 0.0f, -.015f,
3125 0.0f, 2.0f, 0.0f, -.006f,
3126 0.0f, 0.0f, 1.0f, 0.0f,
3127 0.0f, 0.0f, 0.0f, 3.0f
3128 // clang-format on
3129 );
3130 Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3131 // Exactly two of these should have a W<0
3132 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3133 Vector3(200.0f, 200.0f, 0.9f));
3134 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3135 Vector3(400.0f, 200.0f, -0.6f));
3136 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3137 Vector3(200.0f, 400.0f, 0.3f));
3138 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3139 Vector3(400.0f, 400.0f, -1.2f));
3140
3141 Rect expect = Rect::MakeLTRB(222.2222f, 222.2222f, 5898373.f, 6553600.f);
3142 EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3143 EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3144 }
3145
3146 {
3147 // This matrix should clip three corners.
3149 // clang-format off
3150 2.0f, 0.0f, 0.0f, -.02f,
3151 0.0f, 2.0f, 0.0f, -.006f,
3152 0.0f, 0.0f, 1.0f, 0.0f,
3153 0.0f, 0.0f, 0.0f, 3.0f
3154 // clang-format on
3155 );
3156 Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3157 // Exactly three of these should have a W<0
3158 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3159 Vector3(200.0f, 200.0f, 0.4f));
3160 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3161 Vector3(400.0f, 200.0f, -1.6f));
3162 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3163 Vector3(200.0f, 400.0f, -0.2f));
3164 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3165 Vector3(400.0f, 400.0f, -2.2f));
3166
3167 Rect expect = Rect::MakeLTRB(499.99988f, 499.99988f, 5898340.f, 4369400.f);
3168 EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3169 EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3170 }
3171
3172 {
3173 // This matrix should clip all four corners.
3175 // clang-format off
3176 2.0f, 0.0f, 0.0f, -.025f,
3177 0.0f, 2.0f, 0.0f, -.006f,
3178 0.0f, 0.0f, 1.0f, 0.0f,
3179 0.0f, 0.0f, 0.0f, 3.0f
3180 // clang-format on
3181 );
3182 Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3183 // All of these should have a W<0
3184 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3185 Vector3(200.0f, 200.0f, -0.1f));
3186 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3187 Vector3(400.0f, 200.0f, -2.6f));
3188 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3189 Vector3(200.0f, 400.0f, -0.7f));
3190 EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3191 Vector3(400.0f, 400.0f, -3.2f));
3192
3193 EXPECT_TRUE(src.TransformAndClipBounds(matrix).IsEmpty());
3194 }
3195}
#define EXPECT_VECTOR3_NEAR(a, b)
static constexpr Matrix MakeColumn(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
Definition: matrix.h:69

◆ TEST() [312/377]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesMSAAResolveWithCorrectStore   
)

Definition at line 102 of file render_pass_builder_vk_unittests.cc.

102 {
104 auto const context = MockVulkanContextBuilder().Build();
105
106 // Create an MSAA color attachment.
107 builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
108 SampleCount::kCount4, LoadAction::kClear,
109 StoreAction::kMultisampleResolve);
110
111 auto render_pass = builder.Build(context->GetDevice());
112
113 EXPECT_TRUE(!!render_pass);
114
115 auto maybe_color = builder.GetColorAttachments().find(0u);
116 ASSERT_NE(maybe_color, builder.GetColorAttachments().end());
117 auto color = maybe_color->second;
118
119 // MSAA Texture.
120 EXPECT_EQ(color.initialLayout, vk::ImageLayout::eGeneral);
121 EXPECT_EQ(color.finalLayout, vk::ImageLayout::eGeneral);
122 EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eClear);
123 EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eDontCare);
124
125 auto maybe_resolve = builder.GetResolves().find(0u);
126 ASSERT_NE(maybe_resolve, builder.GetResolves().end());
127 auto resolve = maybe_resolve->second;
128
129 // MSAA Resolve Texture.
130 EXPECT_EQ(resolve.initialLayout, vk::ImageLayout::eGeneral);
131 EXPECT_EQ(resolve.finalLayout, vk::ImageLayout::eGeneral);
132 EXPECT_EQ(resolve.loadOp, vk::AttachmentLoadOp::eClear);
133 EXPECT_EQ(resolve.storeOp, vk::AttachmentStoreOp::eStore);
134}

◆ TEST() [313/377]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithCombinedDepthStencil   
)

Definition at line 30 of file render_pass_builder_vk_unittests.cc.

30 {
32 auto const context = MockVulkanContextBuilder().Build();
33
34 // Create a single color attachment with a transient depth stencil.
35 builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
36 SampleCount::kCount1, LoadAction::kClear,
37 StoreAction::kStore);
38 builder.SetDepthStencilAttachment(PixelFormat::kD24UnormS8Uint,
39 SampleCount::kCount1, LoadAction::kDontCare,
40 StoreAction::kDontCare);
41
42 auto render_pass = builder.Build(context->GetDevice());
43
44 EXPECT_TRUE(!!render_pass);
45
46 auto maybe_color = builder.GetColorAttachments().find(0u);
47 ASSERT_NE(maybe_color, builder.GetColorAttachments().end());
48 auto color = maybe_color->second;
49
50 EXPECT_EQ(color.initialLayout, vk::ImageLayout::eGeneral);
51 EXPECT_EQ(color.finalLayout, vk::ImageLayout::eGeneral);
52 EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eClear);
53 EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eStore);
54
55 auto maybe_depth_stencil = builder.GetDepthStencil();
56 ASSERT_TRUE(maybe_depth_stencil.has_value());
57 if (!maybe_depth_stencil.has_value()) {
58 return;
59 }
60 auto depth_stencil = maybe_depth_stencil.value();
61
62 EXPECT_EQ(depth_stencil.initialLayout, vk::ImageLayout::eUndefined);
63 EXPECT_EQ(depth_stencil.finalLayout,
64 vk::ImageLayout::eDepthStencilAttachmentOptimal);
65 EXPECT_EQ(depth_stencil.loadOp, vk::AttachmentLoadOp::eDontCare);
66 EXPECT_EQ(depth_stencil.storeOp, vk::AttachmentStoreOp::eDontCare);
67 EXPECT_EQ(depth_stencil.stencilLoadOp, vk::AttachmentLoadOp::eDontCare);
68 EXPECT_EQ(depth_stencil.stencilStoreOp, vk::AttachmentStoreOp::eDontCare);
69}

◆ TEST() [314/377]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithNoDepthStencil   
)

Definition at line 15 of file render_pass_builder_vk_unittests.cc.

15 {
17 auto const context = MockVulkanContextBuilder().Build();
18
19 // Create a single color attachment with a transient depth stencil.
20 builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
21 SampleCount::kCount1, LoadAction::kClear,
22 StoreAction::kStore);
23
24 auto render_pass = builder.Build(context->GetDevice());
25
26 EXPECT_TRUE(!!render_pass);
27 EXPECT_FALSE(builder.GetDepthStencil().has_value());
28}

◆ TEST() [315/377]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithOnlyStencil   
)

Definition at line 71 of file render_pass_builder_vk_unittests.cc.

71 {
73 auto const context = MockVulkanContextBuilder().Build();
74
75 // Create a single color attachment with a transient depth stencil.
76 builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
77 SampleCount::kCount1, LoadAction::kClear,
78 StoreAction::kStore);
79 builder.SetStencilAttachment(PixelFormat::kS8UInt, SampleCount::kCount1,
80 LoadAction::kDontCare, StoreAction::kDontCare);
81
82 auto render_pass = builder.Build(context->GetDevice());
83
84 EXPECT_TRUE(!!render_pass);
85
86 auto maybe_depth_stencil = builder.GetDepthStencil();
87 ASSERT_TRUE(maybe_depth_stencil.has_value());
88 if (!maybe_depth_stencil.has_value()) {
89 return;
90 }
91 auto depth_stencil = maybe_depth_stencil.value();
92
93 EXPECT_EQ(depth_stencil.initialLayout, vk::ImageLayout::eUndefined);
94 EXPECT_EQ(depth_stencil.finalLayout,
95 vk::ImageLayout::eDepthStencilAttachmentOptimal);
96 EXPECT_EQ(depth_stencil.loadOp, vk::AttachmentLoadOp::eDontCare);
97 EXPECT_EQ(depth_stencil.storeOp, vk::AttachmentStoreOp::eDontCare);
98 EXPECT_EQ(depth_stencil.stencilLoadOp, vk::AttachmentLoadOp::eDontCare);
99 EXPECT_EQ(depth_stencil.stencilStoreOp, vk::AttachmentStoreOp::eDontCare);
100}

◆ TEST() [316/377]

impeller::testing::TEST ( ResourceManagerVKTest  ,
CreatesANewInstance   
)

Definition at line 18 of file resource_manager_vk_unittests.cc.

18 {
19 auto const a = ResourceManagerVK::Create();
20 auto const b = ResourceManagerVK::Create();
21 EXPECT_NE(a, b);
22}
static sk_sp< Effect > Create()
Definition: RefCntTest.cpp:117

◆ TEST() [317/377]

impeller::testing::TEST ( ResourceManagerVKTest  ,
IsThreadSafe   
)

Definition at line 58 of file resource_manager_vk_unittests.cc.

58 {
59 // In a typical app, there is a single ResourceManagerVK per app, shared b/w
60 // threads.
61 //
62 // This test ensures that the ResourceManagerVK is thread-safe.
63 std::weak_ptr<ResourceManagerVK> manager;
64
65 {
67
68 // Spawn two threads, and have them both put resources into the manager.
69 struct MockResource {};
70
71 std::thread thread1([&manager]() {
73 });
74
75 std::thread thread2([&manager]() {
76 UniqueResourceVKT<MockResource>(manager, MockResource{});
77 });
78
79 thread1.join();
80 thread2.join();
81 }
82
83 // The thread should have terminated.
84 EXPECT_EQ(manager.lock(), nullptr);
85}
A unique handle to a resource which will be reclaimed by the specified resource manager.
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 manager
Definition: switches.h:218

◆ TEST() [318/377]

impeller::testing::TEST ( ResourceManagerVKTest  ,
ReclaimMovesAResourceAndDestroysIt   
)

Definition at line 24 of file resource_manager_vk_unittests.cc.

24 {
26
27 auto waiter = fml::AutoResetWaitableEvent();
28 auto dead = false;
29 auto rattle = fml::ScopedCleanupClosure([&waiter]() { waiter.Signal(); });
30
31 // Not killed immediately.
32 EXPECT_FALSE(waiter.IsSignaledForTest());
33
34 {
36 manager, std::move(rattle));
37 }
38
39 waiter.Wait();
40}

◆ TEST() [319/377]

impeller::testing::TEST ( ResourceManagerVKTest  ,
TerminatesWhenOutOfScope   
)

Definition at line 43 of file resource_manager_vk_unittests.cc.

43 {
44 // Originally, this shared_ptr was never destroyed, and the thread never
45 // terminated. This test ensures that the thread terminates when the
46 // ResourceManagerVK is out of scope.
47 std::weak_ptr<ResourceManagerVK> manager;
48
49 {
50 auto shared = ResourceManagerVK::Create();
51 manager = shared;
52 }
53
54 // The thread should have terminated.
55 EXPECT_EQ(manager.lock(), nullptr);
56}

◆ TEST() [320/377]

impeller::testing::TEST ( SaturatedMath  ,
CastingFiniteDoubleToFloatStaysFinite   
)

Definition at line 981 of file saturated_math_unittests.cc.

981 {
982 const double d_max = std::numeric_limits<double>::max();
983 const float f_max = std::numeric_limits<float>::max();
984
985 {
986 const float result = saturated::Cast<double, float>(d_max);
987 EXPECT_EQ(result, f_max);
988 }
989
990 {
991 const float result = saturated::Cast<double, float>(-d_max);
992 EXPECT_EQ(result, -f_max);
993 }
994}

◆ TEST() [321/377]

impeller::testing::TEST ( SaturatedMath  ,
CastingInfiniteDoubleToFloatStaysInfinite   
)

Definition at line 996 of file saturated_math_unittests.cc.

996 {
997 const double d_inf = std::numeric_limits<double>::infinity();
998 const float f_max = std::numeric_limits<float>::infinity();
999
1000 {
1001 const float result = saturated::Cast<double, float>(d_inf);
1002 EXPECT_EQ(result, f_max);
1003 }
1004
1005 {
1006 const float result = saturated::Cast<double, float>(-d_inf);
1007 EXPECT_EQ(result, -f_max);
1008 }
1009}

◆ TEST() [322/377]

impeller::testing::TEST ( SaturatedMath  ,
CastingInfiniteScalarToSignedIntProducesLimit   
)

Definition at line 1066 of file saturated_math_unittests.cc.

1066 {
1067 // larger than even any [u]int64_t;
1068 const Scalar inf = std::numeric_limits<Scalar>::infinity();
1069
1070 {
1071 const auto result = saturated::Cast<Scalar, int8_t>(inf);
1072 EXPECT_EQ(result, int8_t(0x7F));
1073 }
1074 {
1075 const auto result = saturated::Cast<Scalar, int8_t>(-inf);
1076 EXPECT_EQ(result, int8_t(0x80));
1077 }
1078
1079 {
1080 const auto result = saturated::Cast<Scalar, int16_t>(inf);
1081 EXPECT_EQ(result, int16_t(0x7FFF));
1082 }
1083 {
1084 const auto result = saturated::Cast<Scalar, int16_t>(-inf);
1085 EXPECT_EQ(result, int16_t(0x8000));
1086 }
1087
1088 {
1089 const auto result = saturated::Cast<Scalar, int32_t>(inf);
1090 EXPECT_EQ(result, int32_t(0x7FFFFFFF));
1091 }
1092 {
1093 const auto result = saturated::Cast<Scalar, int32_t>(-inf);
1094 EXPECT_EQ(result, int32_t(0x80000000));
1095 }
1096
1097 {
1098 const auto result = saturated::Cast<Scalar, int64_t>(inf);
1099 EXPECT_EQ(result, int64_t(0x7FFFFFFFFFFFFFFF));
1100 }
1101 {
1102 const auto result = saturated::Cast<Scalar, int64_t>(-inf);
1103 EXPECT_EQ(result, int64_t(0x8000000000000000));
1104 }
1105}

◆ TEST() [323/377]

impeller::testing::TEST ( SaturatedMath  ,
CastingLargeScalarToSignedIntProducesLimit   
)

Definition at line 1025 of file saturated_math_unittests.cc.

1025 {
1026 // larger than even any [u]int64_t;
1027 const Scalar large = 1e20f;
1028
1029 {
1030 const auto result = saturated::Cast<Scalar, int8_t>(large);
1031 EXPECT_EQ(result, int8_t(0x7F));
1032 }
1033 {
1034 const auto result = saturated::Cast<Scalar, int8_t>(-large);
1035 EXPECT_EQ(result, int8_t(0x80));
1036 }
1037
1038 {
1039 const auto result = saturated::Cast<Scalar, int16_t>(large);
1040 EXPECT_EQ(result, int16_t(0x7FFF));
1041 }
1042 {
1043 const auto result = saturated::Cast<Scalar, int16_t>(-large);
1044 EXPECT_EQ(result, int16_t(0x8000));
1045 }
1046
1047 {
1048 const auto result = saturated::Cast<Scalar, int32_t>(large);
1049 EXPECT_EQ(result, int32_t(0x7FFFFFFF));
1050 }
1051 {
1052 const auto result = saturated::Cast<Scalar, int32_t>(-large);
1053 EXPECT_EQ(result, int32_t(0x80000000));
1054 }
1055
1056 {
1057 const auto result = saturated::Cast<Scalar, int64_t>(large);
1058 EXPECT_EQ(result, int64_t(0x7FFFFFFFFFFFFFFF));
1059 }
1060 {
1061 const auto result = saturated::Cast<Scalar, int64_t>(-large);
1062 EXPECT_EQ(result, int64_t(0x8000000000000000));
1063 }
1064}

◆ TEST() [324/377]

impeller::testing::TEST ( SaturatedMath  ,
CastingNaNDoubleToFloatStaysNaN   
)

Definition at line 1011 of file saturated_math_unittests.cc.

1011 {
1012 const double d_nan = std::numeric_limits<double>::quiet_NaN();
1013
1014 {
1015 const float result = saturated::Cast<double, float>(d_nan);
1016 EXPECT_TRUE(std::isnan(result));
1017 }
1018
1019 {
1020 const float result = saturated::Cast<double, float>(-d_nan);
1021 EXPECT_TRUE(std::isnan(result));
1022 }
1023}

◆ TEST() [325/377]

impeller::testing::TEST ( SaturatedMath  ,
CastingNaNScalarToSignedIntProducesZero   
)

Definition at line 1107 of file saturated_math_unittests.cc.

1107 {
1108 // larger than even any [u]int64_t;
1109 const Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1110
1111 {
1112 const auto result = saturated::Cast<Scalar, int8_t>(nan);
1113 EXPECT_EQ(result, int8_t(0));
1114 }
1115
1116 {
1117 const auto result = saturated::Cast<Scalar, int16_t>(nan);
1118 EXPECT_EQ(result, int16_t(0));
1119 }
1120
1121 {
1122 const auto result = saturated::Cast<Scalar, int32_t>(nan);
1123 EXPECT_EQ(result, int32_t(0));
1124 }
1125
1126 {
1127 const auto result = saturated::Cast<Scalar, int64_t>(nan);
1128 EXPECT_EQ(result, int64_t(0));
1129 }
1130}

◆ TEST() [326/377]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitAddOfFloatingPoint   
)

Definition at line 136 of file saturated_math_unittests.cc.

136 {
137 {
138 const float inf = std::numeric_limits<float>::infinity();
139 const float max = std::numeric_limits<float>::max();
140 const float big = max * 0.5f;
141
142 EXPECT_EQ(saturated::Add<float>(big, big), max);
143 EXPECT_EQ(saturated::Add<float>(max, big), inf);
144 EXPECT_EQ(saturated::Add<float>(big, max), inf);
145 EXPECT_EQ(saturated::Add<float>(max, max), inf);
146 EXPECT_EQ(saturated::Add<float>(max, inf), inf);
147 EXPECT_EQ(saturated::Add<float>(inf, max), inf);
148 EXPECT_EQ(saturated::Add<float>(inf, inf), inf);
149
150 EXPECT_EQ(saturated::Add<float>(-big, -big), -max);
151 EXPECT_EQ(saturated::Add<float>(-max, -big), -inf);
152 EXPECT_EQ(saturated::Add<float>(-big, -max), -inf);
153 EXPECT_EQ(saturated::Add<float>(-max, -max), -inf);
154 EXPECT_EQ(saturated::Add<float>(-max, -inf), -inf);
155 EXPECT_EQ(saturated::Add<float>(-inf, -max), -inf);
156 EXPECT_EQ(saturated::Add<float>(-inf, -inf), -inf);
157
158 EXPECT_EQ(saturated::Add<float>(big, -big), 0.0f);
159 EXPECT_EQ(saturated::Add<float>(max, -big), big);
160 EXPECT_EQ(saturated::Add<float>(big, -max), -big);
161 EXPECT_EQ(saturated::Add<float>(max, -max), 0.0f);
162 EXPECT_EQ(saturated::Add<float>(max, -inf), -inf);
163 EXPECT_EQ(saturated::Add<float>(inf, -max), inf);
164 EXPECT_TRUE(std::isnan(saturated::Add<float>(inf, -inf)));
165
166 EXPECT_EQ(saturated::Add<float>(-big, big), 0.0f);
167 EXPECT_EQ(saturated::Add<float>(-max, big), -big);
168 EXPECT_EQ(saturated::Add<float>(-big, max), big);
169 EXPECT_EQ(saturated::Add<float>(-max, max), 0.0f);
170 EXPECT_EQ(saturated::Add<float>(-max, inf), inf);
171 EXPECT_EQ(saturated::Add<float>(-inf, max), -inf);
172 EXPECT_TRUE(std::isnan(saturated::Add<float>(-inf, inf)));
173 }
174 {
175 const double inf = std::numeric_limits<double>::infinity();
176 const double max = std::numeric_limits<double>::max();
177 const double big = max * 0.5f;
178
179 EXPECT_EQ(saturated::Add<double>(big, big), max);
180 EXPECT_EQ(saturated::Add<double>(max, big), inf);
181 EXPECT_EQ(saturated::Add<double>(big, max), inf);
182 EXPECT_EQ(saturated::Add<double>(max, max), inf);
183 EXPECT_EQ(saturated::Add<double>(max, inf), inf);
184 EXPECT_EQ(saturated::Add<double>(inf, max), inf);
185 EXPECT_EQ(saturated::Add<double>(inf, inf), inf);
186
187 EXPECT_EQ(saturated::Add<double>(-big, -big), -max);
188 EXPECT_EQ(saturated::Add<double>(-max, -big), -inf);
189 EXPECT_EQ(saturated::Add<double>(-big, -max), -inf);
190 EXPECT_EQ(saturated::Add<double>(-max, -max), -inf);
191 EXPECT_EQ(saturated::Add<double>(-max, -inf), -inf);
192 EXPECT_EQ(saturated::Add<double>(-inf, -max), -inf);
193 EXPECT_EQ(saturated::Add<double>(-inf, -inf), -inf);
194
195 EXPECT_EQ(saturated::Add<double>(big, -big), 0.0f);
196 EXPECT_EQ(saturated::Add<double>(max, -big), big);
197 EXPECT_EQ(saturated::Add<double>(big, -max), -big);
198 EXPECT_EQ(saturated::Add<double>(max, -max), 0.0f);
199 EXPECT_EQ(saturated::Add<double>(max, -inf), -inf);
200 EXPECT_EQ(saturated::Add<double>(inf, -max), inf);
201 EXPECT_TRUE(std::isnan(saturated::Add<double>(inf, -inf)));
202
203 EXPECT_EQ(saturated::Add<double>(-big, big), 0.0f);
204 EXPECT_EQ(saturated::Add<double>(-max, big), -big);
205 EXPECT_EQ(saturated::Add<double>(-big, max), big);
206 EXPECT_EQ(saturated::Add<double>(-max, max), 0.0f);
207 EXPECT_EQ(saturated::Add<double>(-max, inf), inf);
208 EXPECT_EQ(saturated::Add<double>(-inf, max), -inf);
209 EXPECT_TRUE(std::isnan(saturated::Add<double>(-inf, inf)));
210 }
211 {
212 const Scalar inf = std::numeric_limits<Scalar>::infinity();
214 const Scalar big = max * 0.5f;
215
216 EXPECT_EQ(saturated::Add<Scalar>(big, big), max);
217 EXPECT_EQ(saturated::Add<Scalar>(max, big), inf);
218 EXPECT_EQ(saturated::Add<Scalar>(big, max), inf);
219 EXPECT_EQ(saturated::Add<Scalar>(max, max), inf);
220 EXPECT_EQ(saturated::Add<Scalar>(max, inf), inf);
221 EXPECT_EQ(saturated::Add<Scalar>(inf, max), inf);
222 EXPECT_EQ(saturated::Add<Scalar>(inf, inf), inf);
223
224 EXPECT_EQ(saturated::Add<Scalar>(-big, -big), -max);
225 EXPECT_EQ(saturated::Add<Scalar>(-max, -big), -inf);
226 EXPECT_EQ(saturated::Add<Scalar>(-big, -max), -inf);
227 EXPECT_EQ(saturated::Add<Scalar>(-max, -max), -inf);
228 EXPECT_EQ(saturated::Add<Scalar>(-max, -inf), -inf);
229 EXPECT_EQ(saturated::Add<Scalar>(-inf, -max), -inf);
230 EXPECT_EQ(saturated::Add<Scalar>(-inf, -inf), -inf);
231
232 EXPECT_EQ(saturated::Add<Scalar>(big, -big), 0.0f);
233 EXPECT_EQ(saturated::Add<Scalar>(max, -big), big);
234 EXPECT_EQ(saturated::Add<Scalar>(big, -max), -big);
235 EXPECT_EQ(saturated::Add<Scalar>(max, -max), 0.0f);
236 EXPECT_EQ(saturated::Add<Scalar>(max, -inf), -inf);
237 EXPECT_EQ(saturated::Add<Scalar>(inf, -max), inf);
238 EXPECT_TRUE(std::isnan(saturated::Add<Scalar>(inf, -inf)));
239
240 EXPECT_EQ(saturated::Add<Scalar>(-big, big), 0.0f);
241 EXPECT_EQ(saturated::Add<Scalar>(-max, big), -big);
242 EXPECT_EQ(saturated::Add<Scalar>(-big, max), big);
243 EXPECT_EQ(saturated::Add<Scalar>(-max, max), 0.0f);
244 EXPECT_EQ(saturated::Add<Scalar>(-max, inf), inf);
245 EXPECT_EQ(saturated::Add<Scalar>(-inf, max), -inf);
246 EXPECT_TRUE(std::isnan(saturated::Add<Scalar>(-inf, inf)));
247 }
248}

◆ TEST() [327/377]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitAddOfSignedInts   
)

Definition at line 12 of file saturated_math_unittests.cc.

12 {
13 {
14 EXPECT_EQ(saturated::Add<int8_t>(0x79, 5), int8_t(0x7E));
15 EXPECT_EQ(saturated::Add<int8_t>(0x7A, 5), int8_t(0x7F));
16 EXPECT_EQ(saturated::Add<int8_t>(0x7B, 5), int8_t(0x7F));
17 }
18 {
19 EXPECT_EQ(saturated::Add<int8_t>(0x86, -5), int8_t(0x81));
20 EXPECT_EQ(saturated::Add<int8_t>(0x85, -5), int8_t(0x80));
21 EXPECT_EQ(saturated::Add<int8_t>(0x84, -5), int8_t(0x80));
22 }
23 {
24 EXPECT_EQ(saturated::Add<int16_t>(0x7FF9, 5), int16_t(0x7FFE));
25 EXPECT_EQ(saturated::Add<int16_t>(0x7FFA, 5), int16_t(0x7FFF));
26 EXPECT_EQ(saturated::Add<int16_t>(0x7FFB, 5), int16_t(0x7FFF));
27 }
28 {
29 EXPECT_EQ(saturated::Add<int16_t>(0x8006, -5), int16_t(0x8001));
30 EXPECT_EQ(saturated::Add<int16_t>(0x8005, -5), int16_t(0x8000));
31 EXPECT_EQ(saturated::Add<int16_t>(0x8004, -5), int16_t(0x8000));
32 }
33 {
34 EXPECT_EQ(saturated::Add<int32_t>(0x7FFFFFF9, 5), int32_t(0x7FFFFFFE));
35 EXPECT_EQ(saturated::Add<int32_t>(0x7FFFFFFA, 5), int32_t(0x7FFFFFFF));
36 EXPECT_EQ(saturated::Add<int32_t>(0x7FFFFFFB, 5), int32_t(0x7FFFFFFF));
37 }
38 {
39 EXPECT_EQ(saturated::Add<int32_t>(0x80000006, -5), int32_t(0x80000001));
40 EXPECT_EQ(saturated::Add<int32_t>(0x80000005, -5), int32_t(0x80000000));
41 EXPECT_EQ(saturated::Add<int32_t>(0x80000004, -5), int32_t(0x80000000));
42 }
43 {
44 EXPECT_EQ(saturated::Add<int64_t>(0x7FFFFFFFFFFFFFF9, 5),
45 int64_t(0x7FFFFFFFFFFFFFFE));
46 EXPECT_EQ(saturated::Add<int64_t>(0x7FFFFFFFFFFFFFFA, 5),
47 int64_t(0x7FFFFFFFFFFFFFFF));
48 EXPECT_EQ(saturated::Add<int64_t>(0x7FFFFFFFFFFFFFFB, 5),
49 int64_t(0x7FFFFFFFFFFFFFFF));
50 }
51 {
52 EXPECT_EQ(saturated::Add<int64_t>(0x8000000000000006, -5),
53 int64_t(0x8000000000000001));
54 EXPECT_EQ(saturated::Add<int64_t>(0x8000000000000005, -5),
55 int64_t(0x8000000000000000));
56 EXPECT_EQ(saturated::Add<int64_t>(0x8000000000000004, -5),
57 int64_t(0x8000000000000000));
58 }
59}

◆ TEST() [328/377]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitAverageScalarOfFloatingPoint   
)

Definition at line 828 of file saturated_math_unittests.cc.

828 {
829 const Scalar s_inf = std::numeric_limits<Scalar>::infinity();
831 const Scalar s_big = s_max * 0.5f;
832
833 {
834 const float inf = std::numeric_limits<Scalar>::infinity();
835 const float max = std::numeric_limits<float>::max();
836 const float big = max * 0.5f;
837
838 EXPECT_EQ(saturated::AverageScalar<float>(big, big), s_big);
839 EXPECT_EQ(saturated::AverageScalar<float>(max, max), s_max);
840 EXPECT_EQ(saturated::AverageScalar<float>(big, -big), 0.0f);
841 EXPECT_EQ(saturated::AverageScalar<float>(max, -max), 0.0f);
842 EXPECT_EQ(saturated::AverageScalar<float>(-big, big), 0.0f);
843 EXPECT_EQ(saturated::AverageScalar<float>(-max, max), 0.0f);
844 EXPECT_EQ(saturated::AverageScalar<float>(-big, -big), -s_big);
845 EXPECT_EQ(saturated::AverageScalar<float>(-max, -max), -s_max);
846
847 EXPECT_EQ(saturated::AverageScalar<float>(inf, inf), s_inf);
848 EXPECT_EQ(saturated::AverageScalar<float>(-inf, -inf), -s_inf);
849 EXPECT_TRUE(std::isnan(saturated::AverageScalar<float>(-inf, inf)));
850 EXPECT_TRUE(std::isnan(saturated::AverageScalar<float>(inf, -inf)));
851 }
852 {
853 const double inf = std::numeric_limits<Scalar>::infinity();
854 const double max = std::numeric_limits<double>::max();
855 const double big = max * 0.5;
856
857 // Most of the averages below using the double constants will
858 // overflow the Scalar return value and result in infinity,
859 // so we also test with some Scalar constants (promoted to double)
860 // to verify that they don't overflow in the double template
861 EXPECT_EQ(saturated::AverageScalar<double>(s_big, s_big), s_big);
862 EXPECT_EQ(saturated::AverageScalar<double>(s_max, s_max), s_max);
863 EXPECT_EQ(saturated::AverageScalar<double>(-s_big, -s_big), -s_big);
864 EXPECT_EQ(saturated::AverageScalar<double>(-s_max, -s_max), -s_max);
865
866 // And now testing continues with the double constants which
867 // mostly overflow
868 EXPECT_EQ(saturated::AverageScalar<double>(big, big), s_inf);
869 EXPECT_EQ(saturated::AverageScalar<double>(max, max), s_inf);
870 EXPECT_EQ(saturated::AverageScalar<double>(big, -big), 0.0f);
871 EXPECT_EQ(saturated::AverageScalar<double>(max, -max), 0.0f);
872 EXPECT_EQ(saturated::AverageScalar<double>(-big, big), 0.0f);
873 EXPECT_EQ(saturated::AverageScalar<double>(-max, max), 0.0f);
874 EXPECT_EQ(saturated::AverageScalar<double>(-big, -big), -s_inf);
875 EXPECT_EQ(saturated::AverageScalar<double>(-max, -max), -s_inf);
876
877 EXPECT_EQ(saturated::AverageScalar<double>(inf, inf), s_inf);
878 EXPECT_EQ(saturated::AverageScalar<double>(-inf, -inf), -s_inf);
879 EXPECT_TRUE(std::isnan(saturated::AverageScalar<double>(-inf, inf)));
880 EXPECT_TRUE(std::isnan(saturated::AverageScalar<double>(inf, -inf)));
881 }
882 {
883 const Scalar inf = std::numeric_limits<Scalar>::infinity();
885 const Scalar big = max * 0.5f;
886
887 EXPECT_EQ(saturated::AverageScalar<Scalar>(big, big), s_big);
888 EXPECT_EQ(saturated::AverageScalar<Scalar>(max, max), s_max);
889 EXPECT_EQ(saturated::AverageScalar<Scalar>(big, -big), 0.0f);
890 EXPECT_EQ(saturated::AverageScalar<Scalar>(max, -max), 0.0f);
891 EXPECT_EQ(saturated::AverageScalar<Scalar>(-big, big), 0.0f);
892 EXPECT_EQ(saturated::AverageScalar<Scalar>(-max, max), 0.0f);
893 EXPECT_EQ(saturated::AverageScalar<Scalar>(-big, -big), -s_big);
894 EXPECT_EQ(saturated::AverageScalar<Scalar>(-max, -max), -s_max);
895
896 EXPECT_EQ(saturated::AverageScalar<Scalar>(inf, inf), s_inf);
897 EXPECT_EQ(saturated::AverageScalar<Scalar>(-inf, -inf), -s_inf);
898 EXPECT_TRUE(std::isnan(saturated::AverageScalar<Scalar>(-inf, s_inf)));
899 EXPECT_TRUE(std::isnan(saturated::AverageScalar<Scalar>(inf, -s_inf)));
900 }
901}

◆ TEST() [329/377]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitAverageScalarOfSignedInts   
)

Definition at line 716 of file saturated_math_unittests.cc.

716 {
717 // For each type try:
718 //
719 // - near the limits, averaging to 0
720 // - at the limits, averaging to 0 or 0.5 depending on precision
721 // - both large enough for the sum to overflow
722 // - both negative enough for the sum to underflow
723 {
724 EXPECT_EQ(saturated::AverageScalar<int8_t>(0x81, 0x7F), -0.0f);
725 EXPECT_EQ(saturated::AverageScalar<int8_t>(0x80, 0x7F), -0.5f);
726 EXPECT_EQ(saturated::AverageScalar<int8_t>(0x70, 0x75), 114.5f);
727 EXPECT_EQ(saturated::AverageScalar<int8_t>(0x85, 0x8A), -120.5f);
728 }
729 {
730 EXPECT_EQ(saturated::AverageScalar<int16_t>(0x8001, 0x7FFF), -0.0f);
731 EXPECT_EQ(saturated::AverageScalar<int16_t>(0x8000, 0x7FFF), -0.5f);
732 EXPECT_EQ(saturated::AverageScalar<int16_t>(0x7000, 0x7005), 28674.5f);
733 EXPECT_EQ(saturated::AverageScalar<int16_t>(0x8005, 0x800A), -32760.5f);
734 }
735 {
736 EXPECT_EQ(saturated::AverageScalar<int32_t>(0x80000001, 0x7FFFFFFF), -0.0f);
737 EXPECT_EQ(saturated::AverageScalar<int32_t>(0x80000000, 0x7FFFFFFF), -0.5f);
738 EXPECT_EQ(saturated::AverageScalar<int32_t>(0x70000000, 0x70000005),
739 1879048195.5f);
740 EXPECT_EQ(saturated::AverageScalar<int32_t>(0x80000005, 0x8000000A),
741 -2147483655.5f);
742 }
743 {
744 EXPECT_EQ(saturated::AverageScalar<int64_t>(0x8000000000000001,
745 0x7FFFFFFFFFFFFFFF),
746 0.0f);
747 // 64-bit integers overflow the ability of a Scalar (float) to
748 // represent discrete integers and so the two numbers we are
749 // averaging here will look like the same number with different
750 // signs and the answer will be "0"
751 EXPECT_EQ(saturated::AverageScalar<int64_t>(0x8000000000000000,
752 0x7FFFFFFFFFFFFFFF),
753 0.0f);
754 EXPECT_NEAR(saturated::AverageScalar<int64_t>(0x7000000000000000,
755 0x7000000000000005),
756 8.07045053e+18, 1e18);
757 EXPECT_NEAR(saturated::AverageScalar<int64_t>(0x8000000000000005,
758 0x800000000000000A),
759 -9.223372e+18, 1e18);
760 }
761}

◆ TEST() [330/377]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitSubOfFloatingPoint   
)

Definition at line 488 of file saturated_math_unittests.cc.

488 {
489 {
490 const float inf = std::numeric_limits<float>::infinity();
491 const float max = std::numeric_limits<float>::max();
492 const float big = max * 0.5f;
493
494 EXPECT_EQ(saturated::Sub<float>(big, big), 0.0f);
495 EXPECT_EQ(saturated::Sub<float>(max, big), big);
496 EXPECT_EQ(saturated::Sub<float>(big, max), -big);
497 EXPECT_EQ(saturated::Sub<float>(max, max), 0.0f);
498 EXPECT_EQ(saturated::Sub<float>(max, inf), -inf);
499 EXPECT_EQ(saturated::Sub<float>(inf, max), inf);
500 EXPECT_TRUE(std::isnan(saturated::Sub<float>(inf, inf)));
501
502 EXPECT_EQ(saturated::Sub<float>(-big, -big), 0.0f);
503 EXPECT_EQ(saturated::Sub<float>(-max, -big), -big);
504 EXPECT_EQ(saturated::Sub<float>(-big, -max), big);
505 EXPECT_EQ(saturated::Sub<float>(-max, -max), 0.0f);
506 EXPECT_EQ(saturated::Sub<float>(-max, -inf), inf);
507 EXPECT_EQ(saturated::Sub<float>(-inf, -max), -inf);
508 EXPECT_TRUE(std::isnan(saturated::Sub<float>(-inf, -inf)));
509
510 EXPECT_EQ(saturated::Sub<float>(big, -big), max);
511 EXPECT_EQ(saturated::Sub<float>(max, -big), inf);
512 EXPECT_EQ(saturated::Sub<float>(big, -max), inf);
513 EXPECT_EQ(saturated::Sub<float>(max, -max), inf);
514 EXPECT_EQ(saturated::Sub<float>(max, -inf), inf);
515 EXPECT_EQ(saturated::Sub<float>(inf, -max), inf);
516 EXPECT_EQ(saturated::Sub<float>(inf, -inf), inf);
517
518 EXPECT_EQ(saturated::Sub<float>(-big, big), -max);
519 EXPECT_EQ(saturated::Sub<float>(-max, big), -inf);
520 EXPECT_EQ(saturated::Sub<float>(-big, max), -inf);
521 EXPECT_EQ(saturated::Sub<float>(-max, max), -inf);
522 EXPECT_EQ(saturated::Sub<float>(-max, inf), -inf);
523 EXPECT_EQ(saturated::Sub<float>(-inf, max), -inf);
524 EXPECT_EQ(saturated::Sub<float>(-inf, inf), -inf);
525 }
526 {
527 const double inf = std::numeric_limits<double>::infinity();
528 const double max = std::numeric_limits<double>::max();
529 const double big = max * 0.5f;
530
531 EXPECT_EQ(saturated::Sub<double>(big, big), 0.0f);
532 EXPECT_EQ(saturated::Sub<double>(max, big), big);
533 EXPECT_EQ(saturated::Sub<double>(big, max), -big);
534 EXPECT_EQ(saturated::Sub<double>(max, max), 0.0f);
535 EXPECT_EQ(saturated::Sub<double>(max, inf), -inf);
536 EXPECT_EQ(saturated::Sub<double>(inf, max), inf);
537 EXPECT_TRUE(std::isnan(saturated::Sub<double>(inf, inf)));
538
539 EXPECT_EQ(saturated::Sub<double>(-big, -big), 0.0f);
540 EXPECT_EQ(saturated::Sub<double>(-max, -big), -big);
541 EXPECT_EQ(saturated::Sub<double>(-big, -max), big);
542 EXPECT_EQ(saturated::Sub<double>(-max, -max), 0.0f);
543 EXPECT_EQ(saturated::Sub<double>(-max, -inf), inf);
544 EXPECT_EQ(saturated::Sub<double>(-inf, -max), -inf);
545 EXPECT_TRUE(std::isnan(saturated::Sub<double>(-inf, -inf)));
546
547 EXPECT_EQ(saturated::Sub<double>(big, -big), max);
548 EXPECT_EQ(saturated::Sub<double>(max, -big), inf);
549 EXPECT_EQ(saturated::Sub<double>(big, -max), inf);
550 EXPECT_EQ(saturated::Sub<double>(max, -max), inf);
551 EXPECT_EQ(saturated::Sub<double>(max, -inf), inf);
552 EXPECT_EQ(saturated::Sub<double>(inf, -max), inf);
553 EXPECT_EQ(saturated::Sub<double>(inf, -inf), inf);
554
555 EXPECT_EQ(saturated::Sub<double>(-big, big), -max);
556 EXPECT_EQ(saturated::Sub<double>(-max, big), -inf);
557 EXPECT_EQ(saturated::Sub<double>(-big, max), -inf);
558 EXPECT_EQ(saturated::Sub<double>(-max, max), -inf);
559 EXPECT_EQ(saturated::Sub<double>(-max, inf), -inf);
560 EXPECT_EQ(saturated::Sub<double>(-inf, max), -inf);
561 EXPECT_EQ(saturated::Sub<double>(-inf, inf), -inf);
562 }
563 {
564 const Scalar inf = std::numeric_limits<Scalar>::infinity();
566 const Scalar big = max * 0.5f;
567
568 EXPECT_EQ(saturated::Sub<Scalar>(big, big), 0.0f);
569 EXPECT_EQ(saturated::Sub<Scalar>(max, big), big);
570 EXPECT_EQ(saturated::Sub<Scalar>(big, max), -big);
571 EXPECT_EQ(saturated::Sub<Scalar>(max, max), 0.0f);
572 EXPECT_EQ(saturated::Sub<Scalar>(max, inf), -inf);
573 EXPECT_EQ(saturated::Sub<Scalar>(inf, max), inf);
574 EXPECT_TRUE(std::isnan(saturated::Sub<Scalar>(inf, inf)));
575
576 EXPECT_EQ(saturated::Sub<Scalar>(-big, -big), 0.0f);
577 EXPECT_EQ(saturated::Sub<Scalar>(-max, -big), -big);
578 EXPECT_EQ(saturated::Sub<Scalar>(-big, -max), big);
579 EXPECT_EQ(saturated::Sub<Scalar>(-max, -max), 0.0f);
580 EXPECT_EQ(saturated::Sub<Scalar>(-max, -inf), inf);
581 EXPECT_EQ(saturated::Sub<Scalar>(-inf, -max), -inf);
582 EXPECT_TRUE(std::isnan(saturated::Sub<Scalar>(-inf, -inf)));
583
584 EXPECT_EQ(saturated::Sub<Scalar>(big, -big), max);
585 EXPECT_EQ(saturated::Sub<Scalar>(max, -big), inf);
586 EXPECT_EQ(saturated::Sub<Scalar>(big, -max), inf);
587 EXPECT_EQ(saturated::Sub<Scalar>(max, -max), inf);
588 EXPECT_EQ(saturated::Sub<Scalar>(max, -inf), inf);
589 EXPECT_EQ(saturated::Sub<Scalar>(inf, -max), inf);
590 EXPECT_EQ(saturated::Sub<Scalar>(inf, -inf), inf);
591
592 EXPECT_EQ(saturated::Sub<Scalar>(-big, big), -max);
593 EXPECT_EQ(saturated::Sub<Scalar>(-max, big), -inf);
594 EXPECT_EQ(saturated::Sub<Scalar>(-big, max), -inf);
595 EXPECT_EQ(saturated::Sub<Scalar>(-max, max), -inf);
596 EXPECT_EQ(saturated::Sub<Scalar>(-max, inf), -inf);
597 EXPECT_EQ(saturated::Sub<Scalar>(-inf, max), -inf);
598 EXPECT_EQ(saturated::Sub<Scalar>(-inf, inf), -inf);
599 }
600}

◆ TEST() [331/377]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitSubOfSignedInts   
)

Definition at line 364 of file saturated_math_unittests.cc.

364 {
365 {
366 EXPECT_EQ(saturated::Sub<int8_t>(0x79, -5), int8_t(0x7E));
367 EXPECT_EQ(saturated::Sub<int8_t>(0x7A, -5), int8_t(0x7F));
368 EXPECT_EQ(saturated::Sub<int8_t>(0x7B, -5), int8_t(0x7F));
369 }
370 {
371 EXPECT_EQ(saturated::Sub<int8_t>(0x86, 5), int8_t(0x81));
372 EXPECT_EQ(saturated::Sub<int8_t>(0x85, 5), int8_t(0x80));
373 EXPECT_EQ(saturated::Sub<int8_t>(0x84, 5), int8_t(0x80));
374 }
375 {
376 EXPECT_EQ(saturated::Sub<int16_t>(0x7FF9, -5), int16_t(0x7FFE));
377 EXPECT_EQ(saturated::Sub<int16_t>(0x7FFA, -5), int16_t(0x7FFF));
378 EXPECT_EQ(saturated::Sub<int16_t>(0x7FFB, -5), int16_t(0x7FFF));
379 }
380 {
381 EXPECT_EQ(saturated::Sub<int16_t>(0x8006, 5), int16_t(0x8001));
382 EXPECT_EQ(saturated::Sub<int16_t>(0x8005, 5), int16_t(0x8000));
383 EXPECT_EQ(saturated::Sub<int16_t>(0x8004, 5), int16_t(0x8000));
384 }
385 {
386 EXPECT_EQ(saturated::Sub<int32_t>(0x7FFFFFF9, -5), int32_t(0x7FFFFFFE));
387 EXPECT_EQ(saturated::Sub<int32_t>(0x7FFFFFFA, -5), int32_t(0x7FFFFFFF));
388 EXPECT_EQ(saturated::Sub<int32_t>(0x7FFFFFFB, -5), int32_t(0x7FFFFFFF));
389 }
390 {
391 EXPECT_EQ(saturated::Sub<int32_t>(0x80000006, 5), int32_t(0x80000001));
392 EXPECT_EQ(saturated::Sub<int32_t>(0x80000005, 5), int32_t(0x80000000));
393 EXPECT_EQ(saturated::Sub<int32_t>(0x80000004, 5), int32_t(0x80000000));
394 }
395 {
396 EXPECT_EQ(saturated::Sub<int64_t>(0x7FFFFFFFFFFFFFF9, -5),
397 int64_t(0x7FFFFFFFFFFFFFFE));
398 EXPECT_EQ(saturated::Sub<int64_t>(0x7FFFFFFFFFFFFFFA, -5),
399 int64_t(0x7FFFFFFFFFFFFFFF));
400 EXPECT_EQ(saturated::Sub<int64_t>(0x7FFFFFFFFFFFFFFB, -5),
401 int64_t(0x7FFFFFFFFFFFFFFF));
402 }
403 {
404 EXPECT_EQ(saturated::Sub<int64_t>(0x8000000000000006, 5),
405 int64_t(0x8000000000000001));
406 EXPECT_EQ(saturated::Sub<int64_t>(0x8000000000000005, 5),
407 int64_t(0x8000000000000000));
408 EXPECT_EQ(saturated::Sub<int64_t>(0x8000000000000004, 5),
409 int64_t(0x8000000000000000));
410 }
411}

◆ TEST() [332/377]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitAddOfFloatingPoint   
)

Definition at line 250 of file saturated_math_unittests.cc.

250 {
251 {
252 const float inf = std::numeric_limits<float>::infinity();
253 const float max = std::numeric_limits<float>::max();
254 const float big = max * 0.5f;
255
256 EXPECT_EQ(saturated::Add(big, big), max);
257 EXPECT_EQ(saturated::Add(max, big), inf);
258 EXPECT_EQ(saturated::Add(big, max), inf);
259 EXPECT_EQ(saturated::Add(max, max), inf);
260 EXPECT_EQ(saturated::Add(max, inf), inf);
261 EXPECT_EQ(saturated::Add(inf, max), inf);
262 EXPECT_EQ(saturated::Add(inf, inf), inf);
263
264 EXPECT_EQ(saturated::Add(-big, -big), -max);
265 EXPECT_EQ(saturated::Add(-max, -big), -inf);
266 EXPECT_EQ(saturated::Add(-big, -max), -inf);
267 EXPECT_EQ(saturated::Add(-max, -max), -inf);
268 EXPECT_EQ(saturated::Add(-max, -inf), -inf);
269 EXPECT_EQ(saturated::Add(-inf, -max), -inf);
270 EXPECT_EQ(saturated::Add(-inf, -inf), -inf);
271
272 EXPECT_EQ(saturated::Add(big, -big), 0.0f);
273 EXPECT_EQ(saturated::Add(max, -big), big);
274 EXPECT_EQ(saturated::Add(big, -max), -big);
275 EXPECT_EQ(saturated::Add(max, -max), 0.0f);
276 EXPECT_EQ(saturated::Add(max, -inf), -inf);
277 EXPECT_EQ(saturated::Add(inf, -max), inf);
278 EXPECT_TRUE(std::isnan(saturated::Add(inf, -inf)));
279
280 EXPECT_EQ(saturated::Add(-big, big), 0.0f);
281 EXPECT_EQ(saturated::Add(-max, big), -big);
282 EXPECT_EQ(saturated::Add(-big, max), big);
283 EXPECT_EQ(saturated::Add(-max, max), 0.0f);
284 EXPECT_EQ(saturated::Add(-max, inf), inf);
285 EXPECT_EQ(saturated::Add(-inf, max), -inf);
286 EXPECT_TRUE(std::isnan(saturated::Add(-inf, inf)));
287 }
288 {
289 const double inf = std::numeric_limits<double>::infinity();
290 const double max = std::numeric_limits<double>::max();
291 const double big = max * 0.5f;
292
293 EXPECT_EQ(saturated::Add(big, big), max);
294 EXPECT_EQ(saturated::Add(max, big), inf);
295 EXPECT_EQ(saturated::Add(big, max), inf);
296 EXPECT_EQ(saturated::Add(max, max), inf);
297 EXPECT_EQ(saturated::Add(max, inf), inf);
298 EXPECT_EQ(saturated::Add(inf, max), inf);
299 EXPECT_EQ(saturated::Add(inf, inf), inf);
300
301 EXPECT_EQ(saturated::Add(-big, -big), -max);
302 EXPECT_EQ(saturated::Add(-max, -big), -inf);
303 EXPECT_EQ(saturated::Add(-big, -max), -inf);
304 EXPECT_EQ(saturated::Add(-max, -max), -inf);
305 EXPECT_EQ(saturated::Add(-max, -inf), -inf);
306 EXPECT_EQ(saturated::Add(-inf, -max), -inf);
307 EXPECT_EQ(saturated::Add(-inf, -inf), -inf);
308
309 EXPECT_EQ(saturated::Add(big, -big), 0.0f);
310 EXPECT_EQ(saturated::Add(max, -big), big);
311 EXPECT_EQ(saturated::Add(big, -max), -big);
312 EXPECT_EQ(saturated::Add(max, -max), 0.0f);
313 EXPECT_EQ(saturated::Add(max, -inf), -inf);
314 EXPECT_EQ(saturated::Add(inf, -max), inf);
315 EXPECT_TRUE(std::isnan(saturated::Add(inf, -inf)));
316
317 EXPECT_EQ(saturated::Add(-big, big), 0.0f);
318 EXPECT_EQ(saturated::Add(-max, big), -big);
319 EXPECT_EQ(saturated::Add(-big, max), big);
320 EXPECT_EQ(saturated::Add(-max, max), 0.0f);
321 EXPECT_EQ(saturated::Add(-max, inf), inf);
322 EXPECT_EQ(saturated::Add(-inf, max), -inf);
323 EXPECT_TRUE(std::isnan(saturated::Add(-inf, inf)));
324 }
325 {
326 const Scalar inf = std::numeric_limits<Scalar>::infinity();
328 const Scalar big = max * 0.5f;
329
330 EXPECT_EQ(saturated::Add(big, big), max);
331 EXPECT_EQ(saturated::Add(max, big), inf);
332 EXPECT_EQ(saturated::Add(big, max), inf);
333 EXPECT_EQ(saturated::Add(max, max), inf);
334 EXPECT_EQ(saturated::Add(max, inf), inf);
335 EXPECT_EQ(saturated::Add(inf, max), inf);
336 EXPECT_EQ(saturated::Add(inf, inf), inf);
337
338 EXPECT_EQ(saturated::Add(-big, -big), -max);
339 EXPECT_EQ(saturated::Add(-max, -big), -inf);
340 EXPECT_EQ(saturated::Add(-big, -max), -inf);
341 EXPECT_EQ(saturated::Add(-max, -max), -inf);
342 EXPECT_EQ(saturated::Add(-max, -inf), -inf);
343 EXPECT_EQ(saturated::Add(-inf, -max), -inf);
344 EXPECT_EQ(saturated::Add(-inf, -inf), -inf);
345
346 EXPECT_EQ(saturated::Add(big, -big), 0.0f);
347 EXPECT_EQ(saturated::Add(max, -big), big);
348 EXPECT_EQ(saturated::Add(big, -max), -big);
349 EXPECT_EQ(saturated::Add(max, -max), 0.0f);
350 EXPECT_EQ(saturated::Add(max, -inf), -inf);
351 EXPECT_EQ(saturated::Add(inf, -max), inf);
352 EXPECT_TRUE(std::isnan(saturated::Add(inf, -inf)));
353
354 EXPECT_EQ(saturated::Add(-big, big), 0.0f);
355 EXPECT_EQ(saturated::Add(-max, big), -big);
356 EXPECT_EQ(saturated::Add(-big, max), big);
357 EXPECT_EQ(saturated::Add(-max, max), 0.0f);
358 EXPECT_EQ(saturated::Add(-max, inf), inf);
359 EXPECT_EQ(saturated::Add(-inf, max), -inf);
360 EXPECT_TRUE(std::isnan(saturated::Add(-inf, inf)));
361 }
362}

◆ TEST() [333/377]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitAddOfSignedInts   
)

Definition at line 61 of file saturated_math_unittests.cc.

61 {
62 {
63 int8_t a = 0x79;
64 int8_t b = 5;
65 EXPECT_EQ(saturated::Add(a, b), int8_t(0x7E));
66 a = 0x7A;
67 EXPECT_EQ(saturated::Add(a, b), int8_t(0x7F));
68 a = 0x7B;
69 EXPECT_EQ(saturated::Add(a, b), int8_t(0x7F));
70 }
71 {
72 int8_t a = 0x86;
73 int8_t b = -5;
74 EXPECT_EQ(saturated::Add(a, b), int8_t(0x81));
75 a = 0x85;
76 EXPECT_EQ(saturated::Add(a, b), int8_t(0x80));
77 a = 0x84;
78 EXPECT_EQ(saturated::Add(a, b), int8_t(0x80));
79 }
80 {
81 int16_t a = 0x7FF9;
82 int16_t b = 5;
83 EXPECT_EQ(saturated::Add(a, b), int16_t(0x7FFE));
84 a = 0x7FFA;
85 EXPECT_EQ(saturated::Add(a, b), int16_t(0x7FFF));
86 a = 0x7FFB;
87 EXPECT_EQ(saturated::Add(a, b), int16_t(0x7FFF));
88 }
89 {
90 int16_t a = 0x8006;
91 int16_t b = -5;
92 EXPECT_EQ(saturated::Add(a, b), int16_t(0x8001));
93 a = 0x8005;
94 EXPECT_EQ(saturated::Add(a, b), int16_t(0x8000));
95 a = 0x8004;
96 EXPECT_EQ(saturated::Add(a, b), int16_t(0x8000));
97 }
98 {
99 int32_t a = 0x7FFFFFF9;
100 int32_t b = 5;
101 EXPECT_EQ(saturated::Add(a, b), int32_t(0x7FFFFFFE));
102 a = 0x7FFFFFFA;
103 EXPECT_EQ(saturated::Add(a, b), int32_t(0x7FFFFFFF));
104 a = 0x7FFFFFFB;
105 EXPECT_EQ(saturated::Add(a, b), int32_t(0x7FFFFFFF));
106 }
107 {
108 int32_t a = 0x80000006;
109 int32_t b = -5;
110 EXPECT_EQ(saturated::Add(a, b), int32_t(0x80000001));
111 a = 0x80000005;
112 EXPECT_EQ(saturated::Add(a, b), int32_t(0x80000000));
113 a = 0x80000004;
114 EXPECT_EQ(saturated::Add(a, b), int32_t(0x80000000));
115 }
116 {
117 int64_t a = 0x7FFFFFFFFFFFFFF9;
118 int64_t b = 5;
119 EXPECT_EQ(saturated::Add(a, b), int64_t(0x7FFFFFFFFFFFFFFE));
120 a = 0x7FFFFFFFFFFFFFFA;
121 EXPECT_EQ(saturated::Add(a, b), int64_t(0x7FFFFFFFFFFFFFFF));
122 a = 0x7FFFFFFFFFFFFFFB;
123 EXPECT_EQ(saturated::Add(a, b), int64_t(0x7FFFFFFFFFFFFFFF));
124 }
125 {
126 int64_t a = 0x8000000000000006;
127 int64_t b = -5;
128 EXPECT_EQ(saturated::Add(a, b), int64_t(0x8000000000000001));
129 a = 0x8000000000000005;
130 EXPECT_EQ(saturated::Add(a, b), int64_t(0x8000000000000000));
131 a = 0x8000000000000004;
132 EXPECT_EQ(saturated::Add(a, b), int64_t(0x8000000000000000));
133 }
134}

◆ TEST() [334/377]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitAverageScalarOfFloatingPoint   
)

Definition at line 903 of file saturated_math_unittests.cc.

903 {
904 // All return values are Scalar regardless of the operand types
905 // so these constants are used as the expected answers.
906 const Scalar s_inf = std::numeric_limits<Scalar>::infinity();
908 const Scalar s_big = s_max * 0.5f;
909
910 {
911 const float inf = std::numeric_limits<float>::infinity();
912 const float max = std::numeric_limits<float>::max();
913 const float big = max * 0.5f;
914
915 EXPECT_EQ(saturated::AverageScalar(big, big), s_big);
916 EXPECT_EQ(saturated::AverageScalar(max, max), s_max);
917 EXPECT_EQ(saturated::AverageScalar(big, -big), 0.0f);
918 EXPECT_EQ(saturated::AverageScalar(max, -max), 0.0f);
919 EXPECT_EQ(saturated::AverageScalar(-big, big), 0.0f);
920 EXPECT_EQ(saturated::AverageScalar(-max, max), 0.0f);
921 EXPECT_EQ(saturated::AverageScalar(-big, -big), -s_big);
922 EXPECT_EQ(saturated::AverageScalar(-max, -max), -s_max);
923
924 EXPECT_EQ(saturated::AverageScalar(inf, inf), s_inf);
925 EXPECT_EQ(saturated::AverageScalar(-inf, -inf), -s_inf);
926 EXPECT_TRUE(std::isnan(saturated::AverageScalar(-inf, inf)));
927 EXPECT_TRUE(std::isnan(saturated::AverageScalar(inf, -inf)));
928 }
929 {
930 const double inf = std::numeric_limits<double>::infinity();
931 const double max = std::numeric_limits<double>::max();
932 const double big = max * 0.5;
933
934 // The s_constants converted to double. We should get finite results
935 // from finding the averages of these values, but we'll get a lot of
936 // overflow to infinity when testing the large double constants.
937 const double d_s_max = s_max;
938 const double d_s_big = s_big;
939 EXPECT_EQ(saturated::AverageScalar(d_s_big, d_s_big), s_big);
940 EXPECT_EQ(saturated::AverageScalar(d_s_max, d_s_max), s_max);
941 EXPECT_EQ(saturated::AverageScalar(-d_s_big, -d_s_big), -s_big);
942 EXPECT_EQ(saturated::AverageScalar(-d_s_max, -d_s_max), -s_max);
943
944 // And now testing continues with the double constants which
945 // mostly overflow
946 EXPECT_EQ(saturated::AverageScalar(big, big), s_inf);
947 EXPECT_EQ(saturated::AverageScalar(max, max), s_inf);
948 EXPECT_EQ(saturated::AverageScalar(big, -big), 0.0f);
949 EXPECT_EQ(saturated::AverageScalar(max, -max), 0.0f);
950 EXPECT_EQ(saturated::AverageScalar(-big, big), 0.0f);
951 EXPECT_EQ(saturated::AverageScalar(-max, max), 0.0f);
952 EXPECT_EQ(saturated::AverageScalar(-big, -big), -s_inf);
953 EXPECT_EQ(saturated::AverageScalar(-max, -max), -s_inf);
954
955 EXPECT_EQ(saturated::AverageScalar(inf, inf), s_inf);
956 EXPECT_EQ(saturated::AverageScalar(-inf, -inf), -s_inf);
957 EXPECT_TRUE(std::isnan(saturated::AverageScalar(-inf, inf)));
958 EXPECT_TRUE(std::isnan(saturated::AverageScalar(inf, -inf)));
959 }
960 {
961 const Scalar inf = std::numeric_limits<Scalar>::infinity();
963 const Scalar big = max * 0.5f;
964
965 EXPECT_EQ(saturated::AverageScalar(big, big), s_big);
966 EXPECT_EQ(saturated::AverageScalar(max, max), s_max);
967 EXPECT_EQ(saturated::AverageScalar(big, -big), 0.0f);
968 EXPECT_EQ(saturated::AverageScalar(max, -max), 0.0f);
969 EXPECT_EQ(saturated::AverageScalar(-big, big), 0.0f);
970 EXPECT_EQ(saturated::AverageScalar(-max, max), 0.0f);
971 EXPECT_EQ(saturated::AverageScalar(-big, -big), -s_big);
972 EXPECT_EQ(saturated::AverageScalar(-max, -max), -s_max);
973
974 EXPECT_EQ(saturated::AverageScalar(inf, inf), s_inf);
975 EXPECT_EQ(saturated::AverageScalar(-inf, -inf), -s_inf);
976 EXPECT_TRUE(std::isnan(saturated::AverageScalar(-inf, s_inf)));
977 EXPECT_TRUE(std::isnan(saturated::AverageScalar(inf, -s_inf)));
978 }
979}

◆ TEST() [335/377]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitAverageScalarOfSignedInts   
)

Definition at line 763 of file saturated_math_unittests.cc.

763 {
764 // For each type try:
765 //
766 // - near the limits, averaging to 0
767 // - at the limits, averaging to 0 or 0.5 depending on precision
768 // - both large enough for the sum to overflow
769 // - both negative enough for the sum to underflow
770 {
771 int8_t a = 0x81;
772 int8_t b = 0x7f;
773 EXPECT_EQ(saturated::AverageScalar(a, b), -0.0f);
774 a = 0x80;
775 EXPECT_EQ(saturated::AverageScalar(a, b), -0.5f);
776 a = 0x70;
777 b = 0x75;
778 EXPECT_EQ(saturated::AverageScalar(a, b), 114.5f);
779 a = 0x85;
780 b = 0x8A;
781 EXPECT_EQ(saturated::AverageScalar(a, b), -120.5f);
782 }
783 {
784 int16_t a = 0x8001;
785 int16_t b = 0x7FFF;
786 EXPECT_EQ(saturated::AverageScalar(a, b), -0.0f);
787 a = 0x8000;
788 EXPECT_EQ(saturated::AverageScalar(a, b), -0.5f);
789 a = 0x7000;
790 b = 0x7005;
791 EXPECT_EQ(saturated::AverageScalar(a, b), 28674.5f);
792 a = 0x8005;
793 b = 0x800A;
794 EXPECT_EQ(saturated::AverageScalar(a, b), -32760.5f);
795 }
796 {
797 int32_t a = 0x80000001;
798 int32_t b = 0x7FFFFFFF;
799 EXPECT_EQ(saturated::AverageScalar(a, b), -0.0f);
800 a = 0x80000000;
801 EXPECT_EQ(saturated::AverageScalar(a, b), -0.5f);
802 a = 0x70000000;
803 b = 0x70000005;
804 EXPECT_EQ(saturated::AverageScalar(a, b), 1879048195.5f);
805 a = 0x80000005;
806 b = 0x8000000A;
807 EXPECT_EQ(saturated::AverageScalar(a, b), -2147483655.5f);
808 }
809 {
810 int64_t a = 0x8000000000000001;
811 int64_t b = 0x7FFFFFFFFFFFFFFF;
812 EXPECT_EQ(saturated::AverageScalar(a, b), 0.0f);
813 // 64-bit integers overflow the ability of a Scalar (float) to
814 // represent discrete integers and so the two numbers we are
815 // averaging here will look like the same number with different
816 // signs and the answer will be "0"
817 a = 0x8000000000000000;
818 EXPECT_EQ(saturated::AverageScalar<int64_t>(a, b), 0.0f);
819 a = 0x7000000000000000;
820 b = 0x7000000000000005;
821 EXPECT_NEAR(saturated::AverageScalar<int64_t>(a, b), 8.0704505e+18, 1e18);
822 a = 0x8000000000000005;
823 b = 0x800000000000000A;
824 EXPECT_NEAR(saturated::AverageScalar<int64_t>(a, b), -9.223372e+18, 1e18);
825 }
826}

◆ TEST() [336/377]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitSubOfFloatingPoint   
)

Definition at line 602 of file saturated_math_unittests.cc.

602 {
603 {
604 const float inf = std::numeric_limits<float>::infinity();
605 const float max = std::numeric_limits<float>::max();
606 const float big = max * 0.5f;
607
608 EXPECT_EQ(saturated::Sub(big, big), 0.0f);
609 EXPECT_EQ(saturated::Sub(max, big), big);
610 EXPECT_EQ(saturated::Sub(big, max), -big);
611 EXPECT_EQ(saturated::Sub(max, max), 0.0f);
612 EXPECT_EQ(saturated::Sub(max, inf), -inf);
613 EXPECT_EQ(saturated::Sub(inf, max), inf);
614 EXPECT_TRUE(std::isnan(saturated::Sub(inf, inf)));
615
616 EXPECT_EQ(saturated::Sub(-big, -big), 0.0f);
617 EXPECT_EQ(saturated::Sub(-max, -big), -big);
618 EXPECT_EQ(saturated::Sub(-big, -max), big);
619 EXPECT_EQ(saturated::Sub(-max, -max), 0.0f);
620 EXPECT_EQ(saturated::Sub(-max, -inf), inf);
621 EXPECT_EQ(saturated::Sub(-inf, -max), -inf);
622 EXPECT_TRUE(std::isnan(saturated::Sub(-inf, -inf)));
623
624 EXPECT_EQ(saturated::Sub(big, -big), max);
625 EXPECT_EQ(saturated::Sub(max, -big), inf);
626 EXPECT_EQ(saturated::Sub(big, -max), inf);
627 EXPECT_EQ(saturated::Sub(max, -max), inf);
628 EXPECT_EQ(saturated::Sub(max, -inf), inf);
629 EXPECT_EQ(saturated::Sub(inf, -max), inf);
630 EXPECT_EQ(saturated::Sub(inf, -inf), inf);
631
632 EXPECT_EQ(saturated::Sub(-big, big), -max);
633 EXPECT_EQ(saturated::Sub(-max, big), -inf);
634 EXPECT_EQ(saturated::Sub(-big, max), -inf);
635 EXPECT_EQ(saturated::Sub(-max, max), -inf);
636 EXPECT_EQ(saturated::Sub(-max, inf), -inf);
637 EXPECT_EQ(saturated::Sub(-inf, max), -inf);
638 EXPECT_EQ(saturated::Sub(-inf, inf), -inf);
639 }
640 {
641 const double inf = std::numeric_limits<double>::infinity();
642 const double max = std::numeric_limits<double>::max();
643 const double big = max * 0.5f;
644
645 EXPECT_EQ(saturated::Sub(big, big), 0.0f);
646 EXPECT_EQ(saturated::Sub(max, big), big);
647 EXPECT_EQ(saturated::Sub(big, max), -big);
648 EXPECT_EQ(saturated::Sub(max, max), 0.0f);
649 EXPECT_EQ(saturated::Sub(max, inf), -inf);
650 EXPECT_EQ(saturated::Sub(inf, max), inf);
651 EXPECT_TRUE(std::isnan(saturated::Sub(inf, inf)));
652
653 EXPECT_EQ(saturated::Sub(-big, -big), 0.0f);
654 EXPECT_EQ(saturated::Sub(-max, -big), -big);
655 EXPECT_EQ(saturated::Sub(-big, -max), big);
656 EXPECT_EQ(saturated::Sub(-max, -max), 0.0f);
657 EXPECT_EQ(saturated::Sub(-max, -inf), inf);
658 EXPECT_EQ(saturated::Sub(-inf, -max), -inf);
659 EXPECT_TRUE(std::isnan(saturated::Sub(-inf, -inf)));
660
661 EXPECT_EQ(saturated::Sub(big, -big), max);
662 EXPECT_EQ(saturated::Sub(max, -big), inf);
663 EXPECT_EQ(saturated::Sub(big, -max), inf);
664 EXPECT_EQ(saturated::Sub(max, -max), inf);
665 EXPECT_EQ(saturated::Sub(max, -inf), inf);
666 EXPECT_EQ(saturated::Sub(inf, -max), inf);
667 EXPECT_EQ(saturated::Sub(inf, -inf), inf);
668
669 EXPECT_EQ(saturated::Sub(-big, big), -max);
670 EXPECT_EQ(saturated::Sub(-max, big), -inf);
671 EXPECT_EQ(saturated::Sub(-big, max), -inf);
672 EXPECT_EQ(saturated::Sub(-max, max), -inf);
673 EXPECT_EQ(saturated::Sub(-max, inf), -inf);
674 EXPECT_EQ(saturated::Sub(-inf, max), -inf);
675 EXPECT_EQ(saturated::Sub(-inf, inf), -inf);
676 }
677 {
678 const Scalar inf = std::numeric_limits<Scalar>::infinity();
680 const Scalar big = max * 0.5f;
681
682 EXPECT_EQ(saturated::Sub(big, big), 0.0f);
683 EXPECT_EQ(saturated::Sub(max, big), big);
684 EXPECT_EQ(saturated::Sub(big, max), -big);
685 EXPECT_EQ(saturated::Sub(max, max), 0.0f);
686 EXPECT_EQ(saturated::Sub(max, inf), -inf);
687 EXPECT_EQ(saturated::Sub(inf, max), inf);
688 EXPECT_TRUE(std::isnan(saturated::Sub(inf, inf)));
689
690 EXPECT_EQ(saturated::Sub(-big, -big), 0.0f);
691 EXPECT_EQ(saturated::Sub(-max, -big), -big);
692 EXPECT_EQ(saturated::Sub(-big, -max), big);
693 EXPECT_EQ(saturated::Sub(-max, -max), 0.0f);
694 EXPECT_EQ(saturated::Sub(-max, -inf), inf);
695 EXPECT_EQ(saturated::Sub(-inf, -max), -inf);
696 EXPECT_TRUE(std::isnan(saturated::Sub(-inf, -inf)));
697
698 EXPECT_EQ(saturated::Sub(big, -big), max);
699 EXPECT_EQ(saturated::Sub(max, -big), inf);
700 EXPECT_EQ(saturated::Sub(big, -max), inf);
701 EXPECT_EQ(saturated::Sub(max, -max), inf);
702 EXPECT_EQ(saturated::Sub(max, -inf), inf);
703 EXPECT_EQ(saturated::Sub(inf, -max), inf);
704 EXPECT_EQ(saturated::Sub(inf, -inf), inf);
705
706 EXPECT_EQ(saturated::Sub(-big, big), -max);
707 EXPECT_EQ(saturated::Sub(-max, big), -inf);
708 EXPECT_EQ(saturated::Sub(-big, max), -inf);
709 EXPECT_EQ(saturated::Sub(-max, max), -inf);
710 EXPECT_EQ(saturated::Sub(-max, inf), -inf);
711 EXPECT_EQ(saturated::Sub(-inf, max), -inf);
712 EXPECT_EQ(saturated::Sub(-inf, inf), -inf);
713 }
714}

◆ TEST() [337/377]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitSubOfSignedInts   
)

Definition at line 413 of file saturated_math_unittests.cc.

413 {
414 {
415 int8_t a = 0x79;
416 int8_t b = -5;
417 EXPECT_EQ(saturated::Sub(a, b), int8_t(0x7E));
418 a = 0x7A;
419 EXPECT_EQ(saturated::Sub(a, b), int8_t(0x7F));
420 a = 0x7B;
421 EXPECT_EQ(saturated::Sub(a, b), int8_t(0x7F));
422 }
423 {
424 int8_t a = 0x86;
425 int8_t b = 5;
426 EXPECT_EQ(saturated::Sub(a, b), int8_t(0x81));
427 a = 0x85;
428 EXPECT_EQ(saturated::Sub(a, b), int8_t(0x80));
429 a = 0x84;
430 EXPECT_EQ(saturated::Sub(a, b), int8_t(0x80));
431 }
432 {
433 int16_t a = 0x7FF9;
434 int16_t b = -5;
435 EXPECT_EQ(saturated::Sub(a, b), int16_t(0x7FFE));
436 a = 0x7FFA;
437 EXPECT_EQ(saturated::Sub(a, b), int16_t(0x7FFF));
438 a = 0x7FFB;
439 EXPECT_EQ(saturated::Sub(a, b), int16_t(0x7FFF));
440 }
441 {
442 int16_t a = 0x8006;
443 int16_t b = 5;
444 EXPECT_EQ(saturated::Sub(a, b), int16_t(0x8001));
445 a = 0x8005;
446 EXPECT_EQ(saturated::Sub(a, b), int16_t(0x8000));
447 a = 0x8004;
448 EXPECT_EQ(saturated::Sub(a, b), int16_t(0x8000));
449 }
450 {
451 int32_t a = 0x7FFFFFF9;
452 int32_t b = -5;
453 EXPECT_EQ(saturated::Sub(a, b), int32_t(0x7FFFFFFE));
454 a = 0x7FFFFFFA;
455 EXPECT_EQ(saturated::Sub(a, b), int32_t(0x7FFFFFFF));
456 a = 0x7FFFFFFB;
457 EXPECT_EQ(saturated::Sub(a, b), int32_t(0x7FFFFFFF));
458 }
459 {
460 int32_t a = 0x80000006;
461 int32_t b = 5;
462 EXPECT_EQ(saturated::Sub(a, b), int32_t(0x80000001));
463 a = 0x80000005;
464 EXPECT_EQ(saturated::Sub(a, b), int32_t(0x80000000));
465 a = 0x80000004;
466 EXPECT_EQ(saturated::Sub(a, b), int32_t(0x80000000));
467 }
468 {
469 int64_t a = 0x7FFFFFFFFFFFFFF9;
470 int64_t b = -5;
471 EXPECT_EQ(saturated::Sub(a, b), int64_t(0x7FFFFFFFFFFFFFFE));
472 a = 0x7FFFFFFFFFFFFFFA;
473 EXPECT_EQ(saturated::Sub(a, b), int64_t(0x7FFFFFFFFFFFFFFF));
474 a = 0x7FFFFFFFFFFFFFFB;
475 EXPECT_EQ(saturated::Sub(a, b), int64_t(0x7FFFFFFFFFFFFFFF));
476 }
477 {
478 int64_t a = 0x8000000000000006;
479 int64_t b = 5;
480 EXPECT_EQ(saturated::Sub(a, b), int64_t(0x8000000000000001));
481 a = 0x8000000000000005;
482 EXPECT_EQ(saturated::Sub(a, b), int64_t(0x8000000000000000));
483 a = 0x8000000000000004;
484 EXPECT_EQ(saturated::Sub(a, b), int64_t(0x8000000000000000));
485 }
486}

◆ TEST() [338/377]

impeller::testing::TEST ( ShaderArchiveTest  ,
CanReadAndWriteBlobs   
)

Definition at line 28 of file shader_archive_unittests.cc.

28 {
30 ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Hello",
31 CreateMappingFromString("World")));
32 ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kFragment, "Foo",
34 ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Baz",
36 ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Ping",
38 ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kFragment, "Pang",
39 CreateMappingFromString("World")));
40
41 auto mapping = writer.CreateMapping();
42 ASSERT_NE(mapping, nullptr);
43
44 ShaderArchive library(mapping);
45 ASSERT_TRUE(library.IsValid());
46 ASSERT_EQ(library.GetShaderCount(), 5u);
47
48 // Wrong type.
49 ASSERT_EQ(library.GetMapping(ArchiveShaderType::kFragment, "Hello"), nullptr);
50
51 auto hello_vtx = library.GetMapping(ArchiveShaderType::kVertex, "Hello");
52 ASSERT_NE(hello_vtx, nullptr);
53 ASSERT_EQ(CreateStringFromMapping(*hello_vtx), "World");
54}
bool AddShader(ArchiveShaderType type, std::string name, std::shared_ptr< fml::Mapping > mapping)
std::shared_ptr< fml::Mapping > CreateMapping() const
const std::string CreateStringFromMapping(const fml::Mapping &mapping)
static std::shared_ptr< fml::Mapping > CreateMappingFromString(std::string p_string)

◆ TEST() [339/377]

impeller::testing::TEST ( SizeTest  ,
ISizeIsEmpty   
)

Definition at line 36 of file size_unittests.cc.

36 {
37 // Non-empty
38 EXPECT_FALSE(ISize(10, 7).IsEmpty());
39
40 // Empty both width and height both 0 or negative, in all combinations
41 EXPECT_TRUE(ISize(0, 0).IsEmpty());
42 EXPECT_TRUE(ISize(-1, -1).IsEmpty());
43 EXPECT_TRUE(ISize(-1, 0).IsEmpty());
44 EXPECT_TRUE(ISize(0, -1).IsEmpty());
45
46 // Empty for 0 or negative width or height (but not both at the same time)
47 EXPECT_TRUE(ISize(10, 0).IsEmpty());
48 EXPECT_TRUE(ISize(10, -1).IsEmpty());
49 EXPECT_TRUE(ISize(0, 7).IsEmpty());
50 EXPECT_TRUE(ISize(-1, 7).IsEmpty());
51}

◆ TEST() [340/377]

impeller::testing::TEST ( SizeTest  ,
IsSquare   
)

Definition at line 53 of file size_unittests.cc.

53 {
54 EXPECT_TRUE(Size(20, 20).IsSquare());
55 EXPECT_FALSE(Size(20, 19).IsSquare());
56 EXPECT_FALSE(Size(19, 20).IsSquare());
57
58 EXPECT_TRUE(ISize(20, 20).IsSquare());
59 EXPECT_FALSE(ISize(20, 19).IsSquare());
60 EXPECT_FALSE(ISize(19, 20).IsSquare());
61}

◆ TEST() [341/377]

impeller::testing::TEST ( SizeTest  ,
MaxDimension   
)

Definition at line 63 of file size_unittests.cc.

63 {
64 EXPECT_EQ(Size(20, 20).MaxDimension(), 20);
65 EXPECT_EQ(Size(20, 19).MaxDimension(), 20);
66 EXPECT_EQ(Size(19, 20).MaxDimension(), 20);
67 EXPECT_EQ(Size(20, 21).MaxDimension(), 21);
68 EXPECT_EQ(Size(21, 20).MaxDimension(), 21);
69
70 EXPECT_EQ(ISize(20, 20).MaxDimension(), 20);
71 EXPECT_EQ(ISize(20, 19).MaxDimension(), 20);
72 EXPECT_EQ(ISize(19, 20).MaxDimension(), 20);
73 EXPECT_EQ(ISize(20, 21).MaxDimension(), 21);
74 EXPECT_EQ(ISize(21, 20).MaxDimension(), 21);
75}

◆ TEST() [342/377]

impeller::testing::TEST ( SizeTest  ,
NegationOperator   
)

Definition at line 77 of file size_unittests.cc.

77 {
78 EXPECT_EQ(-Size(10, 20), Size(-10, -20));
79 EXPECT_EQ(-Size(-10, 20), Size(10, -20));
80 EXPECT_EQ(-Size(10, -20), Size(-10, 20));
81 EXPECT_EQ(-Size(-10, -20), Size(10, 20));
82}

◆ TEST() [343/377]

impeller::testing::TEST ( SizeTest  ,
SizeIsEmpty   
)

Definition at line 12 of file size_unittests.cc.

12 {
13 auto nan = std::numeric_limits<Scalar>::quiet_NaN();
14
15 // Non-empty
16 EXPECT_FALSE(Size(10.5, 7.2).IsEmpty());
17
18 // Empty both width and height both 0 or negative, in all combinations
19 EXPECT_TRUE(Size(0.0, 0.0).IsEmpty());
20 EXPECT_TRUE(Size(-1.0, -1.0).IsEmpty());
21 EXPECT_TRUE(Size(-1.0, 0.0).IsEmpty());
22 EXPECT_TRUE(Size(0.0, -1.0).IsEmpty());
23
24 // Empty for 0 or negative width or height (but not both at the same time)
25 EXPECT_TRUE(Size(10.5, 0.0).IsEmpty());
26 EXPECT_TRUE(Size(10.5, -1.0).IsEmpty());
27 EXPECT_TRUE(Size(0.0, 7.2).IsEmpty());
28 EXPECT_TRUE(Size(-1.0, 7.2).IsEmpty());
29
30 // Empty for NaN in width or height or both
31 EXPECT_TRUE(Size(10.5, nan).IsEmpty());
32 EXPECT_TRUE(Size(nan, 7.2).IsEmpty());
33 EXPECT_TRUE(Size(nan, nan).IsEmpty());
34}

◆ TEST() [344/377]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientConversionNonMonotonic   
)

Definition at line 151 of file skia_conversions_unittests.cc.

151 {
152 std::vector<flutter::DlColor> colors = {
155 std::vector<float> stops = {0.0, 0.5, 0.4, 1.0};
156 const auto gradient =
158 SkPoint::Make(1.0, 1.0), //
159 4, //
160 colors.data(), //
161 stops.data(), //
163 nullptr //
164 );
165
166 std::vector<Color> converted_colors;
167 std::vector<Scalar> converted_stops;
168 skia_conversions::ConvertStops(gradient.get(), converted_colors,
169 converted_stops);
170
171 // Value is clamped to 0.5
172 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
173 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
174 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 0.5f));
175 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[3], 1.0f));
176}
static std::shared_ptr< DlLinearGradientColorSource > MakeLinear(const SkPoint start_point, const SkPoint end_point, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const SkMatrix *matrix=nullptr)
void ConvertStops(const flutter::DlGradientColorSourceBase *gradient, std::vector< Color > &colors, std::vector< float > &stops)
Convert display list colors + stops into impeller colors and stops, taking care to ensure that the st...
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173
static constexpr DlColor kBlue()
Definition: dl_color.h:26
static constexpr DlColor kRed()
Definition: dl_color.h:24
static constexpr DlColor kGreen()
Definition: dl_color.h:25

◆ TEST() [345/377]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientMissing0   
)

Definition at line 73 of file skia_conversions_unittests.cc.

73 {
74 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
76 std::vector<float> stops = {0.5, 1.0};
77 const auto gradient =
79 SkPoint::Make(1.0, 1.0), //
80 2, //
81 colors.data(), //
82 stops.data(), //
84 nullptr //
85 );
86
87 std::vector<Color> converted_colors;
88 std::vector<Scalar> converted_stops;
89 skia_conversions::ConvertStops(gradient.get(), converted_colors,
90 converted_stops);
91
92 // First color is inserted as blue.
93 ASSERT_TRUE(ScalarNearlyEqual(converted_colors[0].blue, 1.0f));
94 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
95 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
96 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
97}

◆ TEST() [346/377]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientMissingLastValue   
)

Definition at line 99 of file skia_conversions_unittests.cc.

99 {
100 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
102 std::vector<float> stops = {0.0, .5};
103 const auto gradient =
105 SkPoint::Make(1.0, 1.0), //
106 2, //
107 colors.data(), //
108 stops.data(), //
110 nullptr //
111 );
112
113 std::vector<Color> converted_colors;
114 std::vector<Scalar> converted_stops;
115 skia_conversions::ConvertStops(gradient.get(), converted_colors,
116 converted_stops);
117
118 // Last color is inserted as red.
119 ASSERT_TRUE(ScalarNearlyEqual(converted_colors[2].red, 1.0f));
120 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
121 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
122 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
123}

◆ TEST() [347/377]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientStopConversion   
)

Definition at line 47 of file skia_conversions_unittests.cc.

47 {
48 // Typical gradient.
49 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
52 std::vector<float> stops = {0.0, 0.5, 1.0};
53 const auto gradient =
55 SkPoint::Make(1.0, 1.0), //
56 3, //
57 colors.data(), //
58 stops.data(), //
60 nullptr //
61 );
62
63 std::vector<Color> converted_colors;
64 std::vector<Scalar> converted_stops;
65 skia_conversions::ConvertStops(gradient.get(), converted_colors,
66 converted_stops);
67
68 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
69 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
70 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
71}

◆ TEST() [348/377]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientStopGreaterThan1   
)

Definition at line 125 of file skia_conversions_unittests.cc.

125 {
126 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
129 std::vector<float> stops = {0.0, 100, 1.0};
130 const auto gradient =
132 SkPoint::Make(1.0, 1.0), //
133 3, //
134 colors.data(), //
135 stops.data(), //
137 nullptr //
138 );
139
140 std::vector<Color> converted_colors;
141 std::vector<Scalar> converted_stops;
142 skia_conversions::ConvertStops(gradient.get(), converted_colors,
143 converted_stops);
144
145 // Value is clamped to 1.0
146 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
147 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 1.0f));
148 ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
149}

◆ TEST() [349/377]

impeller::testing::TEST ( SkiaConversionsTest  ,
IsNearlySimpleRRect   
)

Definition at line 178 of file skia_conversions_unittests.cc.

178 {
180 SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 10)));
182 SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 9.999)));
184 SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 9)));
185}
bool IsNearlySimpleRRect(const SkRRect &rr)
Like SkRRect.isSimple, but allows the corners to differ by kEhCloseEnough.

◆ TEST() [350/377]

impeller::testing::TEST ( SkiaConversionsTest  ,
SkPointToPoint   
)

Definition at line 15 of file skia_conversions_unittests.cc.

15 {
16 for (int x = -100; x < 100; x += 4) {
17 for (int y = -100; y < 100; y += 4) {
18 EXPECT_EQ(skia_conversions::ToPoint(SkPoint::Make(x * 0.25f, y * 0.25f)),
19 Point(x * 0.25f, y * 0.25f));
20 }
21 }
22}
Point ToPoint(const SkPoint &point)

◆ TEST() [351/377]

impeller::testing::TEST ( SkiaConversionsTest  ,
SkPointToSize   
)

Definition at line 24 of file skia_conversions_unittests.cc.

24 {
25 for (int x = -100; x < 100; x += 4) {
26 for (int y = -100; y < 100; y += 4) {
27 EXPECT_EQ(skia_conversions::ToSize(SkPoint::Make(x * 0.25f, y * 0.25f)),
28 Size(x * 0.25f, y * 0.25f));
29 }
30 }
31}
Size ToSize(const SkPoint &point)

◆ TEST() [352/377]

impeller::testing::TEST ( SkiaConversionsTest  ,
ToColor   
)

Definition at line 33 of file skia_conversions_unittests.cc.

33 {
34 // Create a color with alpha, red, green, and blue values that are all
35 // trivially divisible by 255 so that we can test the conversion results in
36 // correct scalar values.
37 // AARRGGBB
38 const flutter::DlColor color = flutter::DlColor(0x8040C020);
39 auto converted_color = skia_conversions::ToColor(color);
40
41 ASSERT_TRUE(ScalarNearlyEqual(converted_color.alpha, 0x80 * (1.0f / 255)));
42 ASSERT_TRUE(ScalarNearlyEqual(converted_color.red, 0x40 * (1.0f / 255)));
43 ASSERT_TRUE(ScalarNearlyEqual(converted_color.green, 0xC0 * (1.0f / 255)));
44 ASSERT_TRUE(ScalarNearlyEqual(converted_color.blue, 0x20 * (1.0f / 255)));
45}
Color ToColor(const flutter::DlColor &color)

◆ TEST() [353/377]

impeller::testing::TEST ( SpecConstant  ,
CanCreateShaderWithSpecializationConstant   
)

Definition at line 14 of file specialization_constants_unittests.cc.

14 {
15 auto mock_gles = MockGLES::Init();
16 auto& proc_table = mock_gles->GetProcTable();
17 auto shader_source =
18 "#version 100\n"
19 "#ifndef SPIRV_CROSS_CONSTANT_ID_0\n"
20 "#define SPIRV_CROSS_CONSTANT_ID_0 1\n"
21 "#endif\n"
22 "void main() { return vec4(0.0); }";
23 auto test_shader = std::make_shared<fml::DataMapping>(shader_source);
24
25 auto result = proc_table.ComputeShaderWithDefines(*test_shader, {0});
26
27 auto expected_shader_source =
28 "#version 100\n"
29 "#define SPIRV_CROSS_CONSTANT_ID_0 0.000000\n"
30 "#ifndef SPIRV_CROSS_CONSTANT_ID_0\n"
31 "#define SPIRV_CROSS_CONSTANT_ID_0 1\n"
32 "#endif\n"
33 "void main() { return vec4(0.0); }";
34
35 if (!result.has_value()) {
36 GTEST_FAIL() << "Expected shader source";
37 }
38 ASSERT_EQ(result.value(), expected_shader_source);
39}

◆ TEST() [354/377]

impeller::testing::TEST ( SpecConstant  ,
CanCreateShaderWithSpecializationConstantMultipleValues   
)

Definition at line 41 of file specialization_constants_unittests.cc.

41 {
42 auto mock_gles = MockGLES::Init();
43 auto& proc_table = mock_gles->GetProcTable();
44 auto shader_source =
45 "#version 100\n"
46 "#ifndef SPIRV_CROSS_CONSTANT_ID_0\n"
47 "#define SPIRV_CROSS_CONSTANT_ID_0 1\n"
48 "#endif\n"
49 "void main() { return vec4(0.0); }";
50 auto test_shader = std::make_shared<fml::DataMapping>(shader_source);
51
52 auto result =
53 proc_table.ComputeShaderWithDefines(*test_shader, {0, 1, 2, 3, 4, 5});
54
55 auto expected_shader_source =
56 "#version 100\n"
57 "#define SPIRV_CROSS_CONSTANT_ID_0 0.000000\n"
58 "#define SPIRV_CROSS_CONSTANT_ID_1 1.000000\n"
59 "#define SPIRV_CROSS_CONSTANT_ID_2 2.000000\n"
60 "#define SPIRV_CROSS_CONSTANT_ID_3 3.000000\n"
61 "#define SPIRV_CROSS_CONSTANT_ID_4 4.000000\n"
62 "#define SPIRV_CROSS_CONSTANT_ID_5 5.000000\n"
63 "#ifndef SPIRV_CROSS_CONSTANT_ID_0\n"
64 "#define SPIRV_CROSS_CONSTANT_ID_0 1\n"
65 "#endif\n"
66 "void main() { return vec4(0.0); }";
67
68 if (!result.has_value()) {
69 GTEST_FAIL() << "Expected shader source";
70 }
71 ASSERT_EQ(result.value(), expected_shader_source);
72}

◆ TEST() [355/377]

impeller::testing::TEST ( StringsTest  ,
CanSPrintF   
)

Definition at line 86 of file base_unittests.cc.

86 {
87 ASSERT_EQ(SPrintF("%sx%d", "Hello", 12), "Hellox12");
88 ASSERT_EQ(SPrintF(""), "");
89 ASSERT_EQ(SPrintF("Hello"), "Hello");
90 ASSERT_EQ(SPrintF("%sx%.2f", "Hello", 12.122222), "Hellox12.12");
91}
std::string SPrintF(const char *format,...)
Definition: strings.cc:12

◆ TEST() [356/377]

impeller::testing::TEST ( SwapchainTest  ,
CachesRenderPassOnSwapchainImage   
)

Definition at line 59 of file swapchain_unittests.cc.

59 {
60 auto const context = MockVulkanContextBuilder().Build();
61
62 auto surface = CreateSurface(*context);
63 auto swapchain =
64 KHRSwapchainVK::Create(context, std::move(surface), ISize{1, 1});
65
66 EXPECT_TRUE(swapchain->IsValid());
67
68 // The mock swapchain will always create 3 images, verify each one starts
69 // out with the same MSAA and depth+stencil texture, and no cached
70 // framebuffer.
71 std::vector<std::shared_ptr<Texture>> msaa_textures;
72 std::vector<std::shared_ptr<Texture>> depth_stencil_textures;
73 for (auto i = 0u; i < 3u; i++) {
74 auto drawable = swapchain->AcquireNextDrawable();
75 RenderTarget render_target = drawable->GetTargetRenderPassDescriptor();
76
77 auto texture = render_target.GetRenderTargetTexture();
78 auto& texture_vk = TextureVK::Cast(*texture);
79 EXPECT_EQ(texture_vk.GetCachedFramebuffer(), nullptr);
80 EXPECT_EQ(texture_vk.GetCachedRenderPass(), nullptr);
81
82 auto command_buffer = context->CreateCommandBuffer();
83 auto render_pass = command_buffer->CreateRenderPass(render_target);
84 render_pass->EncodeCommands();
85
86 auto& depth = render_target.GetDepthAttachment();
87 depth_stencil_textures.push_back(depth.has_value() ? depth->texture
88 : nullptr);
89 msaa_textures.push_back(
90 render_target.GetColorAttachments().find(0u)->second.texture);
91 }
92
93 for (auto i = 1; i < 3; i++) {
94 EXPECT_EQ(msaa_textures[i - 1], msaa_textures[i]);
95 EXPECT_EQ(depth_stencil_textures[i - 1], depth_stencil_textures[i]);
96 }
97
98 // After each images has been acquired once and the render pass presented,
99 // each should have a cached framebuffer and render pass.
100
101 std::vector<SharedHandleVK<vk::Framebuffer>> framebuffers;
102 std::vector<SharedHandleVK<vk::RenderPass>> render_passes;
103 for (auto i = 0u; i < 3u; i++) {
104 auto drawable = swapchain->AcquireNextDrawable();
105 RenderTarget render_target = drawable->GetTargetRenderPassDescriptor();
106
107 auto texture = render_target.GetRenderTargetTexture();
108 auto& texture_vk = TextureVK::Cast(*texture);
109
110 EXPECT_NE(texture_vk.GetCachedFramebuffer(), nullptr);
111 EXPECT_NE(texture_vk.GetCachedRenderPass(), nullptr);
112 framebuffers.push_back(texture_vk.GetCachedFramebuffer());
113 render_passes.push_back(texture_vk.GetCachedRenderPass());
114 }
115
116 // Iterate through once more to verify render passes and framebuffers are
117 // unchanged.
118 for (auto i = 0u; i < 3u; i++) {
119 auto drawable = swapchain->AcquireNextDrawable();
120 RenderTarget render_target = drawable->GetTargetRenderPassDescriptor();
121
122 auto texture = render_target.GetRenderTargetTexture();
123 auto& texture_vk = TextureVK::Cast(*texture);
124
125 EXPECT_EQ(texture_vk.GetCachedFramebuffer(), framebuffers[i]);
126 EXPECT_EQ(texture_vk.GetCachedRenderPass(), render_passes[i]);
127 }
128}
std::shared_ptr< Texture > GetRenderTargetTexture() const
const std::map< size_t, ColorAttachment > & GetColorAttachments() const
const std::optional< DepthAttachment > & GetDepthAttachment() const
VkSwapchainKHR swapchain
Definition: main.cc:64
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
vk::UniqueSurfaceKHR CreateSurface(const ContextVK &context)

◆ TEST() [357/377]

impeller::testing::TEST ( SwapchainTest  ,
CanCreateSwapchain   
)

Definition at line 29 of file swapchain_unittests.cc.

29 {
30 auto const context = MockVulkanContextBuilder().Build();
31
32 auto surface = CreateSurface(*context);
33 auto swapchain =
34 KHRSwapchainVK::Create(context, std::move(surface), ISize{1, 1});
35
36 EXPECT_TRUE(swapchain->IsValid());
37}

◆ TEST() [358/377]

impeller::testing::TEST ( SwapchainTest  ,
RecreateSwapchainWhenSizeChanges   
)

Definition at line 39 of file swapchain_unittests.cc.

39 {
40 auto const context = MockVulkanContextBuilder().Build();
41
42 auto surface = CreateSurface(*context);
44 auto swapchain =
45 KHRSwapchainVK::Create(context, std::move(surface), ISize{1, 1},
46 /*enable_msaa=*/false);
47 auto image = swapchain->AcquireNextDrawable();
48 auto expected_size = ISize{1, 1};
49 EXPECT_EQ(image->GetSize(), expected_size);
50
52 swapchain->UpdateSurfaceSize(ISize{100, 100});
53
54 auto image_b = swapchain->AcquireNextDrawable();
55 expected_size = ISize{100, 100};
56 EXPECT_EQ(image_b->GetSize(), expected_size);
57}
sk_sp< const SkImage > image
Definition: SkRecords.h:269
void SetSwapchainImageSize(ISize size)
Override the image size returned by all swapchain images.
Definition: mock_vulkan.cc:932

◆ TEST() [359/377]

impeller::testing::TEST ( TessellatorTest  ,
ChecksConcurrentPolylineUsage   
)

Definition at line 515 of file tessellator_unittests.cc.

515 {
516 auto tessellator = std::make_shared<Tessellator>();
518 builder.AddLine({0, 0}, {100, 100});
519 auto path = builder.TakePath();
520
521 auto polyline = tessellator->CreateTempPolyline(path, 0.1);
522 EXPECT_DEBUG_DEATH(tessellator->CreateTempPolyline(path, 0.1),
523 "point_buffer_");
524}

◆ TEST() [360/377]

impeller::testing::TEST ( TessellatorTest  ,
CircleVertexCounts   
)

Definition at line 139 of file tessellator_unittests.cc.

139 {
140 auto tessellator = std::make_shared<Tessellator>();
141
142 auto test = [&tessellator](const Matrix& transform, Scalar radius) {
143 auto generator = tessellator->FilledCircle(transform, {}, radius);
144 size_t quadrant_divisions = generator.GetVertexCount() / 4;
145
146 // Confirm the approximation error is within the currently accepted
147 // |kCircleTolerance| value advertised by |CircleTessellator|.
148 // (With an additional 1% tolerance for floating point rounding.)
149 double angle = kPiOver2 / quadrant_divisions;
150 Point first = {radius, 0};
151 Point next = {static_cast<Scalar>(cos(angle) * radius),
152 static_cast<Scalar>(sin(angle) * radius)};
153 Point midpoint = (first + next) * 0.5;
154 EXPECT_GE(midpoint.GetLength(),
155 radius - Tessellator::kCircleTolerance * 1.01)
156 << ", transform = " << transform << ", radius = " << radius
157 << ", divisions = " << quadrant_divisions;
158 };
159
160 test({}, 0.0);
161 test({}, 0.9);
162 test({}, 1.0);
163 test({}, 1.9);
164 test(Matrix::MakeScale(Vector2(2.0, 2.0)), 0.95);
165 test({}, 2.0);
166 test(Matrix::MakeScale(Vector2(2.0, 2.0)), 1.0);
167 test({}, 11.9);
168 test({}, 12.0);
169 test({}, 35.9);
170 for (int i = 36; i < 10000; i += 4) {
171 test({}, i);
172 }
173}
static float next(float f)
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition: p3.cpp:47

◆ TEST() [361/377]

impeller::testing::TEST ( TessellatorTest  ,
EarlyReturnEmptyConvexShape   
)

Definition at line 499 of file tessellator_unittests.cc.

499 {
500 // This path is not technically empty (it has a size in one dimension),
501 // but is otherwise completely flat.
503 builder.MoveTo({0, 0});
504 builder.MoveTo({10, 10}, /*relative=*/true);
505
506 std::vector<Point> points;
507 std::vector<uint16_t> indices;
508 Tessellator::TessellateConvexInternal(builder.TakePath(), points, indices,
509 3.0);
510
511 EXPECT_TRUE(points.empty());
512}

◆ TEST() [362/377]

impeller::testing::TEST ( TessellatorTest  ,
FilledCircleTessellationVertices   
)

Definition at line 175 of file tessellator_unittests.cc.

175 {
176 auto tessellator = std::make_shared<Tessellator>();
177
178 auto test = [&tessellator](const Matrix& transform, const Point& center,
179 Scalar radius) {
180 auto generator = tessellator->FilledCircle(transform, center, radius);
181 EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
182
183 auto vertex_count = generator.GetVertexCount();
184 auto vertices = std::vector<Point>();
185 generator.GenerateVertices([&vertices](const Point& p) { //
186 vertices.push_back(p);
187 });
188 EXPECT_EQ(vertices.size(), vertex_count);
189 ASSERT_EQ(vertex_count % 4, 0u);
190
191 auto quadrant_count = vertex_count / 4;
192 for (size_t i = 0; i < quadrant_count; i++) {
193 double angle = kPiOver2 * i / (quadrant_count - 1);
194 double degrees = angle * 180.0 / kPi;
195 double rsin = sin(angle) * radius;
196 // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
197 double rcos = (i == quadrant_count - 1) ? 0.0f : cos(angle) * radius;
198 EXPECT_POINT_NEAR(vertices[i * 2],
199 Point(center.x - rcos, center.y + rsin))
200 << "vertex " << i << ", angle = " << degrees << std::endl;
201 EXPECT_POINT_NEAR(vertices[i * 2 + 1],
202 Point(center.x - rcos, center.y - rsin))
203 << "vertex " << i << ", angle = " << degrees << std::endl;
204 EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
205 Point(center.x + rcos, center.y - rsin))
206 << "vertex " << i << ", angle = " << degrees << std::endl;
207 EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
208 Point(center.x + rcos, center.y + rsin))
209 << "vertex " << i << ", angle = " << degrees << std::endl;
210 }
211 };
212
213 test({}, {}, 2.0);
214 test({}, {10, 10}, 2.0);
215 test(Matrix::MakeScale({500.0, 500.0, 0.0}), {}, 2.0);
216 test(Matrix::MakeScale({0.002, 0.002, 0.0}), {}, 1000.0);
217}
static SkScalar center(float pos0, float pos1)

◆ TEST() [363/377]

impeller::testing::TEST ( TessellatorTest  ,
FilledEllipseTessellationVertices   
)

Definition at line 364 of file tessellator_unittests.cc.

364 {
365 auto tessellator = std::make_shared<Tessellator>();
366
367 auto test = [&tessellator](const Matrix& transform, const Rect& bounds) {
368 auto center = bounds.GetCenter();
369 auto half_size = bounds.GetSize() * 0.5f;
370
371 auto generator = tessellator->FilledEllipse(transform, bounds);
372 EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
373
374 auto vertex_count = generator.GetVertexCount();
375 auto vertices = std::vector<Point>();
376 generator.GenerateVertices([&vertices](const Point& p) { //
377 vertices.push_back(p);
378 });
379 EXPECT_EQ(vertices.size(), vertex_count);
380 ASSERT_EQ(vertex_count % 4, 0u);
381
382 auto quadrant_count = vertex_count / 4;
383 for (size_t i = 0; i < quadrant_count; i++) {
384 double angle = kPiOver2 * i / (quadrant_count - 1);
385 double degrees = angle * 180.0 / kPi;
386 // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
387 double rcos =
388 (i == quadrant_count - 1) ? 0.0f : cos(angle) * half_size.width;
389 double rsin = sin(angle) * half_size.height;
390 EXPECT_POINT_NEAR(vertices[i * 2],
391 Point(center.x - rcos, center.y + rsin))
392 << "vertex " << i << ", angle = " << degrees << ", " //
393 << "bounds = " << bounds << std::endl;
394 EXPECT_POINT_NEAR(vertices[i * 2 + 1],
395 Point(center.x - rcos, center.y - rsin))
396 << "vertex " << i << ", angle = " << degrees << ", " //
397 << "bounds = " << bounds << std::endl;
398 EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
399 Point(center.x + rcos, center.y - rsin))
400 << "vertex " << i << ", angle = " << degrees << ", " //
401 << "bounds = " << bounds << std::endl;
402 EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
403 Point(center.x + rcos, center.y + rsin))
404 << "vertex " << i << ", angle = " << degrees << ", " //
405 << "bounds = " << bounds << std::endl;
406 }
407 };
408
409 // Square bounds should actually use the circle generator, but its
410 // results should match the same math as the ellipse generator.
411 test({}, Rect::MakeXYWH(0, 0, 2, 2));
412
413 test({}, Rect::MakeXYWH(0, 0, 2, 3));
414 test({}, Rect::MakeXYWH(0, 0, 3, 2));
415 test({}, Rect::MakeXYWH(5, 10, 2, 3));
416 test({}, Rect::MakeXYWH(16, 7, 3, 2));
417 test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 3, 2));
418 test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 2, 3));
419 test(Matrix::MakeScale({0.002, 0.002, 0.0}),
420 Rect::MakeXYWH(5000, 10000, 3000, 2000));
421 test(Matrix::MakeScale({0.002, 0.002, 0.0}),
422 Rect::MakeXYWH(5000, 10000, 2000, 3000));
423}

◆ TEST() [364/377]

impeller::testing::TEST ( TessellatorTest  ,
FilledRoundRectTessellationVertices   
)

Definition at line 425 of file tessellator_unittests.cc.

425 {
426 auto tessellator = std::make_shared<Tessellator>();
427
428 auto test = [&tessellator](const Matrix& transform, const Rect& bounds,
429 const Size& radii) {
430 FML_DCHECK(radii.width * 2 <= bounds.GetWidth()) << radii << bounds;
431 FML_DCHECK(radii.height * 2 <= bounds.GetHeight()) << radii << bounds;
432
433 Scalar middle_left = bounds.GetX() + radii.width;
434 Scalar middle_top = bounds.GetY() + radii.height;
435 Scalar middle_right = bounds.GetX() + bounds.GetWidth() - radii.width;
436 Scalar middle_bottom = bounds.GetY() + bounds.GetHeight() - radii.height;
437
438 auto generator = tessellator->FilledRoundRect(transform, bounds, radii);
439 EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
440
441 auto vertex_count = generator.GetVertexCount();
442 auto vertices = std::vector<Point>();
443 generator.GenerateVertices([&vertices](const Point& p) { //
444 vertices.push_back(p);
445 });
446 EXPECT_EQ(vertices.size(), vertex_count);
447 ASSERT_EQ(vertex_count % 4, 0u);
448
449 auto quadrant_count = vertex_count / 4;
450 for (size_t i = 0; i < quadrant_count; i++) {
451 double angle = kPiOver2 * i / (quadrant_count - 1);
452 double degrees = angle * 180.0 / kPi;
453 // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
454 double rcos = (i == quadrant_count - 1) ? 0.0f : cos(angle) * radii.width;
455 double rsin = sin(angle) * radii.height;
456 EXPECT_POINT_NEAR(vertices[i * 2],
457 Point(middle_left - rcos, middle_bottom + rsin))
458 << "vertex " << i << ", angle = " << degrees << ", " //
459 << "bounds = " << bounds << std::endl;
460 EXPECT_POINT_NEAR(vertices[i * 2 + 1],
461 Point(middle_left - rcos, middle_top - rsin))
462 << "vertex " << i << ", angle = " << degrees << ", " //
463 << "bounds = " << bounds << std::endl;
464 EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
465 Point(middle_right + rcos, middle_top - rsin))
466 << "vertex " << i << ", angle = " << degrees << ", " //
467 << "bounds = " << bounds << std::endl;
468 EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
469 Point(middle_right + rcos, middle_bottom + rsin))
470 << "vertex " << i << ", angle = " << degrees << ", " //
471 << "bounds = " << bounds << std::endl;
472 }
473 };
474
475 // Both radii spanning the bounds should actually use the circle/ellipse
476 // generator, but their results should match the same math as the round
477 // rect generator.
478 test({}, Rect::MakeXYWH(0, 0, 20, 20), {10, 10});
479
480 // One radius spanning the bounds, but not the other will not match the
481 // round rect math if the generator transfers to circle/ellipse
482 test({}, Rect::MakeXYWH(0, 0, 20, 20), {10, 5});
483 test({}, Rect::MakeXYWH(0, 0, 20, 20), {5, 10});
484
485 test({}, Rect::MakeXYWH(0, 0, 20, 30), {2, 2});
486 test({}, Rect::MakeXYWH(0, 0, 30, 20), {2, 2});
487 test({}, Rect::MakeXYWH(5, 10, 20, 30), {2, 3});
488 test({}, Rect::MakeXYWH(16, 7, 30, 20), {2, 3});
489 test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 30, 20),
490 {2, 3});
491 test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 20, 30),
492 {2, 3});
493 test(Matrix::MakeScale({0.002, 0.002, 0.0}),
494 Rect::MakeXYWH(5000, 10000, 3000, 2000), {50, 70});
495 test(Matrix::MakeScale({0.002, 0.002, 0.0}),
496 Rect::MakeXYWH(5000, 10000, 2000, 3000), {50, 70});
497}

◆ TEST() [365/377]

impeller::testing::TEST ( TessellatorTest  ,
RoundCapLineTessellationVertices   
)

Definition at line 291 of file tessellator_unittests.cc.

291 {
292 auto tessellator = std::make_shared<Tessellator>();
293
294 auto test = [&tessellator](const Matrix& transform, const Point& p0,
295 const Point& p1, Scalar radius) {
296 auto generator = tessellator->RoundCapLine(transform, p0, p1, radius);
297 EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
298
299 auto vertex_count = generator.GetVertexCount();
300 auto vertices = std::vector<Point>();
301 generator.GenerateVertices([&vertices](const Point& p) { //
302 vertices.push_back(p);
303 });
304 EXPECT_EQ(vertices.size(), vertex_count);
305 ASSERT_EQ(vertex_count % 4, 0u);
306
307 Point along = p1 - p0;
308 Scalar length = along.GetLength();
309 if (length > 0) {
310 along *= radius / length;
311 } else {
312 along = {radius, 0};
313 }
314 Point across = {-along.y, along.x};
315
316 auto quadrant_count = vertex_count / 4;
317 for (size_t i = 0; i < quadrant_count; i++) {
318 double angle = kPiOver2 * i / (quadrant_count - 1);
319 double degrees = angle * 180.0 / kPi;
320 // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
321 Point relative_along =
322 along * ((i == quadrant_count - 1) ? 0.0f : cos(angle));
323 Point relative_across = across * sin(angle);
324 EXPECT_POINT_NEAR(vertices[i * 2], //
325 p0 - relative_along + relative_across)
326 << "vertex " << i << ", angle = " << degrees << ", " //
327 << "line = " << p0 << " => " << p1 << ", " //
328 << "radius = " << radius << std::endl;
329 EXPECT_POINT_NEAR(vertices[i * 2 + 1], //
330 p0 - relative_along - relative_across)
331 << "vertex " << i << ", angle = " << degrees << ", " //
332 << "line = " << p0 << " => " << p1 << ", " //
333 << "radius = " << radius << std::endl;
334 EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1], //
335 p1 + relative_along - relative_across)
336 << "vertex " << i << ", angle = " << degrees << ", " //
337 << "line = " << p0 << " => " << p1 << ", " //
338 << "radius = " << radius << std::endl;
339 EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2], //
340 p1 + relative_along + relative_across)
341 << "vertex " << i << ", angle = " << degrees << ", " //
342 << "line = " << p0 << " => " << p1 << ", " //
343 << "radius = " << radius << std::endl;
344 }
345 };
346
347 // Empty line should actually use the circle generator, but its
348 // results should match the same math as the round cap generator.
349 test({}, {0, 0}, {0, 0}, 10);
350
351 test({}, {0, 0}, {10, 0}, 2);
352 test({}, {10, 0}, {0, 0}, 2);
353 test({}, {0, 0}, {10, 10}, 2);
354
355 test(Matrix::MakeScale({500.0, 500.0, 0.0}), {0, 0}, {10, 0}, 2);
356 test(Matrix::MakeScale({500.0, 500.0, 0.0}), {10, 0}, {0, 0}, 2);
357 test(Matrix::MakeScale({500.0, 500.0, 0.0}), {0, 0}, {10, 10}, 2);
358
359 test(Matrix::MakeScale({0.002, 0.002, 0.0}), {0, 0}, {10, 0}, 2);
360 test(Matrix::MakeScale({0.002, 0.002, 0.0}), {10, 0}, {0, 0}, 2);
361 test(Matrix::MakeScale({0.002, 0.002, 0.0}), {0, 0}, {10, 10}, 2);
362}
size_t length
constexpr Type GetLength() const
Definition: point.h:206

◆ TEST() [366/377]

impeller::testing::TEST ( TessellatorTest  ,
StrokedCircleTessellationVertices   
)

Definition at line 219 of file tessellator_unittests.cc.

219 {
220 auto tessellator = std::make_shared<Tessellator>();
221
222 auto test = [&tessellator](const Matrix& transform, const Point& center,
223 Scalar radius, Scalar half_width) {
224 ASSERT_GT(radius, half_width);
225 auto generator =
226 tessellator->StrokedCircle(transform, center, radius, half_width);
227 EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
228
229 auto vertex_count = generator.GetVertexCount();
230 auto vertices = std::vector<Point>();
231 generator.GenerateVertices([&vertices](const Point& p) { //
232 vertices.push_back(p);
233 });
234 EXPECT_EQ(vertices.size(), vertex_count);
235 ASSERT_EQ(vertex_count % 4, 0u);
236
237 auto quadrant_count = vertex_count / 8;
238
239 // Test outer points first
240 for (size_t i = 0; i < quadrant_count; i++) {
241 double angle = kPiOver2 * i / (quadrant_count - 1);
242 double degrees = angle * 180.0 / kPi;
243 double rsin = sin(angle) * (radius + half_width);
244 // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
245 double rcos =
246 (i == quadrant_count - 1) ? 0.0f : cos(angle) * (radius + half_width);
247 EXPECT_POINT_NEAR(vertices[i * 2],
248 Point(center.x - rcos, center.y - rsin))
249 << "vertex " << i << ", angle = " << degrees << std::endl;
250 EXPECT_POINT_NEAR(vertices[quadrant_count * 2 + i * 2],
251 Point(center.x + rsin, center.y - rcos))
252 << "vertex " << i << ", angle = " << degrees << std::endl;
253 EXPECT_POINT_NEAR(vertices[quadrant_count * 4 + i * 2],
254 Point(center.x + rcos, center.y + rsin))
255 << "vertex " << i << ", angle = " << degrees << std::endl;
256 EXPECT_POINT_NEAR(vertices[quadrant_count * 6 + i * 2],
257 Point(center.x - rsin, center.y + rcos))
258 << "vertex " << i << ", angle = " << degrees << std::endl;
259 }
260
261 // Then test innerer points
262 for (size_t i = 0; i < quadrant_count; i++) {
263 double angle = kPiOver2 * i / (quadrant_count - 1);
264 double degrees = angle * 180.0 / kPi;
265 double rsin = sin(angle) * (radius - half_width);
266 // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
267 double rcos =
268 (i == quadrant_count - 1) ? 0.0f : cos(angle) * (radius - half_width);
269 EXPECT_POINT_NEAR(vertices[i * 2 + 1],
270 Point(center.x - rcos, center.y - rsin))
271 << "vertex " << i << ", angle = " << degrees << std::endl;
272 EXPECT_POINT_NEAR(vertices[quadrant_count * 2 + i * 2 + 1],
273 Point(center.x + rsin, center.y - rcos))
274 << "vertex " << i << ", angle = " << degrees << std::endl;
275 EXPECT_POINT_NEAR(vertices[quadrant_count * 4 + i * 2 + 1],
276 Point(center.x + rcos, center.y + rsin))
277 << "vertex " << i << ", angle = " << degrees << std::endl;
278 EXPECT_POINT_NEAR(vertices[quadrant_count * 6 + i * 2 + 1],
279 Point(center.x - rsin, center.y + rcos))
280 << "vertex " << i << ", angle = " << degrees << std::endl;
281 }
282 };
283
284 test({}, {}, 2.0, 1.0);
285 test({}, {}, 2.0, 0.5);
286 test({}, {10, 10}, 2.0, 1.0);
287 test(Matrix::MakeScale({500.0, 500.0, 0.0}), {}, 2.0, 1.0);
288 test(Matrix::MakeScale({0.002, 0.002, 0.0}), {}, 1000.0, 10.0);
289}

◆ TEST() [367/377]

impeller::testing::TEST ( TessellatorTest  ,
TessellateConvex   
)

Definition at line 84 of file tessellator_unittests.cc.

84 {
85 {
86 std::vector<Point> points;
87 std::vector<uint16_t> indices;
88 // Sanity check simple rectangle.
89 Tessellator::TessellateConvexInternal(
90 PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 10, 10)).TakePath(), points,
91 indices, 1.0);
92
93 // Note: the origin point is repeated but not referenced in the indices
94 // below
95 std::vector<Point> expected = {{0, 0}, {10, 0}, {10, 10}, {0, 10}, {0, 0}};
96 std::vector<uint16_t> expected_indices = {0, 1, 3, 2};
97 EXPECT_EQ(points, expected);
98 EXPECT_EQ(indices, expected_indices);
99 }
100
101 {
102 std::vector<Point> points;
103 std::vector<uint16_t> indices;
104 Tessellator::TessellateConvexInternal(
105 PathBuilder{}
106 .AddRect(Rect::MakeLTRB(0, 0, 10, 10))
107 .AddRect(Rect::MakeLTRB(20, 20, 30, 30))
108 .TakePath(),
109 points, indices, 1.0);
110
111 std::vector<Point> expected = {{0, 0}, {10, 0}, {10, 10}, {0, 10},
112 {0, 0}, {20, 20}, {30, 20}, {30, 30},
113 {20, 30}, {20, 20}};
114 std::vector<uint16_t> expected_indices = {0, 1, 3, 2, 2, 5, 5, 6, 8, 7};
115 EXPECT_EQ(points, expected);
116 EXPECT_EQ(indices, expected_indices);
117 }
118}

◆ TEST() [368/377]

impeller::testing::TEST ( TessellatorTest  ,
TessellateConvexUnclosedPath   
)

Definition at line 121 of file tessellator_unittests.cc.

121 {
122 std::vector<Point> points;
123 std::vector<uint16_t> indices;
124
125 // Create a rectangle that lacks an explicit close.
127 .LineTo({100, 0})
128 .LineTo({100, 100})
129 .LineTo({0, 100})
130 .TakePath();
131 Tessellator::TessellateConvexInternal(path, points, indices, 1.0);
132
133 std::vector<Point> expected = {{0, 0}, {100, 0}, {100, 100}, {0, 100}};
134 std::vector<uint16_t> expected_indices = {0, 1, 3, 2};
135 EXPECT_EQ(points, expected);
136 EXPECT_EQ(indices, expected_indices);
137}
PathBuilder & LineTo(Point point, bool relative=false)
Insert a line from the current position to point.
Definition: path_builder.cc:52

◆ TEST() [369/377]

impeller::testing::TEST ( TessellatorTest  ,
TessellatorBuilderReturnsCorrectResultStatus   
)

Definition at line 17 of file tessellator_unittests.cc.

17 {
18 // Zero points.
19 {
21 auto path = PathBuilder{}.TakePath(FillType::kOdd);
23 path, 1.0f,
24 [](const float* vertices, size_t vertices_count,
25 const uint16_t* indices, size_t indices_count) { return true; });
26
27 ASSERT_EQ(result, TessellatorLibtess::Result::kInputError);
28 }
29
30 // One point.
31 {
32 TessellatorLibtess t;
33 auto path = PathBuilder{}.LineTo({0, 0}).TakePath(FillType::kOdd);
34 TessellatorLibtess::Result result = t.Tessellate(
35 path, 1.0f,
36 [](const float* vertices, size_t vertices_count,
37 const uint16_t* indices, size_t indices_count) { return true; });
38
40 }
41
42 // Two points.
43 {
44 TessellatorLibtess t;
45 auto path = PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath(FillType::kOdd);
46 TessellatorLibtess::Result result = t.Tessellate(
47 path, 1.0f,
48 [](const float* vertices, size_t vertices_count,
49 const uint16_t* indices, size_t indices_count) { return true; });
50
52 }
53
54 // Many points.
55 {
56 TessellatorLibtess t;
57 PathBuilder builder;
58 for (int i = 0; i < 1000; i++) {
59 auto coord = i * 1.0f;
60 builder.AddLine({coord, coord}, {coord + 1, coord + 1});
61 }
62 auto path = builder.TakePath(FillType::kOdd);
63 TessellatorLibtess::Result result = t.Tessellate(
64 path, 1.0f,
65 [](const float* vertices, size_t vertices_count,
66 const uint16_t* indices, size_t indices_count) { return true; });
67
69 }
70
71 // Closure fails.
72 {
73 TessellatorLibtess t;
74 auto path = PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath(FillType::kOdd);
75 TessellatorLibtess::Result result = t.Tessellate(
76 path, 1.0f,
77 [](const float* vertices, size_t vertices_count,
78 const uint16_t* indices, size_t indices_count) { return false; });
79
80 ASSERT_EQ(result, TessellatorLibtess::Result::kInputError);
81 }
82}
An extended tessellator that offers arbitrary/concave tessellation via the libtess2 library.
TessellatorLibtess::Result Tessellate(const Path &path, Scalar tolerance, const BuilderCallback &callback)
Generates filled triangles from the path. A callback is invoked once for the entire tessellation.
@ kSuccess
Definition: embedder.h:73

◆ TEST() [370/377]

impeller::testing::TEST ( TextureMTL  ,
CreateFromDrawable   
)

Definition at line 21 of file texture_mtl_unittests.mm.

21 {
22 auto device = MTLCreateSystemDefaultDevice();
23 auto layer = [[CAMetalLayer alloc] init];
24 layer.device = device;
25 layer.drawableSize = CGSize{100, 100};
26 layer.pixelFormat = ToMTLPixelFormat(PixelFormat::kB8G8R8A8UNormInt);
27
29 desc.size = {100, 100};
30 desc.format = PixelFormat::kB8G8R8A8UNormInt;
31 auto drawable_future = GetDrawableDeferred(layer);
32 auto drawable_texture =
33 CreateTextureFromDrawableFuture(desc, drawable_future);
34
35 ASSERT_TRUE(drawable_texture->IsValid());
36 EXPECT_TRUE(drawable_texture->IsDrawable());
37
38 // Spawn a thread and acquire the drawable in the thread.
39 auto thread = std::thread([&drawable_texture]() {
40 // Force the drawable to be acquired.
41 drawable_texture->GetMTLTexture();
42 });
43 thread.join();
44 // Block until drawable is acquired.
45 EXPECT_TRUE(drawable_future.get() != nil);
46 // Drawable is cached.
47 EXPECT_TRUE(drawable_texture->GetMTLTexture() != nil);
48 // Once more for good measure.
49 EXPECT_TRUE(drawable_texture->GetMTLTexture() != nil);
50}
static bool init()
std::shared_ptr< TextureMTL > CreateTextureFromDrawableFuture(TextureDescriptor desc, const std::shared_future< id< CAMetalDrawable > > &drawble_future)
Create a TextureMTL from a deferred drawable.
constexpr MTLPixelFormat ToMTLPixelFormat(PixelFormat format)
Definition: formats_mtl.h:76
std::shared_future< id< CAMetalDrawable > > GetDrawableDeferred(CAMetalLayer *layer)
Create a deferred drawable from a CAMetalLayer.

◆ TEST() [371/377]

impeller::testing::TEST ( ThreadTest  ,
CanCreateMutex   
)

Definition at line 36 of file base_unittests.cc.

36 {
37 Foo f = {};
38
39 // f.a = 100; <--- Static analysis error.
40 f.mtx.Lock();
41 f.a = 100;
42 f.mtx.Unlock();
43}

◆ TEST() [372/377]

impeller::testing::TEST ( ThreadTest  ,
CanCreateMutexLock   
)

Definition at line 45 of file base_unittests.cc.

45 {
46 Foo f = {};
47
48 // f.a = 100; <--- Static analysis error.
49 auto a = Lock(f.mtx);
50 f.a = 100;
51}

◆ TEST() [373/377]

impeller::testing::TEST ( ThreadTest  ,
CanCreateRWMutex   
)

Definition at line 53 of file base_unittests.cc.

53 {
54 RWFoo f = {};
55
56 // f.a = 100; <--- Static analysis error.
57 f.mtx.LockWriter();
58 f.a = 100;
59 f.mtx.UnlockWriter();
60 // int b = f.a; <--- Static analysis error.
61 f.mtx.LockReader();
62 int b = f.a; // NOLINT(clang-analyzer-deadcode.DeadStores)
64 f.mtx.UnlockReader();
65}
#define FML_ALLOW_UNUSED_LOCAL(x)

◆ TEST() [374/377]

impeller::testing::TEST ( ThreadTest  ,
CanCreateRWMutexLock   
)

Definition at line 67 of file base_unittests.cc.

67 {
68 RWFoo f = {};
69
70 // f.a = 100; <--- Static analysis error.
71 {
72 auto write_lock = WriterLock{f.mtx};
73 f.a = 100;
74 }
75
76 // int b = f.a; <--- Static analysis error.
77 {
78 auto read_lock = ReaderLock(f.mtx);
79 int b = f.a; // NOLINT(clang-analyzer-deadcode.DeadStores)
81 }
82
83 // f.mtx.UnlockReader(); <--- Static analysis error.
84}

◆ TEST() [375/377]

impeller::testing::TEST ( TrigTest  ,
MultiplyByScalarRadius   
)

Definition at line 65 of file trig_unittests.cc.

65 {
66 for (int i = 0; i <= 360; i++) {
67 for (int i = 1; i <= 10; i++) {
68 Scalar radius = i * 5.0f;
69 EXPECT_EQ(Trig(Degrees(i)) * radius,
70 Point(radius * std::cos(i * kPi / 180),
71 radius * std::sin(i * kPi / 180)))
72 << "at " << i << " degrees and radius " << radius;
73 }
74 }
75}
A structure to store the sine and cosine of an angle.
Definition: trig.h:16

◆ TEST() [376/377]

impeller::testing::TEST ( TrigTest  ,
TrigAngles   
)

Definition at line 15 of file trig_unittests.cc.

15 {
16 {
17 Trig trig(Degrees(0.0));
18 EXPECT_EQ(trig.cos, 1.0);
19 EXPECT_EQ(trig.sin, 0.0);
20 }
21
22 {
23 Trig trig(Radians(0.0));
24 EXPECT_EQ(trig.cos, 1.0);
25 EXPECT_EQ(trig.sin, 0.0);
26 }
27
28 {
29 Trig trig(Degrees(30.0));
30 EXPECT_NEAR(trig.cos, sqrt(0.75), kEhCloseEnough);
31 EXPECT_NEAR(trig.sin, 0.5, kEhCloseEnough);
32 }
33
34 {
35 Trig trig(Radians(kPi / 6.0));
36 EXPECT_NEAR(trig.cos, sqrt(0.75), kEhCloseEnough);
37 EXPECT_NEAR(trig.sin, 0.5, kEhCloseEnough);
38 }
39
40 {
41 Trig trig(Degrees(60.0));
42 EXPECT_NEAR(trig.cos, 0.5, kEhCloseEnough);
43 EXPECT_NEAR(trig.sin, sqrt(0.75), kEhCloseEnough);
44 }
45
46 {
47 Trig trig(Radians(kPi / 3.0));
48 EXPECT_NEAR(trig.cos, 0.5, kEhCloseEnough);
49 EXPECT_NEAR(trig.sin, sqrt(0.75), kEhCloseEnough);
50 }
51
52 {
53 Trig trig(Degrees(90.0));
54 EXPECT_NEAR(trig.cos, 0.0, kEhCloseEnough);
55 EXPECT_NEAR(trig.sin, 1.0, kEhCloseEnough);
56 }
57
58 {
59 Trig trig(Radians(kPi / 2.0));
60 EXPECT_NEAR(trig.cos, 0.0, kEhCloseEnough);
61 EXPECT_NEAR(trig.sin, 1.0, kEhCloseEnough);
62 }
63}
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
Definition: SkVx.h:706

◆ TEST() [377/377]

impeller::testing::TEST ( TypographerTest  ,
RectanglePackerFillsRows   
)

Definition at line 398 of file typographer_unittests.cc.

398 {
399 auto skyline = RectanglePacker::Factory(257, 256);
400
401 // Fill up the first row.
402 IPoint16 loc;
403 for (auto i = 0u; i < 16; i++) {
404 skyline->AddRect(16, 16, &loc);
405 }
406 // Last rectangle still in first row.
407 EXPECT_EQ(loc.x(), 256 - 16);
408 EXPECT_EQ(loc.y(), 0);
409
410 // Fill up second row.
411 for (auto i = 0u; i < 16; i++) {
412 skyline->AddRect(16, 16, &loc);
413 }
414
415 EXPECT_EQ(loc.x(), 256 - 16);
416 EXPECT_EQ(loc.y(), 16);
417}
SKSHAPER_API sk_sp< Factory > Factory()
int16_t y() const
int16_t x() const

◆ TEST_F()

impeller::testing::TEST_F ( GoldenTests  ,
ConicalGradient   
)

Definition at line 72 of file golden_tests.cc.

72 {
73 Canvas canvas;
75
76 paint.color_source = ColorSource::MakeConicalGradient(
77 {125, 125}, 125, {Color(1.0, 0.0, 0.0, 1.0), Color(0.0, 0.0, 1.0, 1.0)},
78 {0, 1}, {180, 180}, 0, Entity::TileMode::kClamp, {});
79
80 paint.stroke_width = 0.0;
81 paint.style = Paint::Style::kFill;
82 canvas.DrawRect(Rect::MakeXYWH(10, 10, 250, 250), paint);
83 Picture picture = canvas.EndRecordingAsPicture();
84
85 auto aiks_context =
86 AiksContext(Screenshotter().GetPlayground().GetContext(), nullptr);
87 auto screenshot = Screenshotter().MakeScreenshot(aiks_context, picture);
88 ASSERT_TRUE(SaveScreenshot(std::move(screenshot)));
89}
SK_API GrDirectContext * GetContext(const SkImage *src)
SK_API sk_sp< PrecompileShader > Picture()

◆ TEST_P() [1/450]

impeller::testing::TEST_P ( AiksTest  ,
ArcWithZeroSweepAndBlur   
)

Definition at line 371 of file aiks_path_unittests.cc.

371 {
372 Canvas canvas;
373 canvas.Scale(GetContentScale());
374
375 Paint paint;
376 paint.color = Color::Red();
377 std::vector<Color> colors = {Color{1.0, 0.0, 0.0, 1.0},
378 Color{0.0, 0.0, 0.0, 1.0}};
379 std::vector<Scalar> stops = {0.0, 1.0};
380 paint.color_source = ColorSource::MakeSweepGradient(
381 {100, 100}, Degrees(45), Degrees(135), std::move(colors),
382 std::move(stops), Entity::TileMode::kMirror, {});
383 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
385 .sigma = Sigma(20),
386 };
387
388 PathBuilder builder;
389 builder.AddArc(Rect::MakeXYWH(10, 10, 100, 100), Degrees(0), Degrees(0),
390 false);
391 canvas.DrawPath(builder.TakePath(), paint);
392
393 // Check that this empty picture can be created without crashing.
394 canvas.EndRecordingAsPicture();
395}

◆ TEST_P() [2/450]

impeller::testing::TEST_P ( AiksTest  ,
BlendModePlusAlphaColorFilterWideGamut   
)

Definition at line 157 of file aiks_blend_unittests.cc.

157 {
158 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
159 PixelFormat::kB10G10R10A10XR);
160 auto texture = CreateTextureForFixture("airplane.jpg",
161 /*enable_mipmapping=*/true);
162
163 Canvas canvas;
164 canvas.Scale(GetContentScale());
165 canvas.DrawPaint({.color = Color(0.1, 0.2, 0.1, 1.0)});
166 canvas.SaveLayer({
167 .color_filter =
168 ColorFilter::MakeBlend(BlendMode::kPlus, Color(Vector4{1, 0, 0, 1})),
169 });
170 Paint paint;
171 paint.color = Color::Red();
172 canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
173 paint.color = Color::White();
174 canvas.DrawImageRect(
175 std::make_shared<Image>(texture), Rect::MakeSize(texture->GetSize()),
176 Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100), paint);
177 canvas.Restore();
178 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
179}

◆ TEST_P() [3/450]

impeller::testing::TEST_P ( AiksTest  ,
BlendModePlusAlphaWideGamut   
)

Definition at line 134 of file aiks_blend_unittests.cc.

134 {
135 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
136 PixelFormat::kB10G10R10A10XR);
137 auto texture = CreateTextureForFixture("airplane.jpg",
138 /*enable_mipmapping=*/true);
139
140 Canvas canvas;
141 canvas.Scale(GetContentScale());
142 canvas.DrawPaint({.color = Color(0.9, 1.0, 0.9, 1.0)});
143 canvas.SaveLayer({});
144 Paint paint;
145 paint.blend_mode = BlendMode::kPlus;
146 paint.color = Color::Red();
147 canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
148 paint.color = Color::White();
149 canvas.DrawImageRect(
150 std::make_shared<Image>(texture), Rect::MakeSize(texture->GetSize()),
151 Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100), paint);
152 canvas.Restore();
153 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
154}

◆ TEST_P() [4/450]

impeller::testing::TEST_P ( AiksTest  ,
BlendModeShouldCoverWholeScreen   
)

Definition at line 43 of file aiks_blend_unittests.cc.

43 {
44 Canvas canvas;
46
47 paint.color = Color::Red();
48 canvas.DrawPaint(paint);
49
50 paint.blend_mode = BlendMode::kSourceOver;
51 canvas.SaveLayer(paint);
52
53 paint.color = Color::White();
54 canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
55
56 paint.blend_mode = BlendMode::kSource;
57 canvas.SaveLayer(paint);
58
59 paint.color = Color::Blue();
60 canvas.DrawRect(Rect::MakeXYWH(200, 200, 200, 200), paint);
61
62 canvas.Restore();
63 canvas.Restore();
64
65 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
66}

◆ TEST_P() [5/450]

impeller::testing::TEST_P ( AiksTest  ,
BlurHasNoEdge   
)

Definition at line 201 of file aiks_blur_unittests.cc.

201 {
202 Scalar sigma = 47.6;
203 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
204 if (AiksTest::ImGuiBegin("Controls", nullptr,
205 ImGuiWindowFlags_AlwaysAutoResize)) {
206 ImGui::SliderFloat("Sigma", &sigma, 0, 50);
207 ImGui::End();
208 }
209 Canvas canvas;
210 canvas.Scale(GetContentScale());
211 canvas.DrawPaint({});
212 Paint blur = {
213 .color = Color::Green(),
214 .mask_blur_descriptor =
215 Paint::MaskBlurDescriptor{
217 .sigma = Sigma(sigma),
218 },
219 };
220 canvas.DrawRect(Rect::MakeXYWH(300, 300, 200, 200), blur);
221 return canvas.EndRecordingAsPicture();
222 };
223
224 ASSERT_TRUE(OpenPlaygroundHere(callback));
225}
void DrawPaint(const Paint &paint)
Definition: canvas.cc:352
void Scale(const Vector2 &scale)
Definition: canvas.cc:315
Picture EndRecordingAsPicture()
Definition: canvas.cc:804
void DrawRect(const Rect &rect, const Paint &paint)
Definition: canvas.cc:495
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback

◆ TEST_P() [6/450]

impeller::testing::TEST_P ( AiksTest  ,
BlurredRectangleWithShader   
)

Definition at line 227 of file aiks_blur_unittests.cc.

227 {
228 Canvas canvas;
229 canvas.Scale(GetContentScale());
230
231 auto paint_lines = [&canvas](Scalar dx, Scalar dy, Paint paint) {
232 auto draw_line = [&canvas, &paint](Point a, Point b) {
233 canvas.DrawPath(PathBuilder{}.AddLine(a, b).TakePath(), paint);
234 };
235 paint.stroke_width = 5;
236 paint.style = Paint::Style::kStroke;
237 draw_line(Point(dx + 100, dy + 100), Point(dx + 200, dy + 200));
238 draw_line(Point(dx + 100, dy + 200), Point(dx + 200, dy + 100));
239 draw_line(Point(dx + 150, dy + 100), Point(dx + 200, dy + 150));
240 draw_line(Point(dx + 100, dy + 150), Point(dx + 150, dy + 200));
241 };
242
243 AiksContext renderer(GetContext(), nullptr);
244 Canvas recorder_canvas;
245 for (int x = 0; x < 5; ++x) {
246 for (int y = 0; y < 5; ++y) {
247 Rect rect = Rect::MakeXYWH(x * 20, y * 20, 20, 20);
248 Paint paint{.color =
249 ((x + y) & 1) == 0 ? Color::Yellow() : Color::Blue()};
250 recorder_canvas.DrawRect(rect, paint);
251 }
252 }
253 Picture picture = recorder_canvas.EndRecordingAsPicture();
254 std::shared_ptr<Texture> texture =
255 picture.ToImage(renderer, ISize{100, 100})->GetTexture();
256
257 ColorSource image_source = ColorSource::MakeImage(
258 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, {});
259 std::shared_ptr<ImageFilter> blur_filter = ImageFilter::MakeBlur(
260 Sigma(5), Sigma(5), FilterContents::BlurStyle::kNormal,
261 Entity::TileMode::kDecal);
262 canvas.DrawRect(Rect::MakeLTRB(0, 0, 300, 600),
263 Paint{.color = Color::DarkGreen()});
264 canvas.DrawRect(Rect::MakeLTRB(100, 100, 200, 200),
265 Paint{.color_source = image_source});
266 canvas.DrawRect(Rect::MakeLTRB(300, 0, 600, 600),
267 Paint{.color = Color::Red()});
268 canvas.DrawRect(
269 Rect::MakeLTRB(400, 100, 500, 200),
270 Paint{.color_source = image_source, .image_filter = blur_filter});
271 paint_lines(0, 300, Paint{.color_source = image_source});
272 paint_lines(300, 300,
273 Paint{.color_source = image_source, .image_filter = blur_filter});
274 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
275}
static void draw_line(SkCanvas *canvas, SkImage *, const SkRect &r, sk_sp< SkImageFilter > imf)
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208

◆ TEST_P() [7/450]

impeller::testing::TEST_P ( AiksTest  ,
CanConvertTriangleFanToTriangles   
)

Definition at line 153 of file aiks_dl_vertices_unittests.cc.

153 {
154 constexpr Scalar hexagon_radius = 125;
155 auto hex_start = Point(200.0, -hexagon_radius + 200.0);
156 auto center_to_flat = 1.73 / 2 * hexagon_radius;
157
158 // clang-format off
159 std::vector<SkPoint> vertices = {
160 SkPoint::Make(hex_start.x, hex_start.y),
161 SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 0.5 * hexagon_radius),
162 SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
163 SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
164 SkPoint::Make(hex_start.x, hex_start.y + 2 * hexagon_radius),
165 SkPoint::Make(hex_start.x, hex_start.y + 2 * hexagon_radius),
166 SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
167 SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
168 SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 0.5 * hexagon_radius)
169 };
170 // clang-format on
172 auto dl_vertices = flutter::DlVertices::Make(
173 flutter::DlVertexMode::kTriangleFan, vertices.size(), vertices.data(),
174 nullptr, nullptr);
176 builder.DrawVertices(dl_vertices, flutter::DlBlendMode::kSrcOver, paint);
177 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
178}
static std::shared_ptr< DlVertices > Make(DlVertexMode mode, int vertex_count, const SkPoint vertices[], const SkPoint texture_coordinates[], const DlColor colors[], int index_count=0, const uint16_t indices[]=nullptr)
Constructs a DlVector with compact inline storage for all of its required and optional lists of data.
Definition: dl_vertices.cc:39
@ kSrcOver
r = s + (1-sa)*d
flutter::DlPaint DlPaint
static constexpr DlColor kDarkGrey()
Definition: dl_color.h:30

◆ TEST_P() [8/450]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawAnOpenPath   
)

Definition at line 142 of file aiks_path_unittests.cc.

142 {
143 Canvas canvas;
144
145 // Starting at (50, 50), draw lines from:
146 // 1. (50, height)
147 // 2. (width, height)
148 // 3. (width, 50)
150 builder.MoveTo({50, 50});
151 builder.LineTo({50, 100});
152 builder.LineTo({100, 100});
153 builder.LineTo({100, 50});
154
155 Paint paint;
156 paint.color = Color::Red();
157 paint.style = Paint::Style::kStroke;
158 paint.stroke_width = 10;
159
160 canvas.DrawPath(builder.TakePath(), paint);
161
162 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
163}

◆ TEST_P() [9/450]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawAnOpenPathThatIsntARect   
)

Definition at line 165 of file aiks_path_unittests.cc.

165 {
166 Canvas canvas;
167
168 // Draw a stroked path that is explicitly closed to verify
169 // It doesn't become a rectangle.
171 builder.MoveTo({50, 50});
172 builder.LineTo({520, 120});
173 builder.LineTo({300, 310});
174 builder.LineTo({100, 50});
175 builder.Close();
176
177 Paint paint;
178 paint.color = Color::Red();
179 paint.style = Paint::Style::kStroke;
180 paint.stroke_width = 10;
181
182 canvas.DrawPath(builder.TakePath(), paint);
183
184 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
185}

◆ TEST_P() [10/450]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawMultiContourConvexPath   
)

Definition at line 351 of file aiks_path_unittests.cc.

351 {
352 PathBuilder builder = {};
353 for (auto i = 0; i < 10; i++) {
354 if (i % 2 == 0) {
355 builder.AddCircle(Point(100 + 50 * i, 100 + 50 * i), 100);
356 } else {
357 builder.MoveTo({100.f + 50.f * i - 100, 100.f + 50.f * i});
358 builder.LineTo({100.f + 50.f * i, 100.f + 50.f * i - 100});
359 builder.LineTo({100.f + 50.f * i - 100, 100.f + 50.f * i - 100});
360 builder.Close();
361 }
362 }
363 builder.SetConvexity(Convexity::kConvex);
364
365 Canvas canvas;
366 canvas.DrawPath(builder.TakePath(), {.color = Color::Red().WithAlpha(0.4)});
367
368 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
369}

◆ TEST_P() [11/450]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaint   
)

Definition at line 843 of file aiks_unittests.cc.

843 {
844 Canvas canvas;
845 canvas.Scale(Vector2(0.2, 0.2));
846 canvas.DrawPaint({.color = Color::MediumTurquoise()});
847 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
848}

◆ TEST_P() [12/450]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintMultipleTimes   
)

Definition at line 850 of file aiks_unittests.cc.

850 {
851 Canvas canvas;
852 canvas.Scale(Vector2(0.2, 0.2));
853 canvas.DrawPaint({.color = Color::MediumTurquoise()});
854 canvas.DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5)});
855 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
856}

◆ TEST_P() [13/450]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintMultipleTimesInteractive   
)

Definition at line 524 of file aiks_blend_unittests.cc.

524 {
525 auto modes = GetBlendModeSelection();
526
527 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
528 static Color background = Color::MediumTurquoise();
529 static Color foreground = Color::Color::OrangeRed().WithAlpha(0.5);
530 static int current_blend_index = 3;
531
532 if (AiksTest::ImGuiBegin("Controls", nullptr,
533 ImGuiWindowFlags_AlwaysAutoResize)) {
534 ImGui::ColorEdit4("Background", reinterpret_cast<float*>(&background));
535 ImGui::ColorEdit4("Foreground", reinterpret_cast<float*>(&foreground));
536 ImGui::ListBox("Blend mode", &current_blend_index,
537 modes.blend_mode_names.data(),
538 modes.blend_mode_names.size());
539 ImGui::End();
540 }
541
542 Canvas canvas;
543 canvas.Scale(Vector2(0.2, 0.2));
544 canvas.DrawPaint({.color = background});
545 canvas.DrawPaint(
546 {.color = foreground,
547 .blend_mode = static_cast<BlendMode>(current_blend_index)});
548 return canvas.EndRecordingAsPicture();
549 };
550 ASSERT_TRUE(OpenPlaygroundHere(callback));
551}
static BlendModeSelection GetBlendModeSelection()

◆ TEST_P() [14/450]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintWithAdvancedBlend   
)

Definition at line 68 of file aiks_blend_unittests.cc.

68 {
69 Canvas canvas;
70 canvas.Scale(Vector2(0.2, 0.2));
71 canvas.DrawPaint({.color = Color::MediumTurquoise()});
72 canvas.DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5),
73 .blend_mode = BlendMode::kHue});
74 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
75}

◆ TEST_P() [15/450]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPerspectiveTransformWithClips   
)

Definition at line 2667 of file aiks_unittests.cc.

2667 {
2668 // Avoiding `GetSecondsElapsed()` to reduce risk of golden flakiness.
2669 int time = 0;
2670 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
2671 Canvas canvas;
2672
2673 canvas.Save();
2674 {
2675 canvas.Translate({300, 300});
2676
2677 // 1. Draw/restore a clip before drawing the image, which will get drawn
2678 // to the depth buffer behind the image.
2679 canvas.Save();
2680 {
2681 canvas.DrawPaint({.color = Color::Green()});
2682 canvas.ClipRect(Rect::MakeLTRB(-180, -180, 180, 180),
2683 Entity::ClipOperation::kDifference);
2684 canvas.DrawPaint({.color = Color::Black()});
2685 }
2686 canvas.Restore(); // Restore rectangle difference clip.
2687
2688 canvas.Save();
2689 {
2690 // 2. Draw an oval clip that applies to the image, which will get drawn
2691 // in front of the image on the depth buffer.
2692 canvas.ClipOval(Rect::MakeLTRB(-200, -200, 200, 200));
2693
2694 // 3. Draw the rotating image with a perspective transform.
2695 canvas.Transform(
2696 Matrix(1.0, 0.0, 0.0, 0.0, //
2697 0.0, 1.0, 0.0, 0.0, //
2698 0.0, 0.0, 1.0, 0.003, //
2699 0.0, 0.0, 0.0, 1.0) * //
2700 Matrix::MakeRotationY({Radians{-1.0f + (time++ / 60.0f)}}));
2701 auto image =
2702 std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2703 canvas.DrawImage(image, -Point(image->GetSize()) / 2, {});
2704 }
2705 canvas.Restore(); // Restore oval intersect clip.
2706
2707 // 4. Draw a semi-translucent blue circle atop all previous draws.
2708 canvas.DrawCircle({}, 230, {.color = Color::Blue().WithAlpha(0.4)});
2709 }
2710 canvas.Restore(); // Restore translation.
2711
2712 return canvas.EndRecordingAsPicture();
2713 };
2714 ASSERT_TRUE(OpenPlaygroundHere(callback));
2715}
static double time(int loops, Benchmark *bench, Target *target)
Definition: nanobench.cpp:394

◆ TEST_P() [16/450]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPoints   
)

Definition at line 2205 of file aiks_unittests.cc.

2205 {
2206 std::vector<Point> points = {
2207 {0, 0}, //
2208 {100, 100}, //
2209 {100, 0}, //
2210 {0, 100}, //
2211 {0, 0}, //
2212 {48, 48}, //
2213 {52, 52}, //
2214 };
2215 std::vector<PointStyle> caps = {
2216 PointStyle::kRound,
2217 PointStyle::kSquare,
2218 };
2219 Paint paint;
2220 paint.color = Color::Yellow().WithAlpha(0.5);
2221
2222 Paint background;
2223 background.color = Color::Black();
2224
2225 Canvas canvas;
2226 canvas.DrawPaint(background);
2227 canvas.Translate({200, 200});
2228 canvas.DrawPoints(points, 10, paint, PointStyle::kRound);
2229 canvas.Translate({150, 0});
2230 canvas.DrawPoints(points, 10, paint, PointStyle::kSquare);
2231
2232 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2233}

◆ TEST_P() [17/450]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPointsWithTextureMap   
)

Definition at line 2235 of file aiks_unittests.cc.

2235 {
2236 auto texture = CreateTextureForFixture("table_mountain_nx.png",
2237 /*enable_mipmapping=*/true);
2238
2239 std::vector<Point> points = {
2240 {0, 0}, //
2241 {100, 100}, //
2242 {100, 0}, //
2243 {0, 100}, //
2244 {0, 0}, //
2245 {48, 48}, //
2246 {52, 52}, //
2247 };
2248 std::vector<PointStyle> caps = {
2249 PointStyle::kRound,
2250 PointStyle::kSquare,
2251 };
2252 Paint paint;
2253 paint.color_source = ColorSource::MakeImage(texture, Entity::TileMode::kClamp,
2254 Entity::TileMode::kClamp, {}, {});
2255
2256 Canvas canvas;
2257 canvas.Translate({200, 200});
2258 canvas.DrawPoints(points, 100, paint, PointStyle::kRound);
2259 canvas.Translate({150, 0});
2260 canvas.DrawPoints(points, 100, paint, PointStyle::kSquare);
2261
2262 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2263}

◆ TEST_P() [18/450]

impeller::testing::TEST_P ( AiksTest  ,
CanEmptyPictureConvertToImage   
)

Definition at line 385 of file aiks_unittests.cc.

385 {
386 Canvas recorder_canvas;
387
388 Canvas canvas;
389 AiksContext renderer(GetContext(), nullptr);
390 Paint paint;
391 paint.color = Color::BlackTransparent();
392 canvas.DrawPaint(paint);
393 Picture picture = recorder_canvas.EndRecordingAsPicture();
394 auto image = picture.ToImage(renderer, ISize{1000, 1000});
395 if (image) {
396 canvas.DrawImage(image, Point(), Paint());
397 paint.color = Color{0.1, 0.1, 0.1, 0.2};
398 canvas.DrawRect(Rect::MakeSize(ISize{1000, 1000}), paint);
399 }
400
401 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
402}

◆ TEST_P() [19/450]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformFullScreenMSAA   
)

Definition at line 445 of file aiks_unittests.cc.

445 {
446 Canvas canvas;
447
448 Paint red;
449 red.color = Color::Red();
450
451 canvas.DrawCircle({250, 250}, 125, red);
452
453 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
454}

◆ TEST_P() [20/450]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSaveLayerWithBounds   
)

Definition at line 468 of file aiks_unittests.cc.

468 {
469 Canvas canvas;
470
471 Paint red;
472 red.color = Color::Red();
473
474 Paint green;
475 green.color = Color::Green();
476
477 Paint blue;
478 blue.color = Color::Blue();
479
480 Paint save;
481 save.color = Color::Black();
482
483 canvas.SaveLayer(save, Rect::MakeXYWH(0, 0, 50, 50));
484
485 canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
486 canvas.DrawRect(Rect::MakeXYWH(10, 10, 100, 100), green);
487 canvas.DrawRect(Rect::MakeXYWH(20, 20, 100, 100), blue);
488
489 canvas.Restore();
490
491 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
492}

◆ TEST_P() [21/450]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated   
)

Definition at line 494 of file aiks_unittests.cc.

495 {
496 Canvas canvas;
497
498 Paint red;
499 red.color = Color::Red();
500
501 Paint green;
502 green.color = Color::Green();
503
504 Paint blue;
505 blue.color = Color::Blue();
506
507 Paint save;
508 save.color = Color::Black().WithAlpha(0.5);
509
510 canvas.SaveLayer(save, Rect::MakeXYWH(0, 0, 100000, 100000));
511
512 canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
513 canvas.DrawRect(Rect::MakeXYWH(10, 10, 100, 100), green);
514 canvas.DrawRect(Rect::MakeXYWH(20, 20, 100, 100), blue);
515
516 canvas.Restore();
517
518 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
519}

◆ TEST_P() [22/450]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSkew   
)

Definition at line 456 of file aiks_unittests.cc.

456 {
457 Canvas canvas;
458
459 Paint red;
460 red.color = Color::Red();
461
462 canvas.Skew(2, 5);
463 canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
464
465 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
466}

◆ TEST_P() [23/450]

impeller::testing::TEST_P ( AiksTest  ,
CanPictureConvertToImage   
)

Definition at line 359 of file aiks_unittests.cc.

359 {
360 Canvas recorder_canvas;
361 Paint paint;
362 paint.color = Color{0.9568, 0.2627, 0.2118, 1.0};
363 recorder_canvas.DrawRect(Rect::MakeXYWH(100.0, 100.0, 600, 600), paint);
364 paint.color = Color{0.1294, 0.5882, 0.9529, 1.0};
365 recorder_canvas.DrawRect(Rect::MakeXYWH(200.0, 200.0, 600, 600), paint);
366
367 Canvas canvas;
368 AiksContext renderer(GetContext(), nullptr);
369 paint.color = Color::BlackTransparent();
370 canvas.DrawPaint(paint);
371 Picture picture = recorder_canvas.EndRecordingAsPicture();
372 auto image = picture.ToImage(renderer, ISize{1000, 1000});
373 if (image) {
374 canvas.DrawImage(image, Point(), Paint());
375 paint.color = Color{0.1, 0.1, 0.1, 0.2};
376 canvas.DrawRect(Rect::MakeSize(ISize{1000, 1000}), paint);
377 }
378
379 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
380}

◆ TEST_P() [24/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderAdvancedBlendColorFilterWithSaveLayer   
)

Definition at line 21 of file aiks_blend_unittests.cc.

21 {
22 Canvas canvas;
23
24 Rect layer_rect = Rect::MakeXYWH(0, 0, 500, 500);
25 canvas.ClipRect(layer_rect);
26
27 canvas.SaveLayer(
28 {
29 .color_filter = ColorFilter::MakeBlend(BlendMode::kDifference,
30 Color(0, 1, 0, 0.5)),
31 },
32 layer_rect);
33
35 canvas.DrawPaint({.color = Color::Black()});
36 canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300),
37 {.color = Color::White()});
38 canvas.Restore();
39
40 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
41}

◆ TEST_P() [25/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlur   
)

Definition at line 102 of file aiks_blur_unittests.cc.

102 {
103 Canvas canvas;
104 canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
105 canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()});
106 canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()});
107 canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()});
108 canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), {20, 20});
109 canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
110 ImageFilter::MakeBlur(Sigma(30.0), Sigma(30.0),
112 Entity::TileMode::kClamp));
113 canvas.Restore();
114
115 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
116}

◆ TEST_P() [26/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlurHugeSigma   
)

Definition at line 118 of file aiks_blur_unittests.cc.

118 {
119 Canvas canvas;
120 canvas.DrawCircle({400, 400}, 300, {.color = Color::Green()});
121 canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
122 ImageFilter::MakeBlur(Sigma(999999), Sigma(999999),
124 Entity::TileMode::kClamp));
125 canvas.Restore();
126
127 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
128}

◆ TEST_P() [27/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlurInteractive   
)

Definition at line 78 of file aiks_blur_unittests.cc.

78 {
79 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
80 static PlaygroundPoint point_a(Point(50, 50), 30, Color::White());
81 static PlaygroundPoint point_b(Point(300, 200), 30, Color::White());
82 auto [a, b] = DrawPlaygroundLine(point_a, point_b);
83
84 Canvas canvas;
85 canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
86 canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()});
87 canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()});
88 canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()});
89 canvas.ClipRRect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), {20, 20});
90 canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
91 ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
93 Entity::TileMode::kClamp));
94 canvas.Restore();
95
96 return canvas.EndRecordingAsPicture();
97 };
98
99 ASSERT_TRUE(OpenPlaygroundHere(callback));
100}
std::tuple< Point, Point > DrawPlaygroundLine(PlaygroundPoint &point_a, PlaygroundPoint &point_b)
Definition: widgets.cc:50

◆ TEST_P() [28/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedBackdropFilter   
)

Definition at line 2717 of file aiks_unittests.cc.

2717 {
2718 Canvas canvas;
2719 Paint paint;
2720
2721 canvas.Scale(GetContentScale());
2722
2723 // Draw something interesting in the background.
2724 std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
2725 Color{0.1294, 0.5882, 0.9529, 1.0}};
2726 std::vector<Scalar> stops = {
2727 0.0,
2728 1.0,
2729 };
2730 paint.color_source = ColorSource::MakeLinearGradient(
2731 {0, 0}, {100, 100}, std::move(colors), std::move(stops),
2732 Entity::TileMode::kRepeat, {});
2733 canvas.DrawPaint(paint);
2734
2735 Rect clip_rect = Rect::MakeLTRB(50, 50, 400, 300);
2736
2737 // Draw a clipped SaveLayer, where the clip coverage and SaveLayer size are
2738 // the same.
2739 canvas.ClipRRect(clip_rect, Size(100, 100),
2740 Entity::ClipOperation::kIntersect);
2741 canvas.SaveLayer({}, clip_rect,
2742 ImageFilter::MakeFromColorFilter(*ColorFilter::MakeBlend(
2743 BlendMode::kExclusion, Color::Red())));
2744 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2745}

◆ TEST_P() [29/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedBlur   
)

Definition at line 130 of file aiks_blur_unittests.cc.

130 {
131 Canvas canvas;
132 canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
133 canvas.DrawCircle(
134 {400, 400}, 200,
135 {
136 .color = Color::Green(),
137 .image_filter = ImageFilter::MakeBlur(
139 Entity::TileMode::kDecal),
140 });
141 canvas.Restore();
142
143 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
144}

◆ TEST_P() [30/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedLayers   
)

Definition at line 1431 of file aiks_unittests.cc.

1431 {
1432 Canvas canvas;
1433
1434 canvas.DrawPaint({.color = Color::White()});
1435
1436 // Draw a green circle on the screen.
1437 {
1438 // Increase the clip depth for the savelayer to contend with.
1439 canvas.ClipPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath());
1440
1441 canvas.SaveLayer({}, Rect::MakeXYWH(50, 50, 100, 100));
1442
1443 // Fill the layer with white.
1444 canvas.DrawRect(Rect::MakeSize(Size{400, 400}), {.color = Color::White()});
1445 // Fill the layer with green, but do so with a color blend that can't be
1446 // collapsed into the parent pass.
1447 // TODO(jonahwilliams): this blend mode was changed from color burn to
1448 // hardlight to work around https://github.com/flutter/flutter/issues/136554
1449 // .
1450 canvas.DrawRect(
1451 Rect::MakeSize(Size{400, 400}),
1452 {.color = Color::Green(), .blend_mode = BlendMode::kHardLight});
1453 }
1454
1455 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1456}

◆ TEST_P() [31/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedRuntimeEffects   
)

Definition at line 2143 of file aiks_unittests.cc.

2143 {
2144 auto runtime_stages =
2145 OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2146
2147 auto runtime_stage =
2148 runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2149 ASSERT_TRUE(runtime_stage);
2150 ASSERT_TRUE(runtime_stage->IsDirty());
2151
2152 struct FragUniforms {
2153 Vector2 iResolution;
2154 Scalar iTime;
2155 } frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
2156 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2157 uniform_data->resize(sizeof(FragUniforms));
2158 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2159
2160 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2161
2162 Paint paint;
2163 paint.color_source = ColorSource::MakeRuntimeEffect(
2164 runtime_stage, uniform_data, texture_inputs);
2165
2166 Canvas canvas;
2167 canvas.Save();
2168 canvas.ClipRRect(Rect::MakeXYWH(0, 0, 400, 400), {10.0, 10.0},
2169 Entity::ClipOperation::kIntersect);
2170 canvas.DrawRect(Rect::MakeXYWH(0, 0, 400, 400), paint);
2171 canvas.Restore();
2172
2173 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2174}
constexpr RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend(PlaygroundBackend backend)
Definition: playground.h:33

◆ TEST_P() [32/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClips   
)

Definition at line 397 of file aiks_path_unittests.cc.

397 {
398 Canvas canvas;
399 Paint paint;
400 paint.color = Color::Fuchsia();
401 canvas.ClipPath(
402 PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 500, 500)).TakePath());
403 canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
404 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
405}

◆ TEST_P() [33/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderColoredRect   
)

Definition at line 73 of file aiks_unittests.cc.

73 {
74 Canvas canvas;
76 paint.color = Color::Blue();
77 canvas.DrawPath(PathBuilder{}
78 .AddRect(Rect::MakeXYWH(100.0, 100.0, 100.0, 100.0))
79 .TakePath(),
80 paint);
81 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
82}

◆ TEST_P() [34/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderColorFilterWithInvertColors   
)

Definition at line 106 of file aiks_unittests.cc.

106 {
107 Canvas canvas;
108 Paint paint;
109 paint.color = Color::Red();
110 paint.color_filter =
111 ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Yellow());
112 paint.invert_colors = true;
113
114 canvas.DrawRect(Rect::MakeLTRB(0, 0, 100, 100), paint);
115 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
116}

◆ TEST_P() [35/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderColorFilterWithInvertColorsDrawPaint   
)

Definition at line 118 of file aiks_unittests.cc.

118 {
119 Canvas canvas;
120 Paint paint;
121 paint.color = Color::Red();
122 paint.color_filter =
123 ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Yellow());
124 paint.invert_colors = true;
125
126 canvas.DrawPaint(paint);
127 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
128}

◆ TEST_P() [36/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderConicalGradient   
)

Definition at line 550 of file aiks_dl_gradient_unittests.cc.

550 {
551 Scalar size = 256;
554 paint.setColor(DlColor::kWhite());
555 builder.DrawRect(SkRect::MakeXYWH(0, 0, size * 3, size * 3), paint);
556 std::vector<DlColor> colors = {
557 DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
558 DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
559 DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
560 DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
561 std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
562 std::array<std::tuple<SkPoint, float, SkPoint, float>, 8> array{
563 std::make_tuple(SkPoint::Make(size / 2.f, size / 2.f), 0.f,
564 SkPoint::Make(size / 2.f, size / 2.f), size / 2.f),
565 std::make_tuple(SkPoint::Make(size / 2.f, size / 2.f), size / 4.f,
566 SkPoint::Make(size / 2.f, size / 2.f), size / 2.f),
567 std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), 0.f,
568 SkPoint::Make(size / 2.f, size / 2.f), size / 2.f),
569 std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), size / 2.f,
570 SkPoint::Make(size / 2.f, size / 2.f), 0),
571 std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), size / 4.f,
572 SkPoint::Make(size / 2.f, size / 2.f), size / 2.f),
573 std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), size / 16.f,
574 SkPoint::Make(size / 2.f, size / 2.f), size / 8.f),
575 std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), size / 8.f,
576 SkPoint::Make(size / 2.f, size / 2.f), size / 16.f),
577 std::make_tuple(SkPoint::Make(size / 8.f, size / 8.f), size / 8.f,
578 SkPoint::Make(size / 2.f, size / 2.f), size / 8.f),
579 };
580 for (int i = 0; i < 8; i++) {
581 builder.Save();
582 builder.Translate((i % 3) * size, i / 3 * size);
583 paint.setColorSource(DlColorSource::MakeConical(
584 std::get<2>(array[i]), std::get<3>(array[i]), std::get<0>(array[i]),
585 std::get<1>(array[i]), stops.size(), colors.data(), stops.data(),
586 DlTileMode::kClamp));
587 builder.DrawRect(SkRect::MakeXYWH(0, 0, size, size), paint);
588 builder.Restore();
589 }
590 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
591}
constexpr SkColor4f kWhite
Definition: SkColor.h:439
const myers::Point & get< 1 >(const myers::Segment &s)
Definition: Myers.h:81
const myers::Point & get< 0 >(const myers::Segment &s)
Definition: Myers.h:80

◆ TEST_P() [37/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderConicalGradientWithDitheringEnabled   
)

Definition at line 186 of file aiks_dl_gradient_unittests.cc.

186 {
188}
static void CanRenderConicalGradientWithDithering(AiksTest *aiks_test)

◆ TEST_P() [38/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderCurvedStrokes   
)

Definition at line 31 of file aiks_path_unittests.cc.

31 {
32 Canvas canvas;
34 paint.color = Color::Red();
35 paint.stroke_width = 25.0;
36 paint.style = Paint::Style::kStroke;
37 canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
38 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
39}

◆ TEST_P() [39/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDestructiveSaveLayer   
)

Definition at line 2128 of file aiks_unittests.cc.

2128 {
2129 Canvas canvas;
2130
2131 canvas.DrawPaint({.color = Color::Red()});
2132 // Draw an empty savelayer with a destructive blend mode, which will replace
2133 // the entire red screen with fully transparent black, except for the green
2134 // circle drawn within the layer.
2135 canvas.SaveLayer({.blend_mode = BlendMode::kSource});
2136 canvas.DrawCircle({300, 300}, 100, {.color = Color::Green()});
2137 canvas.Restore();
2138
2139 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2140}

◆ TEST_P() [40/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDifferenceClips   
)

Definition at line 42 of file aiks_dl_clip_unittests.cc.

42 {
44 builder.Translate(400, 400);
45
46 // Limit drawing to face circle with a clip.
47 builder.ClipPath(CreateCircle(0, 0, 200));
48 builder.Save();
49
50 // Cut away eyes/mouth using difference clips.
51 builder.ClipPath(CreateCircle(-100, -50, 30), DlCanvas::ClipOp::kDifference);
52 builder.ClipPath(CreateCircle(100, -50, 30), DlCanvas::ClipOp::kDifference);
53
55 path.moveTo(-100, 50);
56 path.quadTo(0, 150, 100, 50);
57 builder.ClipPath(path, DlCanvas::ClipOp::kDifference);
58
59 // Draw a huge yellow rectangle to prove the clipping works.
61 paint.setColor(DlColor::kYellow());
62 builder.DrawRect(SkRect::MakeXYWH(-1000, -1000, 2000, 2000), paint);
63
64 // Remove the difference clips and draw hair that partially covers the eyes.
65 builder.Restore();
66 paint.setColor(DlColor::kMaroon());
67 SkPath path_2;
68 path_2.moveTo(200, -200);
69 path_2.lineTo(-200, -200);
70 path_2.lineTo(-200, -40);
71 path_2.cubicTo({0, -40}, {0, -80}, {200, -80});
72
73 builder.DrawPath(path_2, paint);
74
75 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
76}
SkPath & moveTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:688
SkPath & lineTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:728
SkPath & cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3)
Definition: SkPath.cpp:799
constexpr SkColor4f kYellow
Definition: SkColor.h:443

◆ TEST_P() [41/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDifferencePaths   
)

Definition at line 113 of file aiks_path_unittests.cc.

113 {
114 Canvas canvas;
115
116 Paint paint;
117 paint.color = Color::Red();
118
120
122 radii.top_left = {50, 25};
123 radii.top_right = {25, 50};
124 radii.bottom_right = {50, 25};
125 radii.bottom_left = {25, 50};
126
127 builder.AddRoundedRect(Rect::MakeXYWH(100, 100, 200, 200), radii);
128 builder.AddCircle({200, 200}, 50);
129 auto path = builder.TakePath(FillType::kOdd);
130
131 canvas.DrawImage(
132 std::make_shared<Image>(CreateTextureForFixture("boston.jpg")), {10, 10},
133 Paint{});
134 canvas.DrawPath(path, paint);
135
136 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
137}

◆ TEST_P() [42/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDifferentShapesWithSameColorSource   
)

Definition at line 332 of file aiks_unittests.cc.

332 {
333 Canvas canvas;
334 Paint paint;
335
336 std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
337 Color{0.1294, 0.5882, 0.9529, 1.0}};
338 std::vector<Scalar> stops = {
339 0.0,
340 1.0,
341 };
342
343 paint.color_source = ColorSource::MakeLinearGradient(
344 {0, 0}, {100, 100}, std::move(colors), std::move(stops),
345 Entity::TileMode::kRepeat, {});
346
347 canvas.Save();
348 canvas.Translate({100, 100, 0});
349 canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), paint);
350 canvas.Restore();
351
352 canvas.Save();
353 canvas.Translate({100, 400, 0});
354 canvas.DrawCircle({100, 100}, 100, paint);
355 canvas.Restore();
356 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
357}

◆ TEST_P() [43/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrame   
)

Definition at line 735 of file aiks_unittests.cc.

735 {
736 Canvas canvas;
737 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
738
739 ASSERT_TRUE(RenderTextInCanvasSkia(
740 GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture));
741 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
742}
static constexpr std::string_view kFontFixture
bool RenderTextInCanvasSkia(const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string_view &font_fixture, TextRenderOptions options={})

◆ TEST_P() [44/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrameWithAlpha   
)

Definition at line 757 of file aiks_unittests.cc.

757 {
758 Canvas canvas;
759 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
760
761 ASSERT_TRUE(RenderTextInCanvasSkia(
762 GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
763 {.color = Color::Black().WithAlpha(0.5)}));
764 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
765}

◆ TEST_P() [45/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrameWithBlur   
)

Definition at line 744 of file aiks_unittests.cc.

744 {
745 Canvas canvas;
746 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
747
748 ASSERT_TRUE(RenderTextInCanvasSkia(
749 GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
750 TextRenderOptions{.color = Color::Blue(),
751 .mask_blur_descriptor = Paint::MaskBlurDescriptor{
753 .sigma = Sigma(4)}}));
754 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
755}

◆ TEST_P() [46/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderForegroundAdvancedBlendWithMaskBlur   
)

Definition at line 57 of file aiks_blur_unittests.cc.

57 {
58 // This case triggers the ForegroundAdvancedBlend path. The color filter
59 // should apply to the color only, and respect the alpha mask.
60 Canvas canvas;
61 canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
62 canvas.DrawCircle({400, 400}, 200,
63 {
64 .color = Color::Grey(),
65 .color_filter = ColorFilter::MakeBlend(
66 BlendMode::kColor, Color::Green()),
67 .mask_blur_descriptor =
70 .sigma = Radius(20),
71 },
72 });
73 canvas.Restore();
74
75 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
76}
static constexpr SkColor kColor
Definition: CanvasTest.cpp:265
For convolution filters, the "radius" is the size of the convolution kernel to use on the local space...
Definition: sigma.h:48

◆ TEST_P() [47/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderForegroundBlendWithMaskBlur   
)

Definition at line 36 of file aiks_blur_unittests.cc.

36 {
37 // This case triggers the ForegroundPorterDuffBlend path. The color filter
38 // should apply to the color only, and respect the alpha mask.
39 Canvas canvas;
40 canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
41 canvas.DrawCircle({400, 400}, 200,
42 {
43 .color = Color::White(),
44 .color_filter = ColorFilter::MakeBlend(
45 BlendMode::kSource, Color::Green()),
46 .mask_blur_descriptor =
49 .sigma = Radius(20),
50 },
51 });
52 canvas.Restore();
53
54 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
55}

◆ TEST_P() [48/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderGradientDecalWithBackground   
)

Definition at line 593 of file aiks_dl_gradient_unittests.cc.

593 {
594 std::vector<DlColor> colors = {
595 DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
596 DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
597 DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
598 DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
599 std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
600
601 std::array<std::shared_ptr<DlColorSource>, 3> color_sources = {
602 DlColorSource::MakeLinear({0, 0}, {100, 100}, stops.size(), colors.data(),
603 stops.data(), DlTileMode::kDecal),
604 DlColorSource::MakeRadial({100, 100}, 100, stops.size(), colors.data(),
605 stops.data(), DlTileMode::kDecal),
606 DlColorSource::MakeSweep({100, 100}, 45, 135, stops.size(), colors.data(),
607 stops.data(), DlTileMode::kDecal),
608 };
609
612 paint.setColor(DlColor::kWhite());
613 builder.DrawRect(SkRect::MakeLTRB(0, 0, 605, 205), paint);
614 for (int i = 0; i < 3; i++) {
615 builder.Save();
616 builder.Translate(i * 200.0f, 0);
617 paint.setColorSource(color_sources[i]);
618 builder.DrawRect(SkRect::MakeLTRB(0, 0, 200, 200), paint);
619 builder.Restore();
620 }
621 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
622}

◆ TEST_P() [49/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderGroupOpacity   
)

Definition at line 35 of file aiks_dl_opacity_unittests.cc.

35 {
37
38 DlPaint red;
40 DlPaint green;
41 green.setColor(DlColor::kGreen().modulateOpacity(0.5));
42 DlPaint blue;
44
45 DlPaint alpha;
46 alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
47
48 builder.SaveLayer(nullptr, &alpha);
49 builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), red);
50 builder.DrawRect(SkRect::MakeXYWH(200, 200, 100, 100), green);
51 builder.DrawRect(SkRect::MakeXYWH(400, 400, 100, 100), blue);
52 builder.Restore();
53
54 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
55}
static const uint64_t kGreen
static const uint64_t kBlue
static const uint64_t kRed
DlPaint & setColor(DlColor color)
Definition: dl_paint.h:70

◆ TEST_P() [50/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderGroupOpacityToSavelayer   
)

Definition at line 57 of file aiks_dl_opacity_unittests.cc.

57 {
59
60 DlPaint red;
62
63 DlPaint alpha;
64 alpha.setColor(DlColor::kRed().modulateOpacity(0.7));
65
66 // Create a saveLayer that will forward its opacity to another
67 // saveLayer, to verify that we correctly distribute opacity.
68 SkRect bounds = SkRect::MakeLTRB(0, 0, 500, 500);
69 builder.SaveLayer(&bounds, &alpha);
70 builder.SaveLayer(&bounds, &alpha);
71 builder.DrawRect(SkRect::MakeXYWH(0, 0, 400, 400), red);
72 builder.DrawRect(SkRect::MakeXYWH(0, 0, 450, 450), red);
73 builder.Restore();
74 builder.Restore();
75
76 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
77}

◆ TEST_P() [51/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderImage   
)

Definition at line 84 of file aiks_unittests.cc.

84 {
85 Canvas canvas;
87 auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
88 paint.color = Color::Red();
89 canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
90 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
91}

◆ TEST_P() [52/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderImageRect   
)

Definition at line 219 of file aiks_unittests.cc.

219 {
220 Canvas canvas;
221 Paint paint;
222 auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
223 Size image_half_size = Size(image->GetSize()) * 0.5;
224
225 // Render the bottom right quarter of the source image in a stretched rect.
226 auto source_rect = Rect::MakeSize(image_half_size);
227 source_rect = source_rect.Shift(Point(image_half_size));
228
229 canvas.DrawImageRect(image, source_rect, Rect::MakeXYWH(100, 100, 600, 600),
230 paint);
231 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
232}

◆ TEST_P() [53/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderInvertedImageWithColorFilter   
)

Definition at line 93 of file aiks_unittests.cc.

93 {
94 Canvas canvas;
96 auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
97 paint.color = Color::Red();
98 paint.color_filter =
99 ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Yellow());
100 paint.invert_colors = true;
101
102 canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
103 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
104}

◆ TEST_P() [54/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderItalicizedText   
)

Definition at line 718 of file aiks_unittests.cc.

718 {
719 Canvas canvas;
720 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
721
722 ASSERT_TRUE(RenderTextInCanvasSkia(
723 GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
724 "HomemadeApple.ttf"));
725 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
726}

◆ TEST_P() [55/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientClamp   
)

Definition at line 67 of file aiks_dl_gradient_unittests.cc.

67 {
68 CanRenderLinearGradient(this, DlTileMode::kClamp);
69}

◆ TEST_P() [56/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientDecal   
)

Definition at line 76 of file aiks_dl_gradient_unittests.cc.

76 {
77 CanRenderLinearGradient(this, DlTileMode::kDecal);
78}

◆ TEST_P() [57/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientDecalWithColorFilter   
)

Definition at line 80 of file aiks_dl_gradient_unittests.cc.

80 {
82 Point scale = GetContentScale();
83 builder.Scale(scale.x, scale.y);
85 builder.Translate(100.0f, 0);
86
87 std::vector<DlColor> colors = {
88 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
89 DlColor(Color{0.1294, 0.5882, 0.9529, 0.0}.ToARGB())};
90 std::vector<Scalar> stops = {0.0, 1.0};
91
92 paint.setColorSource(DlColorSource::MakeLinear(
93 {0, 0}, {200, 200}, 2, colors.data(), stops.data(), DlTileMode::kDecal));
94 // Overlay the gradient with 25% green. This should appear as the entire
95 // rectangle being drawn with 25% green, including the border area outside the
96 // decal gradient.
97 paint.setColorFilter(DlBlendColorFilter::Make(DlColor::kGreen().withAlpha(64),
98 DlBlendMode::kSrcOver));
99 paint.setColor(DlColor::kWhite());
100 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
101 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
102}

◆ TEST_P() [58/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsClamp   
)

Definition at line 256 of file aiks_dl_gradient_unittests.cc.

256 {
257 CanRenderLinearGradientManyColors(this, DlTileMode::kClamp);
258}

◆ TEST_P() [59/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsDecal   
)

Definition at line 265 of file aiks_dl_gradient_unittests.cc.

265 {
266 CanRenderLinearGradientManyColors(this, DlTileMode::kDecal);
267}

◆ TEST_P() [60/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsMirror   
)

Definition at line 262 of file aiks_dl_gradient_unittests.cc.

262 {
263 CanRenderLinearGradientManyColors(this, DlTileMode::kMirror);
264}

◆ TEST_P() [61/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsRepeat   
)

Definition at line 259 of file aiks_dl_gradient_unittests.cc.

259 {
260 CanRenderLinearGradientManyColors(this, DlTileMode::kRepeat);
261}

◆ TEST_P() [62/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsUnevenStops   
)

Definition at line 300 of file aiks_dl_gradient_unittests.cc.

300 {
301 auto callback = [&]() -> sk_sp<DisplayList> {
302 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
303 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
304 DlTileMode::kMirror, DlTileMode::kDecal};
305
306 static int selected_tile_mode = 0;
307 static Matrix matrix;
308 if (AiksTest::ImGuiBegin("Controls", nullptr,
309 ImGuiWindowFlags_AlwaysAutoResize)) {
310 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
311 sizeof(tile_mode_names) / sizeof(char*));
312 std::string label = "##1";
313 for (int i = 0; i < 4; i++) {
314 ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
315 &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
316 label[2]++;
317 }
318 ImGui::End();
319 }
320
323 builder.Translate(100.0, 100.0);
324 auto tile_mode = tile_modes[selected_tile_mode];
325
326 std::vector<DlColor> colors = {
327 DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
328 DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
329 DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
330 DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
331 DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
332 DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
333 DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
334 std::vector<Scalar> stops = {
335 0.0, 2.0 / 62.0, 4.0 / 62.0, 8.0 / 62.0, 16.0 / 62.0, 32.0 / 62.0, 1.0,
336 };
337
338 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {200, 200},
339 stops.size(), colors.data(),
340 stops.data(), tile_mode));
341
342 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
343 return builder.Build();
344 };
345 ASSERT_TRUE(OpenPlaygroundHere(callback));
346}

◆ TEST_P() [63/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientMaskBlur   
)

Definition at line 348 of file aiks_dl_gradient_unittests.cc.

348 {
350
351 std::vector<DlColor> colors = {
355 std::vector<Scalar> stops = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5,
356 0.6, 0.7, 0.8, 0.9, 1.0};
357
359 paint.setColor(DlColor::kWhite());
360 paint.setColorSource(DlColorSource::MakeLinear(
361 {200, 200}, {400, 400}, stops.size(), colors.data(), stops.data(),
362 DlTileMode::kClamp));
364
365 builder.DrawCircle({300, 300}, 200, paint);
366 builder.DrawRect(SkRect::MakeLTRB(100, 300, 500, 600), paint);
367
368 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
369}

◆ TEST_P() [64/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientMirror   
)

Definition at line 73 of file aiks_dl_gradient_unittests.cc.

73 {
74 CanRenderLinearGradient(this, DlTileMode::kMirror);
75}

◆ TEST_P() [65/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientRepeat   
)

Definition at line 70 of file aiks_dl_gradient_unittests.cc.

70 {
71 CanRenderLinearGradient(this, DlTileMode::kRepeat);
72}

◆ TEST_P() [66/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWayManyColorsClamp   
)

Definition at line 296 of file aiks_dl_gradient_unittests.cc.

296 {
297 CanRenderLinearGradientWayManyColors(this, DlTileMode::kClamp);
298}

◆ TEST_P() [67/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWithDitheringEnabled   
)

Definition at line 120 of file aiks_dl_gradient_unittests.cc.

120 {
122}
static void CanRenderLinearGradientWithDithering(AiksTest *aiks_test)

◆ TEST_P() [68/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWithOverlappingStopsClamp   
)

Definition at line 215 of file aiks_dl_gradient_unittests.cc.

215 {
216 CanRenderLinearGradientWithOverlappingStops(this, DlTileMode::kClamp);
217}

◆ TEST_P() [69/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderMaskBlurHugeSigma   
)

Definition at line 23 of file aiks_blur_unittests.cc.

23 {
24 Canvas canvas;
25 canvas.DrawCircle({400, 400}, 300,
26 {.color = Color::Green(),
27 .mask_blur_descriptor = Paint::MaskBlurDescriptor{
29 .sigma = Sigma(99999),
30 }});
31 canvas.Restore();
32
33 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
34}

◆ TEST_P() [70/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderNestedClips   
)

Definition at line 27 of file aiks_dl_clip_unittests.cc.

27 {
30 paint.setColor(DlColor::kFuchsia());
31
32 builder.Save();
33 builder.ClipPath(CreateCircle(200, 400, 300));
34 builder.Restore();
35 builder.ClipPath(CreateCircle(600, 400, 300));
36 builder.ClipPath(CreateCircle(400, 600, 300));
37 builder.DrawRect(SkRect::MakeXYWH(200, 200, 400, 400), paint);
38
39 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
40}

◆ TEST_P() [71/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderOverlappingMultiContourPath   
)

Definition at line 407 of file aiks_path_unittests.cc.

407 {
408 Canvas canvas;
409
410 Paint paint;
411 paint.color = Color::Red();
412
414 radii.top_left = {50, 50};
415 radii.top_right = {50, 50};
416 radii.bottom_right = {50, 50};
417 radii.bottom_left = {50, 50};
418
419 const Scalar kTriangleHeight = 100;
420 canvas.Translate(Vector2(200, 200));
421 // Form a path similar to the Material drop slider value indicator. Both
422 // shapes should render identically side-by-side.
423 {
424 auto path =
425 PathBuilder{}
426 .MoveTo({0, kTriangleHeight})
427 .LineTo({-kTriangleHeight / 2.0f, 0})
428 .LineTo({kTriangleHeight / 2.0f, 0})
429 .Close()
430 .AddRoundedRect(
431 Rect::MakeXYWH(-kTriangleHeight / 2.0f, -kTriangleHeight / 2.0f,
432 kTriangleHeight, kTriangleHeight),
433 radii)
434 .TakePath();
435
436 canvas.DrawPath(path, paint);
437 }
438 canvas.Translate(Vector2(100, 0));
439 {
440 auto path =
441 PathBuilder{}
442 .MoveTo({0, kTriangleHeight})
443 .LineTo({-kTriangleHeight / 2.0f, 0})
444 .LineTo({0, -10})
445 .LineTo({kTriangleHeight / 2.0f, 0})
446 .Close()
447 .AddRoundedRect(
448 Rect::MakeXYWH(-kTriangleHeight / 2.0f, -kTriangleHeight / 2.0f,
449 kTriangleHeight, kTriangleHeight),
450 radii)
451 .TakePath();
452
453 canvas.DrawPath(path, paint);
454 }
455
456 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
457}

◆ TEST_P() [72/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderQuadraticStrokeWithInstantTurn   
)

Definition at line 94 of file aiks_path_unittests.cc.

94 {
95 Canvas canvas;
96
98 paint.color = Color::Red();
99 paint.style = Paint::Style::kStroke;
100 paint.stroke_cap = Cap::kRound;
101 paint.stroke_width = 50;
102
103 // Should draw a diagonal pill shape. If flat on either end, the stroke is
104 // rendering wrong.
106 builder.MoveTo({250, 250});
107 builder.QuadraticCurveTo({100, 100}, {250, 250});
108
109 canvas.DrawPath(builder.TakePath(), paint);
110 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
111}

◆ TEST_P() [73/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradient   
)

Definition at line 371 of file aiks_dl_gradient_unittests.cc.

371 {
372 auto callback = [&]() -> sk_sp<DisplayList> {
373 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
374 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
375 DlTileMode::kMirror, DlTileMode::kDecal};
376
377 static int selected_tile_mode = 0;
378 static Matrix matrix;
379 if (AiksTest::ImGuiBegin("Controls", nullptr,
380 ImGuiWindowFlags_AlwaysAutoResize)) {
381 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
382 sizeof(tile_mode_names) / sizeof(char*));
383 std::string label = "##1";
384 for (int i = 0; i < 4; i++) {
385 ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
386 &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
387 label[2]++;
388 }
389 ImGui::End();
390 }
391
394 builder.Translate(100.0, 100.0);
395 auto tile_mode = tile_modes[selected_tile_mode];
396
397 std::vector<DlColor> colors = {
398 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
399 DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
400 std::vector<Scalar> stops = {0.0, 1.0};
401
402 paint.setColorSource(DlColorSource::MakeRadial(
403 {100, 100}, 100, 2, colors.data(), stops.data(), tile_mode));
404
405 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
406 return builder.Build();
407 };
408 ASSERT_TRUE(OpenPlaygroundHere(callback));
409}

◆ TEST_P() [74/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradientManyColors   
)

Definition at line 411 of file aiks_dl_gradient_unittests.cc.

411 {
412 auto callback = [&]() -> sk_sp<DisplayList> {
413 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
414 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
415 DlTileMode::kMirror, DlTileMode::kDecal};
416
417 static int selected_tile_mode = 0;
418 static Matrix matrix = {
419 1, 0, 0, 0, //
420 0, 1, 0, 0, //
421 0, 0, 1, 0, //
422 0, 0, 0, 1 //
423 };
424 if (AiksTest::ImGuiBegin("Controls", nullptr,
425 ImGuiWindowFlags_AlwaysAutoResize)) {
426 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
427 sizeof(tile_mode_names) / sizeof(char*));
428 std::string label = "##1";
429 for (int i = 0; i < 4; i++) {
430 ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
431 &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
432 label[2]++;
433 }
434 ImGui::End();
435 }
436
439 builder.Translate(100.0, 100.0);
440 auto tile_mode = tile_modes[selected_tile_mode];
441
442 std::vector<DlColor> colors = {
443 DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
444 DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
445 DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
446 DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
447 DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
448 DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
449 DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
450 std::vector<Scalar> stops = {
451 0.0,
452 (1.0 / 6.0) * 1,
453 (1.0 / 6.0) * 2,
454 (1.0 / 6.0) * 3,
455 (1.0 / 6.0) * 4,
456 (1.0 / 6.0) * 5,
457 1.0,
458 };
459
460 paint.setColorSource(DlColorSource::MakeRadial(
461 {100, 100}, 100, stops.size(), colors.data(), stops.data(), tile_mode));
462
463 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
464 return builder.Build();
465 };
466 ASSERT_TRUE(OpenPlaygroundHere(callback));
467}

◆ TEST_P() [75/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradientWithDitheringEnabled   
)

Definition at line 140 of file aiks_dl_gradient_unittests.cc.

140 {
142}
static void CanRenderRadialGradientWithDithering(AiksTest *aiks_test)

◆ TEST_P() [76/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRoundedRectWithNonUniformRadii   
)

Definition at line 521 of file aiks_unittests.cc.

521 {
522 Canvas canvas;
523
524 Paint paint;
525 paint.color = Color::Red();
526
528 radii.top_left = {50, 25};
529 radii.top_right = {25, 50};
530 radii.bottom_right = {50, 25};
531 radii.bottom_left = {25, 50};
532
533 auto path = PathBuilder{}
534 .AddRoundedRect(Rect::MakeXYWH(100, 100, 500, 500), radii)
535 .TakePath();
536
537 canvas.DrawPath(path, paint);
538
539 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
540}

◆ TEST_P() [77/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSimpleClips   
)

Definition at line 234 of file aiks_unittests.cc.

234 {
235 Canvas canvas;
236 canvas.Scale(GetContentScale());
237 Paint paint;
238
239 paint.color = Color::White();
240 canvas.DrawPaint(paint);
241
242 auto draw = [&canvas](const Paint& paint, Scalar x, Scalar y) {
243 canvas.Save();
244 canvas.Translate({x, y});
245 {
246 canvas.Save();
247 canvas.ClipRect(Rect::MakeLTRB(50, 50, 150, 150));
248 canvas.DrawPaint(paint);
249 canvas.Restore();
250 }
251 {
252 canvas.Save();
253 canvas.ClipOval(Rect::MakeLTRB(200, 50, 300, 150));
254 canvas.DrawPaint(paint);
255 canvas.Restore();
256 }
257 {
258 canvas.Save();
259 canvas.ClipRRect(Rect::MakeLTRB(50, 200, 150, 300), {20, 20});
260 canvas.DrawPaint(paint);
261 canvas.Restore();
262 }
263 {
264 canvas.Save();
265 canvas.ClipRRect(Rect::MakeLTRB(200, 230, 300, 270), {20, 20});
266 canvas.DrawPaint(paint);
267 canvas.Restore();
268 }
269 {
270 canvas.Save();
271 canvas.ClipRRect(Rect::MakeLTRB(230, 200, 270, 300), {20, 20});
272 canvas.DrawPaint(paint);
273 canvas.Restore();
274 }
275 canvas.Restore();
276 };
277
278 paint.color = Color::Blue();
279 draw(paint, 0, 0);
280
281 std::vector<Color> gradient_colors = {
282 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
283 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
284 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
285 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
286 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
287 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
288 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
289 std::vector<Scalar> stops = {
290 0.0,
291 (1.0 / 6.0) * 1,
292 (1.0 / 6.0) * 2,
293 (1.0 / 6.0) * 3,
294 (1.0 / 6.0) * 4,
295 (1.0 / 6.0) * 5,
296 1.0,
297 };
298 auto texture = CreateTextureForFixture("airplane.jpg",
299 /*enable_mipmapping=*/true);
300
301 paint.color_source = ColorSource::MakeRadialGradient(
302 {500, 600}, 75, std::move(gradient_colors), std::move(stops),
303 Entity::TileMode::kMirror, {});
304 draw(paint, 0, 300);
305
306 paint.color_source = ColorSource::MakeImage(
307 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
308 Matrix::MakeTranslation({0, 0}));
309 draw(paint, 300, 0);
310
311 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
312}
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition: aaclip.cpp:27

◆ TEST_P() [78/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokedTextFrame   
)

Definition at line 629 of file aiks_unittests.cc.

629 {
630 Canvas canvas;
631 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
632 ASSERT_TRUE(RenderTextInCanvasSkia(
633 GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
634 "Roboto-Regular.ttf",
635 {
636 .stroke = true,
637 }));
638 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
639}

◆ TEST_P() [79/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokePathThatEndsAtSharpTurn   
)

Definition at line 63 of file aiks_path_unittests.cc.

63 {
64 Canvas canvas;
65
67 paint.color = Color::Red();
68 paint.style = Paint::Style::kStroke;
69 paint.stroke_width = 200;
70
71 Rect rect = Rect::MakeXYWH(100, 100, 200, 200);
73 builder.AddArc(rect, Degrees(0), Degrees(90), false);
74
75 canvas.DrawPath(builder.TakePath(), paint);
76 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
77}

◆ TEST_P() [80/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokePathWithCubicLine   
)

Definition at line 79 of file aiks_path_unittests.cc.

79 {
80 Canvas canvas;
81
83 paint.color = Color::Red();
84 paint.style = Paint::Style::kStroke;
85 paint.stroke_width = 20;
86
88 builder.AddCubicCurve({0, 200}, {50, 400}, {350, 0}, {400, 200});
89
90 canvas.DrawPath(builder.TakePath(), paint);
91 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
92}

◆ TEST_P() [81/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokes   
)

Definition at line 20 of file aiks_path_unittests.cc.

20 {
21 Canvas canvas;
23 paint.color = Color::Red();
24 paint.stroke_width = 20.0;
25 paint.style = Paint::Style::kStroke;
26 canvas.DrawPath(PathBuilder{}.AddLine({200, 100}, {800, 100}).TakePath(),
27 paint);
28 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
29}

◆ TEST_P() [82/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientClamp   
)

Definition at line 490 of file aiks_dl_gradient_unittests.cc.

490 {
491 CanRenderSweepGradient(this, DlTileMode::kClamp);
492}

◆ TEST_P() [83/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientDecal   
)

Definition at line 499 of file aiks_dl_gradient_unittests.cc.

499 {
500 CanRenderSweepGradient(this, DlTileMode::kDecal);
501}

◆ TEST_P() [84/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsClamp   
)

Definition at line 537 of file aiks_dl_gradient_unittests.cc.

537 {
538 CanRenderSweepGradientManyColors(this, DlTileMode::kClamp);
539}

◆ TEST_P() [85/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsDecal   
)

Definition at line 546 of file aiks_dl_gradient_unittests.cc.

546 {
547 CanRenderSweepGradientManyColors(this, DlTileMode::kDecal);
548}

◆ TEST_P() [86/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsMirror   
)

Definition at line 543 of file aiks_dl_gradient_unittests.cc.

543 {
544 CanRenderSweepGradientManyColors(this, DlTileMode::kMirror);
545}

◆ TEST_P() [87/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsRepeat   
)

Definition at line 540 of file aiks_dl_gradient_unittests.cc.

540 {
541 CanRenderSweepGradientManyColors(this, DlTileMode::kRepeat);
542}

◆ TEST_P() [88/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientMirror   
)

Definition at line 496 of file aiks_dl_gradient_unittests.cc.

496 {
497 CanRenderSweepGradient(this, DlTileMode::kMirror);
498}

◆ TEST_P() [89/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientRepeat   
)

Definition at line 493 of file aiks_dl_gradient_unittests.cc.

493 {
494 CanRenderSweepGradient(this, DlTileMode::kRepeat);
495}

◆ TEST_P() [90/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientWithDitheringEnabled   
)

Definition at line 163 of file aiks_dl_gradient_unittests.cc.

163 {
165}
static void CanRenderSweepGradientWithDithering(AiksTest *aiks_test)

◆ TEST_P() [91/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrame   
)

Definition at line 620 of file aiks_unittests.cc.

620 {
621 Canvas canvas;
622 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
623 ASSERT_TRUE(RenderTextInCanvasSkia(
624 GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
625 "Roboto-Regular.ttf"));
626 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
627}

◆ TEST_P() [92/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameSTB   
)

Definition at line 661 of file aiks_unittests.cc.

661 {
662 Canvas canvas;
663 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
664 ASSERT_TRUE(RenderTextInCanvasSTB(
665 GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
666 "Roboto-Regular.ttf"));
667
668 SetTypographerContext(TypographerContextSTB::Make());
669 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
670}
bool RenderTextInCanvasSTB(const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string &font_fixture, TextRenderOptions options={})

◆ TEST_P() [93/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithFractionScaling   
)

Definition at line 651 of file aiks_unittests.cc.

651 {
652 Canvas canvas;
653 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
654 canvas.Scale({2.625, 2.625, 1});
655 ASSERT_TRUE(RenderTextInCanvasSkia(
656 GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
657 "Roboto-Regular.ttf"));
658 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
659}

◆ TEST_P() [94/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithHalfScaling   
)

Definition at line 641 of file aiks_unittests.cc.

641 {
642 Canvas canvas;
643 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
644 canvas.Scale({0.5, 0.5, 1});
645 ASSERT_TRUE(RenderTextInCanvasSkia(
646 GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
647 "Roboto-Regular.ttf"));
648 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
649}

◆ TEST_P() [95/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextInSaveLayer   
)

Definition at line 767 of file aiks_unittests.cc.

767 {
768 Canvas canvas;
769 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
770
771 canvas.Translate({100, 100});
772 canvas.Scale(Vector2{0.5, 0.5});
773
774 // Blend the layer with the parent pass using kClear to expose the coverage.
775 canvas.SaveLayer({.blend_mode = BlendMode::kClear});
776 ASSERT_TRUE(RenderTextInCanvasSkia(
777 GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
778 "Roboto-Regular.ttf"));
779 canvas.Restore();
780
781 // Render the text again over the cleared coverage rect.
782 ASSERT_TRUE(RenderTextInCanvasSkia(
783 GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
784 "Roboto-Regular.ttf"));
785
786 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
787}

◆ TEST_P() [96/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextOutsideBoundaries   
)

Definition at line 789 of file aiks_unittests.cc.

789 {
790 Canvas canvas;
791 canvas.Translate({200, 150});
792
793 // Construct the text blob.
794 auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf");
795 ASSERT_NE(mapping, nullptr);
796
797 Scalar font_size = 80;
799 SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
800
801 Paint text_paint;
802 text_paint.color = Color::Blue().WithAlpha(0.8);
803
804 struct {
805 Point position;
806 const char* text;
807 } text[] = {{Point(0, 0), "0F0F0F0"},
808 {Point(1, 2), "789"},
809 {Point(1, 3), "456"},
810 {Point(1, 4), "123"},
811 {Point(0, 6), "0F0F0F0"}};
812 for (auto& t : text) {
813 canvas.Save();
814 canvas.Translate(t.position * Point(font_size * 2, font_size * 1.1));
815 {
816 auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
817 ASSERT_NE(blob, nullptr);
819 canvas.DrawTextFrame(frame, Point(), text_paint);
820 }
821 canvas.Restore();
822 }
823
824 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
825}
SkScalar font_size

◆ TEST_P() [97/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextWithLargePerspectiveTransform   
)

Definition at line 2822 of file aiks_unittests.cc.

2822 {
2823 // Verifies that text scales are clamped to work around
2824 // https://github.com/flutter/flutter/issues/136112 .
2825
2826 Canvas canvas;
2827 Paint save_paint;
2828 canvas.SaveLayer(save_paint);
2829 canvas.Transform(Matrix(2000, 0, 0, 0, //
2830 0, 2000, 0, 0, //
2831 0, 0, -1, 9000, //
2832 0, 0, -1, 7000 //
2833 ));
2834
2835 ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
2836 "Roboto-Regular.ttf"));
2837 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2838}

◆ TEST_P() [98/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderThickCurvedStrokes   
)

Definition at line 41 of file aiks_path_unittests.cc.

41 {
42 Canvas canvas;
44 paint.color = Color::Red();
45 paint.stroke_width = 100.0;
46 paint.style = Paint::Style::kStroke;
47 canvas.DrawPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath(), paint);
48 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
49}

◆ TEST_P() [99/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderThinCurvedStrokes   
)

Definition at line 51 of file aiks_path_unittests.cc.

51 {
52 Canvas canvas;
54 paint.color = Color::Red();
55 // Impeller doesn't support hairlines yet, but size this guarantees
56 // the smallest possible stroke width.
57 paint.stroke_width = 0.01;
58 paint.style = Paint::Style::kStroke;
59 canvas.DrawPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath(), paint);
60 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
61}

◆ TEST_P() [100/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureClamp   
)

Definition at line 198 of file aiks_unittests.cc.

198 {
199 CanRenderTiledTexture(this, Entity::TileMode::kClamp);
200}

◆ TEST_P() [101/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureClampWithTranslate   
)

Definition at line 214 of file aiks_unittests.cc.

214 {
215 CanRenderTiledTexture(this, Entity::TileMode::kClamp,
216 Matrix::MakeTranslation({172.f, 172.f, 0.f}));
217}

◆ TEST_P() [102/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureDecal   
)

Definition at line 210 of file aiks_unittests.cc.

210 {
211 CanRenderTiledTexture(this, Entity::TileMode::kDecal);
212}

◆ TEST_P() [103/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureMirror   
)

Definition at line 206 of file aiks_unittests.cc.

206 {
207 CanRenderTiledTexture(this, Entity::TileMode::kMirror);
208}

◆ TEST_P() [104/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureRepeat   
)

Definition at line 202 of file aiks_unittests.cc.

202 {
203 CanRenderTiledTexture(this, Entity::TileMode::kRepeat);
204}

◆ TEST_P() [105/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTinyOverlappingSubpasses   
)

This is a regression check for https://github.com/flutter/engine/pull/41129 The entire screen is green if successful. If failing, no frames will render, or the entire screen will be transparent black.

Definition at line 2082 of file aiks_unittests.cc.

2082 {
2083 Canvas canvas;
2084 canvas.DrawPaint({.color = Color::Red()});
2085
2086 // Draw two overlapping subpixel circles.
2087 canvas.SaveLayer({});
2088 canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2089 canvas.Restore();
2090 canvas.SaveLayer({});
2091 canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2092 canvas.Restore();
2093
2094 canvas.DrawPaint({.color = Color::Green()});
2095
2096 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2097}

◆ TEST_P() [106/450]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderWithContiguousClipRestores   
)

Definition at line 78 of file aiks_dl_clip_unittests.cc.

78 {
80
81 // Cover the whole canvas with red.
83 paint.setColor(DlColor::kRed());
84 builder.DrawPaint(paint);
85
86 builder.Save();
87
88 // Append two clips, the second resulting in empty coverage.
89 builder.ClipRect(SkRect::MakeXYWH(100, 100, 100, 100));
90 builder.ClipRect(SkRect::MakeXYWH(300, 300, 100, 100));
91
92 // Restore to no clips.
93 builder.Restore();
94
95 // Replace the whole canvas with green.
96 paint.setColor(DlColor::kGreen());
97 builder.DrawPaint(paint);
98
99 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
100}

◆ TEST_P() [107/450]

impeller::testing::TEST_P ( AiksTest  ,
CanSaveLayerStandalone   
)

Definition at line 314 of file aiks_unittests.cc.

314 {
315 Canvas canvas;
316
317 Paint red;
318 red.color = Color::Red();
319
320 Paint alpha;
321 alpha.color = Color::Red().WithAlpha(0.5);
322
323 canvas.SaveLayer(alpha);
324
325 canvas.DrawCircle({125, 125}, 125, red);
326
327 canvas.Restore();
328
329 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
330}

◆ TEST_P() [108/450]

impeller::testing::TEST_P ( AiksTest  ,
CanvasCanPushPopCTM   
)

Definition at line 57 of file aiks_unittests.cc.

57 {
58 Canvas canvas;
59 ASSERT_EQ(canvas.GetSaveCount(), 1u);
60 ASSERT_EQ(canvas.Restore(), false);
61
62 canvas.Translate(Size{100, 100});
63 canvas.Save();
64 ASSERT_EQ(canvas.GetSaveCount(), 2u);
65 ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(),
66 Matrix::MakeTranslation({100.0, 100.0, 0.0}));
67 ASSERT_TRUE(canvas.Restore());
68 ASSERT_EQ(canvas.GetSaveCount(), 1u);
69 ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(),
70 Matrix::MakeTranslation({100.0, 100.0, 0.0}));
71}

◆ TEST_P() [109/450]

impeller::testing::TEST_P ( AiksTest  ,
CanvasCTMCanBeUpdated   
)

Definition at line 48 of file aiks_unittests.cc.

48 {
49 Canvas canvas;
51 ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(), identity);
52 canvas.Translate(Size{100, 100});
53 ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(),
54 Matrix::MakeTranslation({100.0, 100.0, 0.0}));
55}

◆ TEST_P() [110/450]

impeller::testing::TEST_P ( AiksTest  ,
ClearBlend   
)

Definition at line 356 of file aiks_blend_unittests.cc.

356 {
357 Canvas canvas;
358 Paint white;
359 white.color = Color::Blue();
360 canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
361
362 Paint clear;
363 clear.blend_mode = BlendMode::kClear;
364
365 canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
366}

◆ TEST_P() [111/450]

impeller::testing::TEST_P ( AiksTest  ,
ClearBlendWithBlur   
)

Definition at line 183 of file aiks_blur_unittests.cc.

183 {
184 Canvas canvas;
185 Paint white;
186 white.color = Color::Blue();
187 canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
188
189 Paint clear;
190 clear.blend_mode = BlendMode::kClear;
191 clear.mask_blur_descriptor = Paint::MaskBlurDescriptor{
193 .sigma = Sigma(20),
194 };
195
196 canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
197
198 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
199}

◆ TEST_P() [112/450]

impeller::testing::TEST_P ( AiksTest  ,
ClearColorOptimizationDoesNotApplyForBackdropFilters   
)

Definition at line 1707 of file aiks_unittests.cc.

1707 {
1708 Canvas canvas;
1709 canvas.SaveLayer({}, std::nullopt,
1710 ImageFilter::MakeBlur(Sigma(3), Sigma(3),
1712 Entity::TileMode::kClamp));
1713 canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1714 canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1715 .blend_mode = BlendMode::kSourceOver});
1716 canvas.Restore();
1717
1718 Picture picture = canvas.EndRecordingAsPicture();
1719
1720 std::optional<Color> actual_color;
1721 bool found_subpass = false;
1722 picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool {
1723 if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
1724 actual_color = subpass->get()->GetClearColor();
1725 found_subpass = true;
1726 }
1727 // Fail if the first element isn't a subpass.
1728 return true;
1729 });
1730
1731 EXPECT_TRUE(found_subpass);
1732 EXPECT_FALSE(actual_color.has_value());
1733}

◆ TEST_P() [113/450]

impeller::testing::TEST_P ( AiksTest  ,
ClearColorOptimizationWhenSubpassIsBiggerThanParentPass   
)

Definition at line 2511 of file aiks_unittests.cc.

2511 {
2512 SetWindowSize({400, 400});
2513 Canvas canvas;
2514 canvas.Scale(GetContentScale());
2515 canvas.DrawRect(Rect::MakeLTRB(200, 200, 300, 300), {.color = Color::Red()});
2516 canvas.SaveLayer({
2517 .image_filter = std::make_shared<MatrixImageFilter>(
2518 Matrix::MakeScale({2, 2, 1}), SamplerDescriptor{}),
2519 });
2520 // Draw a rectangle that would fully cover the parent pass size, but not
2521 // the subpass that it is rendered in.
2522 canvas.DrawRect(Rect::MakeLTRB(0, 0, 400, 400), {.color = Color::Green()});
2523 // Draw a bigger rectangle to force the subpass to be bigger.
2524 canvas.DrawRect(Rect::MakeLTRB(0, 0, 800, 800), {.color = Color::Red()});
2525 canvas.Restore();
2526
2527 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2528}

◆ TEST_P() [114/450]

impeller::testing::TEST_P ( AiksTest  ,
ClippedBlurFilterRendersCorrectly   
)

Definition at line 168 of file aiks_blur_unittests.cc.

168 {
169 Canvas canvas;
170 canvas.Translate(Point(0, -400));
171 Paint paint;
172 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
174 .sigma = Radius{120 * 3},
175 };
176 paint.color = Color::Red();
177 PathBuilder builder{};
178 builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800));
179 canvas.DrawPath(builder.TakePath(), paint);
180 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
181}

◆ TEST_P() [115/450]

impeller::testing::TEST_P ( AiksTest  ,
ClippedBlurFilterRendersCorrectlyInteractive   
)

Definition at line 146 of file aiks_blur_unittests.cc.

146 {
147 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
148 static PlaygroundPoint playground_point(Point(400, 400), 20,
149 Color::Green());
150 auto point = DrawPlaygroundPoint(playground_point);
151
152 Canvas canvas;
153 canvas.Translate(point - Point(400, 400));
154 Paint paint;
155 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
157 .sigma = Radius{120 * 3},
158 };
159 paint.color = Color::Red();
160 PathBuilder builder{};
161 builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800));
162 canvas.DrawPath(builder.TakePath(), paint);
163 return canvas.EndRecordingAsPicture();
164 };
165 ASSERT_TRUE(OpenPlaygroundHere(callback));
166}
Point DrawPlaygroundPoint(PlaygroundPoint &point)
Definition: widgets.cc:9

◆ TEST_P() [116/450]

impeller::testing::TEST_P ( AiksTest  ,
ClipRectElidesNoOpClips   
)

Definition at line 1683 of file aiks_unittests.cc.

1683 {
1684 Canvas canvas(Rect::MakeXYWH(0, 0, 100, 100));
1685 canvas.ClipRect(Rect::MakeXYWH(0, 0, 100, 100));
1686 canvas.ClipRect(Rect::MakeXYWH(-100, -100, 300, 300));
1687 canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1688 canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1689 .blend_mode = BlendMode::kSourceOver});
1690
1691 Picture picture = canvas.EndRecordingAsPicture();
1692 auto expected = Color::Red().Blend(Color::CornflowerBlue().WithAlpha(0.75),
1693 BlendMode::kSourceOver);
1694 ASSERT_EQ(picture.pass->GetClearColor(), expected);
1695
1696 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1697 std::shared_ptr<Context> real_context = GetContext();
1698 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1699 AiksContext renderer(mock_context, nullptr);
1700 std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1701
1702 ASSERT_EQ(spy->render_passes_.size(), 1llu);
1703 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1704 ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1705}
static MockContext mock_context
Definition: mock_epoxy.cc:51

◆ TEST_P() [117/450]

impeller::testing::TEST_P ( AiksTest  ,
ClipsUseCurrentTransform   
)

Definition at line 102 of file aiks_dl_clip_unittests.cc.

102 {
103 std::array<DlColor, 5> colors = {DlColor::kWhite(), DlColor::kBlack(),
104 DlColor::kSkyBlue(), DlColor::kRed(),
106 DisplayListBuilder builder;
108
109 builder.Translate(300, 300);
110 for (int i = 0; i < 15; i++) {
111 builder.Scale(0.8, 0.8);
112
113 paint.setColor(colors[i % colors.size()]);
114 builder.ClipPath(CreateCircle(0, 0, 300));
115 builder.DrawRect(SkRect::MakeXYWH(-300, -300, 600, 600), paint);
116 }
117 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
118}
constexpr SkColor4f kBlack
Definition: SkColor.h:435

◆ TEST_P() [118/450]

impeller::testing::TEST_P ( AiksTest  ,
CollapsedDrawPaintInSubpass   
)

Definition at line 1735 of file aiks_unittests.cc.

1735 {
1736 Canvas canvas;
1737 canvas.DrawPaint(
1738 {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
1739 canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
1740 canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1741 .blend_mode = BlendMode::kSourceOver});
1742
1743 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1744}

◆ TEST_P() [119/450]

impeller::testing::TEST_P ( AiksTest  ,
CollapsedDrawPaintInSubpassBackdropFilter   
)

Definition at line 1746 of file aiks_unittests.cc.

1746 {
1747 // Bug: https://github.com/flutter/flutter/issues/131576
1748 Canvas canvas;
1749 canvas.DrawPaint(
1750 {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
1751 canvas.SaveLayer({}, {},
1752 ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
1754 Entity::TileMode::kDecal));
1755 canvas.DrawPaint(
1756 {.color = Color::CornflowerBlue(), .blend_mode = BlendMode::kSourceOver});
1757
1758 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1759}

◆ TEST_P() [120/450]

impeller::testing::TEST_P ( AiksTest  ,
ColorMatrixFilterSubpassCollapseOptimization   
)

Definition at line 1761 of file aiks_unittests.cc.

1761 {
1762 Canvas canvas;
1763
1764 canvas.SaveLayer({
1765 .color_filter =
1766 ColorFilter::MakeMatrix({.array =
1767 {
1768 -1.0, 0, 0, 1.0, 0, //
1769 0, -1.0, 0, 1.0, 0, //
1770 0, 0, -1.0, 1.0, 0, //
1771 1.0, 1.0, 1.0, 1.0, 0 //
1772 }}),
1773 });
1774
1775 canvas.Translate({500, 300, 0});
1776 canvas.Rotate(Radians(2 * kPi / 3));
1777 canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
1778
1779 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1780}
static sk_sp< SkColorFilter > MakeMatrix(const float array[20], SkMatrixColorFilter::Domain domain)

◆ TEST_P() [121/450]

impeller::testing::TEST_P ( AiksTest  ,
ColorWheel   
)

color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 -> cyan domain: r >= 0 (because modulo used is non euclidean)

Definition at line 205 of file aiks_blend_unittests.cc.

205 {
206 // Compare with https://fiddle.skia.org/c/@BlendModes
207
209
210 auto draw_color_wheel = [](Canvas& canvas) {
211 /// color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 ->
212 /// cyan domain: r >= 0 (because modulo used is non euclidean)
213 auto color_wheel_sampler = [](Radians r) {
214 Scalar x = r.radians / k2Pi + 1;
215
216 // https://www.desmos.com/calculator/6nhjelyoaj
217 auto color_cycle = [](Scalar x) {
218 Scalar cycle = std::fmod(x, 6.0f);
219 return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
220 };
221 return Color(color_cycle(6 * x + 1), //
222 color_cycle(6 * x - 1), //
223 color_cycle(6 * x - 3), //
224 1);
225 };
226
227 Paint paint;
228 paint.blend_mode = BlendMode::kSourceOver;
229
230 // Draw a fancy color wheel for the backdrop.
231 // https://www.desmos.com/calculator/xw7kafthwd
232 const int max_dist = 900;
233 for (int i = 0; i <= 900; i++) {
234 Radians r(kPhi / k2Pi * i);
235 Scalar distance = r.radians / std::powf(4.12, 0.0026 * r.radians);
236 Scalar normalized_distance = static_cast<Scalar>(i) / max_dist;
237
238 paint.color =
239 color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
240 Point position(distance * std::sin(r.radians),
241 -distance * std::cos(r.radians));
242
243 canvas.DrawCircle(position, 9 + normalized_distance * 3, paint);
244 }
245 };
246
247 std::shared_ptr<Image> color_wheel_image;
248 Matrix color_wheel_transform;
249
250 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
251 // UI state.
252 static bool cache_the_wheel = true;
253 static int current_blend_index = 3;
254 static float dst_alpha = 1;
255 static float src_alpha = 1;
256 static Color color0 = Color::Red();
257 static Color color1 = Color::Green();
258 static Color color2 = Color::Blue();
259
260 if (AiksTest::ImGuiBegin("Controls", nullptr,
261 ImGuiWindowFlags_AlwaysAutoResize)) {
262 ImGui::Checkbox("Cache the wheel", &cache_the_wheel);
263 ImGui::ListBox("Blending mode", &current_blend_index,
264 blend_modes.blend_mode_names.data(),
265 blend_modes.blend_mode_names.size());
266 ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
267 ImGui::ColorEdit4("Color A", reinterpret_cast<float*>(&color0));
268 ImGui::ColorEdit4("Color B", reinterpret_cast<float*>(&color1));
269 ImGui::ColorEdit4("Color C", reinterpret_cast<float*>(&color2));
270 ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
271 ImGui::End();
272 }
273
274 static Point content_scale;
275 Point new_content_scale = GetContentScale();
276
277 if (!cache_the_wheel || new_content_scale != content_scale) {
278 content_scale = new_content_scale;
279
280 // Render the color wheel to an image.
281
282 Canvas canvas;
283 canvas.Scale(content_scale);
284
285 canvas.Translate(Vector2(500, 400));
286 canvas.Scale(Vector2(3, 3));
287
288 draw_color_wheel(canvas);
289 auto color_wheel_picture = canvas.EndRecordingAsPicture();
290 auto snapshot = color_wheel_picture.Snapshot(renderer);
291 if (!snapshot.has_value() || !snapshot->texture) {
292 return std::nullopt;
293 }
294 color_wheel_image = std::make_shared<Image>(snapshot->texture);
295 color_wheel_transform = snapshot->transform;
296 }
297
298 Canvas canvas;
299
300 // Blit the color wheel backdrop to the screen with managed alpha.
301 canvas.SaveLayer({.color = Color::White().WithAlpha(dst_alpha),
302 .blend_mode = BlendMode::kSource});
303 {
304 canvas.DrawPaint({.color = Color::White()});
305
306 canvas.Save();
307 canvas.Transform(color_wheel_transform);
308 canvas.DrawImage(color_wheel_image, Point(), Paint());
309 canvas.Restore();
310 }
311 canvas.Restore();
312
313 canvas.Scale(content_scale);
314 canvas.Translate(Vector2(500, 400));
315 canvas.Scale(Vector2(3, 3));
316
317 // Draw 3 circles to a subpass and blend it in.
318 canvas.SaveLayer(
319 {.color = Color::White().WithAlpha(src_alpha),
320 .blend_mode = blend_modes.blend_mode_values[current_blend_index]});
321 {
322 Paint paint;
323 paint.blend_mode = BlendMode::kPlus;
324 const Scalar x = std::sin(k2Pi / 3);
325 const Scalar y = -std::cos(k2Pi / 3);
326 paint.color = color0;
327 canvas.DrawCircle(Point(-x, y) * 45, 65, paint);
328 paint.color = color1;
329 canvas.DrawCircle(Point(0, -1) * 45, 65, paint);
330 paint.color = color2;
331 canvas.DrawCircle(Point(x, y) * 45, 65, paint);
332 }
333 canvas.Restore();
334
335 return canvas.EndRecordingAsPicture();
336 };
337
338 ASSERT_TRUE(OpenPlaygroundHere(callback));
339}
constexpr float kPhi
Definition: constants.h:53
SIN Vec< N, float > abs(const Vec< N, float > &x)
Definition: SkVx.h:707
std::vector< const char * > blend_mode_names

◆ TEST_P() [122/450]

impeller::testing::TEST_P ( AiksTest  ,
CoordinateConversionsAreCorrect   
)

Definition at line 404 of file aiks_unittests.cc.

404 {
405 Canvas canvas;
406
407 // Render a texture directly.
408 {
409 Paint paint;
410 auto image =
411 std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
412 paint.color = Color::Red();
413
414 canvas.Save();
415 canvas.Translate({100, 200, 0});
416 canvas.Scale(Vector2{0.5, 0.5});
417 canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
418 canvas.Restore();
419 }
420
421 // Render an offscreen rendered texture.
422 {
423 Paint red;
424 red.color = Color::Red();
425 Paint green;
426 green.color = Color::Green();
427 Paint blue;
428 blue.color = Color::Blue();
429
430 Paint alpha;
431 alpha.color = Color::Red().WithAlpha(0.5);
432
433 canvas.SaveLayer(alpha);
434
435 canvas.DrawRect(Rect::MakeXYWH(000, 000, 100, 100), red);
436 canvas.DrawRect(Rect::MakeXYWH(020, 020, 100, 100), green);
437 canvas.DrawRect(Rect::MakeXYWH(040, 040, 100, 100), blue);
438
439 canvas.Restore();
440 }
441
442 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
443}

◆ TEST_P() [123/450]

impeller::testing::TEST_P ( AiksTest  ,
CorrectClipDepthAssignedToEntities   
)

Definition at line 2620 of file aiks_unittests.cc.

2620 {
2621 Canvas canvas; // Depth 1 (base pass)
2622 canvas.DrawRRect(Rect::MakeLTRB(0, 0, 100, 100), {10, 10}, {}); // Depth 2
2623 canvas.Save();
2624 {
2625 canvas.ClipRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 4
2626 canvas.SaveLayer({}); // Depth 4
2627 {
2628 canvas.DrawRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 3
2629 }
2630 canvas.Restore(); // Restore the savelayer.
2631 }
2632 canvas.Restore(); // Depth 5 -- this will no longer append a restore entity
2633 // once we switch to the clip depth approach.
2634
2635 auto picture = canvas.EndRecordingAsPicture();
2636
2637 std::vector<uint32_t> expected = {
2638 2, // DrawRRect
2639 4, // ClipRRect -- Has a depth value equal to the max depth of all the
2640 // content it affect. In this case, the SaveLayer and all
2641 // its contents are affected.
2642 4, // SaveLayer -- The SaveLayer is drawn to the parent pass after its
2643 // contents are rendered, so it should have a depth value
2644 // greater than all its contents.
2645 3, // DrawRRect
2646 5, // Restore (no longer necessary when clipping on the depth buffer)
2647 };
2648
2649 std::vector<uint32_t> actual;
2650
2651 picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool {
2652 if (auto* subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
2653 actual.push_back(subpass->get()->GetClipDepth());
2654 }
2655 if (Entity* entity = std::get_if<Entity>(&element)) {
2656 actual.push_back(entity->GetClipDepth());
2657 }
2658 return true;
2659 });
2660
2661 ASSERT_EQ(actual.size(), expected.size());
2662 for (size_t i = 0; i < expected.size(); i++) {
2663 EXPECT_EQ(expected[i], actual[i]) << "Index: " << i;
2664 }
2665}

◆ TEST_P() [124/450]

impeller::testing::TEST_P ( AiksTest  ,
CoverageOriginShouldBeAccountedForInSubpasses   
)

Definition at line 1339 of file aiks_unittests.cc.

1339 {
1340 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1341 Canvas canvas;
1342 canvas.Scale(GetContentScale());
1343
1344 Paint alpha;
1345 alpha.color = Color::Red().WithAlpha(0.5);
1346
1347 auto current = Point{25, 25};
1348 const auto offset = Point{25, 25};
1349 const auto size = Size(100, 100);
1350
1351 static PlaygroundPoint point_a(Point(40, 40), 10, Color::White());
1352 static PlaygroundPoint point_b(Point(160, 160), 10, Color::White());
1353 auto [b0, b1] = DrawPlaygroundLine(point_a, point_b);
1354 auto bounds = Rect::MakeLTRB(b0.x, b0.y, b1.x, b1.y);
1355
1356 canvas.DrawRect(bounds, Paint{.color = Color::Yellow(),
1357 .stroke_width = 5.0f,
1358 .style = Paint::Style::kStroke});
1359
1360 canvas.SaveLayer(alpha, bounds);
1361
1362 canvas.DrawRect(Rect::MakeOriginSize(current, size),
1363 Paint{.color = Color::Red()});
1364 canvas.DrawRect(Rect::MakeOriginSize(current += offset, size),
1365 Paint{.color = Color::Green()});
1366 canvas.DrawRect(Rect::MakeOriginSize(current += offset, size),
1367 Paint{.color = Color::Blue()});
1368
1369 canvas.Restore();
1370
1371 return canvas.EndRecordingAsPicture();
1372 };
1373
1374 ASSERT_TRUE(OpenPlaygroundHere(callback));
1375}

◆ TEST_P() [125/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawAdvancedBlendPartlyOffscreen   
)

Definition at line 94 of file aiks_blend_unittests.cc.

94 {
95 std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
96 Color{0.1294, 0.5882, 0.9529, 1.0}};
97 std::vector<Scalar> stops = {0.0, 1.0};
98
99 Paint paint = {
100 .color_source = ColorSource::MakeLinearGradient(
101 {0, 0}, {100, 100}, std::move(colors), std::move(stops),
102 Entity::TileMode::kRepeat, Matrix::MakeScale(Vector3(0.3, 0.3, 0.3))),
103 .blend_mode = BlendMode::kLighten,
104 };
105
106 Canvas canvas;
107 canvas.DrawPaint({.color = Color::Blue()});
108 canvas.Scale(Vector2(2, 2));
109 canvas.ClipRect(Rect::MakeLTRB(0, 0, 200, 200));
110 canvas.DrawCircle({100, 100}, 100, paint);
111 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
112}

◆ TEST_P() [126/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasAdvancedAndTransform   
)

Definition at line 129 of file aiks_dl_atlas_unittests.cc.

129 {
131 // Draws the image as four squares stiched together.
132 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
133
134 builder.Scale(0.25, 0.25);
135 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
136 /*colors=*/nullptr, /*count=*/4, DlBlendMode::kModulate,
137 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
138
139 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
140}
sk_sp< const SkImage > atlas
Definition: SkRecords.h:331

◆ TEST_P() [127/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasNoColor   
)

Definition at line 52 of file aiks_dl_atlas_unittests.cc.

52 {
54 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
55
56 builder.Scale(GetContentScale().x, GetContentScale().y);
57 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
58 /*colors=*/nullptr, /*count=*/4, DlBlendMode::kSrcOver,
59 DlImageSampling::kNearestNeighbor, nullptr);
60
61 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
62}

◆ TEST_P() [128/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasNoColorFullSize   
)

Definition at line 112 of file aiks_dl_atlas_unittests.cc.

112 {
113 auto atlas = DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
114 auto size = atlas->impeller_texture()->GetSize();
115 std::vector<SkRect> texture_coordinates = {
116 SkRect::MakeLTRB(0, 0, size.width, size.height)};
117 std::vector<SkRSXform> transforms = {MakeTranslation(0, 0)};
118
119 DisplayListBuilder builder;
120 builder.Scale(GetContentScale().x, GetContentScale().y);
121 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
122 /*colors=*/nullptr, /*count=*/1, DlBlendMode::kSrcOver,
123 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
124
125 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
126}

◆ TEST_P() [129/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasPlusWideGamut   
)

Definition at line 158 of file aiks_dl_atlas_unittests.cc.

158 {
160 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
161 PixelFormat::kB10G10R10A10XR);
162
163 // Draws the image as four squares stiched together.
164 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
165 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
167
168 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
169 colors.data(), /*count=*/4, DlBlendMode::kPlus,
170 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
171
172 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
173}

◆ TEST_P() [130/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorAdvanced   
)

Definition at line 64 of file aiks_dl_atlas_unittests.cc.

64 {
66 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
67
68 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
70
71 builder.Scale(GetContentScale().x, GetContentScale().y);
72 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
73 colors.data(), /*count=*/4, DlBlendMode::kModulate,
74 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
75
76 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
77}

◆ TEST_P() [131/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorAdvancedAndTransform   
)

Definition at line 143 of file aiks_dl_atlas_unittests.cc.

143 {
145 // Draws the image as four squares stiched together.
146 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
147 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
149
150 builder.Scale(0.25, 0.25);
151 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
152 colors.data(), /*count=*/4, DlBlendMode::kModulate,
153 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
154
155 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
156}

◆ TEST_P() [132/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorSimple   
)

Definition at line 79 of file aiks_dl_atlas_unittests.cc.

79 {
81 // Draws the image as four squares stiched together.
82 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
83
84 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
86
87 builder.Scale(GetContentScale().x, GetContentScale().y);
88 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
89 colors.data(), /*count=*/4, DlBlendMode::kSrcATop,
90 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
91
92 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
93}

◆ TEST_P() [133/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithOpacity   
)

Definition at line 95 of file aiks_dl_atlas_unittests.cc.

95 {
97 // Draws the image as four squares stiched together slightly
98 // opaque
99 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
100
102 paint.setAlpha(128);
103 builder.Scale(GetContentScale().x, GetContentScale().y);
104 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
105 /*colors=*/nullptr, 4, DlBlendMode::kSrcOver,
106 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr,
107 &paint);
108
109 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
110}

◆ TEST_P() [134/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawLinesRenderCorrectly   
)

Definition at line 256 of file aiks_path_unittests.cc.

256 {
257 Canvas canvas;
258 canvas.Scale(GetContentScale());
259 Paint paint;
260 paint.color = Color::Blue();
261 paint.stroke_width = 10;
262
263 auto draw = [&canvas](Paint& paint) {
264 for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
265 paint.stroke_cap = cap;
266 Point origin = {100, 100};
267 Point p0 = {50, 0};
268 Point p1 = {150, 0};
269 canvas.DrawLine({150, 100}, {250, 100}, paint);
270 for (int d = 15; d < 90; d += 15) {
271 Matrix m = Matrix::MakeRotationZ(Degrees(d));
272 canvas.DrawLine(origin + m * p0, origin + m * p1, paint);
273 }
274 canvas.DrawLine({100, 150}, {100, 250}, paint);
275 canvas.DrawCircle({origin}, 35, paint);
276
277 canvas.DrawLine({250, 250}, {250, 250}, paint);
278
279 canvas.Translate({250, 0});
280 }
281 canvas.Translate({-750, 250});
282 };
283
284 std::vector<Color> colors = {
285 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
286 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
287 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
288 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
289 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
290 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
291 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
292 std::vector<Scalar> stops = {
293 0.0,
294 (1.0 / 6.0) * 1,
295 (1.0 / 6.0) * 2,
296 (1.0 / 6.0) * 3,
297 (1.0 / 6.0) * 4,
298 (1.0 / 6.0) * 5,
299 1.0,
300 };
301
302 auto texture = CreateTextureForFixture("airplane.jpg",
303 /*enable_mipmapping=*/true);
304
305 draw(paint);
306
307 paint.color_source = ColorSource::MakeRadialGradient(
308 {100, 100}, 200, std::move(colors), std::move(stops),
309 Entity::TileMode::kMirror, {});
310 draw(paint);
311
312 paint.color_source = ColorSource::MakeImage(
313 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
314 Matrix::MakeTranslation({-150, 75}));
315 draw(paint);
316
317 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
318}

◆ TEST_P() [135/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawOpacityPeephole   
)

Definition at line 19 of file aiks_dl_opacity_unittests.cc.

19 {
21
22 DlPaint green;
23 green.setColor(DlColor::kGreen().modulateOpacity(0.5));
24
25 DlPaint alpha;
26 alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
27
28 builder.SaveLayer(nullptr, &alpha);
29 builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), green);
30 builder.Restore();
31
32 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
33}

◆ TEST_P() [136/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawPaintAbsorbsClears   
)

Definition at line 1556 of file aiks_unittests.cc.

1556 {
1557 Canvas canvas;
1558 canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1559 canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1560 .blend_mode = BlendMode::kSourceOver});
1561
1562 Picture picture = canvas.EndRecordingAsPicture();
1563 auto expected = Color::Red().Blend(Color::CornflowerBlue().WithAlpha(0.75),
1564 BlendMode::kSourceOver);
1565 ASSERT_EQ(picture.pass->GetClearColor(), expected);
1566
1567 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1568 std::shared_ptr<Context> real_context = GetContext();
1569 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1570 AiksContext renderer(mock_context, nullptr);
1571 std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1572
1573 ASSERT_EQ(spy->render_passes_.size(), 1llu);
1574 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1575 ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1576}

◆ TEST_P() [137/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawPaintTransformsBounds   
)

Definition at line 2176 of file aiks_unittests.cc.

2176 {
2177 auto runtime_stages = OpenAssetAsRuntimeStage("gradient.frag.iplr");
2178 auto runtime_stage =
2179 runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2180 ASSERT_TRUE(runtime_stage);
2181 ASSERT_TRUE(runtime_stage->IsDirty());
2182
2183 struct FragUniforms {
2184 Size size;
2185 } frag_uniforms = {.size = Size::MakeWH(400, 400)};
2186 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2187 uniform_data->resize(sizeof(FragUniforms));
2188 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2189
2190 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2191
2192 Paint paint;
2193 paint.color_source = ColorSource::MakeRuntimeEffect(
2194 runtime_stage, uniform_data, texture_inputs);
2195
2196 Canvas canvas;
2197 canvas.Save();
2198 canvas.Scale(GetContentScale());
2199 canvas.DrawPaint(paint);
2200 canvas.Restore();
2201
2202 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2203}

◆ TEST_P() [138/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawPaintWithAdvancedBlendOverFilter   
)

Definition at line 77 of file aiks_blend_unittests.cc.

77 {
78 Paint filtered = {
79 .color = Color::Black(),
80 .mask_blur_descriptor =
83 .sigma = Sigma(60),
84 },
85 };
86
87 Canvas canvas;
88 canvas.DrawPaint({.color = Color::White()});
89 canvas.DrawCircle({300, 300}, 200, filtered);
90 canvas.DrawPaint({.color = Color::Green(), .blend_mode = BlendMode::kScreen});
91 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
92}
def filtered(names, to_skip)
Definition: zip_utils.py:20

◆ TEST_P() [139/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectAbsorbsClears   
)

Definition at line 1603 of file aiks_unittests.cc.

1603 {
1604 Canvas canvas;
1605 canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1606 {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1607 canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1608 {.color = Color::CornflowerBlue().WithAlpha(0.75),
1609 .blend_mode = BlendMode::kSourceOver});
1610
1611 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1612 Picture picture = canvas.EndRecordingAsPicture();
1613 std::shared_ptr<Context> real_context = GetContext();
1614 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1615 AiksContext renderer(mock_context, nullptr);
1616 std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1617
1618 ASSERT_EQ(spy->render_passes_.size(), 1llu);
1619 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1620 ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1621}

◆ TEST_P() [140/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectAbsorbsClearsNegative   
)

Definition at line 1663 of file aiks_unittests.cc.

1663 {
1664 Canvas canvas;
1665 canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1666 {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1667 canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1668 {.color = Color::CornflowerBlue().WithAlpha(0.75),
1669 .blend_mode = BlendMode::kSourceOver});
1670
1671 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1672 Picture picture = canvas.EndRecordingAsPicture();
1673 std::shared_ptr<Context> real_context = GetContext();
1674 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1675 AiksContext renderer(mock_context, nullptr);
1676 std::shared_ptr<Image> image = picture.ToImage(renderer, {301, 301});
1677
1678 ASSERT_EQ(spy->render_passes_.size(), 1llu);
1679 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1680 ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
1681}

◆ TEST_P() [141/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectAbsorbsClearsNegativeRotation   
)

Definition at line 1643 of file aiks_unittests.cc.

1643 {
1644 Canvas canvas;
1645 canvas.Translate(Vector3(150.0, 150.0, 0.0));
1646 canvas.Rotate(Degrees(45.0));
1647 canvas.Translate(Vector3(-150.0, -150.0, 0.0));
1648 canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1649 {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1650
1651 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1652 Picture picture = canvas.EndRecordingAsPicture();
1653 std::shared_ptr<Context> real_context = GetContext();
1654 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1656 std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1657
1658 ASSERT_EQ(spy->render_passes_.size(), 1llu);
1659 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1660 ASSERT_EQ(render_pass->GetCommands().size(), 1llu);
1661}

◆ TEST_P() [142/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectAbsorbsClearsNegativeRRect   
)

Definition at line 1623 of file aiks_unittests.cc.

1623 {
1624 Canvas canvas;
1625 canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), {5.0, 5.0},
1626 {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1627 canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), {5.0, 5.0},
1628 {.color = Color::CornflowerBlue().WithAlpha(0.75),
1629 .blend_mode = BlendMode::kSourceOver});
1630
1631 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1632 Picture picture = canvas.EndRecordingAsPicture();
1633 std::shared_ptr<Context> real_context = GetContext();
1634 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1635 AiksContext renderer(mock_context, nullptr);
1636 std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1637
1638 ASSERT_EQ(spy->render_passes_.size(), 1llu);
1639 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1640 ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
1641}

◆ TEST_P() [143/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectStrokesRenderCorrectly   
)

Definition at line 320 of file aiks_path_unittests.cc.

320 {
321 Canvas canvas;
322 Paint paint;
323 paint.color = Color::Red();
324 paint.style = Paint::Style::kStroke;
325 paint.stroke_width = 10;
326
327 canvas.Translate({100, 100});
328 canvas.DrawPath(
329 PathBuilder{}.AddRect(Rect::MakeSize(Size{100, 100})).TakePath(),
330 {paint});
331
332 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
333}

◆ TEST_P() [144/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectStrokesWithBevelJoinRenderCorrectly   
)

Definition at line 335 of file aiks_path_unittests.cc.

335 {
336 Canvas canvas;
337 Paint paint;
338 paint.color = Color::Red();
339 paint.style = Paint::Style::kStroke;
340 paint.stroke_width = 10;
341 paint.stroke_join = Join::kBevel;
342
343 canvas.Translate({100, 100});
344 canvas.DrawPath(
345 PathBuilder{}.AddRect(Rect::MakeSize(Size{100, 100})).TakePath(),
346 {paint});
347
348 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
349}

◆ TEST_P() [145/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawScaledTextWithPerspectiveNoSaveLayer   
)

Definition at line 2363 of file aiks_unittests.cc.

2363 {
2364 Canvas canvas;
2365 canvas.Transform(Matrix(1.0, 0.0, 0.0, 0.0, //
2366 0.0, 1.0, 0.0, 0.0, //
2367 0.0, 0.0, 1.0, 0.01, //
2368 0.0, 0.0, 0.0, 1.0) * //
2369 Matrix::MakeRotationY({Degrees{10}}));
2370
2371 ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
2372 "Roboto-Regular.ttf"));
2373
2374 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2375}

◆ TEST_P() [146/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawScaledTextWithPerspectiveSaveLayer   
)

Definition at line 2377 of file aiks_unittests.cc.

2377 {
2378 Canvas canvas;
2379 Paint save_paint;
2380 canvas.SaveLayer(save_paint);
2381 canvas.Transform(Matrix(1.0, 0.0, 0.0, 0.0, //
2382 0.0, 1.0, 0.0, 0.0, //
2383 0.0, 0.0, 1.0, 0.01, //
2384 0.0, 0.0, 0.0, 1.0) * //
2385 Matrix::MakeRotationY({Degrees{10}}));
2386
2387 ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
2388 "Roboto-Regular.ttf"));
2389 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2390}

◆ TEST_P() [147/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesImageSourceWithTextureCoordinates   
)

Definition at line 259 of file aiks_dl_vertices_unittests.cc.

259 {
260 auto texture = CreateTextureForFixture("embarcadero.jpg");
261 auto dl_image = DlImageImpeller::Make(texture);
262 std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
263 SkPoint::Make(200, 100),
264 SkPoint::Make(300, 300)};
265 std::vector<SkPoint> texture_coordinates = {
266 SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
267
268 auto vertices = flutter::DlVertices::Make(
269 flutter::DlVertexMode::kTriangles, 3, positions.data(),
270 texture_coordinates.data(), /*colors=*/nullptr);
271
274
275 auto image_source = flutter::DlImageColorSource(
277
278 paint.setColorSource(&image_source);
279 builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
280
281 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
282}
@ kTriangles
The vertices are taken 3 at a time to form a triangle.

◆ TEST_P() [148/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending   
)

Definition at line 284 of file aiks_dl_vertices_unittests.cc.

285 {
286 auto texture = CreateTextureForFixture("embarcadero.jpg");
287 auto dl_image = DlImageImpeller::Make(texture);
288 std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
289 SkPoint::Make(200, 100),
290 SkPoint::Make(300, 300)};
291 std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
294 std::vector<SkPoint> texture_coordinates = {
295 SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
296
297 auto vertices = flutter::DlVertices::Make(
298 flutter::DlVertexMode::kTriangles, 3, positions.data(),
299 texture_coordinates.data(), colors.data());
300
303
304 auto image_source = flutter::DlImageColorSource(
306
307 paint.setColorSource(&image_source);
308 builder.DrawVertices(vertices, flutter::DlBlendMode::kModulate, paint);
309
310 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
311}
static constexpr DlColor kWhite()
Definition: dl_color.h:23

◆ TEST_P() [149/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesLinearGradientWithoutIndices   
)

Definition at line 204 of file aiks_dl_vertices_unittests.cc.

204 {
205 std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
206 SkPoint::Make(200, 100),
207 SkPoint::Make(300, 300)};
208
209 auto vertices = flutter::DlVertices::Make(
210 flutter::DlVertexMode::kTriangles, 3, positions.data(),
211 /*texture_coordinates=*/nullptr, /*colors=*/nullptr);
212
213 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
215 const float stops[2] = {0.0, 1.0};
216
218 {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
220
223
224 paint.setColorSource(linear);
225 builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
226
227 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
228}

◆ TEST_P() [150/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesLinearGradientWithTextureCoordinates   
)

Definition at line 230 of file aiks_dl_vertices_unittests.cc.

230 {
231 std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
232 SkPoint::Make(200, 100),
233 SkPoint::Make(300, 300)};
234 std::vector<SkPoint> texture_coordinates = {SkPoint::Make(300, 100),
235 SkPoint::Make(100, 200),
236 SkPoint::Make(300, 300)};
237
238 auto vertices = flutter::DlVertices::Make(
239 flutter::DlVertexMode::kTriangles, 3, positions.data(),
240 texture_coordinates.data(), /*colors=*/nullptr);
241
242 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
244 const float stops[2] = {0.0, 1.0};
245
247 {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
249
252
253 paint.setColorSource(linear);
254 builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
255
256 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
257}

◆ TEST_P() [151/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesPremultipliesColors   
)

Definition at line 333 of file aiks_dl_vertices_unittests.cc.

333 {
334 std::vector<SkPoint> positions = {
335 SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
336 SkPoint::Make(200, 500)};
338 std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
339 std::vector<flutter::DlColor> colors = {color, color, color, color};
340
341 auto vertices = flutter::DlVertices::Make(
342 flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
343 /*texture_coordinates=*/nullptr, colors.data(), indices.size(),
344 indices.data());
345
349 paint.setColor(flutter::DlColor::kRed());
350
351 builder.DrawRect(SkRect::MakeLTRB(0, 0, 400, 400), paint);
352 builder.DrawVertices(vertices, flutter::DlBlendMode::kDst, paint);
353
354 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
355}
constexpr DlColor withAlpha(uint8_t alpha) const
Definition: dl_color.h:63

◆ TEST_P() [152/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesSolidColorTrianglesWithIndices   
)

Definition at line 313 of file aiks_dl_vertices_unittests.cc.

313 {
314 std::vector<SkPoint> positions = {
315 SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
316 SkPoint::Make(200, 500)};
317 std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
318
319 auto vertices = flutter::DlVertices::Make(
320 flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
321 /*texture_coordinates=*/nullptr, /*colors=*/nullptr, indices.size(),
322 indices.data());
323
326
327 paint.setColor(flutter::DlColor::kRed());
328 builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
329
330 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
331}

◆ TEST_P() [153/450]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesSolidColorTrianglesWithoutIndices   
)

Definition at line 180 of file aiks_dl_vertices_unittests.cc.

180 {
181 // Use negative coordinates and then scale the transform by -1, -1 to make
182 // sure coverage is taking the transform into account.
183 std::vector<SkPoint> positions = {SkPoint::Make(-100, -300),
184 SkPoint::Make(-200, -100),
185 SkPoint::Make(-300, -300)};
186 std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
189
190 auto vertices = flutter::DlVertices::Make(
191 flutter::DlVertexMode::kTriangles, 3, positions.data(),
192 /*texture_coordinates=*/nullptr, colors.data());
193
196
197 paint.setColor(flutter::DlColor::kRed().modulateOpacity(0.5));
198 builder.Scale(-1, -1);
199 builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
200
201 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
202}

◆ TEST_P() [154/450]

impeller::testing::TEST_P ( AiksTest  ,
EmptySaveLayerIgnoresPaint   
)

Definition at line 2530 of file aiks_unittests.cc.

2530 {
2531 Canvas canvas;
2532 canvas.Scale(GetContentScale());
2533 canvas.DrawPaint(Paint{.color = Color::Red()});
2534 canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
2535 canvas.SaveLayer(Paint{.color = Color::Blue()});
2536 canvas.Restore();
2537 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2538}

◆ TEST_P() [155/450]

impeller::testing::TEST_P ( AiksTest  ,
EmptySaveLayerRendersWithClear   
)

Definition at line 2540 of file aiks_unittests.cc.

2540 {
2541 Canvas canvas;
2542 canvas.Scale(GetContentScale());
2543 auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2544 canvas.DrawImage(image, {10, 10}, {});
2545 canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
2546 canvas.SaveLayer(Paint{.blend_mode = BlendMode::kClear});
2547 canvas.Restore();
2548 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2549}

◆ TEST_P() [156/450]

impeller::testing::TEST_P ( AiksTest  ,
FastGradientTestHorizontal   
)

Definition at line 716 of file aiks_dl_gradient_unittests.cc.

716 {
719 builder.Translate(100.0f, 0);
720
721 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
723 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
724
725 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {300, 0}, stops.size(),
726 colors.data(), stops.data(),
727 DlTileMode::kClamp));
728
729 paint.setColor(DlColor::kWhite());
730 builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
731 builder.Translate(400, 0);
732 builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
733 paint);
734
735 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
736}

◆ TEST_P() [157/450]

impeller::testing::TEST_P ( AiksTest  ,
FastGradientTestHorizontalReversed   
)

Definition at line 762 of file aiks_dl_gradient_unittests.cc.

762 {
765 builder.Translate(100.0f, 0);
766
767 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
769 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
770
771 paint.setColorSource(DlColorSource::MakeLinear({300, 0}, {0, 0}, stops.size(),
772 colors.data(), stops.data(),
773 DlTileMode::kClamp));
774
775 paint.setColor(DlColor::kWhite());
776 builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
777 builder.Translate(400, 0);
778 builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
779 paint);
780
781 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
782}

◆ TEST_P() [158/450]

impeller::testing::TEST_P ( AiksTest  ,
FastGradientTestVertical   
)

Definition at line 739 of file aiks_dl_gradient_unittests.cc.

739 {
742 builder.Translate(100.0f, 0);
743
744 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
746 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
747
748 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {0, 300}, stops.size(),
749 colors.data(), stops.data(),
750 DlTileMode::kClamp));
751
752 paint.setColor(DlColor::kWhite());
753 builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
754 builder.Translate(400, 0);
755 builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
756 paint);
757
758 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
759}

◆ TEST_P() [159/450]

impeller::testing::TEST_P ( AiksTest  ,
FastGradientTestVerticalReversed   
)

Definition at line 785 of file aiks_dl_gradient_unittests.cc.

785 {
788 builder.Translate(100.0f, 0);
789
790 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
792 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
793
794 paint.setColorSource(DlColorSource::MakeLinear({0, 300}, {0, 0}, stops.size(),
795 colors.data(), stops.data(),
796 DlTileMode::kClamp));
797
798 paint.setColor(DlColor::kWhite());
799 builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
800 builder.Translate(400, 0);
801 builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
802 paint);
803
804 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
805}

◆ TEST_P() [160/450]

impeller::testing::TEST_P ( AiksTest  ,
FilledCirclesRenderCorrectly   
)

Definition at line 911 of file aiks_unittests.cc.

911 {
912 Canvas canvas;
913 canvas.Scale(GetContentScale());
914 Paint paint;
915 const int color_count = 3;
916 Color colors[color_count] = {
917 Color::Blue(),
918 Color::Green(),
919 Color::Crimson(),
920 };
921
922 paint.color = Color::White();
923 canvas.DrawPaint(paint);
924
925 int c_index = 0;
926 int radius = 600;
927 while (radius > 0) {
928 paint.color = colors[(c_index++) % color_count];
929 canvas.DrawCircle({10, 10}, radius, paint);
930 if (radius > 30) {
931 radius -= 10;
932 } else {
933 radius -= 2;
934 }
935 }
936
937 std::vector<Color> gradient_colors = {
938 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
939 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
940 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
941 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
942 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
943 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
944 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
945 std::vector<Scalar> stops = {
946 0.0,
947 (1.0 / 6.0) * 1,
948 (1.0 / 6.0) * 2,
949 (1.0 / 6.0) * 3,
950 (1.0 / 6.0) * 4,
951 (1.0 / 6.0) * 5,
952 1.0,
953 };
954 auto texture = CreateTextureForFixture("airplane.jpg",
955 /*enable_mipmapping=*/true);
956
957 paint.color_source = ColorSource::MakeRadialGradient(
958 {500, 600}, 75, std::move(gradient_colors), std::move(stops),
959 Entity::TileMode::kMirror, {});
960 canvas.DrawCircle({500, 600}, 100, paint);
961
962 paint.color_source = ColorSource::MakeImage(
963 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
964 Matrix::MakeTranslation({700, 200}));
965 canvas.DrawCircle({800, 300}, 100, paint);
966
967 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
968}

◆ TEST_P() [161/450]

impeller::testing::TEST_P ( AiksTest  ,
FilledEllipsesRenderCorrectly   
)

Definition at line 1034 of file aiks_unittests.cc.

1034 {
1035 Canvas canvas;
1036 canvas.Scale(GetContentScale());
1037 Paint paint;
1038 const int color_count = 3;
1039 Color colors[color_count] = {
1040 Color::Blue(),
1041 Color::Green(),
1042 Color::Crimson(),
1043 };
1044
1045 paint.color = Color::White();
1046 canvas.DrawPaint(paint);
1047
1048 int c_index = 0;
1049 int long_radius = 600;
1050 int short_radius = 600;
1051 while (long_radius > 0 && short_radius > 0) {
1052 paint.color = colors[(c_index++) % color_count];
1053 canvas.DrawOval(Rect::MakeXYWH(10 - long_radius, 10 - short_radius,
1054 long_radius * 2, short_radius * 2),
1055 paint);
1056 canvas.DrawOval(Rect::MakeXYWH(1000 - short_radius, 750 - long_radius,
1057 short_radius * 2, long_radius * 2),
1058 paint);
1059 if (short_radius > 30) {
1060 short_radius -= 10;
1061 long_radius -= 5;
1062 } else {
1063 short_radius -= 2;
1064 long_radius -= 1;
1065 }
1066 }
1067
1068 std::vector<Color> gradient_colors = {
1069 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1070 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1071 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1072 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1073 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1074 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1075 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1076 std::vector<Scalar> stops = {
1077 0.0,
1078 (1.0 / 6.0) * 1,
1079 (1.0 / 6.0) * 2,
1080 (1.0 / 6.0) * 3,
1081 (1.0 / 6.0) * 4,
1082 (1.0 / 6.0) * 5,
1083 1.0,
1084 };
1085 auto texture = CreateTextureForFixture("airplane.jpg",
1086 /*enable_mipmapping=*/true);
1087
1088 paint.color = Color::White().WithAlpha(0.5);
1089
1090 paint.color_source = ColorSource::MakeRadialGradient(
1091 {300, 650}, 75, std::move(gradient_colors), std::move(stops),
1092 Entity::TileMode::kMirror, {});
1093 canvas.DrawOval(Rect::MakeXYWH(200, 625, 200, 50), paint);
1094 canvas.DrawOval(Rect::MakeXYWH(275, 550, 50, 200), paint);
1095
1096 paint.color_source = ColorSource::MakeImage(
1097 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1098 Matrix::MakeTranslation({610, 15}));
1099 canvas.DrawOval(Rect::MakeXYWH(610, 90, 200, 50), paint);
1100 canvas.DrawOval(Rect::MakeXYWH(685, 15, 50, 200), paint);
1101
1102 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1103}

◆ TEST_P() [162/450]

impeller::testing::TEST_P ( AiksTest  ,
FilledRoundRectPathsRenderCorrectly   
)

Definition at line 1249 of file aiks_unittests.cc.

1249 {
1250 Canvas canvas;
1251 canvas.Scale(GetContentScale());
1252 Paint paint;
1253 const int color_count = 3;
1254 Color colors[color_count] = {
1255 Color::Blue(),
1256 Color::Green(),
1257 Color::Crimson(),
1258 };
1259
1260 paint.color = Color::White();
1261 canvas.DrawPaint(paint);
1262
1263 auto draw_rrect_as_path = [&canvas](const Rect& rect, const Size& radii,
1264 const Paint& paint) {
1266 builder.AddRoundedRect(rect, radii);
1267 canvas.DrawPath(builder.TakePath(), paint);
1268 };
1269
1270 int c_index = 0;
1271 for (int i = 0; i < 4; i++) {
1272 for (int j = 0; j < 4; j++) {
1273 paint.color = colors[(c_index++) % color_count];
1274 draw_rrect_as_path(Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1275 Size(i * 5 + 10, j * 5 + 10), paint);
1276 }
1277 }
1278 paint.color = colors[(c_index++) % color_count];
1279 draw_rrect_as_path(Rect::MakeXYWH(10, 420, 380, 80), Size(40, 40), paint);
1280 paint.color = colors[(c_index++) % color_count];
1281 draw_rrect_as_path(Rect::MakeXYWH(410, 20, 80, 380), Size(40, 40), paint);
1282
1283 std::vector<Color> gradient_colors = {
1284 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1285 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1286 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1287 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1288 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1289 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1290 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1291 std::vector<Scalar> stops = {
1292 0.0,
1293 (1.0 / 6.0) * 1,
1294 (1.0 / 6.0) * 2,
1295 (1.0 / 6.0) * 3,
1296 (1.0 / 6.0) * 4,
1297 (1.0 / 6.0) * 5,
1298 1.0,
1299 };
1300 auto texture = CreateTextureForFixture("airplane.jpg",
1301 /*enable_mipmapping=*/true);
1302
1303 paint.color = Color::White().WithAlpha(0.1);
1304 paint.color_source = ColorSource::MakeRadialGradient(
1305 {550, 550}, 75, gradient_colors, stops, Entity::TileMode::kMirror, {});
1306 for (int i = 1; i <= 10; i++) {
1307 int j = 11 - i;
1308 draw_rrect_as_path(Rect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1309 550 + i * 20, 550 + j * 20),
1310 Size(i * 10, j * 10), paint);
1311 }
1312 paint.color = Color::White().WithAlpha(0.5);
1313 paint.color_source = ColorSource::MakeRadialGradient(
1314 {200, 650}, 75, std::move(gradient_colors), std::move(stops),
1315 Entity::TileMode::kMirror, {});
1316 draw_rrect_as_path(Rect::MakeLTRB(100, 610, 300, 690), Size(40, 40), paint);
1317 draw_rrect_as_path(Rect::MakeLTRB(160, 550, 240, 750), Size(40, 40), paint);
1318
1319 paint.color = Color::White().WithAlpha(0.1);
1320 paint.color_source = ColorSource::MakeImage(
1321 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1322 Matrix::MakeTranslation({520, 20}));
1323 for (int i = 1; i <= 10; i++) {
1324 int j = 11 - i;
1325 draw_rrect_as_path(Rect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1326 720 + i * 20, 220 + j * 20),
1327 Size(i * 10, j * 10), paint);
1328 }
1329 paint.color = Color::White().WithAlpha(0.5);
1330 paint.color_source = ColorSource::MakeImage(
1331 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1332 Matrix::MakeTranslation({800, 300}));
1333 draw_rrect_as_path(Rect::MakeLTRB(800, 410, 1000, 490), Size(40, 40), paint);
1334 draw_rrect_as_path(Rect::MakeLTRB(860, 350, 940, 550), Size(40, 40), paint);
1335
1336 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1337}

◆ TEST_P() [163/450]

impeller::testing::TEST_P ( AiksTest  ,
FilledRoundRectsRenderCorrectly   
)

Definition at line 1105 of file aiks_unittests.cc.

1105 {
1106 Canvas canvas;
1107 canvas.Scale(GetContentScale());
1108 Paint paint;
1109 const int color_count = 3;
1110 Color colors[color_count] = {
1111 Color::Blue(),
1112 Color::Green(),
1113 Color::Crimson(),
1114 };
1115
1116 paint.color = Color::White();
1117 canvas.DrawPaint(paint);
1118
1119 int c_index = 0;
1120 for (int i = 0; i < 4; i++) {
1121 for (int j = 0; j < 4; j++) {
1122 paint.color = colors[(c_index++) % color_count];
1123 canvas.DrawRRect(Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1124 Size(i * 5 + 10, j * 5 + 10), paint);
1125 }
1126 }
1127 paint.color = colors[(c_index++) % color_count];
1128 canvas.DrawRRect(Rect::MakeXYWH(10, 420, 380, 80), Size(40, 40), paint);
1129 paint.color = colors[(c_index++) % color_count];
1130 canvas.DrawRRect(Rect::MakeXYWH(410, 20, 80, 380), Size(40, 40), paint);
1131
1132 std::vector<Color> gradient_colors = {
1133 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1134 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1135 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1136 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1137 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1138 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1139 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1140 std::vector<Scalar> stops = {
1141 0.0,
1142 (1.0 / 6.0) * 1,
1143 (1.0 / 6.0) * 2,
1144 (1.0 / 6.0) * 3,
1145 (1.0 / 6.0) * 4,
1146 (1.0 / 6.0) * 5,
1147 1.0,
1148 };
1149 auto texture = CreateTextureForFixture("airplane.jpg",
1150 /*enable_mipmapping=*/true);
1151
1152 paint.color = Color::White().WithAlpha(0.1);
1153 paint.color_source = ColorSource::MakeRadialGradient(
1154 {550, 550}, 75, gradient_colors, stops, Entity::TileMode::kMirror, {});
1155 for (int i = 1; i <= 10; i++) {
1156 int j = 11 - i;
1157 canvas.DrawRRect(Rect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1158 550 + i * 20, 550 + j * 20),
1159 Size(i * 10, j * 10), paint);
1160 }
1161 paint.color = Color::White().WithAlpha(0.5);
1162 paint.color_source = ColorSource::MakeRadialGradient(
1163 {200, 650}, 75, std::move(gradient_colors), std::move(stops),
1164 Entity::TileMode::kMirror, {});
1165 canvas.DrawRRect(Rect::MakeLTRB(100, 610, 300, 690), Size(40, 40), paint);
1166 canvas.DrawRRect(Rect::MakeLTRB(160, 550, 240, 750), Size(40, 40), paint);
1167
1168 paint.color = Color::White().WithAlpha(0.1);
1169 paint.color_source = ColorSource::MakeImage(
1170 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1171 Matrix::MakeTranslation({520, 20}));
1172 for (int i = 1; i <= 10; i++) {
1173 int j = 11 - i;
1174 canvas.DrawRRect(Rect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1175 720 + i * 20, 220 + j * 20),
1176 Size(i * 10, j * 10), paint);
1177 }
1178 paint.color = Color::White().WithAlpha(0.5);
1179 paint.color_source = ColorSource::MakeImage(
1180 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1181 Matrix::MakeTranslation({800, 300}));
1182 canvas.DrawRRect(Rect::MakeLTRB(800, 410, 1000, 490), Size(40, 40), paint);
1183 canvas.DrawRRect(Rect::MakeLTRB(860, 350, 940, 550), Size(40, 40), paint);
1184
1185 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1186}

◆ TEST_P() [164/450]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundAdvancedBlendAppliesTransformCorrectly   
)

Definition at line 566 of file aiks_blend_unittests.cc.

566 {
567 auto texture = CreateTextureForFixture("airplane.jpg",
568 /*enable_mipmapping=*/true);
569
570 Canvas canvas;
571 canvas.Rotate(Degrees(30));
572 canvas.DrawImage(std::make_shared<Image>(texture), {200, 200},
573 {.color_filter = ColorFilter::MakeBlend(
574 BlendMode::kColorDodge, Color::Orange())});
575
576 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
577}

◆ TEST_P() [165/450]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundBlendSubpassCollapseOptimization   
)

Definition at line 341 of file aiks_blend_unittests.cc.

341 {
342 Canvas canvas;
343
344 canvas.SaveLayer({
345 .color_filter =
346 ColorFilter::MakeBlend(BlendMode::kColorDodge, Color::Red()),
347 });
348
349 canvas.Translate({500, 300, 0});
350 canvas.Rotate(Radians(2 * kPi / 3));
351 canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
352
353 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
354}

◆ TEST_P() [166/450]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundPipelineBlendAppliesTransformCorrectly   
)

Definition at line 553 of file aiks_blend_unittests.cc.

553 {
554 auto texture = CreateTextureForFixture("airplane.jpg",
555 /*enable_mipmapping=*/true);
556
557 Canvas canvas;
558 canvas.Rotate(Degrees(30));
559 canvas.DrawImage(std::make_shared<Image>(texture), {200, 200},
560 {.color_filter = ColorFilter::MakeBlend(BlendMode::kSourceIn,
561 Color::Orange())});
562
563 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
564}

◆ TEST_P() [167/450]

impeller::testing::TEST_P ( AiksTest  ,
FormatSRGB   
)

Definition at line 864 of file aiks_unittests.cc.

864 {
865 PixelFormat pixel_format =
866 GetContext()->GetCapabilities()->GetDefaultColorFormat();
867 EXPECT_TRUE(pixel_format == PixelFormat::kR8G8B8A8UNormInt ||
868 pixel_format == PixelFormat::kB8G8R8A8UNormInt)
869 << "pixel format: " << PixelFormatToString(pixel_format);
870}
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
constexpr const char * PixelFormatToString(PixelFormat format)
Definition: formats.h:140

◆ TEST_P() [168/450]

impeller::testing::TEST_P ( AiksTest  ,
FormatWideGamut   
)

Definition at line 859 of file aiks_unittests.cc.

859 {
860 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
861 PixelFormat::kB10G10R10A10XR);
862}

◆ TEST_P() [169/450]

impeller::testing::TEST_P ( AiksTest  ,
FramebufferAdvancedBlendCoverage   
)

Definition at line 579 of file aiks_blend_unittests.cc.

579 {
580 auto texture = CreateTextureForFixture("airplane.jpg",
581 /*enable_mipmapping=*/true);
582
583 // Draw with an advanced blend that can use FramebufferBlendContents and
584 // verify that the scale transform is correctly applied to the image.
585 Canvas canvas;
586 canvas.DrawPaint({.color = Color::DarkGray()});
587 canvas.Scale(Vector2(0.4, 0.4));
588 canvas.DrawImage(std::make_shared<Image>(texture), {20, 20},
589 {.blend_mode = BlendMode::kMultiply});
590
591 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
592}

◆ TEST_P() [170/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAllocatesCorrectMipCountRenderTarget   
)

Definition at line 1057 of file aiks_blur_unittests.cc.

1057 {
1058 size_t blur_required_mip_count =
1059 GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
1060
1061 Canvas canvas;
1062 canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
1063 canvas.SaveLayer({}, std::nullopt,
1064 ImageFilter::MakeBlur(Sigma(3), Sigma(3),
1066 Entity::TileMode::kClamp));
1067 canvas.Restore();
1068
1069 Picture picture = canvas.EndRecordingAsPicture();
1070 std::shared_ptr<RenderTargetCache> cache =
1071 std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
1072 AiksContext aiks_context(GetContext(), nullptr, cache);
1073 picture.ToImage(aiks_context, {100, 100});
1074
1075 size_t max_mip_count = 0;
1076 for (auto it = cache->GetRenderTargetDataBegin();
1077 it != cache->GetRenderTargetDataEnd(); ++it) {
1078 max_mip_count = std::max(it->config.mip_count, max_mip_count);
1079 }
1080 EXPECT_EQ(max_mip_count, blur_required_mip_count);
1081}
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 to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent cache
Definition: switches.h:191

◆ TEST_P() [171/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAnimatedBackdrop   
)

Definition at line 763 of file aiks_blur_unittests.cc.

763 {
764 // This test is for checking out how stable rendering is when content is
765 // translated underneath a blur. Animating under a blur can cause
766 // *shimmering* to happen as a result of pixel alignment.
767 // See also: https://github.com/flutter/flutter/issues/140193
768 auto boston = std::make_shared<Image>(
769 CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true));
770 ASSERT_TRUE(boston);
771 int64_t count = 0;
772 Scalar sigma = 20.0;
773 Scalar freq = 0.1;
774 Scalar amp = 50.0;
775 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
776 if (AiksTest::ImGuiBegin("Controls", nullptr,
777 ImGuiWindowFlags_AlwaysAutoResize)) {
778 ImGui::SliderFloat("Sigma", &sigma, 0, 200);
779 ImGui::SliderFloat("Frequency", &freq, 0.01, 2.0);
780 ImGui::SliderFloat("Amplitude", &amp, 1, 100);
781 ImGui::End();
782 }
783
784 Canvas canvas;
785 canvas.Scale(GetContentScale());
786 Scalar y = amp * sin(freq * 2.0 * M_PI * count / 60);
787 canvas.DrawImage(boston,
788 Point(1024 / 2 - boston->GetSize().width / 2,
789 (768 / 2 - boston->GetSize().height / 2) + y),
790 {});
791 static PlaygroundPoint point_a(Point(100, 100), 20, Color::Red());
792 static PlaygroundPoint point_b(Point(900, 700), 20, Color::Red());
793 auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
794 canvas.ClipRect(
795 Rect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
796 canvas.ClipRect(Rect::MakeLTRB(100, 100, 900, 700));
797 canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
798 ImageFilter::MakeBlur(Sigma(sigma), Sigma(sigma),
800 Entity::TileMode::kClamp));
801 count += 1;
802 return canvas.EndRecordingAsPicture();
803 };
804 ASSERT_TRUE(OpenPlaygroundHere(callback));
805}
#define M_PI
virtual void SaveLayer(const Paint &paint, std::optional< Rect > bounds=std::nullopt, const std::shared_ptr< ImageFilter > &backdrop_filter=nullptr, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown, uint32_t total_content_depth=kMaxDepth, bool can_distribute_opacity=false)
Definition: canvas.cc:842
void DrawImage(const std::shared_ptr< Image > &image, Point offset, const Paint &paint, SamplerDescriptor sampler={})
Definition: canvas.cc:752
void ClipRect(const Rect &rect, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition: canvas.cc:599

◆ TEST_P() [172/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAtPeripheryHorizontal   
)

Definition at line 479 of file aiks_blur_unittests.cc.

479 {
480 Canvas canvas;
481
482 canvas.Scale(GetContentScale());
483 std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
484 canvas.DrawImageRect(
485 std::make_shared<Image>(boston),
486 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
487 Rect::MakeLTRB(0, 0, GetWindowSize().width, 100), Paint{});
488 canvas.DrawRRect(Rect::MakeLTRB(0, 110, GetWindowSize().width, 210),
489 Size(10, 10), Paint{.color = Color::Magenta()});
490 canvas.ClipRect(Rect::MakeLTRB(0, 50, GetWindowSize().width, 150));
491 canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
492 ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
494 Entity::TileMode::kClamp));
495 canvas.Restore();
496 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
497}
int32_t width

◆ TEST_P() [173/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAtPeripheryVertical   
)

Definition at line 461 of file aiks_blur_unittests.cc.

461 {
462 Canvas canvas;
463
464 canvas.Scale(GetContentScale());
465 canvas.DrawRRect(Rect::MakeLTRB(0, 0, GetWindowSize().width, 100),
466 Size(10, 10), Paint{.color = Color::LimeGreen()});
467 canvas.DrawRRect(Rect::MakeLTRB(0, 110, GetWindowSize().width, 210),
468 Size(10, 10), Paint{.color = Color::Magenta()});
469 canvas.ClipRect(Rect::MakeLTRB(100, 0, 200, GetWindowSize().height));
470 canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
471 ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
473 Entity::TileMode::kClamp));
474 canvas.Restore();
475
476 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
477}
int32_t height

◆ TEST_P() [174/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurBackdropTinyMipMap   
)

Definition at line 737 of file aiks_blur_unittests.cc.

737 {
738 for (int32_t i = 0; i < 5; ++i) {
739 Canvas canvas;
740 ISize clip_size = ISize(i, i);
741 canvas.ClipRect(
742 Rect::MakeXYWH(400, 400, clip_size.width, clip_size.height));
743 canvas.DrawCircle(
744 {400, 400}, 200,
745 {
746 .color = Color::Green(),
747 .image_filter = ImageFilter::MakeBlur(
749 Entity::TileMode::kDecal),
750 });
751 canvas.Restore();
752
753 Picture picture = canvas.EndRecordingAsPicture();
754 std::shared_ptr<RenderTargetCache> cache =
755 std::make_shared<RenderTargetCache>(
756 GetContext()->GetResourceAllocator());
757 AiksContext aiks_context(GetContext(), nullptr, cache);
758 std::shared_ptr<Image> image = picture.ToImage(aiks_context, {1024, 768});
759 EXPECT_TRUE(image) << " clip rect " << i;
760 }
761}

◆ TEST_P() [175/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurMipMapImageFilter   
)

Definition at line 1122 of file aiks_blur_unittests.cc.

1122 {
1123 size_t blur_required_mip_count =
1124 GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
1125 fml::testing::LogCapture log_capture;
1126 Canvas canvas;
1127 canvas.SaveLayer(
1128 {.image_filter = ImageFilter::MakeBlur(Sigma(30), Sigma(30),
1130 Entity::TileMode::kClamp)});
1131 canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()});
1132
1133 Picture picture = canvas.EndRecordingAsPicture();
1134 std::shared_ptr<RenderTargetCache> cache =
1135 std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
1136 AiksContext aiks_context(GetContext(), nullptr, cache);
1137 picture.ToImage(aiks_context, {1024, 768});
1138
1139 size_t max_mip_count = 0;
1140 for (auto it = cache->GetRenderTargetDataBegin();
1141 it != cache->GetRenderTargetDataEnd(); ++it) {
1142 max_mip_count = std::max(it->config.mip_count, max_mip_count);
1143 }
1144 EXPECT_EQ(max_mip_count, blur_required_mip_count);
1145 // The log is FML_DLOG, so only check in debug builds.
1146#ifndef NDEBUG
1147 if (GetParam() != PlaygroundBackend::kOpenGLES) {
1148 EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1149 std::string::npos);
1150 } else {
1151 EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1152 std::string::npos);
1153 }
1154#endif
1155}
std::string str() const
Definition: logging.cc:122

◆ TEST_P() [176/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurMipMapNestedLayer   
)

Definition at line 1083 of file aiks_blur_unittests.cc.

1083 {
1084 fml::testing::LogCapture log_capture;
1085 size_t blur_required_mip_count =
1086 GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
1087
1088 Canvas canvas;
1089 canvas.DrawPaint({.color = Color::Wheat()});
1090 canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
1091 canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
1092 canvas.SaveLayer({}, std::nullopt,
1093 ImageFilter::MakeBlur(Sigma(30), Sigma(30),
1095 Entity::TileMode::kClamp));
1096 canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()});
1097
1098 Picture picture = canvas.EndRecordingAsPicture();
1099 std::shared_ptr<RenderTargetCache> cache =
1100 std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
1101 AiksContext aiks_context(GetContext(), nullptr, cache);
1102 picture.ToImage(aiks_context, {100, 100});
1103
1104 size_t max_mip_count = 0;
1105 for (auto it = cache->GetRenderTargetDataBegin();
1106 it != cache->GetRenderTargetDataEnd(); ++it) {
1107 max_mip_count = std::max(it->config.mip_count, max_mip_count);
1108 }
1109 EXPECT_EQ(max_mip_count, blur_required_mip_count);
1110 // The log is FML_DLOG, so only check in debug builds.
1111#ifndef NDEBUG
1112 if (GetParam() != PlaygroundBackend::kOpenGLES) {
1113 EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1114 std::string::npos);
1115 } else {
1116 EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1117 std::string::npos);
1118 }
1119#endif
1120}

◆ TEST_P() [177/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurMipMapSolidColor   
)

Definition at line 1157 of file aiks_blur_unittests.cc.

1157 {
1158 size_t blur_required_mip_count =
1159 GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
1160 fml::testing::LogCapture log_capture;
1161 Canvas canvas;
1162 canvas.DrawPath(PathBuilder{}
1163 .MoveTo({100, 100})
1164 .LineTo({200, 100})
1165 .LineTo({150, 200})
1166 .LineTo({50, 200})
1167 .Close()
1168 .TakePath(),
1169 {.color = Color::Chartreuse(),
1170 .image_filter = ImageFilter::MakeBlur(
1171 Sigma(30), Sigma(30), FilterContents::BlurStyle::kNormal,
1172 Entity::TileMode::kClamp)});
1173
1174 Picture picture = canvas.EndRecordingAsPicture();
1175 std::shared_ptr<RenderTargetCache> cache =
1176 std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
1177 AiksContext aiks_context(GetContext(), nullptr, cache);
1178 picture.ToImage(aiks_context, {1024, 768});
1179
1180 size_t max_mip_count = 0;
1181 for (auto it = cache->GetRenderTargetDataBegin();
1182 it != cache->GetRenderTargetDataEnd(); ++it) {
1183 max_mip_count = std::max(it->config.mip_count, max_mip_count);
1184 }
1185 EXPECT_EQ(max_mip_count, blur_required_mip_count);
1186 // The log is FML_DLOG, so only check in debug builds.
1187#ifndef NDEBUG
1188 if (GetParam() != PlaygroundBackend::kOpenGLES) {
1189 EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1190 std::string::npos);
1191 } else {
1192 EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1193 std::string::npos);
1194 }
1195#endif
1196}

◆ TEST_P() [178/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurOneDimension   
)

Definition at line 551 of file aiks_blur_unittests.cc.

551 {
552 Canvas canvas;
553
554 canvas.Scale(GetContentScale());
555 canvas.Scale({0.5, 0.5, 1.0});
556 std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
557 canvas.DrawImage(std::make_shared<Image>(boston), Point(100, 100), Paint{});
558 canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
559 ImageFilter::MakeBlur(Sigma(50.0), Sigma(0.0),
561 Entity::TileMode::kClamp));
562 canvas.Restore();
563 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
564}

◆ TEST_P() [179/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedAndClipped   
)

Definition at line 570 of file aiks_blur_unittests.cc.

570 {
571 Canvas canvas;
572 std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
573 Rect bounds =
574 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
575 Vector2 image_center = Vector2(bounds.GetSize() / 2);
576 Paint paint = {.image_filter =
577 ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
579 Entity::TileMode::kDecal)};
580 Vector2 clip_size = {150, 75};
581 Vector2 center = Vector2(1024, 768) / 2;
582 canvas.Scale(GetContentScale());
583 canvas.ClipRect(
584 Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size));
585 canvas.Translate({center.x, center.y, 0});
586 canvas.Scale({0.6, 0.6, 1});
587 canvas.Rotate(Degrees(25));
588
589 canvas.DrawImageRect(std::make_shared<Image>(boston), /*source=*/bounds,
590 /*dest=*/bounds.Shift(-image_center), paint);
591
592 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
593}

◆ TEST_P() [180/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedAndClippedInteractive   
)

Definition at line 619 of file aiks_blur_unittests.cc.

619 {
620 std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
621
622 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
623 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
624 const Entity::TileMode tile_modes[] = {
625 Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
626 Entity::TileMode::kMirror, Entity::TileMode::kDecal};
627
628 static float rotation = 0;
629 static float scale = 0.6;
630 static int selected_tile_mode = 3;
631
632 if (AiksTest::ImGuiBegin("Controls", nullptr,
633 ImGuiWindowFlags_AlwaysAutoResize)) {
634 ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
635 ImGui::SliderFloat("Scale", &scale, 0, 2.0);
636 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
637 sizeof(tile_mode_names) / sizeof(char*));
638 ImGui::End();
639 }
640
641 Canvas canvas;
642 Rect bounds =
643 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
644 Vector2 image_center = Vector2(bounds.GetSize() / 2);
645 Paint paint = {.image_filter =
646 ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
648 tile_modes[selected_tile_mode])};
649 static PlaygroundPoint point_a(Point(362, 309), 20, Color::Red());
650 static PlaygroundPoint point_b(Point(662, 459), 20, Color::Red());
651 auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
652 Vector2 center = Vector2(1024, 768) / 2;
653 canvas.Scale(GetContentScale());
654 canvas.ClipRect(
655 Rect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
656 canvas.Translate({center.x, center.y, 0});
657 canvas.Scale({scale, scale, 1});
658 canvas.Rotate(Degrees(rotation));
659
660 canvas.DrawImageRect(std::make_shared<Image>(boston), /*source=*/bounds,
661 /*dest=*/bounds.Shift(-image_center), paint);
662 return canvas.EndRecordingAsPicture();
663 };
664
665 ASSERT_TRUE(OpenPlaygroundHere(callback));
666}
constexpr TPoint Rotate(const Radians &angle) const
Definition: point.h:226

◆ TEST_P() [181/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedNonUniform   
)

Definition at line 668 of file aiks_blur_unittests.cc.

668 {
669 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
670 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
671 const Entity::TileMode tile_modes[] = {
672 Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
673 Entity::TileMode::kMirror, Entity::TileMode::kDecal};
674
675 static float rotation = 45;
676 static float scale = 0.6;
677 static int selected_tile_mode = 3;
678
679 if (AiksTest::ImGuiBegin("Controls", nullptr,
680 ImGuiWindowFlags_AlwaysAutoResize)) {
681 ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
682 ImGui::SliderFloat("Scale", &scale, 0, 2.0);
683 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
684 sizeof(tile_mode_names) / sizeof(char*));
685 ImGui::End();
686 }
687
688 Canvas canvas;
689 Paint paint = {.color = Color::Green(),
690 .image_filter =
691 ImageFilter::MakeBlur(Sigma(50.0), Sigma(0.0),
693 tile_modes[selected_tile_mode])};
694 Vector2 center = Vector2(1024, 768) / 2;
695 canvas.Scale(GetContentScale());
696 canvas.Translate({center.x, center.y, 0});
697 canvas.Scale({scale, scale, 1});
698 canvas.Rotate(Degrees(rotation));
699
700 canvas.DrawRRect(Rect::MakeXYWH(-100, -100, 200, 200), Size(10, 10), paint);
701 return canvas.EndRecordingAsPicture();
702 };
703
704 ASSERT_TRUE(OpenPlaygroundHere(callback));
705}

◆ TEST_P() [182/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurScaledAndClipped   
)

Definition at line 595 of file aiks_blur_unittests.cc.

595 {
596 Canvas canvas;
597 std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
598 Rect bounds =
599 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
600 Vector2 image_center = Vector2(bounds.GetSize() / 2);
601 Paint paint = {.image_filter =
602 ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
604 Entity::TileMode::kDecal)};
605 Vector2 clip_size = {150, 75};
606 Vector2 center = Vector2(1024, 768) / 2;
607 canvas.Scale(GetContentScale());
608 canvas.ClipRect(
609 Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size));
610 canvas.Translate({center.x, center.y, 0});
611 canvas.Scale({0.6, 0.6, 1});
612
613 canvas.DrawImageRect(std::make_shared<Image>(boston), /*source=*/bounds,
614 /*dest=*/bounds.Shift(-image_center), paint);
615
616 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
617}

◆ TEST_P() [183/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurSetsMipCountOnPass   
)

Definition at line 1044 of file aiks_blur_unittests.cc.

1044 {
1045 Canvas canvas;
1046 canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
1047 canvas.SaveLayer({}, std::nullopt,
1048 ImageFilter::MakeBlur(Sigma(3), Sigma(3),
1050 Entity::TileMode::kClamp));
1051 canvas.Restore();
1052
1053 Picture picture = canvas.EndRecordingAsPicture();
1054 EXPECT_EQ(4, picture.pass->GetRequiredMipCount());
1055}

◆ TEST_P() [184/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurSolidColorTinyMipMap   
)

Definition at line 710 of file aiks_blur_unittests.cc.

710 {
711 for (int32_t i = 1; i < 5; ++i) {
712 Canvas canvas;
713 Scalar fi = i;
714 canvas.DrawPath(
716 .MoveTo({100, 100})
717 .LineTo({100.f + fi, 100.f + fi})
718 .TakePath(),
719 {.color = Color::Chartreuse(),
720 .image_filter = ImageFilter::MakeBlur(
721 Sigma(0.1), Sigma(0.1), FilterContents::BlurStyle::kNormal,
722 Entity::TileMode::kClamp)});
723
724 Picture picture = canvas.EndRecordingAsPicture();
725 std::shared_ptr<RenderTargetCache> cache =
726 std::make_shared<RenderTargetCache>(
727 GetContext()->GetResourceAllocator());
728 AiksContext aiks_context(GetContext(), nullptr, cache);
729 std::shared_ptr<Image> image = picture.ToImage(aiks_context, {1024, 768});
730 EXPECT_TRUE(image) << " length " << i;
731 }
732}

◆ TEST_P() [185/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleInner   
)

Definition at line 906 of file aiks_blur_unittests.cc.

906 {
907 Canvas canvas;
908 canvas.Scale(GetContentScale());
909
910 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
911
912 Paint paint;
913 paint.color = Color::Green();
914 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
915 .style = FilterContents::BlurStyle::kInner,
916 .sigma = Sigma(30),
917 };
918 canvas.DrawPath(PathBuilder()
919 .MoveTo({200, 200})
920 .LineTo({300, 400})
921 .LineTo({100, 400})
922 .Close()
923 .TakePath(),
924 paint);
925
926 // Draw another thing to make sure the clip area is reset.
927 Paint red;
928 red.color = Color::Red();
929 canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
930
931 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
932}

◆ TEST_P() [186/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleInnerGradient   
)

Definition at line 807 of file aiks_blur_unittests.cc.

807 {
808 Canvas canvas;
809 canvas.Scale(GetContentScale());
810
811 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
812
813 std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
814 Color{0.7568, 0.2627, 0.2118, 1.0}};
815 std::vector<Scalar> stops = {0.0, 1.0};
816
817 Paint paint;
818 paint.color_source = ColorSource::MakeLinearGradient(
819 {0, 0}, {200, 200}, std::move(colors), std::move(stops),
820 Entity::TileMode::kMirror, {});
821 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
822 .style = FilterContents::BlurStyle::kInner,
823 .sigma = Sigma(30),
824 };
825 canvas.DrawPath(PathBuilder()
826 .MoveTo({200, 200})
827 .LineTo({300, 400})
828 .LineTo({100, 400})
829 .Close()
830 .TakePath(),
831 paint);
832
833 // Draw another thing to make sure the clip area is reset.
834 Paint red;
835 red.color = Color::Red();
836 canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
837 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
838}

◆ TEST_P() [187/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleOuter   
)

Definition at line 934 of file aiks_blur_unittests.cc.

934 {
935 Canvas canvas;
936 canvas.Scale(GetContentScale());
937
938 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
939
940 Paint paint;
941 paint.color = Color::Green();
942 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
943 .style = FilterContents::BlurStyle::kOuter,
944 .sigma = Sigma(30),
945 };
946 canvas.DrawPath(PathBuilder()
947 .MoveTo({200, 200})
948 .LineTo({300, 400})
949 .LineTo({100, 400})
950 .Close()
951 .TakePath(),
952 paint);
953
954 // Draw another thing to make sure the clip area is reset.
955 Paint red;
956 red.color = Color::Red();
957 canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
958
959 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
960}

◆ TEST_P() [188/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleOuterGradient   
)

Definition at line 873 of file aiks_blur_unittests.cc.

873 {
874 Canvas canvas;
875 canvas.Scale(GetContentScale());
876
877 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
878
879 std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
880 Color{0.7568, 0.2627, 0.2118, 1.0}};
881 std::vector<Scalar> stops = {0.0, 1.0};
882
883 Paint paint;
884 paint.color_source = ColorSource::MakeLinearGradient(
885 {0, 0}, {200, 200}, std::move(colors), std::move(stops),
886 Entity::TileMode::kMirror, {});
887 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
888 .style = FilterContents::BlurStyle::kOuter,
889 .sigma = Sigma(30),
890 };
891 canvas.DrawPath(PathBuilder()
892 .MoveTo({200, 200})
893 .LineTo({300, 400})
894 .LineTo({100, 400})
895 .Close()
896 .TakePath(),
897 paint);
898
899 // Draw another thing to make sure the clip area is reset.
900 Paint red;
901 red.color = Color::Red();
902 canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
903 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
904}

◆ TEST_P() [189/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleSolid   
)

Definition at line 962 of file aiks_blur_unittests.cc.

962 {
963 Canvas canvas;
964 canvas.Scale(GetContentScale());
965
966 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
967
968 Paint paint;
969 paint.color = Color::Green();
970 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
972 .sigma = Sigma(30),
973 };
974 canvas.DrawPath(PathBuilder()
975 .MoveTo({200, 200})
976 .LineTo({300, 400})
977 .LineTo({100, 400})
978 .Close()
979 .TakePath(),
980 paint);
981
982 // Draw another thing to make sure the clip area is reset.
983 Paint red;
984 red.color = Color::Red();
985 canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
986
987 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
988}

◆ TEST_P() [190/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleSolidGradient   
)

Definition at line 840 of file aiks_blur_unittests.cc.

840 {
841 Canvas canvas;
842 canvas.Scale(GetContentScale());
843
844 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
845
846 std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
847 Color{0.7568, 0.2627, 0.2118, 1.0}};
848 std::vector<Scalar> stops = {0.0, 1.0};
849
850 Paint paint;
851 paint.color_source = ColorSource::MakeLinearGradient(
852 {0, 0}, {200, 200}, std::move(colors), std::move(stops),
853 Entity::TileMode::kMirror, {});
854 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
856 .sigma = Sigma(30),
857 };
858 canvas.DrawPath(PathBuilder()
859 .MoveTo({200, 200})
860 .LineTo({300, 400})
861 .LineTo({100, 400})
862 .Close()
863 .TakePath(),
864 paint);
865
866 // Draw another thing to make sure the clip area is reset.
867 Paint red;
868 red.color = Color::Red();
869 canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
870 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
871}

◆ TEST_P() [191/450]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurWithoutDecalSupport   
)

Definition at line 503 of file aiks_blur_unittests.cc.

503 {
504 if (GetParam() != PlaygroundBackend::kMetal) {
505 GTEST_SKIP_(
506 "This backend doesn't yet support setting device capabilities.");
507 }
508 if (!WillRenderSomething()) {
509 // Sometimes these tests are run without playgrounds enabled which is
510 // pointless for this test since we are asserting that
511 // `SupportsDecalSamplerAddressMode` is called.
512 GTEST_SKIP_("This test requires playgrounds.");
513 }
514
515 std::shared_ptr<const Capabilities> old_capabilities =
516 GetContext()->GetCapabilities();
517 auto mock_capabilities = std::make_shared<MockCapabilities>();
518 EXPECT_CALL(*mock_capabilities, SupportsDecalSamplerAddressMode())
519 .Times(::testing::AtLeast(1))
520 .WillRepeatedly(::testing::Return(false));
521 FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
522 FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
523 FLT_FORWARD(mock_capabilities, old_capabilities,
524 GetDefaultDepthStencilFormat);
525 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
526 FLT_FORWARD(mock_capabilities, old_capabilities,
527 SupportsImplicitResolvingMSAA);
528 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsReadFromResolve);
529 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsFramebufferFetch);
530 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsSSBO);
531 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
532 FLT_FORWARD(mock_capabilities, old_capabilities,
533 SupportsTextureToTextureBlits);
534 FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultGlyphAtlasFormat);
535 ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());
536
537 auto texture = std::make_shared<Image>(CreateTextureForFixture("boston.jpg"));
538 Canvas canvas;
539 canvas.Scale(GetContentScale() * 0.5);
540 canvas.DrawPaint({.color = Color::Black()});
541 canvas.DrawImage(
542 texture, Point(200, 200),
543 {
544 .image_filter = ImageFilter::MakeBlur(
545 Sigma(20.0), Sigma(20.0), FilterContents::BlurStyle::kNormal,
546 Entity::TileMode::kDecal),
547 });
548 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
549}
static bool ok(int result)
#define FLT_FORWARD(mock, real, method)
@ kMetal
Definition: embedder.h:85

◆ TEST_P() [192/450]

impeller::testing::TEST_P ( AiksTest  ,
GradientStrokesRenderCorrectly   
)

Definition at line 624 of file aiks_dl_gradient_unittests.cc.

624 {
625 // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
626 auto callback = [&]() -> sk_sp<DisplayList> {
627 static float scale = 3;
628 static bool add_circle_clip = true;
629 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
630 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
631 DlTileMode::kMirror, DlTileMode::kDecal};
632 static int selected_tile_mode = 0;
633 static float alpha = 1;
634
635 if (AiksTest::ImGuiBegin("Controls", nullptr,
636 ImGuiWindowFlags_AlwaysAutoResize)) {
637 ImGui::SliderFloat("Scale", &scale, 0, 6);
638 ImGui::Checkbox("Circle clip", &add_circle_clip);
639 ImGui::SliderFloat("Alpha", &alpha, 0, 1);
640 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
641 sizeof(tile_mode_names) / sizeof(char*));
642 ImGui::End();
643 }
644
646 builder.Scale(GetContentScale().x, GetContentScale().y);
648 paint.setColor(DlColor::kWhite());
649 builder.DrawPaint(paint);
650
651 paint.setDrawStyle(DlDrawStyle::kStroke);
652 paint.setColor(DlColor::kWhite().withAlpha(alpha * 255));
653 paint.setStrokeWidth(10);
654 auto tile_mode = tile_modes[selected_tile_mode];
655
656 std::vector<DlColor> colors = {
657 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
658 DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
659 std::vector<Scalar> stops = {0.0, 1.0};
660
661 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {50, 50},
662 stops.size(), colors.data(),
663 stops.data(), tile_mode));
664
665 SkPath path;
666 path.moveTo(20, 20);
667 path.quadTo({60, 20}, {60, 60});
668 path.close();
669 path.moveTo(60, 20);
670 path.quadTo({60, 60}, {20, 60});
671
672 builder.Scale(scale, scale);
673
674 if (add_circle_clip) {
675 static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
676 Color::Red());
677 static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
678 Color::Red());
679 auto [handle_a, handle_b] =
680 DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
681
682 SkMatrix screen_to_canvas;
683 if (!builder.GetTransform().invert(&screen_to_canvas)) {
684 return nullptr;
685 }
686 Matrix ip_matrix = ToMatrix(screen_to_canvas);
687 Point point_a = ip_matrix * handle_a * GetContentScale();
688 Point point_b = ip_matrix * handle_b * GetContentScale();
689
690 Point middle = (point_a + point_b) / 2;
691 auto radius = point_a.GetDistance(middle);
692 SkPath circle;
693 circle.addCircle(middle.x, middle.y, radius);
694 builder.ClipPath(circle);
695 }
696
697 for (auto join :
698 {DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
699 paint.setStrokeJoin(join);
700 for (auto cap :
701 {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
702 paint.setStrokeCap(cap);
703 builder.DrawPath(path, paint);
704 builder.Translate(80, 0);
705 }
706 builder.Translate(-240, 60);
707 }
708
709 return builder.Build();
710 };
711
712 ASSERT_TRUE(OpenPlaygroundHere(callback));
713}
static Matrix ToMatrix(const SkMatrix &m)
static SkString join(const CommandLineFlags::StringArray &)
Definition: skpbench.cpp:741

◆ TEST_P() [193/450]

impeller::testing::TEST_P ( AiksTest  ,
GuassianBlurUpdatesMipmapContents   
)

Definition at line 1016 of file aiks_blur_unittests.cc.

1016 {
1017 // This makes sure if mip maps are recycled across invocations of blurs the
1018 // contents get updated each frame correctly. If they aren't updated the color
1019 // inside the blur and outside the blur will be different.
1020 //
1021 // If there is some change to render target caching this could display a false
1022 // positive in the future. Also, if the LOD that is rendered is 1 it could
1023 // present a false positive.
1024 int32_t count = 0;
1025 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1026 Canvas canvas;
1027 if (count++ == 0) {
1028 canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
1029 } else {
1030 canvas.DrawCircle({100, 100}, 50, {.color = Color::Chartreuse()});
1031 }
1032 canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), {20, 20});
1033 canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
1034 ImageFilter::MakeBlur(Sigma(30.0), Sigma(30.0),
1036 Entity::TileMode::kClamp));
1037 canvas.Restore();
1038 return canvas.EndRecordingAsPicture();
1039 };
1040
1041 ASSERT_TRUE(OpenPlaygroundHere(callback));
1042}

◆ TEST_P() [194/450]

impeller::testing::TEST_P ( AiksTest  ,
ImageColorSourceEffectTransform   
)

Definition at line 2573 of file aiks_unittests.cc.

2573 {
2574 // Compare with https://fiddle.skia.org/c/6cdc5aefb291fda3833b806ca347a885
2575
2576 Canvas canvas;
2577 auto texture = CreateTextureForFixture("monkey.png");
2578
2579 canvas.DrawPaint({.color = Color::White()});
2580
2581 // Translation
2582 {
2583 Paint paint;
2584 paint.color_source = ColorSource::MakeImage(
2585 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
2586 Matrix::MakeTranslation({50, 50}));
2587 canvas.DrawRect(Rect::MakeLTRB(0, 0, 100, 100), paint);
2588 }
2589
2590 // Rotation/skew
2591 {
2592 canvas.Save();
2593 canvas.Rotate(Degrees(45));
2594 Paint paint;
2595 paint.color_source = ColorSource::MakeImage(
2596 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
2597 Matrix(1, -1, 0, 0, //
2598 1, 1, 0, 0, //
2599 0, 0, 1, 0, //
2600 0, 0, 0, 1) //
2601 );
2602 canvas.DrawRect(Rect::MakeLTRB(100, 0, 200, 100), paint);
2603 canvas.Restore();
2604 }
2605
2606 // Scale
2607 {
2608 canvas.Translate(Vector2(100, 0));
2609 canvas.Scale(Vector2(100, 100));
2610 Paint paint;
2611 paint.color_source = ColorSource::MakeImage(
2612 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
2613 Matrix::MakeScale(Vector2(0.005, 0.005)));
2614 canvas.DrawRect(Rect::MakeLTRB(0, 0, 1, 1), paint);
2615 }
2616
2617 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2618}

◆ TEST_P() [195/450]

impeller::testing::TEST_P ( AiksTest  ,
ImageFilteredSaveLayerWithUnboundedContents   
)

Definition at line 1872 of file aiks_unittests.cc.

1872 {
1873 Canvas canvas;
1874 canvas.Scale(GetContentScale());
1875
1876 auto test = [&canvas](const std::shared_ptr<ImageFilter>& filter) {
1877 auto DrawLine = [&canvas](const Point& p0, const Point& p1,
1878 const Paint& p) {
1879 auto path = PathBuilder{}
1880 .AddLine(p0, p1)
1881 .SetConvexity(Convexity::kConvex)
1882 .TakePath();
1883 Paint paint = p;
1884 paint.style = Paint::Style::kStroke;
1885 canvas.DrawPath(path, paint);
1886 };
1887 // Registration marks for the edge of the SaveLayer
1888 DrawLine(Point(75, 100), Point(225, 100), {.color = Color::White()});
1889 DrawLine(Point(75, 200), Point(225, 200), {.color = Color::White()});
1890 DrawLine(Point(100, 75), Point(100, 225), {.color = Color::White()});
1891 DrawLine(Point(200, 75), Point(200, 225), {.color = Color::White()});
1892
1893 canvas.SaveLayer({.image_filter = filter},
1894 Rect::MakeLTRB(100, 100, 200, 200));
1895 {
1896 // DrawPaint to verify correct behavior when the contents are unbounded.
1897 canvas.DrawPaint({.color = Color::Yellow()});
1898
1899 // Contrasting rectangle to see interior blurring
1900 canvas.DrawRect(Rect::MakeLTRB(125, 125, 175, 175),
1901 {.color = Color::Blue()});
1902 }
1903 canvas.Restore();
1904 };
1905
1906 test(ImageFilter::MakeBlur(Sigma{10.0}, Sigma{10.0},
1908 Entity::TileMode::kDecal));
1909
1910 canvas.Translate({200.0, 0.0});
1911
1912 test(ImageFilter::MakeDilate(Radius{10.0}, Radius{10.0}));
1913
1914 canvas.Translate({200.0, 0.0});
1915
1916 test(ImageFilter::MakeErode(Radius{10.0}, Radius{10.0}));
1917
1918 canvas.Translate({-400.0, 200.0});
1919
1920 auto rotate_filter =
1921 ImageFilter::MakeMatrix(Matrix::MakeTranslation({150, 150}) *
1922 Matrix::MakeRotationZ(Degrees{10.0}) *
1923 Matrix::MakeTranslation({-150, -150}),
1924 SamplerDescriptor{});
1925 test(rotate_filter);
1926
1927 canvas.Translate({200.0, 0.0});
1928
1929 auto rgb_swap_filter = ImageFilter::MakeFromColorFilter(
1930 *ColorFilter::MakeMatrix({.array = {
1931 0, 1, 0, 0, 0, //
1932 0, 0, 1, 0, 0, //
1933 1, 0, 0, 0, 0, //
1934 0, 0, 0, 1, 0 //
1935 }}));
1936 test(rgb_swap_filter);
1937
1938 canvas.Translate({200.0, 0.0});
1939
1940 test(ImageFilter::MakeCompose(*rotate_filter, *rgb_swap_filter));
1941
1942 canvas.Translate({-400.0, 200.0});
1943
1944 test(ImageFilter::MakeLocalMatrix(Matrix::MakeTranslation({25.0, 25.0}),
1945 *rotate_filter));
1946
1947 canvas.Translate({200.0, 0.0});
1948
1949 test(ImageFilter::MakeLocalMatrix(Matrix::MakeTranslation({25.0, 25.0}),
1950 *rgb_swap_filter));
1951
1952 canvas.Translate({200.0, 0.0});
1953
1954 test(ImageFilter::MakeLocalMatrix(
1955 Matrix::MakeTranslation({25.0, 25.0}),
1956 *ImageFilter::MakeCompose(*rotate_filter, *rgb_swap_filter)));
1957
1958 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1959}
PathBuilder & SetConvexity(Convexity value)
Definition: path_builder.cc:85

◆ TEST_P() [196/450]

impeller::testing::TEST_P ( AiksTest  ,
ImageFilteredUnboundedSaveLayerWithUnboundedContents   
)

Definition at line 1961 of file aiks_unittests.cc.

1961 {
1962 Canvas canvas;
1963 canvas.Scale(GetContentScale());
1964
1965 auto blur_filter = ImageFilter::MakeBlur(Sigma{10.0}, Sigma{10.0},
1967 Entity::TileMode::kDecal);
1968
1969 canvas.SaveLayer({.image_filter = blur_filter}, std::nullopt);
1970 {
1971 // DrawPaint to verify correct behavior when the contents are unbounded.
1972 canvas.DrawPaint({.color = Color::Yellow()});
1973
1974 // Contrasting rectangle to see interior blurring
1975 canvas.DrawRect(Rect::MakeLTRB(125, 125, 175, 175),
1976 {.color = Color::Blue()});
1977 }
1978 canvas.Restore();
1979
1980 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1981}

◆ TEST_P() [197/450]

impeller::testing::TEST_P ( AiksTest  ,
LinearToSrgbFilterSubpassCollapseOptimization   
)

Definition at line 1782 of file aiks_unittests.cc.

1782 {
1783 Canvas canvas;
1784
1785 canvas.SaveLayer({
1786 .color_filter = ColorFilter::MakeLinearToSrgb(),
1787 });
1788
1789 canvas.Translate({500, 300, 0});
1790 canvas.Rotate(Radians(2 * kPi / 3));
1791 canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
1792
1793 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1794}

◆ TEST_P() [198/450]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurDoesntStretchContents   
)

Definition at line 1198 of file aiks_blur_unittests.cc.

1198 {
1199 Scalar sigma = 70;
1200 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1201 if (AiksTest::ImGuiBegin("Controls", nullptr,
1202 ImGuiWindowFlags_AlwaysAutoResize)) {
1203 ImGui::SliderFloat("Sigma", &sigma, 0, 500);
1204 ImGui::End();
1205 }
1206 Canvas canvas;
1207 canvas.Scale(GetContentScale());
1208 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
1209
1210 std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1211 ColorSource image_source = ColorSource::MakeImage(
1212 boston, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, {});
1213
1214 canvas.Transform(Matrix::MakeTranslation({100, 100, 0}) *
1215 Matrix::MakeScale({0.5, 0.5, 1.0}));
1216 Paint paint = {
1217 .color_source = image_source,
1218 .mask_blur_descriptor =
1219 Paint::MaskBlurDescriptor{
1221 .sigma = Sigma(sigma),
1222 },
1223 };
1224 canvas.DrawRect(
1225 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
1226 paint);
1227
1228 return canvas.EndRecordingAsPicture();
1229 };
1230 ASSERT_TRUE(OpenPlaygroundHere(callback));
1231}
void Transform(const Matrix &transform)
Definition: canvas.cc:294

◆ TEST_P() [199/450]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurTexture   
)

Definition at line 990 of file aiks_blur_unittests.cc.

990 {
991 Scalar sigma = 30;
992 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
993 if (AiksTest::ImGuiBegin("Controls", nullptr,
994 ImGuiWindowFlags_AlwaysAutoResize)) {
995 ImGui::SliderFloat("Sigma", &sigma, 0, 500);
996 ImGui::End();
997 }
998 Canvas canvas;
999 canvas.Scale(GetContentScale());
1000 Paint paint;
1001 paint.color = Color::Green();
1002 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1004 .sigma = Sigma(sigma),
1005 };
1006 std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1007 canvas.DrawImage(std::make_shared<Image>(boston), {200, 200}, paint);
1008 Paint red;
1009 red.color = Color::Red();
1010 canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
1011 return canvas.EndRecordingAsPicture();
1012 };
1013 ASSERT_TRUE(OpenPlaygroundHere(callback));
1014}

◆ TEST_P() [200/450]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurWithZeroSigmaIsSkipped   
)

Definition at line 277 of file aiks_blur_unittests.cc.

277 {
278 Canvas canvas;
279
280 Paint paint = {
281 .color = Color::Blue(),
282 .mask_blur_descriptor =
285 .sigma = Sigma(0),
286 },
287 };
288
289 canvas.DrawCircle({300, 300}, 200, paint);
290 canvas.DrawRect(Rect::MakeLTRB(100, 300, 500, 600), paint);
291
292 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
293}

◆ TEST_P() [201/450]

impeller::testing::TEST_P ( AiksTest  ,
MatrixBackdropFilter   
)

Definition at line 2328 of file aiks_unittests.cc.

2328 {
2329 Canvas canvas;
2330 canvas.DrawPaint({.color = Color::Black()});
2331 canvas.SaveLayer({}, std::nullopt);
2332 {
2333 canvas.DrawCircle(Point(200, 200), 100,
2334 {.color = Color::Green().WithAlpha(0.5),
2335 .blend_mode = BlendMode::kPlus});
2336 // Should render a second circle, centered on the bottom-right-most edge of
2337 // the circle.
2338 canvas.SaveLayer(
2339 {}, std::nullopt,
2341 Matrix::MakeTranslation(Vector2(1, 1) * (100 + 100 * k1OverSqrt2)) *
2342 Matrix::MakeScale(Vector2(1, 1) * 0.5) *
2343 Matrix::MakeTranslation(Vector2(-100, -100)),
2344 SamplerDescriptor{}));
2345 canvas.Restore();
2346 }
2347 canvas.Restore();
2348
2349 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2350}

◆ TEST_P() [202/450]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen   
)

Definition at line 2492 of file aiks_unittests.cc.

2493 {
2494 Canvas canvas;
2495 canvas.Scale(GetContentScale());
2496 canvas.Translate({100, 100});
2497 // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
2498 // +300 translation applied by a SaveLayer image filter.
2499 canvas.SaveLayer({
2500 .image_filter = std::make_shared<MatrixImageFilter>(
2501 Matrix::MakeTranslation({300, 0}) * Matrix::MakeScale({2, 2, 2}),
2502 SamplerDescriptor{}),
2503 });
2504 canvas.DrawCircle({-150, 0}, 50, {.color = Color::Green()});
2505 canvas.Restore();
2506
2507 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2508}

◆ TEST_P() [203/450]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen   
)

Definition at line 2475 of file aiks_unittests.cc.

2475 {
2476 Canvas canvas;
2477 canvas.Scale(GetContentScale());
2478 canvas.Translate({100, 100});
2479 // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
2480 // +300 translation applied by a SaveLayer image filter.
2481 canvas.SaveLayer({
2482 .image_filter = std::make_shared<MatrixImageFilter>(
2483 Matrix::MakeTranslation({300, 0}), SamplerDescriptor{}),
2484 });
2485 canvas.DrawCircle({-300, 0}, 100, {.color = Color::Green()});
2486 canvas.Restore();
2487
2488 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2489}

◆ TEST_P() [204/450]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterMagnify   
)

Definition at line 2448 of file aiks_unittests.cc.

2448 {
2449 Scalar scale = 2.0;
2450 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
2451 if (AiksTest::ImGuiBegin("Controls", nullptr,
2452 ImGuiWindowFlags_AlwaysAutoResize)) {
2453 ImGui::SliderFloat("Scale", &scale, 1, 2);
2454 ImGui::End();
2455 }
2456 Canvas canvas;
2457 canvas.Scale(GetContentScale());
2458 auto image =
2459 std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2460 canvas.Translate({600, -200});
2461 canvas.SaveLayer({
2462 .image_filter = std::make_shared<MatrixImageFilter>(
2463 Matrix::MakeScale({scale, scale, 1}), SamplerDescriptor{}),
2464 });
2465 canvas.DrawImage(image, {0, 0},
2466 Paint{.color = Color::White().WithAlpha(0.5)});
2467 canvas.Restore();
2468 return canvas.EndRecordingAsPicture();
2469 };
2470
2471 ASSERT_TRUE(OpenPlaygroundHere(callback));
2472}
virtual bool Restore()
Definition: canvas.cc:257
void Translate(const Vector3 &offset)
Definition: canvas.cc:311

◆ TEST_P() [205/450]

impeller::testing::TEST_P ( AiksTest  ,
MatrixSaveLayerFilter   
)

Definition at line 2301 of file aiks_unittests.cc.

2301 {
2302 Canvas canvas;
2303 canvas.DrawPaint({.color = Color::Black()});
2304 canvas.SaveLayer({}, std::nullopt);
2305 {
2306 canvas.DrawCircle(Point(200, 200), 100,
2307 {.color = Color::Green().WithAlpha(0.5),
2308 .blend_mode = BlendMode::kPlus});
2309 // Should render a second circle, centered on the bottom-right-most edge of
2310 // the circle.
2311 canvas.SaveLayer({.image_filter = ImageFilter::MakeMatrix(
2312 Matrix::MakeTranslation(Vector2(1, 1) *
2313 (200 + 100 * k1OverSqrt2)) *
2314 Matrix::MakeScale(Vector2(1, 1) * 0.5) *
2315 Matrix::MakeTranslation(Vector2(-200, -200)),
2316 SamplerDescriptor{})},
2317 std::nullopt);
2318 canvas.DrawCircle(Point(200, 200), 100,
2319 {.color = Color::Green().WithAlpha(0.5),
2320 .blend_mode = BlendMode::kPlus});
2321 canvas.Restore();
2322 }
2323 canvas.Restore();
2324
2325 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2326}

◆ TEST_P() [206/450]

impeller::testing::TEST_P ( AiksTest  ,
MipmapGenerationWorksCorrectly   
)

Definition at line 2747 of file aiks_unittests.cc.

2747 {
2748 TextureDescriptor texture_descriptor;
2749 texture_descriptor.size = ISize{1024, 1024};
2750 texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
2751 texture_descriptor.storage_mode = StorageMode::kHostVisible;
2752 texture_descriptor.mip_count = texture_descriptor.size.MipCount();
2753
2754 std::vector<uint8_t> bytes(4194304);
2755 bool alternate = false;
2756 for (auto i = 0u; i < 4194304; i += 4) {
2757 if (alternate) {
2758 bytes[i] = 255;
2759 bytes[i + 1] = 0;
2760 bytes[i + 2] = 0;
2761 bytes[i + 3] = 255;
2762 } else {
2763 bytes[i] = 0;
2764 bytes[i + 1] = 255;
2765 bytes[i + 2] = 0;
2766 bytes[i + 3] = 255;
2767 }
2768 alternate = !alternate;
2769 }
2770
2771 ASSERT_EQ(texture_descriptor.GetByteSizeOfBaseMipLevel(), bytes.size());
2772 auto mapping = std::make_shared<fml::NonOwnedMapping>(
2773 bytes.data(), // data
2774 texture_descriptor.GetByteSizeOfBaseMipLevel() // size
2775 );
2776 auto texture =
2777 GetContext()->GetResourceAllocator()->CreateTexture(texture_descriptor);
2778
2779 auto device_buffer =
2780 GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
2781 auto command_buffer = GetContext()->CreateCommandBuffer();
2782 auto blit_pass = command_buffer->CreateBlitPass();
2783
2784 blit_pass->AddCopy(DeviceBuffer::AsBufferView(std::move(device_buffer)),
2785 texture);
2786 blit_pass->GenerateMipmap(texture);
2787 EXPECT_TRUE(blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()));
2788 EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({command_buffer}).ok());
2789
2790 auto image = std::make_shared<Image>(texture);
2791
2792 Canvas canvas;
2793 canvas.DrawImageRect(image, Rect::MakeSize(texture->GetSize()),
2794 Rect::MakeLTRB(0, 0, 100, 100), {});
2795
2796 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2797}
constexpr size_t GetByteSizeOfBaseMipLevel() const

◆ TEST_P() [207/450]

impeller::testing::TEST_P ( AiksTest  ,
OpaqueEntitiesGetCoercedToSource   
)

Definition at line 2099 of file aiks_unittests.cc.

2099 {
2100 Canvas canvas;
2101 canvas.Scale(Vector2(1.618, 1.618));
2102 canvas.DrawCircle(Point(), 10,
2103 {
2104 .color = Color::CornflowerBlue(),
2105 .blend_mode = BlendMode::kSourceOver,
2106 });
2107 Picture picture = canvas.EndRecordingAsPicture();
2108
2109 // Extract the SolidColorSource.
2110 // Entity entity;
2111 std::vector<Entity> entity;
2112 std::shared_ptr<SolidColorContents> contents;
2113 picture.pass->IterateAllEntities([e = &entity, &contents](Entity& entity) {
2114 if (ScalarNearlyEqual(entity.GetTransform().GetScale().x, 1.618f)) {
2115 contents =
2116 std::static_pointer_cast<SolidColorContents>(entity.GetContents());
2117 e->emplace_back(entity.Clone());
2118 return false;
2119 }
2120 return true;
2121 });
2122
2123 ASSERT_TRUE(entity.size() >= 1);
2124 ASSERT_TRUE(contents->IsOpaque());
2125 ASSERT_EQ(entity[0].GetBlendMode(), BlendMode::kSource);
2126}
static SkBlendMode GetBlendMode(SkSVGFeBlend::Mode mode)
Entity Clone() const
Definition: entity.cc:191
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:46
constexpr Vector3 GetScale() const
Definition: matrix.h:311

◆ TEST_P() [208/450]

impeller::testing::TEST_P ( AiksTest  ,
PaintBlendModeIsRespected   
)

Definition at line 114 of file aiks_blend_unittests.cc.

114 {
115 Paint paint;
116 Canvas canvas;
117 // Default is kSourceOver.
118 paint.color = Color(1, 0, 0, 0.5);
119 canvas.DrawCircle(Point(150, 200), 100, paint);
120 paint.color = Color(0, 1, 0, 0.5);
121 canvas.DrawCircle(Point(250, 200), 100, paint);
122
123 paint.blend_mode = BlendMode::kPlus;
124 paint.color = Color::Red();
125 canvas.DrawCircle(Point(450, 250), 100, paint);
126 paint.color = Color::Green();
127 canvas.DrawCircle(Point(550, 250), 100, paint);
128 paint.color = Color::Blue();
129 canvas.DrawCircle(Point(500, 150), 100, paint);
130 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
131}

◆ TEST_P() [209/450]

impeller::testing::TEST_P ( AiksTest  ,
PaintWithFilters   
)

Definition at line 1529 of file aiks_unittests.cc.

1529 {
1530 // validate that a paint with a color filter "HasFilters", no other filters
1531 // impact this setting.
1532 Paint paint;
1533
1534 ASSERT_FALSE(paint.HasColorFilter());
1535
1536 paint.color_filter =
1537 ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Blue());
1538
1539 ASSERT_TRUE(paint.HasColorFilter());
1540
1541 paint.image_filter = ImageFilter::MakeBlur(Sigma(1.0), Sigma(1.0),
1543 Entity::TileMode::kClamp);
1544
1545 ASSERT_TRUE(paint.HasColorFilter());
1546
1547 paint.mask_blur_descriptor = {};
1548
1549 ASSERT_TRUE(paint.HasColorFilter());
1550
1551 paint.color_filter = nullptr;
1552
1553 ASSERT_FALSE(paint.HasColorFilter());
1554}

◆ TEST_P() [210/450]

impeller::testing::TEST_P ( AiksTest  ,
ParentSaveLayerCreatesRenderPassWhenChildBackdropFilterIsPresent   
)

Definition at line 1580 of file aiks_unittests.cc.

1581 {
1582 Canvas canvas;
1583 canvas.SaveLayer({}, std::nullopt, ImageFilter::MakeMatrix(Matrix(), {}));
1584 canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1585 canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1586 .blend_mode = BlendMode::kSourceOver});
1587 canvas.Restore();
1588
1589 Picture picture = canvas.EndRecordingAsPicture();
1590
1591 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1592 std::shared_ptr<Context> real_context = GetContext();
1593 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1594 AiksContext renderer(mock_context, nullptr);
1595 std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1596
1597 ASSERT_EQ(spy->render_passes_.size(),
1598 GetBackend() == PlaygroundBackend::kOpenGLES ? 4llu : 3llu);
1599 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1600 ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1601}

◆ TEST_P() [211/450]

impeller::testing::TEST_P ( AiksTest  ,
PipelineBlendSingleParameter   
)

Definition at line 2392 of file aiks_unittests.cc.

2392 {
2393 Canvas canvas;
2394
2395 // Should render a green square in the middle of a blue circle.
2396 canvas.SaveLayer({});
2397 {
2398 canvas.Translate(Point(100, 100));
2399 canvas.DrawCircle(Point(200, 200), 200, {.color = Color::Blue()});
2400 canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
2401 canvas.DrawCircle(Point(200, 200), 200,
2402 {
2403 .color = Color::Green(),
2404 .blend_mode = BlendMode::kSourceOver,
2405 .image_filter = ImageFilter::MakeFromColorFilter(
2406 *ColorFilter::MakeBlend(BlendMode::kDestination,
2407 Color::White())),
2408 });
2409 canvas.Restore();
2410 }
2411
2412 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2413}

◆ TEST_P() [212/450]

impeller::testing::TEST_P ( AiksTest  ,
ReleasesTextureOnTeardown   
)

Definition at line 2416 of file aiks_unittests.cc.

2416 {
2417 auto context = MakeContext();
2418 std::weak_ptr<Texture> weak_texture;
2419
2420 {
2421 auto texture = CreateTextureForFixture("table_mountain_nx.png");
2422
2423 Canvas canvas;
2424 canvas.Scale(GetContentScale());
2425 canvas.Translate({100.0f, 100.0f, 0});
2426
2427 Paint paint;
2428 paint.color_source = ColorSource::MakeImage(
2429 texture, Entity::TileMode::kClamp, Entity::TileMode::kClamp, {}, {});
2430 canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
2431
2432 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2433 }
2434
2435 // See https://github.com/flutter/flutter/issues/134751.
2436 //
2437 // If the fence waiter was working this may not be released by the end of the
2438 // scope above. Adding a manual shutdown so that future changes to the fence
2439 // waiter will not flake this test.
2440 context->Shutdown();
2441
2442 // The texture should be released by now.
2443 ASSERT_TRUE(weak_texture.expired()) << "When the texture is no longer in use "
2444 "by the backend, it should be "
2445 "released.";
2446}

◆ TEST_P() [213/450]

impeller::testing::TEST_P ( AiksTest  ,
RotateColorFilteredPath   
)

Definition at line 19 of file aiks_dl_path_unittests.cc.

19 {
21 builder.Transform(SkMatrix::Translate(300, 300) * SkMatrix::RotateDeg(90));
22
23 SkPath arrow_stem;
24 SkPath arrow_head;
25
26 arrow_stem.moveTo({120, 190}).lineTo({120, 50});
27 arrow_head.moveTo({50, 120}).lineTo({120, 190}).lineTo({190, 120});
28
29 auto filter =
30 DlBlendColorFilter::Make(DlColor::kAliceBlue(), DlBlendMode::kSrcIn);
31
33 paint.setStrokeWidth(15.0);
34 paint.setStrokeCap(DlStrokeCap::kRound);
35 paint.setStrokeJoin(DlStrokeJoin::kRound);
36 paint.setDrawStyle(DlDrawStyle::kStroke);
37 paint.setColorFilter(filter);
38 paint.setColor(DlColor::kBlack());
39
40 builder.DrawPath(arrow_stem, paint);
41 builder.DrawPath(arrow_head, paint);
42
43 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
44}
static SkMatrix RotateDeg(SkScalar deg)
Definition: SkMatrix.h:104
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.h:91

◆ TEST_P() [214/450]

impeller::testing::TEST_P ( AiksTest  ,
SaveLayerDrawsBehindSubsequentEntities   
)

Definition at line 1377 of file aiks_unittests.cc.

1377 {
1378 // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636
1379 Canvas canvas;
1380 Paint paint;
1381
1382 paint.color = Color::Black();
1383 Rect rect = Rect::MakeXYWH(25, 25, 25, 25);
1384 canvas.DrawRect(rect, paint);
1385
1386 canvas.Translate({10, 10});
1387 canvas.SaveLayer({});
1388
1389 paint.color = Color::Green();
1390 canvas.DrawRect(rect, paint);
1391
1392 canvas.Restore();
1393
1394 canvas.Translate({10, 10});
1395 paint.color = Color::Red();
1396 canvas.DrawRect(rect, paint);
1397
1398 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1399}

◆ TEST_P() [215/450]

impeller::testing::TEST_P ( AiksTest  ,
SaveLayerFiltersScaleWithTransform   
)

Definition at line 1458 of file aiks_unittests.cc.

1458 {
1459 Canvas canvas;
1460 canvas.Scale(GetContentScale());
1461 canvas.Translate(Vector2(100, 100));
1462
1463 auto texture = std::make_shared<Image>(CreateTextureForFixture("boston.jpg"));
1464 auto draw_image_layer = [&canvas, &texture](const Paint& paint) {
1465 canvas.SaveLayer(paint);
1466 canvas.DrawImage(texture, {}, Paint{});
1467 canvas.Restore();
1468 };
1469
1470 Paint effect_paint;
1471 effect_paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1473 .sigma = Sigma{6},
1474 };
1475 draw_image_layer(effect_paint);
1476
1477 canvas.Translate(Vector2(300, 300));
1478 canvas.Scale(Vector2(3, 3));
1479 draw_image_layer(effect_paint);
1480
1481 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1482}

◆ TEST_P() [216/450]

impeller::testing::TEST_P ( AiksTest  ,
SetContentsWithRegion   
)

Definition at line 2840 of file aiks_unittests.cc.

2840 {
2841 auto bridge = CreateTextureForFixture("bay_bridge.jpg");
2842
2843 // Replace part of the texture with a red rectangle.
2844 std::vector<uint8_t> bytes(100 * 100 * 4);
2845 for (auto i = 0u; i < bytes.size(); i += 4) {
2846 bytes[i] = 255;
2847 bytes[i + 1] = 0;
2848 bytes[i + 2] = 0;
2849 bytes[i + 3] = 255;
2850 }
2851 auto mapping =
2852 std::make_shared<fml::NonOwnedMapping>(bytes.data(), bytes.size());
2853 auto device_buffer =
2854 GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
2855 auto cmd_buffer = GetContext()->CreateCommandBuffer();
2856 auto blit_pass = cmd_buffer->CreateBlitPass();
2857 blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer), bridge,
2858 IRect::MakeLTRB(50, 50, 150, 150));
2859
2860 auto did_submit =
2861 blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()) &&
2862 GetContext()->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok();
2863 ASSERT_TRUE(did_submit);
2864
2865 auto image = std::make_shared<Image>(bridge);
2866
2867 Canvas canvas;
2868 canvas.DrawImage(image, {0, 0}, {});
2869
2870 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2871}

◆ TEST_P() [217/450]

impeller::testing::TEST_P ( AiksTest  ,
SiblingSaveLayerBoundsAreRespected   
)

Definition at line 1401 of file aiks_unittests.cc.

1401 {
1402 Canvas canvas;
1403 Paint paint;
1404 Rect rect = Rect::MakeXYWH(0, 0, 1000, 1000);
1405
1406 // Black, green, and red squares offset by [10, 10].
1407 {
1408 canvas.SaveLayer({}, Rect::MakeXYWH(25, 25, 25, 25));
1409 paint.color = Color::Black();
1410 canvas.DrawRect(rect, paint);
1411 canvas.Restore();
1412 }
1413
1414 {
1415 canvas.SaveLayer({}, Rect::MakeXYWH(35, 35, 25, 25));
1416 paint.color = Color::Green();
1417 canvas.DrawRect(rect, paint);
1418 canvas.Restore();
1419 }
1420
1421 {
1422 canvas.SaveLayer({}, Rect::MakeXYWH(45, 45, 25, 25));
1423 paint.color = Color::Red();
1424 canvas.DrawRect(rect, paint);
1425 canvas.Restore();
1426 }
1427
1428 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1429}

◆ TEST_P() [218/450]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorApplyColorFilter   
)

Definition at line 2352 of file aiks_unittests.cc.

2352 {
2353 auto contents = SolidColorContents();
2354 contents.SetColor(Color::CornflowerBlue().WithAlpha(0.75));
2355 auto result = contents.ApplyColorFilter([](const Color& color) {
2356 return color.Blend(Color::LimeGreen().WithAlpha(0.75), BlendMode::kScreen);
2357 });
2358 ASSERT_TRUE(result);
2359 ASSERT_COLOR_NEAR(contents.GetColor(),
2360 Color(0.424452, 0.828743, 0.79105, 0.9375));
2361}

◆ TEST_P() [219/450]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorCirclesOvalsRRectsMaskBlurCorrectly   
)

Definition at line 1188 of file aiks_unittests.cc.

1188 {
1189 Canvas canvas;
1190 canvas.Scale(GetContentScale());
1191 Paint paint;
1192 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1194 .sigma = Sigma{1},
1195 };
1196
1197 canvas.DrawPaint({.color = Color::White()});
1198
1199 paint.color = Color::Crimson();
1200 Scalar y = 100.0f;
1201 for (int i = 0; i < 5; i++) {
1202 Scalar x = (i + 1) * 100;
1203 Scalar radius = x / 10.0f;
1204 canvas.DrawRect(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1205 radius, 60.0f - radius),
1206 paint);
1207 }
1208
1209 paint.color = Color::Blue();
1210 y += 100.0f;
1211 for (int i = 0; i < 5; i++) {
1212 Scalar x = (i + 1) * 100;
1213 Scalar radius = x / 10.0f;
1214 canvas.DrawCircle({x + 25, y + 25}, radius, paint);
1215 }
1216
1217 paint.color = Color::Green();
1218 y += 100.0f;
1219 for (int i = 0; i < 5; i++) {
1220 Scalar x = (i + 1) * 100;
1221 Scalar radius = x / 10.0f;
1222 canvas.DrawOval(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1223 radius, 60.0f - radius),
1224 paint);
1225 }
1226
1227 paint.color = Color::Purple();
1228 y += 100.0f;
1229 for (int i = 0; i < 5; i++) {
1230 Scalar x = (i + 1) * 100;
1231 Scalar radius = x / 20.0f;
1232 canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
1233 {radius, radius}, //
1234 paint);
1235 }
1236
1237 paint.color = Color::Orange();
1238 y += 100.0f;
1239 for (int i = 0; i < 5; i++) {
1240 Scalar x = (i + 1) * 100;
1241 Scalar radius = x / 20.0f;
1242 canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
1243 {radius, 5.0f}, paint);
1244 }
1245
1246 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1247}

◆ TEST_P() [220/450]

impeller::testing::TEST_P ( AiksTest  ,
SolidStrokesRenderCorrectly   
)

Definition at line 187 of file aiks_path_unittests.cc.

187 {
188 // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
189 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
190 static Color color = Color::Black().WithAlpha(0.5);
191 static float scale = 3;
192 static bool add_circle_clip = true;
193
194 if (AiksTest::ImGuiBegin("Controls", nullptr,
195 ImGuiWindowFlags_AlwaysAutoResize)) {
196 ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
197 ImGui::SliderFloat("Scale", &scale, 0, 6);
198 ImGui::Checkbox("Circle clip", &add_circle_clip);
199 ImGui::End();
200 }
201
202 Canvas canvas;
203 canvas.Scale(GetContentScale());
204 Paint paint;
205
206 paint.color = Color::White();
207 canvas.DrawPaint(paint);
208
209 paint.color = color;
210 paint.style = Paint::Style::kStroke;
211 paint.stroke_width = 10;
212
214 .MoveTo({20, 20})
215 .QuadraticCurveTo({60, 20}, {60, 60})
216 .Close()
217 .MoveTo({60, 20})
218 .QuadraticCurveTo({60, 60}, {20, 60})
219 .TakePath();
220
221 canvas.Scale(Vector2(scale, scale));
222
223 if (add_circle_clip) {
224 static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
225 Color::Red());
226 static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
227 Color::Red());
228 auto [handle_a, handle_b] =
229 DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
230
231 auto screen_to_canvas = canvas.GetCurrentTransform().Invert();
232 Point point_a = screen_to_canvas * handle_a * GetContentScale();
233 Point point_b = screen_to_canvas * handle_b * GetContentScale();
234
235 Point middle = (point_a + point_b) / 2;
236 auto radius = point_a.GetDistance(middle);
237 canvas.ClipPath(PathBuilder{}.AddCircle(middle, radius).TakePath());
238 }
239
240 for (auto join : {Join::kBevel, Join::kRound, Join::kMiter}) {
241 paint.stroke_join = join;
242 for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
243 paint.stroke_cap = cap;
244 canvas.DrawPath(path, paint);
245 canvas.Translate({80, 0});
246 }
247 canvas.Translate({-240, 60});
248 }
249
250 return canvas.EndRecordingAsPicture();
251 };
252
253 ASSERT_TRUE(OpenPlaygroundHere(callback));
254}
const Matrix & GetCurrentTransform() const
Definition: canvas.cc:298
void ClipPath(const Path &path, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition: canvas.cc:589
void DrawPath(const Path &path, const Paint &paint)
Definition: canvas.cc:343
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:52
constexpr Type GetDistance(const TPoint &p) const
Definition: point.h:200

◆ TEST_P() [221/450]

impeller::testing::TEST_P ( AiksTest  ,
SrgbToLinearFilterSubpassCollapseOptimization   
)

Definition at line 1796 of file aiks_unittests.cc.

1796 {
1797 Canvas canvas;
1798
1799 canvas.SaveLayer({
1800 .color_filter = ColorFilter::MakeSrgbToLinear(),
1801 });
1802
1803 canvas.Translate({500, 300, 0});
1804 canvas.Rotate(Radians(2 * kPi / 3));
1805 canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
1806
1807 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1808}

◆ TEST_P() [222/450]

impeller::testing::TEST_P ( AiksTest  ,
StrokedCirclesRenderCorrectly   
)

Definition at line 970 of file aiks_unittests.cc.

970 {
971 Canvas canvas;
972 canvas.Scale(GetContentScale());
973 Paint paint;
974 const int color_count = 3;
975 Color colors[color_count] = {
976 Color::Blue(),
977 Color::Green(),
978 Color::Crimson(),
979 };
980
981 paint.color = Color::White();
982 canvas.DrawPaint(paint);
983
984 int c_index = 0;
985
986 auto draw = [&paint, &colors, &c_index](Canvas& canvas, Point center,
987 Scalar r, Scalar dr, int n) {
988 for (int i = 0; i < n; i++) {
989 paint.color = colors[(c_index++) % color_count];
990 canvas.DrawCircle(center, r, paint);
991 r += dr;
992 }
993 };
994
995 paint.style = Paint::Style::kStroke;
996 paint.stroke_width = 1;
997 draw(canvas, {10, 10}, 2, 2, 14); // r = [2, 28], covers [1,29]
998 paint.stroke_width = 5;
999 draw(canvas, {10, 10}, 35, 10, 56); // r = [35, 585], covers [30,590]
1000
1001 std::vector<Color> gradient_colors = {
1002 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1003 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1004 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1005 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1006 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1007 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1008 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1009 std::vector<Scalar> stops = {
1010 0.0,
1011 (1.0 / 6.0) * 1,
1012 (1.0 / 6.0) * 2,
1013 (1.0 / 6.0) * 3,
1014 (1.0 / 6.0) * 4,
1015 (1.0 / 6.0) * 5,
1016 1.0,
1017 };
1018 auto texture = CreateTextureForFixture("airplane.jpg",
1019 /*enable_mipmapping=*/true);
1020
1021 paint.color_source = ColorSource::MakeRadialGradient(
1022 {500, 600}, 75, std::move(gradient_colors), std::move(stops),
1023 Entity::TileMode::kMirror, {});
1024 draw(canvas, {500, 600}, 5, 10, 10);
1025
1026 paint.color_source = ColorSource::MakeImage(
1027 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1028 Matrix::MakeTranslation({700, 200}));
1029 draw(canvas, {800, 300}, 5, 10, 10);
1030
1031 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1032}

◆ TEST_P() [223/450]

impeller::testing::TEST_P ( AiksTest  ,
StrokedPathWithMoveToThenCloseDrawnCorrectly   
)

Definition at line 2800 of file aiks_unittests.cc.

2800 {
2802 .MoveTo({0, 400})
2803 .LineTo({0, 0})
2804 .LineTo({400, 0})
2805 // MoveTo implicitly adds a contour, ensure that close doesn't
2806 // add another nearly-empty contour.
2807 .MoveTo({0, 400})
2808 .Close()
2809 .TakePath();
2810
2811 Canvas canvas;
2812 canvas.Translate({50, 50, 0});
2813 canvas.DrawPath(path, {
2814 .color = Color::Blue(),
2815 .stroke_width = 10,
2816 .stroke_cap = Cap::kRound,
2817 .style = Paint::Style::kStroke,
2818 });
2819 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2820}

◆ TEST_P() [224/450]

impeller::testing::TEST_P ( AiksTest  ,
SubpassWithClearColorOptimization   
)

Definition at line 2551 of file aiks_unittests.cc.

2551 {
2552 Canvas canvas;
2553
2554 // Use a non-srcOver blend mode to ensure that we don't detect this as an
2555 // opacity peephole optimization.
2556 canvas.SaveLayer(
2557 {.color = Color::Blue().WithAlpha(0.5), .blend_mode = BlendMode::kSource},
2558 Rect::MakeLTRB(0, 0, 200, 200));
2559 canvas.DrawPaint(
2560 {.color = Color::BlackTransparent(), .blend_mode = BlendMode::kSource});
2561 canvas.Restore();
2562
2563 canvas.SaveLayer(
2564 {.color = Color::Blue(), .blend_mode = BlendMode::kDestinationOver});
2565 canvas.Restore();
2566
2567 // This playground should appear blank on CI since we are only drawing
2568 // transparent black. If the clear color optimization is broken, the texture
2569 // will be filled with NaNs and may produce a magenta texture on macOS or iOS.
2570 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2571}

◆ TEST_P() [225/450]

impeller::testing::TEST_P ( AiksTest  ,
TextForegroundShaderWithTransform   
)

Definition at line 2268 of file aiks_unittests.cc.

2268 {
2269 auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf");
2270 ASSERT_NE(mapping, nullptr);
2271
2272 Scalar font_size = 100;
2274 SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
2275
2276 Paint text_paint;
2277 text_paint.color = Color::Blue();
2278
2279 std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
2280 Color{0.1294, 0.5882, 0.9529, 1.0}};
2281 std::vector<Scalar> stops = {
2282 0.0,
2283 1.0,
2284 };
2285 text_paint.color_source = ColorSource::MakeLinearGradient(
2286 {0, 0}, {100, 100}, std::move(colors), std::move(stops),
2287 Entity::TileMode::kRepeat, {});
2288
2289 Canvas canvas;
2290 canvas.Translate({100, 100});
2291 canvas.Rotate(Radians(kPi / 4));
2292
2293 auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
2294 ASSERT_NE(blob, nullptr);
2296 canvas.DrawTextFrame(frame, Point(), text_paint);
2297
2298 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2299}

◆ TEST_P() [226/450]

impeller::testing::TEST_P ( AiksTest  ,
TextFrameSubpixelAlignment   
)

Definition at line 672 of file aiks_unittests.cc.

672 {
673 // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens.
674 std::array<Scalar, 20> phase_offsets = {
675 7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
676 0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
677 0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
678 0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
679 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
680 static float font_size = 20;
681 static float phase_variation = 0.2;
682 static float speed = 0.5;
683 static float magnitude = 100;
684 if (AiksTest::ImGuiBegin("Controls", nullptr,
685 ImGuiWindowFlags_AlwaysAutoResize)) {
686 ImGui::SliderFloat("Font size", &font_size, 5, 50);
687 ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1);
688 ImGui::SliderFloat("Oscillation speed", &speed, 0, 2);
689 ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300);
690 ImGui::End();
691 }
692
693 Canvas canvas;
694 canvas.Scale(GetContentScale());
695
696 for (size_t i = 0; i < phase_offsets.size(); i++) {
697 auto position =
698 Point(200 + magnitude *
699 std::sin((-phase_offsets[i] * k2Pi * phase_variation +
700 GetSecondsElapsed() * speed)), //
701 200 + i * font_size * 1.1 //
702 );
704 GetContext(), canvas,
705 "the quick brown fox jumped over "
706 "the lazy dog!.?",
707 "Roboto-Regular.ttf",
708 {.font_size = font_size, .position = position})) {
709 return std::nullopt;
710 }
711 }
712 return canvas.EndRecordingAsPicture();
713 };
714
715 ASSERT_TRUE(OpenPlaygroundHere(callback));
716}
static double magnitude(double a)

◆ TEST_P() [227/450]

impeller::testing::TEST_P ( AiksTest  ,
TextRotated   
)

Definition at line 827 of file aiks_unittests.cc.

827 {
828 Canvas canvas;
829 canvas.Scale(GetContentScale());
830 canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
831
832 canvas.Transform(Matrix(0.25, -0.3, 0, -0.002, //
833 0, 0.5, 0, 0, //
834 0, 0, 0.3, 0, //
835 100, 100, 0, 1.3));
836 ASSERT_TRUE(RenderTextInCanvasSkia(
837 GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
838 "Roboto-Regular.ttf"));
839
840 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
841}

◆ TEST_P() [228/450]

impeller::testing::TEST_P ( AiksTest  ,
TransformMultipliesCorrectly   
)

Definition at line 872 of file aiks_unittests.cc.

872 {
873 Canvas canvas;
874 ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(), Matrix());
875
876 // clang-format off
877 canvas.Translate(Vector3(100, 200));
879 canvas.GetCurrentTransform(),
880 Matrix( 1, 0, 0, 0,
881 0, 1, 0, 0,
882 0, 0, 1, 0,
883 100, 200, 0, 1));
884
885 canvas.Rotate(Radians(kPiOver2));
887 canvas.GetCurrentTransform(),
888 Matrix( 0, 1, 0, 0,
889 -1, 0, 0, 0,
890 0, 0, 1, 0,
891 100, 200, 0, 1));
892
893 canvas.Scale(Vector3(2, 3));
895 canvas.GetCurrentTransform(),
896 Matrix( 0, 2, 0, 0,
897 -3, 0, 0, 0,
898 0, 0, 0, 0,
899 100, 200, 0, 1));
900
901 canvas.Translate(Vector3(100, 200));
903 canvas.GetCurrentTransform(),
904 Matrix( 0, 2, 0, 0,
905 -3, 0, 0, 0,
906 0, 0, 0, 0,
907 -500, 400, 0, 1));
908 // clang-format on
909}

◆ TEST_P() [229/450]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerDrawsCorrectly   
)

Definition at line 1810 of file aiks_unittests.cc.

1810 {
1811 Canvas canvas;
1812
1813 canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
1814
1815 canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
1816 canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
1817 canvas.Restore();
1818
1819 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1820}

◆ TEST_P() [230/450]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerImageDrawsCorrectly   
)

Definition at line 1983 of file aiks_unittests.cc.

1983 {
1984 Canvas canvas;
1985
1986 auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
1987 canvas.DrawImage(image, {100, 100}, {});
1988
1989 canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
1990 canvas.DrawImage(image, {100, 500}, {});
1991 canvas.Restore();
1992
1993 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1994}

◆ TEST_P() [231/450]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly   
)

Definition at line 2067 of file aiks_unittests.cc.

2067 {
2068 Canvas canvas;
2069 canvas.DrawRect(Rect::MakeXYWH(0, 0, 400, 400), {.color = Color::Red()});
2070 canvas.SaveLayer({
2071 .color = Color::Black().WithAlpha(0.5),
2072 .blend_mode = BlendMode::kLighten,
2073 });
2074 canvas.DrawCircle({200, 200}, 100, {.color = Color::Green()});
2075 canvas.Restore();
2076 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2077}

◆ TEST_P() [232/450]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly   
)

Definition at line 1822 of file aiks_unittests.cc.

1822 {
1823 Canvas canvas;
1824
1825 canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
1826
1827 canvas.SaveLayer({
1828 .color = Color::Black().WithAlpha(0.5),
1829 .color_filter =
1830 ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
1831 });
1832 canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
1833 canvas.Restore();
1834
1835 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1836}

◆ TEST_P() [233/450]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly   
)

Definition at line 1838 of file aiks_unittests.cc.

1838 {
1839 Canvas canvas;
1840
1841 canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
1842
1843 canvas.SaveLayer({
1844 .color = Color::Black().WithAlpha(0.5),
1845 .image_filter = ImageFilter::MakeFromColorFilter(
1846 *ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red())),
1847 });
1848
1849 canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
1850 canvas.Restore();
1851
1852 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1853}

◆ TEST_P() [234/450]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly   
)

Definition at line 1855 of file aiks_unittests.cc.

1855 {
1856 Canvas canvas;
1857
1858 canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
1859
1860 canvas.SaveLayer({
1861 .color = Color::Black().WithAlpha(0.5),
1862 .color_filter =
1863 ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
1864 });
1865
1866 canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
1867 canvas.Restore();
1868
1869 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1870}

◆ TEST_P() [235/450]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly   
)

Definition at line 2041 of file aiks_unittests.cc.

2042 {
2043 Canvas canvas;
2044
2045 auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2046 canvas.DrawImage(image, {100, 100}, {});
2047
2048 canvas.SaveLayer({
2049 .color = Color::Black().WithAlpha(0.5),
2050 .image_filter = ImageFilter::MakeFromColorFilter(
2051 *ColorFilter::MakeMatrix({.array =
2052 {
2053 1, 0, 0, 0, 0, //
2054 0, 1, 0, 0, 0, //
2055 0, 0.2, 1, 0, 0, //
2056 0, 0, 0, 0.5, 0 //
2057 }})),
2058 .color_filter =
2059 ColorFilter::MakeBlend(BlendMode::kModulate, Color::Green()),
2060 });
2061 canvas.DrawImage(image, {100, 500}, {});
2062 canvas.Restore();
2063
2064 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2065}

◆ TEST_P() [236/450]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly   
)

Definition at line 1996 of file aiks_unittests.cc.

1996 {
1997 Canvas canvas;
1998
1999 auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2000 canvas.DrawImage(image, {100, 100}, {});
2001
2002 canvas.SaveLayer({
2003 .color = Color::Black().WithAlpha(0.5),
2004 .color_filter = ColorFilter::MakeMatrix({.array =
2005 {
2006 1, 0, 0, 0, 0, //
2007 0, 1, 0, 0, 0, //
2008 0, 0, 1, 0, 0, //
2009 0, 0, 0, 2, 0 //
2010 }}),
2011 });
2012 canvas.DrawImage(image, {100, 500}, {});
2013 canvas.Restore();
2014
2015 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2016}

◆ TEST_P() [237/450]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly   
)

Definition at line 2018 of file aiks_unittests.cc.

2018 {
2019 Canvas canvas;
2020
2021 auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2022 canvas.DrawImage(image, {100, 100}, {});
2023
2024 canvas.SaveLayer({
2025 .color = Color::Black().WithAlpha(0.5),
2026 .image_filter = ImageFilter::MakeFromColorFilter(
2027 *ColorFilter::MakeMatrix({.array =
2028 {
2029 1, 0, 0, 0, 0, //
2030 0, 1, 0, 0, 0, //
2031 0, 0, 1, 0, 0, //
2032 0, 0, 0, 2, 0 //
2033 }})),
2034 });
2035 canvas.DrawImage(image, {100, 500}, {});
2036 canvas.Restore();
2037
2038 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2039}

◆ TEST_P() [238/450]

impeller::testing::TEST_P ( AiksTest  ,
VerifyNonOptimizedGradient   
)

Definition at line 807 of file aiks_dl_gradient_unittests.cc.

807 {
810 builder.Translate(100.0f, 0);
811
812 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
814 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
815
816 // Inset the start and end point to verify that we do not apply
817 // the fast gradient condition.
818 paint.setColorSource(
819 DlColorSource::MakeLinear({0, 150}, {0, 100}, stops.size(), colors.data(),
820 stops.data(), DlTileMode::kRepeat));
821
822 paint.setColor(DlColor::kWhite());
823 builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
824 builder.Translate(400, 0);
825 builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
826 paint);
827
828 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
829}

◆ TEST_P() [239/450]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryColorUVPositionData   
)

Definition at line 93 of file aiks_dl_vertices_unittests.cc.

93 {
96 auto image =
97 DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
98 auto size = image->impeller_texture()->GetSize();
99
100 paint.setColorSource(std::make_shared<DlImageColorSource>(
101 image, DlTileMode::kClamp, DlTileMode::kClamp));
102
103 std::vector<SkPoint> positions = {
104 SkPoint::Make(0, 0), SkPoint::Make(size.width, 0),
105 SkPoint::Make(0, size.height), SkPoint::Make(size.width, 0),
106 SkPoint::Make(0, 0), SkPoint::Make(size.width, size.height),
107 };
108 std::vector<DlColor> colors = {
109 DlColor::kRed().withAlpha(128), DlColor::kBlue().withAlpha(128),
110 DlColor::kGreen().withAlpha(128), DlColor::kRed().withAlpha(128),
111 DlColor::kBlue().withAlpha(128), DlColor::kGreen().withAlpha(128),
112 };
113
114 auto vertices =
115 MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
116
117 builder.DrawVertices(vertices, DlBlendMode::kDstOver, paint);
118 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
119}
std::shared_ptr< impeller::VerticesGeometry > MakeVertices(const flutter::DlVertices *vertices)

◆ TEST_P() [240/450]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryColorUVPositionDataAdvancedBlend   
)

Definition at line 121 of file aiks_dl_vertices_unittests.cc.

121 {
124 auto image =
125 DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
126 auto size = image->impeller_texture()->GetSize();
127
128 paint.setColorSource(std::make_shared<DlImageColorSource>(
129 image, DlTileMode::kClamp, DlTileMode::kClamp));
130
131 std::vector<SkPoint> positions = {
132 SkPoint::Make(0, 0), SkPoint::Make(size.width, 0),
133 SkPoint::Make(0, size.height), SkPoint::Make(size.width, 0),
134 SkPoint::Make(0, 0), SkPoint::Make(size.width, size.height),
135 };
136 std::vector<DlColor> colors = {
137 DlColor::kRed().modulateOpacity(0.5),
138 DlColor::kBlue().modulateOpacity(0.5),
139 DlColor::kGreen().modulateOpacity(0.5),
140 DlColor::kRed().modulateOpacity(0.5),
141 DlColor::kBlue().modulateOpacity(0.5),
142 DlColor::kGreen().modulateOpacity(0.5),
143 };
144
145 auto vertices =
146 MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
147
148 builder.DrawVertices(vertices, DlBlendMode::kColorBurn, paint);
149 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
150}

◆ TEST_P() [241/450]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryUVPositionData   
)

Definition at line 47 of file aiks_dl_vertices_unittests.cc.

47 {
50 auto image =
51 DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
52 auto size = image->impeller_texture()->GetSize();
53
54 paint.setColorSource(std::make_shared<DlImageColorSource>(
55 image, DlTileMode::kClamp, DlTileMode::kClamp));
56
57 std::vector<SkPoint> vertex_coordinates = {SkPoint::Make(0, 0),
58 SkPoint::Make(size.width, 0),
59 SkPoint::Make(0, size.height)};
60 auto vertices = MakeVertices(DlVertexMode::kTriangleStrip, vertex_coordinates,
61 {0, 1, 2}, {}, {});
62
63 builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
64 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
65}

◆ TEST_P() [242/450]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryUVPositionDataWithTranslate   
)

Definition at line 68 of file aiks_dl_vertices_unittests.cc.

68 {
71 auto image =
72 DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
73 auto size = image->impeller_texture()->GetSize();
74
76 matrix.setTranslateX(100);
77 matrix.setTranslateY(100);
78 paint.setColorSource(std::make_shared<DlImageColorSource>(
79 image, DlTileMode::kClamp, DlTileMode::kClamp, DlImageSampling::kLinear,
80 &matrix));
81
82 std::vector<SkPoint> positions = {SkPoint::Make(0, 0),
83 SkPoint::Make(size.width, 0),
84 SkPoint::Make(0, size.height)};
85 auto vertices =
86 MakeVertices(DlVertexMode::kTriangleStrip, positions, {0, 1, 2}, {}, {});
87
88 builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
89 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
90}

◆ TEST_P() [243/450]

impeller::testing::TEST_P ( BlendFilterContentsTest  ,
AdvancedBlendColorAlignsColorTo4   
)

Definition at line 45 of file blend_filter_contents_unittests.cc.

45 {
46 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
47 BlendFilterContents filter_contents;
48 filter_contents.SetInputs({FilterInput::Make(texture)});
49 filter_contents.SetForegroundColor(Color(1.0, 0.0, 0.0, 1.0));
50 filter_contents.SetBlendMode(BlendMode::kColorDodge);
51
52 std::shared_ptr<ContentContext> renderer = GetContentContext();
53 // Add random byte to get the HostBuffer in a bad alignment.
54 uint8_t byte = 0xff;
56 renderer->GetTransientsBuffer().Emplace(&byte, /*length=*/1, /*align=*/1);
57 EXPECT_EQ(buffer_view.range.offset, 4u);
58 EXPECT_EQ(buffer_view.range.length, 1u);
59 Entity entity;
60
61 std::optional<Entity> result = filter_contents.GetEntity(
62 *renderer, entity, /*coverage_hint=*/std::nullopt);
63
64 EXPECT_TRUE(result.has_value());
65}
BufferView buffer_view
void SetBlendMode(BlendMode blend_mode)
void SetForegroundColor(std::optional< Color > color)
Sets a source color which is blended after all of the inputs have been blended.
std::optional< Entity > GetEntity(const ContentContext &renderer, const Entity &entity, const std::optional< Rect > &coverage_hint) const
Create an Entity that renders this filter's output.
void SetInputs(FilterInput::Vector inputs)
The input texture sources for this filter. Each input's emitted texture is expected to have premultip...

◆ TEST_P() [244/450]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentPixelFormatsFails   
)

Definition at line 19 of file blit_pass_unittests.cc.

19 {
20 ScopedValidationDisable scope; // avoid noise in output.
21 auto context = GetContext();
22 auto cmd_buffer = context->CreateCommandBuffer();
23 auto blit_pass = cmd_buffer->CreateBlitPass();
24
25 TextureDescriptor src_desc;
26 src_desc.format = PixelFormat::kA8UNormInt;
27 src_desc.size = {100, 100};
28 src_desc.storage_mode = StorageMode::kHostVisible;
29 auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
30
31 TextureDescriptor dst_format;
32 dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
33 dst_format.size = {100, 100};
34 dst_format.storage_mode = StorageMode::kHostVisible;
35 auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
36
37 EXPECT_FALSE(blit_pass->AddCopy(src, dst));
38}

◆ TEST_P() [245/450]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentSampleCountsFails   
)

Definition at line 40 of file blit_pass_unittests.cc.

40 {
41 ScopedValidationDisable scope; // avoid noise in output.
42 auto context = GetContext();
43 auto cmd_buffer = context->CreateCommandBuffer();
44 auto blit_pass = cmd_buffer->CreateBlitPass();
45
46 TextureDescriptor src_desc;
47 src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
48 src_desc.sample_count = SampleCount::kCount4;
49 src_desc.size = {100, 100};
50 auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
51
52 TextureDescriptor dst_format;
53 dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
54 dst_format.size = {100, 100};
55 auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
56
57 EXPECT_FALSE(blit_pass->AddCopy(src, dst));
58}

◆ TEST_P() [246/450]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitPassesForMatchingFormats   
)

Definition at line 60 of file blit_pass_unittests.cc.

60 {
61 ScopedValidationDisable scope; // avoid noise in output.
62 auto context = GetContext();
63 auto cmd_buffer = context->CreateCommandBuffer();
64 auto blit_pass = cmd_buffer->CreateBlitPass();
65
66 TextureDescriptor src_desc;
67 src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
68 src_desc.size = {100, 100};
69 src_desc.storage_mode = StorageMode::kHostVisible;
70 auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
71
72 TextureDescriptor dst_format;
73 dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
74 dst_format.size = {100, 100};
75 dst_format.storage_mode = StorageMode::kHostVisible;
76 auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
77
78 EXPECT_TRUE(blit_pass->AddCopy(src, dst));
79}

◆ TEST_P() [247/450]

impeller::testing::TEST_P ( BlitPassTest  ,
CanBlitSmallRegionToUninitializedTexture   
)

Definition at line 109 of file blit_pass_unittests.cc.

109 {
110 auto context = GetContext();
111 auto cmd_buffer = context->CreateCommandBuffer();
112 auto blit_pass = cmd_buffer->CreateBlitPass();
113
114 TextureDescriptor dst_format;
115 dst_format.storage_mode = StorageMode::kDevicePrivate;
116 dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
117 dst_format.size = {1000, 1000};
118 auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
119
120 DeviceBufferDescriptor src_format;
121 src_format.size = 4;
122 src_format.storage_mode = StorageMode::kHostVisible;
123 auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
124
125 ASSERT_TRUE(dst);
126
127 EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
128 IRect::MakeLTRB(0, 0, 1, 1), "", /*slice=*/0));
129 EXPECT_TRUE(blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()));
130 EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
131}

◆ TEST_P() [248/450]

impeller::testing::TEST_P ( BlitPassTest  ,
ChecksInvalidSliceParameters   
)

Definition at line 81 of file blit_pass_unittests.cc.

81 {
82 ScopedValidationDisable scope; // avoid noise in output.
83 auto context = GetContext();
84 auto cmd_buffer = context->CreateCommandBuffer();
85 auto blit_pass = cmd_buffer->CreateBlitPass();
86
87 TextureDescriptor dst_format;
88 dst_format.storage_mode = StorageMode::kDevicePrivate;
89 dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
90 dst_format.size = {100, 100};
91 auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
92
93 DeviceBufferDescriptor src_format;
94 src_format.size = 40000;
95 src_format.storage_mode = StorageMode::kHostVisible;
96 auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
97
98 ASSERT_TRUE(dst);
99 ASSERT_TRUE(src);
100
101 EXPECT_FALSE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
102 std::nullopt, "", /*slice=*/25));
103 EXPECT_FALSE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
104 std::nullopt, "", /*slice=*/6));
105 EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
106 std::nullopt, "", /*slice=*/0));
107}

◆ TEST_P() [249/450]

impeller::testing::TEST_P ( ComputeTest  ,
1DThreadgroupSizingIsCorrect   
)

Definition at line 175 of file compute_unittests.cc.

175 {
176 using CS = ThreadgroupSizingTestComputeShader;
177 auto context = GetContext();
178 ASSERT_TRUE(context);
179 ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
180
181 using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
182 auto pipeline_desc =
183 SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
184 ASSERT_TRUE(pipeline_desc.has_value());
185 auto compute_pipeline =
186 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
187 ASSERT_TRUE(compute_pipeline);
188
189 auto cmd_buffer = context->CreateCommandBuffer();
190 auto pass = cmd_buffer->CreateComputePass();
191 ASSERT_TRUE(pass && pass->IsValid());
192
193 static constexpr size_t kCount = 2048;
194
195 pass->SetPipeline(compute_pipeline);
196
197 auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
198 context, "Output Buffer");
199
200 CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
201
202 ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
203 ASSERT_TRUE(pass->EncodeCommands());
204
206 ASSERT_TRUE(
207 context->GetCommandQueue()
208 ->Submit({cmd_buffer},
209 [&latch, output_buffer](CommandBuffer::Status status) {
210 EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
211
212 auto view = DeviceBuffer::AsBufferView(output_buffer);
213 EXPECT_EQ(view.range.length,
214 sizeof(CS::OutputData<kCount>));
215
216 CS::OutputData<kCount>* output =
217 reinterpret_cast<CS::OutputData<kCount>*>(
218 output_buffer->OnGetContents());
219 EXPECT_TRUE(output);
220 EXPECT_EQ(output->data[kCount - 1], kCount - 1);
221 latch.Signal();
222 })
223 .ok());
224
225 latch.Wait();
226}
An optional (but highly recommended) utility for creating pipelines from reflected shader information...

◆ TEST_P() [250/450]

impeller::testing::TEST_P ( ComputeTest  ,
CanCompute1DimensionalData   
)

Definition at line 373 of file compute_unittests.cc.

373 {
374 using CS = SampleComputeShader;
375 auto context = GetContext();
376 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
377 ASSERT_TRUE(context);
378 ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
379
380 using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
381 auto pipeline_desc =
382 SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
383 ASSERT_TRUE(pipeline_desc.has_value());
384 auto compute_pipeline =
385 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
386 ASSERT_TRUE(compute_pipeline);
387
388 auto cmd_buffer = context->CreateCommandBuffer();
389 auto pass = cmd_buffer->CreateComputePass();
390 ASSERT_TRUE(pass && pass->IsValid());
391
392 static constexpr size_t kCount = 5;
393
394 pass->SetPipeline(compute_pipeline);
395
396 CS::Info info{.count = kCount};
397 CS::Input0<kCount> input_0;
398 CS::Input1<kCount> input_1;
399 for (size_t i = 0; i < kCount; i++) {
400 input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
401 input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
402 }
403
404 input_0.fixed_array[1] = IPoint32(2, 2);
405 input_1.fixed_array[0] = UintPoint32(3, 3);
406 input_0.some_int = 5;
407 input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
408
409 auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
410 context, "Output Buffer");
411
412 CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
413 CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
414 CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
415 CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
416
417 ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
418 ASSERT_TRUE(pass->EncodeCommands());
419
421 ASSERT_TRUE(
422 context->GetCommandQueue()
423 ->Submit(
424 {cmd_buffer},
425 [&latch, output_buffer, &input_0,
426 &input_1](CommandBuffer::Status status) {
427 EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
428
429 auto view = DeviceBuffer::AsBufferView(output_buffer);
430 EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
431
432 CS::Output<kCount>* output =
433 reinterpret_cast<CS::Output<kCount>*>(
434 output_buffer->OnGetContents());
435 EXPECT_TRUE(output);
436 for (size_t i = 0; i < kCount; i++) {
437 Vector4 vector = output->elements[i];
438 Vector4 computed = input_0.elements[i] * input_1.elements[i];
439 EXPECT_EQ(vector,
440 Vector4(computed.x + 2 + input_1.some_struct.i,
441 computed.y + 3 + input_1.some_struct.vf.x,
442 computed.z + 5 + input_1.some_struct.vf.y,
443 computed.w));
444 }
445 latch.Signal();
446 })
447 .ok());
448
449 latch.Wait();
450}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
TPoint< int32_t > IPoint32
Definition: point.h:324
TPoint< uint32_t > UintPoint32
Definition: point.h:325
Task::Status Status
Definition: TaskList.cpp:15

◆ TEST_P() [251/450]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSum   
)

Definition at line 109 of file compute_unittests.cc.

109 {
110 using CS = PrefixSumTestComputeShader;
111 auto context = GetContext();
112 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
113 ASSERT_TRUE(context);
114 ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
115
116 using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
117 auto pipeline_desc =
118 SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
119 ASSERT_TRUE(pipeline_desc.has_value());
120 auto compute_pipeline =
121 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
122 ASSERT_TRUE(compute_pipeline);
123
124 auto cmd_buffer = context->CreateCommandBuffer();
125 auto pass = cmd_buffer->CreateComputePass();
126 ASSERT_TRUE(pass && pass->IsValid());
127
128 static constexpr size_t kCount = 5;
129
130 pass->SetPipeline(compute_pipeline);
131
132 CS::InputData<kCount> input_data;
133 input_data.count = kCount;
134 for (size_t i = 0; i < kCount; i++) {
135 input_data.data[i] = 1 + i;
136 }
137
138 auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
139 context, "Output Buffer");
140
141 CS::BindInputData(*pass, host_buffer->EmplaceStorageBuffer(input_data));
142 CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
143
144 ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
145 ASSERT_TRUE(pass->EncodeCommands());
146
148 ASSERT_TRUE(
149 context->GetCommandQueue()
150 ->Submit({cmd_buffer},
151 [&latch, output_buffer](CommandBuffer::Status status) {
152 EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
153
154 auto view = DeviceBuffer::AsBufferView(output_buffer);
155 EXPECT_EQ(view.range.length,
156 sizeof(CS::OutputData<kCount>));
157
158 CS::OutputData<kCount>* output =
159 reinterpret_cast<CS::OutputData<kCount>*>(
160 output_buffer->OnGetContents());
161 EXPECT_TRUE(output);
162
163 constexpr uint32_t expected[kCount] = {1, 3, 6, 10, 15};
164 for (size_t i = 0; i < kCount; i++) {
165 auto computed_sum = output->data[i];
166 EXPECT_EQ(computed_sum, expected[i]);
167 }
168 latch.Signal();
169 })
170 .ok());
171
172 latch.Wait();
173}
for(const auto glyph :glyphs)
Definition: FontMgrTest.cpp:52

◆ TEST_P() [252/450]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSumLargeInteractive   
)

Definition at line 228 of file compute_unittests.cc.

228 {
229 using CS = PrefixSumTestComputeShader;
230
231 auto context = GetContext();
232 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
233
234 ASSERT_TRUE(context);
235 ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
236
237 auto callback = [&](RenderPass& render_pass) -> bool {
238 using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
239 auto pipeline_desc =
240 SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
241 auto compute_pipeline =
242 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
243
244 auto cmd_buffer = context->CreateCommandBuffer();
245 auto pass = cmd_buffer->CreateComputePass();
246
247 static constexpr size_t kCount = 1023;
248
249 pass->SetPipeline(compute_pipeline);
250
251 CS::InputData<kCount> input_data;
252 input_data.count = kCount;
253 for (size_t i = 0; i < kCount; i++) {
254 input_data.data[i] = 1 + i;
255 }
256
257 auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
258 context, "Output Buffer");
259
260 CS::BindInputData(*pass, host_buffer->EmplaceStorageBuffer(input_data));
261 CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
262
263 pass->Compute(ISize(kCount, 1));
264 pass->EncodeCommands();
265 host_buffer->Reset();
266 return context->GetCommandQueue()->Submit({cmd_buffer}).ok();
267 };
268 ASSERT_TRUE(OpenPlaygroundHere(callback));
269}
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:33

◆ TEST_P() [253/450]

impeller::testing::TEST_P ( ComputeTest  ,
CanCreateComputePass   
)

Definition at line 30 of file compute_unittests.cc.

30 {
31 using CS = SampleComputeShader;
32 auto context = GetContext();
33 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
34 ASSERT_TRUE(context);
35 ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
36
37 using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
38 auto pipeline_desc =
39 SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
40 ASSERT_TRUE(pipeline_desc.has_value());
41 auto compute_pipeline =
42 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
43 ASSERT_TRUE(compute_pipeline);
44
45 auto cmd_buffer = context->CreateCommandBuffer();
46 auto pass = cmd_buffer->CreateComputePass();
47 ASSERT_TRUE(pass && pass->IsValid());
48
49 static constexpr size_t kCount = 5;
50
51 pass->SetPipeline(compute_pipeline);
52
53 CS::Info info{.count = kCount};
54 CS::Input0<kCount> input_0;
55 CS::Input1<kCount> input_1;
56 for (size_t i = 0; i < kCount; i++) {
57 input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
58 input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
59 }
60
61 input_0.fixed_array[1] = IPoint32(2, 2);
62 input_1.fixed_array[0] = UintPoint32(3, 3);
63 input_0.some_int = 5;
64 input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
65
66 auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
67 context, "Output Buffer");
68
69 CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
70 CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
71 CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
72 CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
73
74 ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
75 ASSERT_TRUE(pass->EncodeCommands());
76
78 ASSERT_TRUE(
79 context->GetCommandQueue()
80 ->Submit(
81 {cmd_buffer},
82 [&latch, output_buffer, &input_0,
83 &input_1](CommandBuffer::Status status) {
84 EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
85
86 auto view = DeviceBuffer::AsBufferView(output_buffer);
87 EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
88
89 CS::Output<kCount>* output =
90 reinterpret_cast<CS::Output<kCount>*>(
91 output_buffer->OnGetContents());
92 EXPECT_TRUE(output);
93 for (size_t i = 0; i < kCount; i++) {
94 Vector4 vector = output->elements[i];
95 Vector4 computed = input_0.elements[i] * input_1.elements[i];
96 EXPECT_EQ(vector,
97 Vector4(computed.x + 2 + input_1.some_struct.i,
98 computed.y + 3 + input_1.some_struct.vf.x,
99 computed.z + 5 + input_1.some_struct.vf.y,
100 computed.w));
101 }
102 latch.Signal();
103 })
104 .ok());
105
106 latch.Wait();
107}

◆ TEST_P() [254/450]

impeller::testing::TEST_P ( ComputeTest  ,
CapabilitiesReportSupport   
)

Definition at line 24 of file compute_unittests.cc.

24 {
25 auto context = GetContext();
26 ASSERT_TRUE(context);
27 ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
28}

◆ TEST_P() [255/450]

impeller::testing::TEST_P ( ComputeTest  ,
MultiStageInputAndOutput   
)

Definition at line 271 of file compute_unittests.cc.

271 {
272 using CS1 = Stage1ComputeShader;
273 using Stage1PipelineBuilder = ComputePipelineBuilder<CS1>;
274 using CS2 = Stage2ComputeShader;
275 using Stage2PipelineBuilder = ComputePipelineBuilder<CS2>;
276
277 auto context = GetContext();
278 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
279 ASSERT_TRUE(context);
280 ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
281
282 auto pipeline_desc_1 =
283 Stage1PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
284 ASSERT_TRUE(pipeline_desc_1.has_value());
285 auto compute_pipeline_1 =
286 context->GetPipelineLibrary()->GetPipeline(pipeline_desc_1).Get();
287 ASSERT_TRUE(compute_pipeline_1);
288
289 auto pipeline_desc_2 =
290 Stage2PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
291 ASSERT_TRUE(pipeline_desc_2.has_value());
292 auto compute_pipeline_2 =
293 context->GetPipelineLibrary()->GetPipeline(pipeline_desc_2).Get();
294 ASSERT_TRUE(compute_pipeline_2);
295
296 auto cmd_buffer = context->CreateCommandBuffer();
297 auto pass = cmd_buffer->CreateComputePass();
298 ASSERT_TRUE(pass && pass->IsValid());
299
300 static constexpr size_t kCount1 = 5;
301 static constexpr size_t kCount2 = kCount1 * 2;
302
303 CS1::Input<kCount1> input_1;
304 input_1.count = kCount1;
305 for (size_t i = 0; i < kCount1; i++) {
306 input_1.elements[i] = i;
307 }
308
309 CS2::Input<kCount2> input_2;
310 input_2.count = kCount2;
311 for (size_t i = 0; i < kCount2; i++) {
312 input_2.elements[i] = i;
313 }
314
315 auto output_buffer_1 = CreateHostVisibleDeviceBuffer<CS1::Output<kCount2>>(
316 context, "Output Buffer Stage 1");
317 auto output_buffer_2 = CreateHostVisibleDeviceBuffer<CS2::Output<kCount2>>(
318 context, "Output Buffer Stage 2");
319
320 {
321 pass->SetPipeline(compute_pipeline_1);
322
323 CS1::BindInput(*pass, host_buffer->EmplaceStorageBuffer(input_1));
324 CS1::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer_1));
325
326 ASSERT_TRUE(pass->Compute(ISize(512, 1)).ok());
327 pass->AddBufferMemoryBarrier();
328 }
329
330 {
331 pass->SetPipeline(compute_pipeline_2);
332
333 CS1::BindInput(*pass, DeviceBuffer::AsBufferView(output_buffer_1));
334 CS2::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer_2));
335 ASSERT_TRUE(pass->Compute(ISize(512, 1)).ok());
336 }
337
338 ASSERT_TRUE(pass->EncodeCommands());
339
341 ASSERT_TRUE(
342 context->GetCommandQueue()
343 ->Submit({cmd_buffer},
344 [&latch, &output_buffer_1,
345 &output_buffer_2](CommandBuffer::Status status) {
346 EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
347
348 CS1::Output<kCount2>* output_1 =
349 reinterpret_cast<CS1::Output<kCount2>*>(
350 output_buffer_1->OnGetContents());
351 EXPECT_TRUE(output_1);
352 EXPECT_EQ(output_1->count, 10u);
353 EXPECT_THAT(
354 output_1->elements,
355 ::testing::ElementsAre(0, 0, 2, 3, 4, 6, 6, 9, 8, 12));
356
357 CS2::Output<kCount2>* output_2 =
358 reinterpret_cast<CS2::Output<kCount2>*>(
359 output_buffer_2->OnGetContents());
360 EXPECT_TRUE(output_2);
361 EXPECT_EQ(output_2->count, 10u);
362 EXPECT_THAT(output_2->elements,
363 ::testing::ElementsAre(0, 0, 4, 6, 8, 12, 12,
364 18, 16, 24));
365
366 latch.Signal();
367 })
368 .ok());
369
370 latch.Wait();
371}

◆ TEST_P() [256/450]

impeller::testing::TEST_P ( ComputeTest  ,
ReturnsEarlyWhenAnyGridDimensionIsZero   
)

Definition at line 452 of file compute_unittests.cc.

452 {
453 using CS = SampleComputeShader;
454 auto context = GetContext();
455 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
456 ASSERT_TRUE(context);
457 ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
458
459 using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
460 auto pipeline_desc =
461 SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
462 ASSERT_TRUE(pipeline_desc.has_value());
463 auto compute_pipeline =
464 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
465 ASSERT_TRUE(compute_pipeline);
466
467 auto cmd_buffer = context->CreateCommandBuffer();
468 auto pass = cmd_buffer->CreateComputePass();
469 ASSERT_TRUE(pass && pass->IsValid());
470
471 static constexpr size_t kCount = 5;
472
473 pass->SetPipeline(compute_pipeline);
474
475 CS::Info info{.count = kCount};
476 CS::Input0<kCount> input_0;
477 CS::Input1<kCount> input_1;
478 for (size_t i = 0; i < kCount; i++) {
479 input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
480 input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
481 }
482
483 input_0.fixed_array[1] = IPoint32(2, 2);
484 input_1.fixed_array[0] = UintPoint32(3, 3);
485 input_0.some_int = 5;
486 input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
487
488 auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
489 context, "Output Buffer");
490
491 CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
492 CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
493 CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
494 CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
495
496 // Intentionally making the grid size zero in one dimension. No GPU will
497 // tolerate this.
498 EXPECT_FALSE(pass->Compute(ISize(0, 1)).ok());
499 pass->EncodeCommands();
500}

◆ TEST_P() [257/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanBlendDstOverAndDstCorrectly   
)

Definition at line 1238 of file dl_unittests.cc.

1238 {
1240
1241 {
1242 builder.SaveLayer(nullptr, nullptr);
1243 builder.Translate(100, 100);
1245 paint.setColor(flutter::DlColor::kRed());
1246 builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1247 paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1249 builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1250 builder.Restore();
1251 }
1252 {
1253 builder.SaveLayer(nullptr, nullptr);
1254 builder.Translate(300, 100);
1256 paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1257 builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1258 paint.setColor(flutter::DlColor::kRed());
1260 builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1261 builder.Restore();
1262 }
1263 {
1264 builder.SaveLayer(nullptr, nullptr);
1265 builder.Translate(100, 300);
1267 paint.setColor(flutter::DlColor::kRed());
1268 builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1269 paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1270 paint.setBlendMode(flutter::DlBlendMode::kSrc);
1271 builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1272 builder.Restore();
1273 }
1274 {
1275 builder.SaveLayer(nullptr, nullptr);
1276 builder.Translate(300, 300);
1278 paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1279 builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1280 paint.setColor(flutter::DlColor::kRed());
1281 paint.setBlendMode(flutter::DlBlendMode::kDst);
1282 builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1283 builder.Restore();
1284 }
1285
1286 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1287}
@ kDstOver
r = d + (1-da)*s
static constexpr SkRect MakeSize(const SkSize &size)
Definition: SkRect.h:633

◆ TEST_P() [258/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanClampTheResultingColorOfColorMatrixFilter   
)

Definition at line 616 of file dl_unittests.cc.

616 {
617 auto texture = CreateTextureForFixture("boston.jpg");
618 const float inner_color_matrix[20] = {
619 1, 0, 0, 0, 0, //
620 0, 1, 0, 0, 0, //
621 0, 0, 1, 0, 0, //
622 0, 0, 0, 2, 0, //
623 };
624 const float outer_color_matrix[20] = {
625 1, 0, 0, 0, 0, //
626 0, 1, 0, 0, 0, //
627 0, 0, 1, 0, 0, //
628 0, 0, 0, 0.5, 0, //
629 };
630 auto inner_color_filter =
631 std::make_shared<flutter::DlMatrixColorFilter>(inner_color_matrix);
632 auto outer_color_filter =
633 std::make_shared<flutter::DlMatrixColorFilter>(outer_color_matrix);
634 auto inner =
635 std::make_shared<flutter::DlColorFilterImageFilter>(inner_color_filter);
636 auto outer =
637 std::make_shared<flutter::DlColorFilterImageFilter>(outer_color_filter);
638 auto compose = std::make_shared<flutter::DlComposeImageFilter>(outer, inner);
639
642 paint.setImageFilter(compose.get());
645 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
646}

◆ TEST_P() [259/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawAnOpenPath   
)

Definition at line 406 of file dl_unittests.cc.

406 {
409
410 paint.setColor(flutter::DlColor::kRed());
412 paint.setStrokeWidth(10);
413
414 builder.Translate(300, 300);
415
416 // Move to (50, 50) and draw lines from:
417 // 1. (50, height)
418 // 2. (width, height)
419 // 3. (width, 50)
420 SkPath path;
421 path.moveTo(50, 50);
422 path.lineTo(50, 100);
423 path.lineTo(100, 100);
424 path.lineTo(100, 50);
425 builder.DrawPath(path, paint);
426
427 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
428}
@ kStroke
strokes boundary of shapes

◆ TEST_P() [260/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawArc   
)

Definition at line 152 of file dl_unittests.cc.

152 {
153 auto callback = [&]() {
154 static float start_angle = 45;
155 static float sweep_angle = 270;
156 static float stroke_width = 10;
157 static bool use_center = true;
158
159 static int selected_cap = 0;
160 const char* cap_names[] = {"Butt", "Round", "Square"};
162
163 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
164 ImGui::SliderFloat("Start angle", &start_angle, -360, 360);
165 ImGui::SliderFloat("Sweep angle", &sweep_angle, -360, 360);
166 ImGui::SliderFloat("Stroke width", &stroke_width, 0, 300);
167 ImGui::Combo("Cap", &selected_cap, cap_names,
168 sizeof(cap_names) / sizeof(char*));
169 ImGui::Checkbox("Use center", &use_center);
170 ImGui::End();
171
172 switch (selected_cap) {
173 case 0:
175 break;
176 case 1:
178 break;
179 case 2:
181 break;
182 default:
184 break;
185 }
186
187 static PlaygroundPoint point_a(Point(200, 200), 20, Color::White());
188 static PlaygroundPoint point_b(Point(400, 400), 20, Color::White());
189 auto [p1, p2] = DrawPlaygroundLine(point_a, point_b);
190
193
194 Vector2 scale = GetContentScale();
195 builder.Scale(scale.x, scale.y);
197 paint.setStrokeCap(cap);
199 paint.setStrokeMiter(10);
200 auto rect = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
202 paint.setStrokeWidth(2);
203 builder.DrawRect(rect, paint);
204 paint.setColor(flutter::DlColor::kRed());
205 paint.setStrokeWidth(stroke_width);
206 builder.DrawArc(rect, start_angle, sweep_angle, use_center, paint);
207
208 return builder.Build();
209 };
210 ASSERT_TRUE(OpenPlaygroundHere(callback));
211}
@ kMiter
extends to miter limit
DlStrokeCap
Definition: dl_paint.h:28
@ kRound
adds circle
@ kButt
no stroke extension
@ kSquare
adds square
const Scalar stroke_width

◆ TEST_P() [261/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawBackdropFilter   
)

Definition at line 648 of file dl_unittests.cc.

648 {
649 auto texture = CreateTextureForFixture("embarcadero.jpg");
650
651 auto callback = [&]() {
652 static float sigma[] = {10, 10};
653 static float ctm_scale = 1;
654 static bool use_bounds = true;
655 static bool draw_circle = true;
656 static bool add_clip = true;
657
658 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
659 ImGui::SliderFloat2("Sigma", sigma, 0, 100);
660 ImGui::SliderFloat("Scale", &ctm_scale, 0, 10);
661 ImGui::NewLine();
662 ImGui::TextWrapped(
663 "If everything is working correctly, none of the options below should "
664 "impact the filter's appearance.");
665 ImGui::Checkbox("Use SaveLayer bounds", &use_bounds);
666 ImGui::Checkbox("Draw child element", &draw_circle);
667 ImGui::Checkbox("Add pre-clip", &add_clip);
668 ImGui::End();
669
671
672 Vector2 scale = ctm_scale * GetContentScale();
673 builder.Scale(scale.x, scale.y);
674
675 auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
677
678 std::optional<SkRect> bounds;
679 if (use_bounds) {
680 static PlaygroundPoint point_a(Point(350, 150), 20, Color::White());
681 static PlaygroundPoint point_b(Point(800, 600), 20, Color::White());
682 auto [p1, p2] = DrawPlaygroundLine(point_a, point_b);
683 bounds = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
684 }
685
686 // Insert a clip to test that the backdrop filter handles stencil depths > 0
687 // correctly.
688 if (add_clip) {
689 builder.ClipRect(SkRect::MakeLTRB(0, 0, 99999, 99999),
691 }
692
695 builder.SaveLayer(bounds.has_value() ? &bounds.value() : nullptr, nullptr,
696 &filter);
697
698 if (draw_circle) {
699 static PlaygroundPoint center_point(Point(500, 400), 20, Color::Red());
700 auto circle_center = DrawPlaygroundPoint(center_point);
701
706 paint.setStrokeWidth(10);
707 paint.setColor(flutter::DlColor::kRed().withAlpha(100));
708 builder.DrawCircle({circle_center.x, circle_center.y}, 100, paint);
709 }
710
711 return builder.Build();
712 };
713
714 ASSERT_TRUE(OpenPlaygroundHere(callback));
715}
@ kBevel
connects outside edges

◆ TEST_P() [262/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCapsAndJoins   
)

Definition at line 106 of file dl_unittests.cc.

106 {
109
111 paint.setStrokeWidth(30);
112 paint.setColor(flutter::DlColor::kRed());
113
114 auto path =
115 SkPathBuilder{}.moveTo(-50, 0).lineTo(0, -50).lineTo(50, 0).snapshot();
116
117 builder.Translate(100, 100);
118 {
121 paint.setStrokeMiter(4);
122 builder.DrawPath(path, paint);
123 }
124
125 {
126 builder.Save();
127 builder.Translate(0, 100);
128 // The joint in the path is 45 degrees. A miter length of 1 convert to a
129 // bevel in this case.
130 paint.setStrokeMiter(1);
131 builder.DrawPath(path, paint);
132 builder.Restore();
133 }
134
135 builder.Translate(150, 0);
136 {
139 builder.DrawPath(path, paint);
140 }
141
142 builder.Translate(150, 0);
143 {
146 builder.DrawPath(path, paint);
147 }
148
149 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
150}
SkPathBuilder & lineTo(SkPoint pt)
SkPathBuilder & moveTo(SkPoint pt)
SkPath snapshot() const

◆ TEST_P() [263/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCorrectlyWithColorFilterAndImageFilter   
)

Definition at line 1289 of file dl_unittests.cc.

1289 {
1291 const float green_color_matrix[20] = {
1292 0, 0, 0, 0, 0, //
1293 0, 0, 0, 0, 1, //
1294 0, 0, 0, 0, 0, //
1295 0, 0, 0, 1, 0, //
1296 };
1297 const float blue_color_matrix[20] = {
1298 0, 0, 0, 0, 0, //
1299 0, 0, 0, 0, 0, //
1300 0, 0, 0, 0, 1, //
1301 0, 0, 0, 1, 0, //
1302 };
1303 auto green_color_filter =
1304 std::make_shared<flutter::DlMatrixColorFilter>(green_color_matrix);
1305 auto blue_color_filter =
1306 std::make_shared<flutter::DlMatrixColorFilter>(blue_color_matrix);
1307 auto blue_image_filter =
1308 std::make_shared<flutter::DlColorFilterImageFilter>(blue_color_filter);
1309
1311 paint.setColor(flutter::DlColor::kRed());
1312 paint.setColorFilter(green_color_filter);
1313 paint.setImageFilter(blue_image_filter);
1314 builder.DrawRect(SkRect::MakeLTRB(100, 100, 500, 500), paint);
1315 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1316}

◆ TEST_P() [264/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawImage   
)

Definition at line 98 of file dl_unittests.cc.

98 {
99 auto texture = CreateTextureForFixture("embarcadero.jpg");
103 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
104}

◆ TEST_P() [265/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImage   
)

Definition at line 717 of file dl_unittests.cc.

717 {
718 // Image is drawn with corners to scale and center pieces stretched to fit.
719 auto texture = CreateTextureForFixture("embarcadero.jpg");
721 auto size = texture->GetSize();
722 builder.DrawImageNine(
724 SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
725 size.height * 3 / 4),
726 SkRect::MakeLTRB(0, 0, size.width * 2, size.height * 2),
728 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
729}
static constexpr SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
Definition: SkRect.h:91

◆ TEST_P() [266/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterBiggerThanDest   
)

Definition at line 763 of file dl_unittests.cc.

763 {
764 // Edge case, the width and height of the corners does not leave any
765 // room for the center slices. Only the corners are displayed.
766 auto texture = CreateTextureForFixture("embarcadero.jpg");
768 auto size = texture->GetSize();
769 builder.DrawImageNine(
771 SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
772 size.height * 3 / 4),
773 SkRect::MakeLTRB(0, 0, size.width / 2, size.height / 2),
775 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
776}

◆ TEST_P() [267/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterHeightBiggerThanDest   
)

Definition at line 747 of file dl_unittests.cc.

747 {
748 // Edge case, the height of the corners does not leave any room for the
749 // center slice. The center (across the horizontal axis) is folded out of the
750 // resulting image.
751 auto texture = CreateTextureForFixture("embarcadero.jpg");
753 auto size = texture->GetSize();
754 builder.DrawImageNine(
756 SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
757 size.height * 3 / 4),
758 SkRect::MakeLTRB(0, 0, size.width, size.height / 2),
760 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
761}

◆ TEST_P() [268/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterWidthBiggerThanDest   
)

Definition at line 731 of file dl_unittests.cc.

731 {
732 // Edge case, the width of the corners does not leave any room for the
733 // center slice. The center (across the vertical axis) is folded out of the
734 // resulting image.
735 auto texture = CreateTextureForFixture("embarcadero.jpg");
737 auto size = texture->GetSize();
738 builder.DrawImageNine(
740 SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
741 size.height * 3 / 4),
742 SkRect::MakeLTRB(0, 0, size.width / 2, size.height),
744 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
745}

◆ TEST_P() [269/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCornersScaledDown   
)

Definition at line 778 of file dl_unittests.cc.

778 {
779 // Edge case, there is not enough room for the corners to be drawn
780 // without scaling them down.
781 auto texture = CreateTextureForFixture("embarcadero.jpg");
783 auto size = texture->GetSize();
784 builder.DrawImageNine(
786 SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
787 size.height * 3 / 4),
788 SkRect::MakeLTRB(0, 0, size.width / 4, size.height / 4),
790 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
791}

◆ TEST_P() [270/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPaintWithColorSource   
)

Definition at line 1186 of file dl_unittests.cc.

1186 {
1187 const flutter::DlColor colors[2] = {
1188 flutter::DlColor(0xFFF44336),
1189 flutter::DlColor(0xFF2196F3),
1190 };
1191 const float stops[2] = {0.0, 1.0};
1194 auto clip_bounds = SkRect::MakeWH(300.0, 300.0);
1195 builder.Save();
1196 builder.Translate(100, 100);
1197 builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1198 auto linear =
1199 flutter::DlColorSource::MakeLinear({0.0, 0.0}, {100.0, 100.0}, 2, colors,
1201 paint.setColorSource(linear);
1202 builder.DrawPaint(paint);
1203 builder.Restore();
1204
1205 builder.Save();
1206 builder.Translate(500, 100);
1207 builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1209 {100.0, 100.0}, 100.0, 2, colors, stops, flutter::DlTileMode::kRepeat);
1210 paint.setColorSource(radial);
1211 builder.DrawPaint(paint);
1212 builder.Restore();
1213
1214 builder.Save();
1215 builder.Translate(100, 500);
1216 builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1217 auto sweep =
1218 flutter::DlColorSource::MakeSweep({100.0, 100.0}, 180.0, 270.0, 2, colors,
1220 paint.setColorSource(sweep);
1221 builder.DrawPaint(paint);
1222 builder.Restore();
1223
1224 builder.Save();
1225 builder.Translate(500, 500);
1226 builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1227 auto texture = CreateTextureForFixture("table_mountain_nx.png");
1228 auto image = std::make_shared<flutter::DlImageColorSource>(
1231 paint.setColorSource(image);
1232 builder.DrawPaint(paint);
1233 builder.Restore();
1234
1235 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1236}
static std::shared_ptr< DlSweepGradientColorSource > MakeSweep(SkPoint center, SkScalar start, SkScalar end, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const SkMatrix *matrix=nullptr)
static std::shared_ptr< DlRadialGradientColorSource > MakeRadial(SkPoint center, SkScalar radius, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const SkMatrix *matrix=nullptr)
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609

◆ TEST_P() [271/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPoints   
)

Definition at line 805 of file dl_unittests.cc.

805 {
807 SkPoint points[7] = {
808 {0, 0}, //
809 {100, 100}, //
810 {100, 0}, //
811 {0, 100}, //
812 {0, 0}, //
813 {48, 48}, //
814 {52, 52}, //
815 };
816 std::vector<flutter::DlStrokeCap> caps = {
820 };
823 .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
824 .setStrokeWidth(20);
825 builder.Translate(50, 50);
826 for (auto cap : caps) {
827 paint.setStrokeCap(cap);
828 builder.Save();
830 builder.Translate(150, 0);
832 builder.Translate(150, 0);
834 paint);
835 builder.Restore();
836 builder.Translate(0, 150);
837 }
838 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
839}
@ kLines
draw each separate pair of points as a line segment
@ kPolygon
draw each pair of overlapping points as a line segment
@ kPoints
draw each point separately
DlPaint & setStrokeWidth(float width)
Definition: dl_paint.h:116
static constexpr DlColor kYellow()
Definition: dl_color.h:29

◆ TEST_P() [272/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRect   
)

Definition at line 49 of file dl_unittests.cc.

49 {
51 builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100),
53 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
54}

◆ TEST_P() [273/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRectWithLinearToSrgbColorFilter   
)

Definition at line 1170 of file dl_unittests.cc.

1170 {
1172 paint.setColor(flutter::DlColor(0xFF2196F3).withAlpha(128));
1174 paint.setColorFilter(
1176 builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1177 builder.Translate(0, 200);
1178
1179 paint.setColorFilter(
1181 builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1182
1183 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1184}
static const std::shared_ptr< DlLinearToSrgbGammaColorFilter > kInstance
static const std::shared_ptr< DlSrgbToLinearGammaColorFilter > kInstance
const myers::Point & get(const myers::Segment &)

◆ TEST_P() [274/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawShadow   
)

Definition at line 864 of file dl_unittests.cc.

864 {
867
868 auto content_scale = GetContentScale() * 0.8;
869 builder.Scale(content_scale.x, content_scale.y);
870
871 constexpr size_t star_spikes = 5;
872 constexpr SkScalar half_spike_rotation = kPi / star_spikes;
873 constexpr SkScalar radius = 40;
874 constexpr SkScalar spike_size = 10;
875 constexpr SkScalar outer_radius = radius + spike_size;
876 constexpr SkScalar inner_radius = radius - spike_size;
877 std::array<SkPoint, star_spikes * 2> star;
878 for (size_t i = 0; i < star_spikes; i++) {
879 const SkScalar rotation = half_spike_rotation * i * 2;
880 star[i * 2] = SkPoint::Make(50 + std::sin(rotation) * outer_radius,
881 50 - std::cos(rotation) * outer_radius);
882 star[i * 2 + 1] = SkPoint::Make(
883 50 + std::sin(rotation + half_spike_rotation) * inner_radius,
884 50 - std::cos(rotation + half_spike_rotation) * inner_radius);
885 }
886
887 std::array<SkPath, 4> paths = {
888 SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100)),
890 SkRRect::MakeRectXY(SkRect::MakeXYWH(20, 0, 200, 100), 30, 30)),
891 SkPath{}.addCircle(100, 50, 50),
892 SkPath{}.addPoly(star.data(), star.size(), true),
893 };
895 builder.DrawPaint(paint);
896 paint.setColor(flutter::DlColor::kCyan());
897 builder.Translate(100, 50);
898 for (size_t x = 0; x < paths.size(); x++) {
899 builder.Save();
900 for (size_t y = 0; y < 6; y++) {
901 builder.DrawShadow(paths[x], flutter::DlColor::kBlack(), 3 + y * 8, false,
902 1);
903 builder.DrawPath(paths[x], paint);
904 builder.Translate(0, 150);
905 }
906 builder.Restore();
907 builder.Translate(250, 0);
908 }
909
910 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
911}
SkPath & addPoly(const SkPoint pts[], int count, bool close)
Definition: SkPath.cpp:890
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
Definition: SkPath.cpp:864
float SkScalar
Definition: extension.cpp:12
static constexpr DlColor kBlack()
Definition: dl_color.h:22
static constexpr DlColor kCyan()
Definition: dl_color.h:27

◆ TEST_P() [275/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawStrokedText   
)

Definition at line 466 of file dl_unittests.cc.

466 {
469
471 paint.setColor(flutter::DlColor::kRed());
472 builder.DrawTextBlob(
473 SkTextBlob::MakeFromString("stoked about stroked text", CreateTestFont()),
474 250, 250, paint);
475
476 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
477}

◆ TEST_P() [276/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlob   
)

Definition at line 56 of file dl_unittests.cc.

56 {
58 builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
60 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
61}

◆ TEST_P() [277/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlobWithGradient   
)

Definition at line 63 of file dl_unittests.cc.

63 {
65
66 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
68 const float stops[2] = {0.0, 1.0};
69
70 auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
71 2, colors.data(), stops,
74 paint.setColorSource(linear);
75
76 builder.DrawTextBlob(
77 SkTextBlob::MakeFromString("Hello World", CreateTestFont()), 100, 100,
78 paint);
79 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
80}

◆ TEST_P() [278/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextWithSaveLayer   
)

Definition at line 82 of file dl_unittests.cc.

82 {
84 builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
86
87 flutter::DlPaint save_paint;
88 float alpha = 0.5;
89 save_paint.setAlpha(static_cast<uint8_t>(255 * alpha));
90 builder.SaveLayer(nullptr, &save_paint);
91 builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello with half alpha",
94 builder.Restore();
95 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
96}
DlPaint & setAlpha(uint8_t alpha)
Definition: dl_paint.h:76
SkFont CreateTestFontOfSize(SkScalar scalar)

◆ TEST_P() [279/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithBlendColorFilter   
)

Definition at line 518 of file dl_unittests.cc.

518 {
519 auto texture = CreateTextureForFixture("embarcadero.jpg");
522
523 // Pipeline blended image.
524 {
527 paint.setColorFilter(&filter);
530 }
531
532 // Advanced blended image.
533 {
536 paint.setColorFilter(&filter);
539 }
540
541 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
542}
@ kScreen
r = s + d - s*d

◆ TEST_P() [280/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithColorFilterImageFilter   
)

Definition at line 544 of file dl_unittests.cc.

544 {
545 const float invert_color_matrix[20] = {
546 -1, 0, 0, 0, 1, //
547 0, -1, 0, 0, 1, //
548 0, 0, -1, 0, 1, //
549 0, 0, 0, 1, 0, //
550 };
551 auto texture = CreateTextureForFixture("boston.jpg");
554
555 auto color_filter =
556 std::make_shared<flutter::DlMatrixColorFilter>(invert_color_matrix);
557 auto image_filter =
558 std::make_shared<flutter::DlColorFilterImageFilter>(color_filter);
559
560 paint.setImageFilter(image_filter.get());
563
564 builder.Translate(0, 700);
565 paint.setColorFilter(color_filter.get());
568 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
569}
static sk_sp< SkImage > color_filter(const SkImage *image, SkColorFilter *colorFilter)
T * get() const
Definition: SkRefCnt.h:303

◆ TEST_P() [281/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithComposeImageFilter   
)

Definition at line 596 of file dl_unittests.cc.

596 {
597 auto texture = CreateTextureForFixture("boston.jpg");
600
601 auto dilate = std::make_shared<flutter::DlDilateImageFilter>(10.0, 10.0);
602 auto erode = std::make_shared<flutter::DlErodeImageFilter>(10.0, 10.0);
603 auto open = std::make_shared<flutter::DlComposeImageFilter>(dilate, erode);
604 auto close = std::make_shared<flutter::DlComposeImageFilter>(erode, dilate);
605
606 paint.setImageFilter(open.get());
609 builder.Translate(0, 700);
610 paint.setImageFilter(close.get());
613 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
614}

◆ TEST_P() [282/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithImageBlurFilter   
)

Definition at line 571 of file dl_unittests.cc.

571 {
572 auto texture = CreateTextureForFixture("embarcadero.jpg");
573
574 auto callback = [&]() {
575 static float sigma[] = {10, 10};
576
577 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
578 ImGui::SliderFloat2("Sigma", sigma, 0, 100);
579 ImGui::End();
580
583
584 auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
586 paint.setImageFilter(&filter);
589
590 return builder.Build();
591 };
592
593 ASSERT_TRUE(OpenPlaygroundHere(callback));
594}

◆ TEST_P() [283/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMaskBlur   
)

Definition at line 430 of file dl_unittests.cc.

430 {
431 auto texture = CreateTextureForFixture("embarcadero.jpg");
434
435 // Mask blurred image.
436 {
437 auto filter =
439 paint.setMaskFilter(&filter);
442 }
443
444 // Mask blurred filled path.
445 {
447 auto filter =
449 paint.setMaskFilter(&filter);
450 builder.DrawArc(SkRect::MakeXYWH(410, 110, 100, 100), 45, 270, true, paint);
451 }
452
453 // Mask blurred text.
454 {
455 auto filter =
457 paint.setMaskFilter(&filter);
458 builder.DrawTextBlob(
459 SkTextBlob::MakeFromString("Testing", CreateTestFont()), 220, 170,
460 paint);
461 }
462
463 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
464}
@ kNormal
fuzzy inside and outside
@ kOuter
nothing inside, fuzzy outside
@ kSolid
solid inside, fuzzy outside

◆ TEST_P() [284/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilter   
)

Definition at line 1010 of file dl_unittests.cc.

1010 {
1011 auto boston = CreateTextureForFixture("boston.jpg");
1012
1013 auto callback = [&]() {
1014 static int selected_matrix_type = 0;
1015 const char* matrix_type_names[] = {"Matrix", "Local Matrix"};
1016
1017 static float ctm_translation[2] = {200, 200};
1018 static float ctm_scale[2] = {0.65, 0.65};
1019 static float ctm_skew[2] = {0, 0};
1020
1021 static bool enable = true;
1022 static float translation[2] = {100, 100};
1023 static float scale[2] = {0.8, 0.8};
1024 static float skew[2] = {0.2, 0.2};
1025
1026 static bool enable_savelayer = true;
1027
1028 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1029 {
1030 ImGui::Combo("Filter type", &selected_matrix_type, matrix_type_names,
1031 sizeof(matrix_type_names) / sizeof(char*));
1032
1033 ImGui::TextWrapped("Current Transform");
1034 ImGui::SliderFloat2("CTM Translation", ctm_translation, 0, 1000);
1035 ImGui::SliderFloat2("CTM Scale", ctm_scale, 0, 3);
1036 ImGui::SliderFloat2("CTM Skew", ctm_skew, -3, 3);
1037
1038 ImGui::TextWrapped(
1039 "MatrixFilter and LocalMatrixFilter modify the CTM in the same way. "
1040 "The only difference is that MatrixFilter doesn't affect the effect "
1041 "transform, whereas LocalMatrixFilter does.");
1042 // Note: See this behavior in:
1043 // https://fiddle.skia.org/c/6cbb551ab36d06f163db8693972be954
1044 ImGui::Checkbox("Enable", &enable);
1045 ImGui::SliderFloat2("Filter Translation", translation, 0, 1000);
1046 ImGui::SliderFloat2("Filter Scale", scale, 0, 3);
1047 ImGui::SliderFloat2("Filter Skew", skew, -3, 3);
1048
1049 ImGui::TextWrapped(
1050 "Rendering the filtered image within a layer can expose bounds "
1051 "issues. If the rendered image gets cut off when this setting is "
1052 "enabled, there's a coverage bug in the filter.");
1053 ImGui::Checkbox("Render in layer", &enable_savelayer);
1054 }
1055 ImGui::End();
1056
1059
1060 if (enable_savelayer) {
1061 builder.SaveLayer(nullptr, nullptr);
1062 }
1063 {
1064 auto content_scale = GetContentScale();
1065 builder.Scale(content_scale.x, content_scale.y);
1066
1067 // Set the current transform
1068 auto ctm_matrix =
1069 SkMatrix::MakeAll(ctm_scale[0], ctm_skew[0], ctm_translation[0], //
1070 ctm_skew[1], ctm_scale[1], ctm_translation[1], //
1071 0, 0, 1);
1072 builder.Transform(ctm_matrix);
1073
1074 // Set the matrix filter
1075 auto filter_matrix =
1076 SkMatrix::MakeAll(scale[0], skew[0], translation[0], //
1077 skew[1], scale[1], translation[1], //
1078 0, 0, 1);
1079
1080 if (enable) {
1081 switch (selected_matrix_type) {
1082 case 0: {
1083 auto filter = flutter::DlMatrixImageFilter(
1084 filter_matrix, flutter::DlImageSampling::kLinear);
1085 paint.setImageFilter(&filter);
1086 break;
1087 }
1088 case 1: {
1089 auto internal_filter =
1091 .shared();
1092 auto filter = flutter::DlLocalMatrixImageFilter(filter_matrix,
1093 internal_filter);
1094 paint.setImageFilter(&filter);
1095 break;
1096 }
1097 }
1098 }
1099
1100 builder.DrawImage(DlImageImpeller::Make(boston), {},
1102 }
1103 if (enable_savelayer) {
1104 builder.Restore();
1105 }
1106
1107 return builder.Build();
1108 };
1109
1110 ASSERT_TRUE(OpenPlaygroundHere(callback));
1111}
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
Definition: SkMatrix.h:179
std::shared_ptr< DlImageFilter > shared() const override

◆ TEST_P() [285/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilterWhenSavingLayer   
)

Definition at line 1113 of file dl_unittests.cc.

1113 {
1114 auto callback = [&]() {
1115 static float translation[2] = {0, 0};
1116 static bool enable_save_layer = true;
1117
1118 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1119 ImGui::SliderFloat2("Translation", translation, -130, 130);
1120 ImGui::Checkbox("Enable save layer", &enable_save_layer);
1121 ImGui::End();
1122
1124 builder.Save();
1125 builder.Scale(2.0, 2.0);
1127 paint.setColor(flutter::DlColor::kYellow());
1128 builder.DrawRect(SkRect::MakeWH(300, 300), paint);
1129 paint.setStrokeWidth(1.0);
1131 paint.setColor(flutter::DlColor::kBlack().withAlpha(0x80));
1132 builder.DrawLine(SkPoint::Make(150, 0), SkPoint::Make(150, 300), paint);
1133 builder.DrawLine(SkPoint::Make(0, 150), SkPoint::Make(300, 150), paint);
1134
1135 flutter::DlPaint save_paint;
1136 SkRect bounds = SkRect::MakeXYWH(100, 100, 100, 100);
1137 SkMatrix translate_matrix =
1138 SkMatrix::Translate(translation[0], translation[1]);
1139 if (enable_save_layer) {
1140 auto filter = flutter::DlMatrixImageFilter(
1142 save_paint.setImageFilter(filter.shared());
1143 builder.SaveLayer(&bounds, &save_paint);
1144 } else {
1145 builder.Save();
1146 builder.Transform(translate_matrix);
1147 }
1148
1149 SkMatrix filter_matrix = SkMatrix::I();
1150 filter_matrix.postTranslate(-150, -150);
1151 filter_matrix.postScale(0.2f, 0.2f);
1152 filter_matrix.postTranslate(150, 150);
1153 auto filter = flutter::DlMatrixImageFilter(
1155
1156 save_paint.setImageFilter(filter.shared());
1157
1158 builder.SaveLayer(&bounds, &save_paint);
1159 flutter::DlPaint paint2;
1161 builder.DrawRect(bounds, paint2);
1162 builder.Restore();
1163 builder.Restore();
1164 return builder.Build();
1165 };
1166
1167 ASSERT_TRUE(OpenPlaygroundHere(callback));
1168}
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:281
SkMatrix & postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:360
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
DlPaint & setImageFilter(const std::shared_ptr< const DlImageFilter > &filter)
Definition: dl_paint.h:157

◆ TEST_P() [286/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithOddPathWinding   
)

Definition at line 386 of file dl_unittests.cc.

386 {
389
390 paint.setColor(flutter::DlColor::kRed());
392
393 builder.Translate(300, 300);
394 SkPath path;
395 path.setFillType(SkPathFillType::kEvenOdd);
396 path.addCircle(0, 0, 100);
397 path.addCircle(0, 0, 50);
398 builder.DrawPath(path, paint);
399
400 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
401}
@ kFill
fills interior of shapes

◆ TEST_P() [287/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroLengthLine   
)

Definition at line 841 of file dl_unittests.cc.

841 {
843 std::vector<flutter::DlStrokeCap> caps = {
847 };
850 .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
853 .setStrokeWidth(20);
854 SkPath path = SkPath().addPoly({{150, 50}, {150, 50}}, false);
855 for (auto cap : caps) {
856 paint.setStrokeCap(cap);
857 builder.DrawLine({50, 50}, {50, 50}, paint);
858 builder.DrawPath(path, paint);
859 builder.Translate(0, 150);
860 }
861 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
862}
DlPaint & setStrokeCap(DlStrokeCap cap)
Definition: dl_paint.h:102
DlPaint & setDrawStyle(DlDrawStyle style)
Definition: dl_paint.h:94

◆ TEST_P() [288/450]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroWidthLine   
)

Definition at line 976 of file dl_unittests.cc.

976 {
978 std::vector<flutter::DlStrokeCap> caps = {
982 };
987 .setStrokeWidth(0);
988 flutter::DlPaint outline_paint = //
993 .setStrokeWidth(1);
994 SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
995 for (auto cap : caps) {
996 paint.setStrokeCap(cap);
997 builder.DrawLine({50, 50}, {60, 50}, paint);
998 builder.DrawRect({45, 45, 65, 55}, outline_paint);
999 builder.DrawLine({100, 50}, {100, 50}, paint);
1000 if (cap != flutter::DlStrokeCap::kButt) {
1001 builder.DrawRect({95, 45, 105, 55}, outline_paint);
1002 }
1003 builder.DrawPath(path, paint);
1004 builder.DrawRect(path.getBounds().makeOutset(5, 5), outline_paint);
1005 builder.Translate(0, 150);
1006 }
1007 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1008}

◆ TEST_P() [289/450]

impeller::testing::TEST_P ( DisplayListTest  ,
ClipDrawRRectWithNonCircularRadii   
)

Definition at line 1393 of file dl_unittests.cc.

1393 {
1395
1396 flutter::DlPaint fill_paint = //
1397 flutter::DlPaint() //
1400 .setStrokeWidth(10);
1401 flutter::DlPaint stroke_paint = //
1402 flutter::DlPaint() //
1405 .setStrokeWidth(10);
1406
1407 builder.DrawRRect(
1408 SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1409 fill_paint);
1410 builder.DrawRRect(
1411 SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1412 stroke_paint);
1413
1414 builder.DrawRRect(
1415 SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1416 fill_paint);
1417 builder.DrawRRect(
1418 SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1419 stroke_paint);
1420
1421 flutter::DlPaint reference_paint = //
1422 flutter::DlPaint() //
1425 .setStrokeWidth(10);
1426
1427 builder.DrawRRect(
1428 SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 500, 300, 300), 40, 40),
1429 reference_paint);
1430 builder.DrawRRect(
1431 SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 100, 300, 300), 120, 120),
1432 reference_paint);
1433
1434 flutter::DlPaint clip_fill_paint = //
1435 flutter::DlPaint() //
1438 .setStrokeWidth(10);
1439
1440 builder.Save();
1441 builder.ClipRRect(
1442 SkRRect::MakeRectXY(SkRect::MakeXYWH(900, 100, 300, 300), 120, 40));
1443 builder.DrawPaint(clip_fill_paint);
1444 builder.Restore();
1445
1446 builder.Save();
1447 builder.ClipRRect(
1448 SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 900, 300, 300), 40, 120));
1449 builder.DrawPaint(clip_fill_paint);
1450 builder.Restore();
1451
1452 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1453}
static constexpr DlColor kMidGrey()
Definition: dl_color.h:31

◆ TEST_P() [290/450]

impeller::testing::TEST_P ( DisplayListTest  ,
DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists   
)

Definition at line 913 of file dl_unittests.cc.

914 {
915 // Regression test for https://github.com/flutter/flutter/issues/130613
916 flutter::DisplayListBuilder sub_builder(true);
917 sub_builder.DrawRect(SkRect::MakeXYWH(0, 0, 50, 50),
919 auto display_list = sub_builder.Build();
920
921 DlDispatcher dispatcher(Rect::MakeLTRB(0, 0, 2400, 1800));
922 dispatcher.scale(2.0, 2.0);
923 dispatcher.translate(-93.0, 0.0);
924 // clang-format off
925 dispatcher.transformFullPerspective(
926 0.8, -0.2, -0.1, -0.0,
927 0.0, 1.0, 0.0, 0.0,
928 1.4, 1.3, 1.0, 0.0,
929 63.2, 65.3, 48.6, 1.1
930 );
931 // clang-format on
932 dispatcher.translate(35.0, 75.0);
933 dispatcher.drawDisplayList(display_list, 1.0f);
934 auto picture = dispatcher.EndRecordingAsPicture();
935
936 bool found = false;
937 picture.pass->IterateAllEntities([&found](Entity& entity) {
938 if (std::static_pointer_cast<SolidColorContents>(entity.GetContents())
939 ->GetColor() == Color::Red()) {
940 found = true;
941 return false;
942 }
943
944 return true;
945 });
946 EXPECT_TRUE(found);
947}

◆ TEST_P() [291/450]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawMaskBlursThatMightUseSaveLayers   
)

Definition at line 1655 of file dl_unittests.cc.

1655 {
1658 Vector2 scale = GetContentScale();
1659 builder.Scale(scale.x, scale.y);
1660
1661 builder.Save();
1662 // We need a small transform op to avoid a deferred save
1663 builder.Translate(1.0f, 1.0f);
1664 auto solid_filter =
1666 flutter::DlPaint solid_alpha_paint =
1667 flutter::DlPaint() //
1668 .setMaskFilter(solid_filter) //
1670 .setAlpha(0x7f);
1671 for (int x = 1; x <= 4; x++) {
1672 for (int y = 1; y <= 4; y++) {
1673 builder.DrawRect(SkRect::MakeXYWH(x * 100, y * 100, 80, 80),
1674 solid_alpha_paint);
1675 }
1676 }
1677 builder.Restore();
1678
1679 builder.Save();
1680 builder.Translate(500.0f, 0.0f);
1681 auto normal_filter =
1683 auto rotate_if = flutter::DlMatrixImageFilter::Make(
1685 flutter::DlPaint normal_if_paint =
1686 flutter::DlPaint() //
1687 .setMaskFilter(solid_filter) //
1688 .setImageFilter(rotate_if) //
1690 .setAlpha(0x7f);
1691 for (int x = 1; x <= 4; x++) {
1692 for (int y = 1; y <= 4; y++) {
1693 builder.DrawRect(SkRect::MakeXYWH(x * 100, y * 100, 80, 80),
1694 normal_if_paint);
1695 }
1696 }
1697 builder.Restore();
1698
1699 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1700}
static std::shared_ptr< DlMaskFilter > Make(DlBlurStyle style, SkScalar sigma, bool respect_ctm=true)
static std::shared_ptr< DlImageFilter > Make(const SkMatrix &matrix, DlImageSampling sampling)
DlPaint & setMaskFilter(const std::shared_ptr< DlMaskFilter > &filter)
Definition: dl_paint.h:170

◆ TEST_P() [292/450]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawPaintIgnoresMaskFilter   
)

Definition at line 1632 of file dl_unittests.cc.

1632 {
1634 builder.DrawPaint(flutter::DlPaint().setColor(flutter::DlColor::kWhite()));
1635
1637 builder.DrawCircle({300, 300}, 200,
1638 flutter::DlPaint().setMaskFilter(&filter));
1639
1640 std::vector<flutter::DlColor> colors = {flutter::DlColor::kGreen(),
1642 const float stops[2] = {0.0, 1.0};
1644 {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1646 flutter::DlPaint blend_paint =
1647 flutter::DlPaint() //
1650 builder.DrawPaint(blend_paint);
1651
1652 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1653}
DlPaint & setBlendMode(DlBlendMode mode)
Definition: dl_paint.h:86
DlPaint & setColorSource(std::shared_ptr< const DlColorSource > source)
Definition: dl_paint.h:131

◆ TEST_P() [293/450]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawShapes   
)

Definition at line 1355 of file dl_unittests.cc.

1355 {
1357 std::vector<flutter::DlStrokeJoin> joins = {
1361 };
1363 flutter::DlPaint() //
1366 .setStrokeWidth(10);
1367 flutter::DlPaint stroke_paint = //
1368 flutter::DlPaint() //
1371 .setStrokeWidth(10);
1372 SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
1373
1374 builder.Translate(300, 50);
1375 builder.Scale(0.8, 0.8);
1376 for (auto join : joins) {
1377 paint.setStrokeJoin(join);
1378 stroke_paint.setStrokeJoin(join);
1379 builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
1380 builder.DrawRect(SkRect::MakeXYWH(0, 150, 100, 100), stroke_paint);
1381 builder.DrawRRect(
1382 SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 0, 100, 100), 30, 30), paint);
1383 builder.DrawRRect(
1384 SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 150, 100, 100), 30, 30),
1385 stroke_paint);
1386 builder.DrawCircle({350, 50}, 50, paint);
1387 builder.DrawCircle({350, 200}, 50, stroke_paint);
1388 builder.Translate(0, 300);
1389 }
1390 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1391}
DlPaint & setStrokeJoin(DlStrokeJoin join)
Definition: dl_paint.h:110

◆ TEST_P() [294/450]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesBlendModes   
)

Definition at line 1455 of file dl_unittests.cc.

1455 {
1456 std::vector<const char*> blend_mode_names;
1457 std::vector<flutter::DlBlendMode> blend_mode_values;
1458 {
1459 const std::vector<std::tuple<const char*, flutter::DlBlendMode>> blends = {
1460 // Pipeline blends (Porter-Duff alpha compositing)
1462 {"Source", flutter::DlBlendMode::kSrc},
1463 {"Destination", flutter::DlBlendMode::kDst},
1464 {"SourceOver", flutter::DlBlendMode::kSrcOver},
1465 {"DestinationOver", flutter::DlBlendMode::kDstOver},
1466 {"SourceIn", flutter::DlBlendMode::kSrcIn},
1467 {"DestinationIn", flutter::DlBlendMode::kDstIn},
1468 {"SourceOut", flutter::DlBlendMode::kSrcOut},
1469 {"DestinationOut", flutter::DlBlendMode::kDstOut},
1470 {"SourceATop", flutter::DlBlendMode::kSrcATop},
1471 {"DestinationATop", flutter::DlBlendMode::kDstATop},
1474 {"Modulate", flutter::DlBlendMode::kModulate},
1475 // Advanced blends (color component blends)
1477 {"Overlay", flutter::DlBlendMode::kOverlay},
1479 {"Lighten", flutter::DlBlendMode::kLighten},
1480 {"ColorDodge", flutter::DlBlendMode::kColorDodge},
1481 {"ColorBurn", flutter::DlBlendMode::kColorBurn},
1482 {"HardLight", flutter::DlBlendMode::kHardLight},
1483 {"SoftLight", flutter::DlBlendMode::kSoftLight},
1484 {"Difference", flutter::DlBlendMode::kDifference},
1485 {"Exclusion", flutter::DlBlendMode::kExclusion},
1486 {"Multiply", flutter::DlBlendMode::kMultiply},
1488 {"Saturation", flutter::DlBlendMode::kSaturation},
1490 {"Luminosity", flutter::DlBlendMode::kLuminosity},
1491 };
1492 assert(blends.size() ==
1493 static_cast<size_t>(flutter::DlBlendMode::kLastMode) + 1);
1494 for (const auto& [name, mode] : blends) {
1495 blend_mode_names.push_back(name);
1496 blend_mode_values.push_back(mode);
1497 }
1498 }
1499
1500 auto callback = [&]() {
1501 static int current_blend_index = 3;
1502 static float dst_alpha = 1;
1503 static float src_alpha = 1;
1504 static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1505 static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1506 static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1507 static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1508
1509 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1510 {
1511 ImGui::ListBox("Blending mode", &current_blend_index,
1512 blend_mode_names.data(), blend_mode_names.size());
1513 ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
1514 ImGui::ColorEdit4("Color A", color0);
1515 ImGui::ColorEdit4("Color B", color1);
1516 ImGui::ColorEdit4("Color C", color2);
1517 ImGui::ColorEdit4("Source Color", src_color);
1518 ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
1519 }
1520 ImGui::End();
1521
1522 std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1523 SkPoint::Make(200, 100),
1524 SkPoint::Make(300, 300)};
1525 std::vector<flutter::DlColor> colors = {
1526 toColor(color0).modulateOpacity(dst_alpha),
1527 toColor(color1).modulateOpacity(dst_alpha),
1528 toColor(color2).modulateOpacity(dst_alpha)};
1529
1530 auto vertices = flutter::DlVertices::Make(
1531 flutter::DlVertexMode::kTriangles, 3, positions.data(),
1532 /*texture_coordinates=*/nullptr, colors.data());
1533
1536
1537 paint.setColor(toColor(src_color).modulateOpacity(src_alpha));
1538 builder.DrawVertices(vertices, blend_mode_values[current_blend_index],
1539 paint);
1540 return builder.Build();
1541 };
1542
1543 ASSERT_TRUE(OpenPlaygroundHere(callback));
1544}
@ kSrcOut
r = s * (1-da)
@ kExclusion
rc = s + d - two(s*d), ra = kSrcOver
@ kSaturation
saturation of source with hue and luminosity of destination
@ kColorBurn
darken destination to reflect source
@ kPlus
r = min(s + d, 1)
@ kLighten
rc = s + d - min(s*da, d*sa), ra = kSrcOver
@ kHue
hue of source with saturation and luminosity of destination
@ kMultiply
r = s*(1-da) + d*(1-sa) + s*d
@ kColorDodge
brighten destination to reflect source
@ kXor
r = s*(1-da) + d*(1-sa)
@ kLuminosity
luminosity of source with hue and saturation of destination
@ kSoftLight
lighten or darken, depending on source
@ kDifference
rc = s + d - 2*(min(s*da, d*sa)), ra = kSrcOver
@ kOverlay
multiply or screen, depending on destination
@ kSrcATop
r = s*da + d*(1-sa)
@ kDstATop
r = d*sa + s*(1-da)
@ kLastMode
last valid value
@ kColor
hue and saturation of source with luminosity of destination
@ kHardLight
multiply or screen, depending on source
@ kDstOut
r = d * (1-sa)
@ kDarken
rc = s + d - max(s*da, d*sa), ra = kSrcOver
flutter::DlColor toColor(const float *components)
Definition: dl_unittests.cc:41
constexpr DlColor modulateOpacity(float opacity) const
Definition: dl_color.h:76

◆ TEST_P() [295/450]

impeller::testing::TEST_P ( DisplayListTest  ,
IgnoreMaskFilterWhenSavingLayer   
)

Definition at line 505 of file dl_unittests.cc.

505 {
506 auto texture = CreateTextureForFixture("embarcadero.jpg");
510 paint.setMaskFilter(&filter);
511 builder.SaveLayer(nullptr, &paint);
514 builder.Restore();
515 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
516}

◆ TEST_P() [296/450]

impeller::testing::TEST_P ( DisplayListTest  ,
MaskBlursApplyCorrectlyToColorSources   
)

Definition at line 1318 of file dl_unittests.cc.

1318 {
1319 auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
1321
1323
1324 std::array<flutter::DlColor, 2> colors = {flutter::DlColor::kBlue(),
1326 std::array<float, 2> stops = {0, 1};
1327 std::array<std::shared_ptr<flutter::DlColorSource>, 2> color_sources = {
1328 std::make_shared<flutter::DlColorColorSource>(flutter::DlColor::kWhite()),
1330 SkPoint::Make(0, 0), SkPoint::Make(100, 50), 2, colors.data(),
1331 stops.data(), flutter::DlTileMode::kClamp)};
1332
1333 int offset = 100;
1334 for (const auto& color_source : color_sources) {
1336 paint.setColorSource(color_source);
1337 paint.setMaskFilter(blur_filter);
1338
1339 paint.setDrawStyle(flutter::DlDrawStyle::kFill);
1340 builder.DrawRRect(
1341 SkRRect::MakeRectXY(SkRect::MakeXYWH(100, offset, 100, 50), 30, 30),
1342 paint);
1344 paint.setStrokeWidth(10);
1345 builder.DrawRRect(
1346 SkRRect::MakeRectXY(SkRect::MakeXYWH(300, offset, 100, 50), 30, 30),
1347 paint);
1348
1349 offset += 100;
1350 }
1351
1352 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1353}

◆ TEST_P() [297/450]

impeller::testing::TEST_P ( DisplayListTest  ,
NinePatchImagePrecision   
)

Definition at line 793 of file dl_unittests.cc.

793 {
794 // Draw a nine patch image with colored corners and verify that the corner
795 // color does not leak outside the intended region.
796 auto texture = CreateTextureForFixture("nine_patch_corners.png");
799 SkIRect::MakeXYWH(10, 10, 1, 1),
800 SkRect::MakeXYWH(0, 0, 200, 100),
802 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
803}
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition: SkRect.h:104

◆ TEST_P() [298/450]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedPathsDrawCorrectly   
)

Definition at line 213 of file dl_unittests.cc.

213 {
214 auto callback = [&]() {
217
218 paint.setColor(flutter::DlColor::kRed());
220
221 static float stroke_width = 10.0f;
222 static int selected_stroke_type = 0;
223 static int selected_join_type = 0;
224 const char* stroke_types[] = {"Butte", "Round", "Square"};
225 const char* join_type[] = {"kMiter", "Round", "kBevel"};
226
227 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
228 ImGui::Combo("Cap", &selected_stroke_type, stroke_types,
229 sizeof(stroke_types) / sizeof(char*));
230 ImGui::Combo("Join", &selected_join_type, join_type,
231 sizeof(join_type) / sizeof(char*));
232 ImGui::SliderFloat("Stroke Width", &stroke_width, 10.0f, 50.0f);
233 ImGui::End();
234
237 switch (selected_stroke_type) {
238 case 0:
240 break;
241 case 1:
243 break;
244 case 2:
246 break;
247 default:
249 break;
250 }
251 switch (selected_join_type) {
252 case 0:
254 break;
255 case 1:
257 break;
258 case 2:
260 break;
261 default:
263 break;
264 }
265 paint.setStrokeCap(cap);
266 paint.setStrokeJoin(join);
267 paint.setStrokeWidth(stroke_width);
268
269 // Make rendering better to watch.
270 builder.Scale(1.5f, 1.5f);
271
272 // Rectangle
273 builder.Translate(100, 100);
274 builder.DrawRect(SkRect::MakeSize({100, 100}), paint);
275
276 // Rounded rectangle
277 builder.Translate(150, 0);
278 builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
279 paint);
280
281 // Double rounded rectangle
282 builder.Translate(150, 0);
283 builder.DrawDRRect(
284 SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
285 SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 30), 10, 10), paint);
286
287 // Contour with duplicate join points
288 {
289 builder.Translate(150, 0);
290 SkPath path;
291 path.moveTo(0, 0);
292 path.lineTo(0, 0);
293 path.lineTo({100, 0});
294 path.lineTo({100, 0});
295 path.lineTo({100, 100});
296 builder.DrawPath(path, paint);
297 }
298
299 // Contour with duplicate start and end points
300
301 // Line.
302 builder.Translate(200, 0);
303 {
304 builder.Save();
305
306 SkPath line_path;
307 line_path.moveTo(0, 0);
308 line_path.moveTo(0, 0);
309 line_path.lineTo({0, 0});
310 line_path.lineTo({0, 0});
311 line_path.lineTo({50, 50});
312 line_path.lineTo({50, 50});
313 line_path.lineTo({100, 0});
314 line_path.lineTo({100, 0});
315 builder.DrawPath(line_path, paint);
316
317 builder.Translate(0, 100);
318 builder.DrawPath(line_path, paint);
319
320 builder.Translate(0, 100);
321 SkPath line_path2;
322 line_path2.moveTo(0, 0);
323 line_path2.lineTo(0, 0);
324 line_path2.lineTo(0, 0);
325 builder.DrawPath(line_path2, paint);
326
327 builder.Restore();
328 }
329
330 // Cubic.
331 builder.Translate(150, 0);
332 {
333 builder.Save();
334
336 cubic_path.moveTo({0, 0});
337 cubic_path.cubicTo(0, 0, 140.0, 100.0, 140, 20);
338 builder.DrawPath(cubic_path, paint);
339
340 builder.Translate(0, 100);
341 SkPath cubic_path2;
342 cubic_path2.moveTo({0, 0});
343 cubic_path2.cubicTo(0, 0, 0, 0, 150, 150);
344 builder.DrawPath(cubic_path2, paint);
345
346 builder.Translate(0, 100);
347 SkPath cubic_path3;
348 cubic_path3.moveTo({0, 0});
349 cubic_path3.cubicTo(0, 0, 0, 0, 0, 0);
350 builder.DrawPath(cubic_path3, paint);
351
352 builder.Restore();
353 }
354
355 // Quad.
356 builder.Translate(200, 0);
357 {
358 builder.Save();
359
361 quad_path.moveTo(0, 0);
362 quad_path.moveTo(0, 0);
363 quad_path.quadTo({100, 40}, {50, 80});
364 builder.DrawPath(quad_path, paint);
365
366 builder.Translate(0, 150);
367 SkPath quad_path2;
368 quad_path2.moveTo(0, 0);
369 quad_path2.moveTo(0, 0);
370 quad_path2.quadTo({0, 0}, {100, 100});
371 builder.DrawPath(quad_path2, paint);
372
373 builder.Translate(0, 100);
374 SkPath quad_path3;
375 quad_path3.moveTo(0, 0);
376 quad_path3.quadTo({0, 0}, {0, 0});
377 builder.DrawPath(quad_path3, paint);
378
379 builder.Restore();
380 }
381 return builder.Build();
382 };
383 ASSERT_TRUE(OpenPlaygroundHere(callback));
384}
SkPath & quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
Definition: SkPath.cpp:746
DlStrokeJoin
Definition: dl_paint.h:37
SkPath quad_path()
Definition: overstroke.cpp:60
SkPath cubic_path()
Definition: overstroke.cpp:68

◆ TEST_P() [299/450]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedTextNotOffsetFromNormalText   
)

Definition at line 480 of file dl_unittests.cc.

480 {
483 auto const& text_blob = SkTextBlob::MakeFromString("00000", CreateTestFont());
484
485 // https://api.flutter.dev/flutter/material/Colors/blue-constant.html.
486 auto const& mat_blue = flutter::DlColor(0xFF2196f3);
487
488 // Draw a blue filled rectangle so the text is easier to see.
490 paint.setColor(mat_blue);
491 builder.DrawRect(SkRect::MakeXYWH(0, 0, 500, 500), paint);
492
493 // Draw stacked text, with stroked text on top.
496 builder.DrawTextBlob(text_blob, 250, 250, paint);
497
500 builder.DrawTextBlob(text_blob, 250, 250, paint);
501
502 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
503}

◆ TEST_P() [300/450]

impeller::testing::TEST_P ( DisplayListTest  ,
TransparentShadowProducesCorrectColor   
)

Definition at line 949 of file dl_unittests.cc.

949 {
950 DlDispatcher dispatcher;
951 dispatcher.save();
952 dispatcher.scale(1.618, 1.618);
953 SkPath path = SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100));
955 dispatcher.drawShadow(cache, flutter::DlColor::kTransparent(), 15, false, 1);
956 dispatcher.restore();
957 auto picture = dispatcher.EndRecordingAsPicture();
958
959 std::shared_ptr<SolidRRectBlurContents> rrect_blur;
960 picture.pass->IterateAllEntities([&rrect_blur](Entity& entity) {
961 if (ScalarNearlyEqual(entity.GetTransform().GetScale().x, 1.618f)) {
962 rrect_blur = std::static_pointer_cast<SolidRRectBlurContents>(
963 entity.GetContents());
964 return false;
965 }
966 return true;
967 });
968
969 ASSERT_NE(rrect_blur, nullptr);
970 ASSERT_EQ(rrect_blur->GetColor().red, 0);
971 ASSERT_EQ(rrect_blur->GetColor().green, 0);
972 ASSERT_EQ(rrect_blur->GetColor().blue, 0);
973 ASSERT_EQ(rrect_blur->GetColor().alpha, 0);
974}
void drawShadow(const SkPath &path, const flutter::DlColor color, const SkScalar elevation, bool transparent_occluder, SkScalar dpr) override
void scale(SkScalar sx, SkScalar sy) override
void save() override
static constexpr DlColor kTransparent()
Definition: dl_color.h:21

◆ TEST_P() [301/450]

impeller::testing::TEST_P ( DriverInfoVKTest  ,
CanDumpToLog   
)

Definition at line 26 of file driver_info_vk_unittests.cc.

26 {
27 ASSERT_TRUE(GetContext());
28 const auto& driver_info =
29 SurfaceContextVK::Cast(*GetContext()).GetParent()->GetDriverInfo();
30 ASSERT_NE(driver_info, nullptr);
32 driver_info->DumpToLog();
33 ASSERT_TRUE(log.str().find("Driver Information") != std::string::npos);
34}

◆ TEST_P() [302/450]

impeller::testing::TEST_P ( DriverInfoVKTest  ,
CanQueryDriverInfo   
)

Definition at line 14 of file driver_info_vk_unittests.cc.

14 {
15 ASSERT_TRUE(GetContext());
16 const auto& driver_info =
17 SurfaceContextVK::Cast(*GetContext()).GetParent()->GetDriverInfo();
18 ASSERT_NE(driver_info, nullptr);
19 // 1.1 is the base Impeller version. The driver can't be lower than that.
20 ASSERT_TRUE(driver_info->GetAPIVersion().IsAtLeast(Version{1, 1, 0}));
21 ASSERT_NE(driver_info->GetVendor(), VendorVK::kUnknown);
22 ASSERT_NE(driver_info->GetDeviceType(), DeviceTypeVK::kUnknown);
23 ASSERT_NE(driver_info->GetDriverName(), "");
24}

◆ TEST_P() [303/450]

impeller::testing::TEST_P ( EntityPassTargetTest  ,
SwapWithMSAAImplicitResolve   
)

Definition at line 53 of file entity_pass_target_unittests.cc.

53 {
54 auto content_context = GetContentContext();
55 auto buffer = content_context->GetContext()->CreateCommandBuffer();
56 auto context = content_context->GetContext();
57 auto& allocator = *context->GetResourceAllocator();
58
59 // Emulate implicit MSAA resolve by making color resolve and msaa texture the
60 // same.
61 RenderTarget render_target;
62 {
63 PixelFormat pixel_format =
64 context->GetCapabilities()->GetDefaultColorFormat();
65
66 // Create MSAA color texture.
67
68 TextureDescriptor color0_tex_desc;
69 color0_tex_desc.storage_mode = StorageMode::kDevicePrivate;
70 color0_tex_desc.type = TextureType::kTexture2DMultisample;
71 color0_tex_desc.sample_count = SampleCount::kCount4;
72 color0_tex_desc.format = pixel_format;
73 color0_tex_desc.size = ISize{100, 100};
74 color0_tex_desc.usage = TextureUsage::kRenderTarget;
75
76 auto color0_msaa_tex = allocator.CreateTexture(color0_tex_desc);
77
78 // Color attachment.
79
80 ColorAttachment color0;
81 color0.load_action = LoadAction::kDontCare;
82 color0.store_action = StoreAction::kStoreAndMultisampleResolve;
83 color0.texture = color0_msaa_tex;
84 color0.resolve_texture = color0_msaa_tex;
85
86 render_target.SetColorAttachment(color0, 0u);
87 render_target.SetStencilAttachment(std::nullopt);
88 }
89
90 auto entity_pass_target = EntityPassTarget(render_target, false, true);
91
92 auto color0 = entity_pass_target.GetRenderTarget()
93 .GetColorAttachments()
94 .find(0u)
95 ->second;
96 auto msaa_tex = color0.texture;
97 auto resolve_tex = color0.resolve_texture;
98
99 ASSERT_EQ(msaa_tex, resolve_tex);
100
101 entity_pass_target.Flip(
102 *content_context->GetContext()->GetResourceAllocator());
103
104 color0 = entity_pass_target.GetRenderTarget()
105 .GetColorAttachments()
106 .find(0u)
107 ->second;
108
109 ASSERT_NE(msaa_tex, color0.texture);
110 ASSERT_NE(resolve_tex, color0.resolve_texture);
111 ASSERT_EQ(color0.texture, color0.resolve_texture);
112}
RenderTarget & SetColorAttachment(const ColorAttachment &attachment, size_t index)
RenderTarget & SetStencilAttachment(std::optional< StencilAttachment > attachment)
std::shared_ptr< Texture > resolve_texture
Definition: formats.h:652
LoadAction load_action
Definition: formats.h:653
std::shared_ptr< Texture > texture
Definition: formats.h:651
StoreAction store_action
Definition: formats.h:654

◆ TEST_P() [304/450]

impeller::testing::TEST_P ( EntityPassTargetTest  ,
SwapWithMSAATexture   
)

Definition at line 19 of file entity_pass_target_unittests.cc.

19 {
20 if (GetContentContext()
21 ->GetDeviceCapabilities()
22 .SupportsImplicitResolvingMSAA()) {
23 GTEST_SKIP() << "Implicit MSAA is used on this device.";
24 }
25 auto content_context = GetContentContext();
26 auto buffer = content_context->GetContext()->CreateCommandBuffer();
27 auto render_target =
28 GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
29 *content_context->GetContext(), {100, 100},
30 /*mip_count=*/1);
31
32 auto entity_pass_target = EntityPassTarget(render_target, false, false);
33
34 auto color0 = entity_pass_target.GetRenderTarget()
35 .GetColorAttachments()
36 .find(0u)
37 ->second;
38 auto msaa_tex = color0.texture;
39 auto resolve_tex = color0.resolve_texture;
40
41 entity_pass_target.Flip(
42 *content_context->GetContext()->GetResourceAllocator());
43
44 color0 = entity_pass_target.GetRenderTarget()
45 .GetColorAttachments()
46 .find(0u)
47 ->second;
48
49 ASSERT_EQ(msaa_tex, color0.texture);
50 ASSERT_NE(resolve_tex, color0.resolve_texture);
51}

◆ TEST_P() [305/450]

impeller::testing::TEST_P ( EntityTest  ,
AdvancedBlendCoverageHintIsNotResetByEntityPass   
)

Definition at line 2370 of file entity_unittests.cc.

2370 {
2371 if (GetContext()->GetCapabilities()->SupportsFramebufferFetch()) {
2372 GTEST_SKIP() << "Backends that support framebuffer fetch dont use coverage "
2373 "for advanced blends.";
2374 }
2375
2376 auto contents = std::make_shared<SolidColorContents>();
2377 contents->SetGeometry(Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100)));
2378 contents->SetColor(Color::Red());
2379
2380 Entity entity;
2381 entity.SetTransform(Matrix::MakeScale(Vector3(2, 2, 1)));
2382 entity.SetBlendMode(BlendMode::kColorBurn);
2383 entity.SetContents(contents);
2384
2385 auto coverage = entity.GetCoverage();
2386 EXPECT_TRUE(coverage.has_value());
2387
2388 auto pass = std::make_unique<EntityPass>();
2389 std::shared_ptr<RenderTargetCache> render_target_allocator =
2390 std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
2391 auto stencil_config = RenderTarget::AttachmentConfig{
2392 .storage_mode = StorageMode::kDevicePrivate,
2393 .load_action = LoadAction::kClear,
2394 .store_action = StoreAction::kDontCare,
2395 .clear_color = Color::BlackTransparent()};
2396 auto rt = render_target_allocator->CreateOffscreen(
2397 *GetContext(), ISize::MakeWH(1000, 1000),
2398 /*mip_count=*/1, "Offscreen", RenderTarget::kDefaultColorAttachmentConfig,
2399 stencil_config);
2400 auto content_context = ContentContext(
2401 GetContext(), TypographerContextSkia::Make(), render_target_allocator);
2402 pass->AddEntity(std::move(entity));
2403
2404 EXPECT_TRUE(pass->Render(content_context, rt));
2405
2406 auto contains_size = [&render_target_allocator](ISize size) -> bool {
2407 return std::find_if(render_target_allocator->GetRenderTargetDataBegin(),
2408 render_target_allocator->GetRenderTargetDataEnd(),
2409 [&size](const auto& data) {
2410 return data.config.size == size;
2411 }) != render_target_allocator->GetRenderTargetDataEnd();
2412 };
2413
2414 EXPECT_TRUE(contains_size(ISize(1000, 1000)))
2415 << "The root texture wasn't allocated";
2416 EXPECT_TRUE(contains_size(ISize(200, 200)))
2417 << "The ColorBurned texture wasn't allocated (100x100 scales up 2x)";
2418}
std::optional< Rect > GetCoverage() const
Definition: entity.cc:66
void SetBlendMode(BlendMode blend_mode)
Definition: entity.cc:115

◆ TEST_P() [306/450]

impeller::testing::TEST_P ( EntityTest  ,
BezierCircleScaled   
)

Definition at line 993 of file entity_unittests.cc.

993 {
994 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
995 static float scale = 20;
996
997 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
998 ImGui::SliderFloat("Scale", &scale, 1, 100);
999 ImGui::End();
1000
1001 Entity entity;
1002 entity.SetTransform(Matrix::MakeScale(GetContentScale()));
1003 auto path = PathBuilder{}
1004 .MoveTo({97.325, 34.818})
1005 .CubicCurveTo({98.50862885295136, 34.81812293973836},
1006 {99.46822048142015, 33.85863261475589},
1007 {99.46822048142015, 32.67499810206613})
1008 .CubicCurveTo({99.46822048142015, 31.491363589376355},
1009 {98.50862885295136, 30.53187326439389},
1010 {97.32499434685802, 30.531998226542708})
1011 .CubicCurveTo({96.14153655073771, 30.532123170035373},
1012 {95.18222070648729, 31.491540299350355},
1013 {95.18222070648729, 32.67499810206613})
1014 .CubicCurveTo({95.18222070648729, 33.85845590478189},
1015 {96.14153655073771, 34.81787303409686},
1016 {97.32499434685802, 34.81799797758954})
1017 .Close()
1018 .TakePath();
1019 entity.SetTransform(
1020 Matrix::MakeScale({scale, scale, 1.0}).Translate({-90, -20, 0}));
1021 entity.SetContents(SolidColorContents::Make(path, Color::Red()));
1022 return entity.Render(context, pass);
1023 };
1024 ASSERT_TRUE(OpenPlaygroundHere(callback));
1025}
bool Render(const ContentContext &renderer, RenderPass &parent_pass) const
Definition: entity.cc:173

◆ TEST_P() [307/450]

impeller::testing::TEST_P ( EntityTest  ,
BlendingModeOptions   
)

Definition at line 862 of file entity_unittests.cc.

862 {
863 std::vector<const char*> blend_mode_names;
864 std::vector<BlendMode> blend_mode_values;
865 {
866 // Force an exhausiveness check with a switch. When adding blend modes,
867 // update this switch with a new name/value to make it selectable in the
868 // test GUI.
869
870 const BlendMode b{};
871 static_assert(b == BlendMode::kClear); // Ensure the first item in
872 // the switch is the first
873 // item in the enum.
874 static_assert(Entity::kLastPipelineBlendMode == BlendMode::kModulate);
875 switch (b) {
876 case BlendMode::kClear:
877 blend_mode_names.push_back("Clear");
878 blend_mode_values.push_back(BlendMode::kClear);
879 case BlendMode::kSource:
880 blend_mode_names.push_back("Source");
881 blend_mode_values.push_back(BlendMode::kSource);
882 case BlendMode::kDestination:
883 blend_mode_names.push_back("Destination");
884 blend_mode_values.push_back(BlendMode::kDestination);
885 case BlendMode::kSourceOver:
886 blend_mode_names.push_back("SourceOver");
887 blend_mode_values.push_back(BlendMode::kSourceOver);
888 case BlendMode::kDestinationOver:
889 blend_mode_names.push_back("DestinationOver");
890 blend_mode_values.push_back(BlendMode::kDestinationOver);
891 case BlendMode::kSourceIn:
892 blend_mode_names.push_back("SourceIn");
893 blend_mode_values.push_back(BlendMode::kSourceIn);
894 case BlendMode::kDestinationIn:
895 blend_mode_names.push_back("DestinationIn");
896 blend_mode_values.push_back(BlendMode::kDestinationIn);
897 case BlendMode::kSourceOut:
898 blend_mode_names.push_back("SourceOut");
899 blend_mode_values.push_back(BlendMode::kSourceOut);
900 case BlendMode::kDestinationOut:
901 blend_mode_names.push_back("DestinationOut");
902 blend_mode_values.push_back(BlendMode::kDestinationOut);
903 case BlendMode::kSourceATop:
904 blend_mode_names.push_back("SourceATop");
905 blend_mode_values.push_back(BlendMode::kSourceATop);
906 case BlendMode::kDestinationATop:
907 blend_mode_names.push_back("DestinationATop");
908 blend_mode_values.push_back(BlendMode::kDestinationATop);
909 case BlendMode::kXor:
910 blend_mode_names.push_back("Xor");
911 blend_mode_values.push_back(BlendMode::kXor);
912 case BlendMode::kPlus:
913 blend_mode_names.push_back("Plus");
914 blend_mode_values.push_back(BlendMode::kPlus);
915 case BlendMode::kModulate:
916 blend_mode_names.push_back("Modulate");
917 blend_mode_values.push_back(BlendMode::kModulate);
918 };
919 }
920
921 auto callback = [&](ContentContext& context, RenderPass& pass) {
922 auto world_matrix = Matrix::MakeScale(GetContentScale());
923 auto draw_rect = [&context, &pass, &world_matrix](
924 Rect rect, Color color, BlendMode blend_mode) -> bool {
925 using VS = SolidFillPipeline::VertexShader;
926 using FS = SolidFillPipeline::FragmentShader;
927
928 VertexBufferBuilder<VS::PerVertexData> vtx_builder;
929 {
930 auto r = rect.GetLTRB();
931 vtx_builder.AddVertices({
932 {Point(r[0], r[1])},
933 {Point(r[2], r[1])},
934 {Point(r[2], r[3])},
935 {Point(r[0], r[1])},
936 {Point(r[2], r[3])},
937 {Point(r[0], r[3])},
938 });
939 }
940
941 pass.SetCommandLabel("Blended Rectangle");
942 auto options = OptionsFromPass(pass);
943 options.blend_mode = blend_mode;
944 options.primitive_type = PrimitiveType::kTriangle;
945 pass.SetPipeline(context.GetSolidFillPipeline(options));
946 pass.SetVertexBuffer(
947 vtx_builder.CreateVertexBuffer(context.GetTransientsBuffer()));
948
949 VS::FrameInfo frame_info;
950 frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
951 VS::BindFrameInfo(
952 pass, context.GetTransientsBuffer().EmplaceUniform(frame_info));
953 FS::FragInfo frag_info;
954 frag_info.color = color.Premultiply();
955 FS::BindFragInfo(
956 pass, context.GetTransientsBuffer().EmplaceUniform(frame_info));
957 return pass.Draw().ok();
958 };
959
960 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
961 static Color color1(1, 0, 0, 0.5), color2(0, 1, 0, 0.5);
962 ImGui::ColorEdit4("Color 1", reinterpret_cast<float*>(&color1));
963 ImGui::ColorEdit4("Color 2", reinterpret_cast<float*>(&color2));
964 static int current_blend_index = 3;
965 ImGui::ListBox("Blending mode", &current_blend_index,
966 blend_mode_names.data(), blend_mode_names.size());
967 ImGui::End();
968
969 BlendMode selected_mode = blend_mode_values[current_blend_index];
970
971 Point a, b, c, d;
972 static PlaygroundPoint point_a(Point(400, 100), 20, Color::White());
973 static PlaygroundPoint point_b(Point(200, 300), 20, Color::White());
974 std::tie(a, b) = DrawPlaygroundLine(point_a, point_b);
975 static PlaygroundPoint point_c(Point(470, 190), 20, Color::White());
976 static PlaygroundPoint point_d(Point(270, 390), 20, Color::White());
977 std::tie(c, d) = DrawPlaygroundLine(point_c, point_d);
978
979 bool result = true;
980 result = result &&
981 draw_rect(Rect::MakeXYWH(0, 0, pass.GetRenderTargetSize().width,
982 pass.GetRenderTargetSize().height),
983 Color(), BlendMode::kClear);
984 result = result && draw_rect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), color1,
985 BlendMode::kSourceOver);
986 result = result && draw_rect(Rect::MakeLTRB(c.x, c.y, d.x, d.y), color2,
987 selected_mode);
988 return result;
989 };
990 ASSERT_TRUE(OpenPlaygroundHere(callback));
991}
SolidFillVertexShader VS
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:19
static void draw_rect(SkCanvas *canvas, const SkRect &r, const SkPaint &p)

◆ TEST_P() [308/450]

impeller::testing::TEST_P ( EntityTest  ,
BorderMaskBlurCoverageIsCorrect   
)

Definition at line 1394 of file entity_unittests.cc.

1394 {
1395 auto fill = std::make_shared<SolidColorContents>();
1396 fill->SetGeometry(Geometry::MakeFillPath(
1397 PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1398 fill->SetColor(Color::CornflowerBlue());
1399 auto border_mask_blur = FilterContents::MakeBorderMaskBlur(
1400 FilterInput::Make(fill), Radius{3}, Radius{4});
1401
1402 {
1403 Entity e;
1404 e.SetTransform(Matrix());
1405 auto actual = border_mask_blur->GetCoverage(e);
1406 auto expected = Rect::MakeXYWH(-3, -4, 306, 408);
1407 ASSERT_TRUE(actual.has_value());
1408 ASSERT_RECT_NEAR(actual.value(), expected);
1409 }
1410
1411 {
1412 Entity e;
1413 e.SetTransform(Matrix::MakeRotationZ(Radians{kPi / 4}));
1414 auto actual = border_mask_blur->GetCoverage(e);
1415 auto expected = Rect::MakeXYWH(-287.792, -4.94975, 504.874, 504.874);
1416 ASSERT_TRUE(actual.has_value());
1417 ASSERT_RECT_NEAR(actual.value(), expected);
1418 }
1419}

◆ TEST_P() [309/450]

impeller::testing::TEST_P ( EntityTest  ,
CanComputeGeometryForEmptyPathsWithoutCrashing   
)

Definition at line 2549 of file entity_unittests.cc.

2549 {
2550 PathBuilder builder = {};
2551 builder.AddRect(Rect::MakeLTRB(0, 0, 0, 0));
2552 Path path = builder.TakePath();
2553
2554 EXPECT_TRUE(path.GetBoundingBox()->IsEmpty());
2555
2556 auto geom = Geometry::MakeFillPath(path);
2557
2558 Entity entity;
2560 GetContentContext()->GetRenderTargetCache()->CreateOffscreen(
2561 *GetContext(), {1, 1}, 1u);
2562 testing::MockRenderPass render_pass(GetContext(), target);
2563 auto position_result =
2564 geom->GetPositionBuffer(*GetContentContext(), entity, render_pass);
2565
2566 EXPECT_EQ(position_result.vertex_buffer.vertex_count, 0u);
2567
2568 EXPECT_EQ(geom->GetResultMode(), GeometryResult::Mode::kNormal);
2569}
uint32_t * target

◆ TEST_P() [310/450]

impeller::testing::TEST_P ( EntityTest  ,
CanCreateEntity   
)

Definition at line 71 of file entity_unittests.cc.

71 {
72 Entity entity;
73 ASSERT_TRUE(entity.GetTransform().IsIdentity());
74}
constexpr bool IsIdentity() const
Definition: matrix.h:379

◆ TEST_P() [311/450]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawCorrectlyWithRotatedTransform   
)

Definition at line 546 of file entity_unittests.cc.

546 {
547 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
548 const char* input_axis[] = {"X", "Y", "Z"};
549 static int rotation_axis_index = 0;
550 static float rotation = 0;
551 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
552 ImGui::SliderFloat("Rotation", &rotation, -kPi, kPi);
553 ImGui::Combo("Rotation Axis", &rotation_axis_index, input_axis,
554 sizeof(input_axis) / sizeof(char*));
555 Matrix rotation_matrix;
556 switch (rotation_axis_index) {
557 case 0:
558 rotation_matrix = Matrix::MakeRotationX(Radians(rotation));
559 break;
560 case 1:
561 rotation_matrix = Matrix::MakeRotationY(Radians(rotation));
562 break;
563 case 2:
564 rotation_matrix = Matrix::MakeRotationZ(Radians(rotation));
565 break;
566 default:
567 rotation_matrix = Matrix{};
568 break;
569 }
570
571 if (ImGui::Button("Reset")) {
572 rotation = 0;
573 }
574 ImGui::End();
575 Matrix current_transform =
576 Matrix::MakeScale(GetContentScale())
577 .MakeTranslation(
578 Vector3(Point(pass.GetRenderTargetSize().width / 2.0,
579 pass.GetRenderTargetSize().height / 2.0)));
580 Matrix result_transform = current_transform * rotation_matrix;
581 Path path =
582 PathBuilder{}.AddRect(Rect::MakeXYWH(-300, -400, 600, 800)).TakePath();
583
584 Entity entity;
585 entity.SetTransform(result_transform);
586 entity.SetContents(SolidColorContents::Make(path, Color::Red()));
587 return entity.Render(context, pass);
588 };
589 ASSERT_TRUE(OpenPlaygroundHere(callback));
590}

◆ TEST_P() [312/450]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawRect   
)

Definition at line 265 of file entity_unittests.cc.

265 {
266 auto contents = std::make_shared<SolidColorContents>();
267 contents->SetGeometry(Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100)));
268 contents->SetColor(Color::Red());
269
270 Entity entity;
271 entity.SetTransform(Matrix::MakeScale(GetContentScale()));
272 entity.SetContents(contents);
273
274 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
275}

◆ TEST_P() [313/450]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawRRect   
)

Definition at line 277 of file entity_unittests.cc.

277 {
278 auto contents = std::make_shared<SolidColorContents>();
279 auto path = PathBuilder{}
280 .SetConvexity(Convexity::kConvex)
281 .AddRoundedRect(Rect::MakeXYWH(100, 100, 100, 100), 10.0)
282 .TakePath();
283 contents->SetGeometry(Geometry::MakeFillPath(path));
284 contents->SetColor(Color::Red());
285
286 Entity entity;
287 entity.SetTransform(Matrix::MakeScale(GetContentScale()));
288 entity.SetContents(contents);
289
290 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
291}
PathBuilder & AddRoundedRect(Rect rect, RoundingRadii radii)

◆ TEST_P() [314/450]

impeller::testing::TEST_P ( EntityTest  ,
CanRenderEmptyPathsWithoutCrashing   
)

Definition at line 2571 of file entity_unittests.cc.

2571 {
2572 PathBuilder builder = {};
2573 builder.AddRect(Rect::MakeLTRB(0, 0, 0, 0));
2574 Path path = builder.TakePath();
2575
2576 EXPECT_TRUE(path.GetBoundingBox()->IsEmpty());
2577
2578 auto contents = std::make_shared<SolidColorContents>();
2579 contents->SetGeometry(Geometry::MakeFillPath(path));
2580 contents->SetColor(Color::Red());
2581
2582 Entity entity;
2583 entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2584 entity.SetContents(contents);
2585
2586 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2587}

◆ TEST_P() [315/450]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsGetClipCoverageIsCorrect   
)

Definition at line 1534 of file entity_unittests.cc.

1534 {
1535 // Intersection: No stencil coverage, no geometry.
1536 {
1537 auto clip = std::make_shared<ClipContents>();
1538 clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1539 auto result = clip->GetClipCoverage(Entity{}, Rect{});
1540
1541 ASSERT_FALSE(result.coverage.has_value());
1542 }
1543
1544 // Intersection: No stencil coverage, with geometry.
1545 {
1546 auto clip = std::make_shared<ClipContents>();
1547 clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1548 clip->SetGeometry(Geometry::MakeFillPath(
1549 PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1550 auto result = clip->GetClipCoverage(Entity{}, Rect{});
1551
1552 ASSERT_FALSE(result.coverage.has_value());
1553 }
1554
1555 // Intersection: With stencil coverage, no geometry.
1556 {
1557 auto clip = std::make_shared<ClipContents>();
1558 clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1559 auto result =
1560 clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1561
1562 ASSERT_FALSE(result.coverage.has_value());
1563 }
1564
1565 // Intersection: With stencil coverage, with geometry.
1566 {
1567 auto clip = std::make_shared<ClipContents>();
1568 clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1569 clip->SetGeometry(Geometry::MakeFillPath(
1570 PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
1571 auto result =
1572 clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1573
1574 ASSERT_TRUE(result.coverage.has_value());
1575 ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
1576 ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
1577 }
1578
1579 // Difference: With stencil coverage, with geometry.
1580 {
1581 auto clip = std::make_shared<ClipContents>();
1582 clip->SetClipOperation(Entity::ClipOperation::kDifference);
1583 clip->SetGeometry(Geometry::MakeFillPath(
1584 PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
1585 auto result =
1586 clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1587
1588 ASSERT_TRUE(result.coverage.has_value());
1589 ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
1590 ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
1591 }
1592}
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892

◆ TEST_P() [316/450]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsOptimizesFullScreenIntersectClips   
)

Definition at line 23 of file clip_contents_unittests.cc.

23 {
24 // Set up mock environment.
25
26 auto content_context = GetContentContext();
27 auto buffer = content_context->GetContext()->CreateCommandBuffer();
28 auto render_target =
29 GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
30 *content_context->GetContext(), {100, 100},
31 /*mip_count=*/1);
32 auto render_pass = buffer->CreateRenderPass(render_target);
33 auto recording_pass = std::make_shared<RecordingRenderPass>(
34 render_pass, GetContext(), render_target);
35
36 // Set up clip contents.
37
38 auto contents = std::make_shared<ClipContents>();
39 contents->SetClipOperation(Entity::ClipOperation::kIntersect);
40 contents->SetGeometry(Geometry::MakeCover());
41
42 Entity entity;
43 entity.SetContents(std::move(contents));
44
45 // Render the clip contents.
46
47 ASSERT_TRUE(recording_pass->GetCommands().empty());
48 ASSERT_TRUE(entity.Render(*content_context, *recording_pass));
49 ASSERT_FALSE(recording_pass->GetCommands().empty());
50}

◆ TEST_P() [317/450]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsShouldRenderIsCorrect   
)

Definition at line 1510 of file entity_unittests.cc.

1510 {
1511 // For clip ops, `ShouldRender` should always return true.
1512
1513 // Clip.
1514 {
1515 auto clip = std::make_shared<ClipContents>();
1516 ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1517 clip->SetGeometry(Geometry::MakeFillPath(
1518 PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1519 ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1520 ASSERT_TRUE(
1521 clip->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1522 }
1523
1524 // Clip restore.
1525 {
1526 auto restore = std::make_shared<ClipRestoreContents>();
1527 ASSERT_TRUE(
1528 restore->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1529 ASSERT_TRUE(
1530 restore->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1531 }
1532}

◆ TEST_P() [318/450]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterContentsWithLargeGeometry   
)

Definition at line 2342 of file entity_unittests.cc.

2342 {
2343 Entity entity;
2344 entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2345 auto src_contents = std::make_shared<SolidColorContents>();
2346 src_contents->SetGeometry(
2347 Geometry::MakeRect(Rect::MakeLTRB(-300, -500, 30000, 50000)));
2348 src_contents->SetColor(Color::Red());
2349
2350 auto dst_contents = std::make_shared<SolidColorContents>();
2351 dst_contents->SetGeometry(
2352 Geometry::MakeRect(Rect::MakeLTRB(300, 500, 20000, 30000)));
2353 dst_contents->SetColor(Color::Blue());
2354
2355 auto contents = ColorFilterContents::MakeBlend(
2356 BlendMode::kSourceOver, {FilterInput::Make(dst_contents, false),
2357 FilterInput::Make(src_contents, false)});
2358 entity.SetContents(std::move(contents));
2359 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2360}

◆ TEST_P() [319/450]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorAdvancedBlend   
)

Definition at line 2175 of file entity_unittests.cc.

2175 {
2176 auto image = CreateTextureForFixture("boston.jpg");
2177 auto filter = ColorFilterContents::MakeBlend(
2178 BlendMode::kColorBurn, FilterInput::Make({image}), Color::Red());
2179
2180 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2181 Entity entity;
2182 entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2183 Matrix::MakeTranslation({500, 300}) *
2184 Matrix::MakeScale(Vector2{0.5, 0.5}));
2185 entity.SetContents(filter);
2186 return entity.Render(context, pass);
2187 };
2188 ASSERT_TRUE(OpenPlaygroundHere(callback));
2189}

◆ TEST_P() [320/450]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorClearBlend   
)

Definition at line 2191 of file entity_unittests.cc.

2191 {
2192 auto image = CreateTextureForFixture("boston.jpg");
2193 auto filter = ColorFilterContents::MakeBlend(
2194 BlendMode::kClear, FilterInput::Make({image}), Color::Red());
2195
2196 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2197 Entity entity;
2198 entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2199 Matrix::MakeTranslation({500, 300}) *
2200 Matrix::MakeScale(Vector2{0.5, 0.5}));
2201 entity.SetContents(filter);
2202 return entity.Render(context, pass);
2203 };
2204 ASSERT_TRUE(OpenPlaygroundHere(callback));
2205}

◆ TEST_P() [321/450]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorDstBlend   
)

Definition at line 2223 of file entity_unittests.cc.

2223 {
2224 auto image = CreateTextureForFixture("boston.jpg");
2225 auto filter = ColorFilterContents::MakeBlend(
2226 BlendMode::kDestination, FilterInput::Make({image}), Color::Red());
2227
2228 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2229 Entity entity;
2230 entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2231 Matrix::MakeTranslation({500, 300}) *
2232 Matrix::MakeScale(Vector2{0.5, 0.5}));
2233 entity.SetContents(filter);
2234 return entity.Render(context, pass);
2235 };
2236 ASSERT_TRUE(OpenPlaygroundHere(callback));
2237}

◆ TEST_P() [322/450]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcBlend   
)

Definition at line 2207 of file entity_unittests.cc.

2207 {
2208 auto image = CreateTextureForFixture("boston.jpg");
2209 auto filter = ColorFilterContents::MakeBlend(
2210 BlendMode::kSource, FilterInput::Make({image}), Color::Red());
2211
2212 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2213 Entity entity;
2214 entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2215 Matrix::MakeTranslation({500, 300}) *
2216 Matrix::MakeScale(Vector2{0.5, 0.5}));
2217 entity.SetContents(filter);
2218 return entity.Render(context, pass);
2219 };
2220 ASSERT_TRUE(OpenPlaygroundHere(callback));
2221}

◆ TEST_P() [323/450]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcInBlend   
)

Definition at line 2239 of file entity_unittests.cc.

2239 {
2240 auto image = CreateTextureForFixture("boston.jpg");
2241 auto filter = ColorFilterContents::MakeBlend(
2242 BlendMode::kSourceIn, FilterInput::Make({image}), Color::Red());
2243
2244 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2245 Entity entity;
2246 entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2247 Matrix::MakeTranslation({500, 300}) *
2248 Matrix::MakeScale(Vector2{0.5, 0.5}));
2249 entity.SetContents(filter);
2250 return entity.Render(context, pass);
2251 };
2252 ASSERT_TRUE(OpenPlaygroundHere(callback));
2253}

◆ TEST_P() [324/450]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterCoverageIsCorrect   
)

Definition at line 1647 of file entity_unittests.cc.

1647 {
1648 // Set up a simple color background.
1649 auto fill = std::make_shared<SolidColorContents>();
1650 fill->SetGeometry(Geometry::MakeFillPath(
1651 PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1652 fill->SetColor(Color::Coral());
1653
1654 // Set the color matrix filter.
1656 1, 1, 1, 1, 1, //
1657 1, 1, 1, 1, 1, //
1658 1, 1, 1, 1, 1, //
1659 1, 1, 1, 1, 1, //
1660 };
1661
1662 auto filter =
1663 ColorFilterContents::MakeColorMatrix(FilterInput::Make(fill), matrix);
1664
1665 Entity e;
1666 e.SetTransform(Matrix());
1667
1668 // Confirm that the actual filter coverage matches the expected coverage.
1669 auto actual = filter->GetCoverage(e);
1670 auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1671
1672 ASSERT_TRUE(actual.has_value());
1673 ASSERT_RECT_NEAR(actual.value(), expected);
1674}

◆ TEST_P() [325/450]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterEditable   
)

Definition at line 1676 of file entity_unittests.cc.

1676 {
1677 auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
1678 ASSERT_TRUE(bay_bridge);
1679
1680 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1681 // UI state.
1682 static ColorMatrix color_matrix = {
1683 1, 0, 0, 0, 0, //
1684 0, 3, 0, 0, 0, //
1685 0, 0, 1, 0, 0, //
1686 0, 0, 0, 1, 0, //
1687 };
1688 static float offset[2] = {500, 400};
1689 static float rotation = 0;
1690 static float scale[2] = {0.65, 0.65};
1691 static float skew[2] = {0, 0};
1692
1693 // Define the ImGui
1694 ImGui::Begin("Color Matrix", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1695 {
1696 std::string label = "##1";
1697 for (int i = 0; i < 20; i += 5) {
1698 ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
1699 &(color_matrix.array[i]), 5, nullptr, nullptr,
1700 "%.2f", 0);
1701 label[2]++;
1702 }
1703
1704 ImGui::SliderFloat2("Translation", &offset[0], 0,
1705 pass.GetRenderTargetSize().width);
1706 ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1707 ImGui::SliderFloat2("Scale", &scale[0], 0, 3);
1708 ImGui::SliderFloat2("Skew", &skew[0], -3, 3);
1709 }
1710 ImGui::End();
1711
1712 // Set the color matrix filter.
1713 auto filter = ColorFilterContents::MakeColorMatrix(
1714 FilterInput::Make(bay_bridge), color_matrix);
1715
1716 // Define the entity with the color matrix filter.
1717 Entity entity;
1718 entity.SetTransform(
1719 Matrix::MakeScale(GetContentScale()) *
1720 Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1721 Matrix::MakeRotationZ(Radians(rotation)) *
1722 Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1723 Matrix::MakeSkew(skew[0], skew[1]) *
1724 Matrix::MakeTranslation(-Point(bay_bridge->GetSize()) / 2));
1725 entity.SetContents(filter);
1726 entity.Render(context, pass);
1727
1728 return true;
1729 };
1730
1731 ASSERT_TRUE(OpenPlaygroundHere(callback));
1732}
Scalar array[20]
Definition: color.h:118

◆ TEST_P() [326/450]

impeller::testing::TEST_P ( EntityTest  ,
ConicalGradientContentsIsOpaque   
)

Definition at line 2283 of file entity_unittests.cc.

2283 {
2284 ConicalGradientContents contents;
2285 contents.SetColors({Color::CornflowerBlue()});
2286 ASSERT_FALSE(contents.IsOpaque());
2287 contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2288 ASSERT_FALSE(contents.IsOpaque());
2289}
void SetColors(std::vector< Color > colors)
virtual bool IsOpaque() const
Whether this Contents only emits opaque source colors from the fragment stage. This value does not ac...
Definition: contents.cc:52

◆ TEST_P() [327/450]

impeller::testing::TEST_P ( EntityTest  ,
ContentContextOptionsHasReasonableHashFunctions   
)

Definition at line 2459 of file entity_unittests.cc.

2459 {
2461 auto hash_a = ContentContextOptions::Hash{}(opts);
2462
2463 opts.blend_mode = BlendMode::kColorBurn;
2464 auto hash_b = ContentContextOptions::Hash{}(opts);
2465
2466 opts.has_depth_stencil_attachments = false;
2467 auto hash_c = ContentContextOptions::Hash{}(opts);
2468
2469 opts.primitive_type = PrimitiveType::kPoint;
2470 auto hash_d = ContentContextOptions::Hash{}(opts);
2471
2472 EXPECT_NE(hash_a, hash_b);
2473 EXPECT_NE(hash_b, hash_c);
2474 EXPECT_NE(hash_c, hash_d);
2475}
static uint32_t Hash(uint32_t key)
Definition: hashmap_test.cc:65

◆ TEST_P() [328/450]

impeller::testing::TEST_P ( EntityTest  ,
ContentsGetBoundsForEmptyPathReturnsNullopt   
)

Definition at line 1335 of file entity_unittests.cc.

1335 {
1336 Entity entity;
1337 entity.SetContents(std::make_shared<SolidColorContents>());
1338 ASSERT_FALSE(entity.GetCoverage().has_value());
1339}

◆ TEST_P() [329/450]

impeller::testing::TEST_P ( EntityTest  ,
CoverageForStrokePathWithNegativeValuesInTransform   
)

Definition at line 2255 of file entity_unittests.cc.

2255 {
2256 auto arrow_head = PathBuilder{}
2257 .MoveTo({50, 120})
2258 .LineTo({120, 190})
2259 .LineTo({190, 120})
2260 .TakePath();
2261 auto geometry = Geometry::MakeStrokePath(arrow_head, 15.0, 4.0, Cap::kRound,
2262 Join::kRound);
2263
2264 auto transform = Matrix::MakeTranslation({300, 300}) *
2265 Matrix::MakeRotationZ(Radians(kPiOver2));
2266 // Note that e[0][0] used to be tested here, but it was -epsilon solely
2267 // due to floating point inaccuracy in the transcendental trig functions.
2268 // e[1][0] is the intended negative value that we care about (-1.0) as it
2269 // comes from the rotation of pi/2.
2270 EXPECT_LT(transform.e[1][0], 0.0f);
2271 auto coverage = geometry->GetCoverage(transform);
2272 ASSERT_RECT_NEAR(coverage.value(), Rect::MakeXYWH(102.5, 342.5, 85, 155));
2273}

◆ TEST_P() [330/450]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveAndOverlapTest   
)

Definition at line 592 of file entity_unittests.cc.

592 {
593 // Compare with https://fiddle.skia.org/c/7a05a3e186c65a8dfb732f68020aae06
594 Path path =
596 .MoveTo({359.934, 96.6335})
597 .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
598 {354.673, 96.8895})
599 .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
600 {354.367, 96.9075})
601 .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
602 {349.259, 97.2355})
603 .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
604 {348.625, 97.2834})
605 .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
606 {343.789, 97.6722})
607 .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
608 {342.703, 97.7734})
609 .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
610 {338.246, 98.207})
611 .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
612 {336.612, 98.3894})
613 .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
614 {332.623, 98.8476})
615 .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
616 {332.237, 98.8982})
617 .LineTo({332.237, 102.601})
618 .LineTo({321.778, 102.601})
619 .LineTo({321.778, 100.382})
620 .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
621 {321.161, 100.476})
622 .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
623 {315.332, 101.479})
624 .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
625 {315.301, 101.484})
626 .LineTo({310.017, 105.94})
627 .LineTo({309.779, 105.427})
628 .LineTo({314.403, 101.651})
629 .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
630 {314.368, 101.658})
631 .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
632 {308.846, 102.748})
633 .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
634 .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
635 {303.425, 103.936})
636 .LineTo({299.105, 107.578})
637 .LineTo({298.867, 107.065})
638 .LineTo({302.394, 104.185})
639 .LineTo({302.412, 104.171})
640 .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
641 {299.344, 104.921})
642 .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
643 .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
644 {291.462, 106.979})
645 .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
646 {290.471, 107.257})
647 .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
648 {287.449, 108.139})
649 .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
650 {284.536, 109.035})
651 .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
652 {281.952, 109.859})
653 .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
654 {279.633, 110.638})
655 .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
656 {276.803, 111.607})
657 .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
658 {276.672, 111.653})
659 .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
660 {271.721, 113.463})
661 .LineTo({271.717, 113.449})
662 .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
663 {270.963, 113.628})
664 .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
665 {270.748, 113.682})
666 .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
667 {269.839, 113.926})
668 .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
669 {269.681, 113.972})
670 .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
671 {268.756, 114.239})
672 .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
673 {268.367, 114.354})
674 .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
675 {267.752, 114.54})
676 .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
677 {253.564, 119.252})
678 .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
679 {253.538, 119.261})
680 .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
681 {248.189, 121.131})
682 .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
683 .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
684 {245.975, 121.912})
685 .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
686 {244.698, 122.364})
687 .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
688 {242.794, 123.04})
689 .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
690 {240.961, 123.693})
691 .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
692 {240.052, 124.018})
693 .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
694 .LineTo({237.164, 125.003})
695 .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
696 {235.81, 125.538})
697 .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
698 {234.592, 125.977})
699 .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
700 {234.59, 125.977})
701 .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
702 {192.381, 141.429})
703 .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
704 .LineTo({360, 160})
705 .LineTo({360, 119.256})
706 .LineTo({360, 106.332})
707 .LineTo({360, 96.6307})
708 .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
709 {359.934, 96.6335})
710 .Close()
711 .MoveTo({337.336, 124.143})
712 .CubicCurveTo({337.274, 122.359}, {338.903, 121.511},
713 {338.903, 121.511})
714 .CubicCurveTo({338.903, 121.511}, {338.96, 123.303},
715 {337.336, 124.143})
716 .Close()
717 .MoveTo({340.082, 121.849})
718 .CubicCurveTo({340.074, 121.917}, {340.062, 121.992},
719 {340.046, 122.075})
720 .CubicCurveTo({340.039, 122.109}, {340.031, 122.142},
721 {340.023, 122.177})
722 .CubicCurveTo({340.005, 122.26}, {339.98, 122.346},
723 {339.952, 122.437})
724 .CubicCurveTo({339.941, 122.473}, {339.931, 122.507},
725 {339.918, 122.544})
726 .CubicCurveTo({339.873, 122.672}, {339.819, 122.804},
727 {339.75, 122.938})
728 .CubicCurveTo({339.747, 122.944}, {339.743, 122.949},
729 {339.74, 122.955})
730 .CubicCurveTo({339.674, 123.08}, {339.593, 123.205},
731 {339.501, 123.328})
732 .CubicCurveTo({339.473, 123.366}, {339.441, 123.401},
733 {339.41, 123.438})
734 .CubicCurveTo({339.332, 123.534}, {339.243, 123.625},
735 {339.145, 123.714})
736 .CubicCurveTo({339.105, 123.75}, {339.068, 123.786},
737 {339.025, 123.821})
738 .CubicCurveTo({338.881, 123.937}, {338.724, 124.048},
739 {338.539, 124.143})
740 .CubicCurveTo({338.532, 123.959}, {338.554, 123.79},
741 {338.58, 123.626})
742 .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625})
743 .CubicCurveTo({338.607, 123.455}, {338.65, 123.299},
744 {338.704, 123.151})
745 .CubicCurveTo({338.708, 123.14}, {338.71, 123.127},
746 {338.714, 123.117})
747 .CubicCurveTo({338.769, 122.971}, {338.833, 122.838},
748 {338.905, 122.712})
749 .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001},
750 {338.922, 122.682})
751 .CubicCurveTo({338.996, 122.557}, {339.072, 122.444},
752 {339.155, 122.34})
753 .CubicCurveTo({339.161, 122.333}, {339.166, 122.326},
754 {339.172, 122.319})
755 .CubicCurveTo({339.256, 122.215}, {339.339, 122.12},
756 {339.425, 122.037})
757 .CubicCurveTo({339.428, 122.033}, {339.431, 122.03},
758 {339.435, 122.027})
759 .CubicCurveTo({339.785, 121.687}, {340.106, 121.511},
760 {340.106, 121.511})
761 .CubicCurveTo({340.106, 121.511}, {340.107, 121.645},
762 {340.082, 121.849})
763 .Close()
764 .MoveTo({340.678, 113.245})
765 .CubicCurveTo({340.594, 113.488}, {340.356, 113.655},
766 {340.135, 113.775})
767 .CubicCurveTo({339.817, 113.948}, {339.465, 114.059},
768 {339.115, 114.151})
769 .CubicCurveTo({338.251, 114.379}, {337.34, 114.516},
770 {336.448, 114.516})
771 .CubicCurveTo({335.761, 114.516}, {335.072, 114.527},
772 {334.384, 114.513})
773 .CubicCurveTo({334.125, 114.508}, {333.862, 114.462},
774 {333.605, 114.424})
775 .CubicCurveTo({332.865, 114.318}, {332.096, 114.184},
776 {331.41, 113.883})
777 .CubicCurveTo({330.979, 113.695}, {330.442, 113.34},
778 {330.672, 112.813})
779 .CubicCurveTo({331.135, 111.755}, {333.219, 112.946},
780 {334.526, 113.833})
781 .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784})
782 .CubicCurveTo({333.38, 112.708}, {331.749, 110.985},
783 {332.76, 110.402})
784 .CubicCurveTo({333.769, 109.82}, {334.713, 111.93},
785 {335.228, 113.395})
786 .CubicCurveTo({334.915, 111.889}, {334.59, 109.636},
787 {335.661, 109.592})
788 .CubicCurveTo({336.733, 109.636}, {336.408, 111.889},
789 {336.07, 113.389})
790 .CubicCurveTo({336.609, 111.93}, {337.553, 109.82},
791 {338.563, 110.402})
792 .CubicCurveTo({339.574, 110.984}, {337.942, 112.708},
793 {336.753, 113.784})
794 .CubicCurveTo({336.768, 113.8}, {336.782, 113.816},
795 {336.796, 113.833})
796 .CubicCurveTo({338.104, 112.946}, {340.187, 111.755},
797 {340.65, 112.813})
798 .CubicCurveTo({340.71, 112.95}, {340.728, 113.102},
799 {340.678, 113.245})
800 .Close()
801 .MoveTo({346.357, 106.771})
802 .CubicCurveTo({346.295, 104.987}, {347.924, 104.139},
803 {347.924, 104.139})
804 .CubicCurveTo({347.924, 104.139}, {347.982, 105.931},
805 {346.357, 106.771})
806 .Close()
807 .MoveTo({347.56, 106.771})
808 .CubicCurveTo({347.498, 104.987}, {349.127, 104.139},
809 {349.127, 104.139})
810 .CubicCurveTo({349.127, 104.139}, {349.185, 105.931},
811 {347.56, 106.771})
812 .Close()
813 .TakePath();
814 Entity entity;
815 entity.SetTransform(Matrix::MakeScale(GetContentScale()));
816 entity.SetContents(SolidColorContents::Make(path, Color::Red()));
817 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
818}

◆ TEST_P() [331/450]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveTest   
)

Definition at line 524 of file entity_unittests.cc.

524 {
525 // Compare with https://fiddle.skia.org/c/b3625f26122c9de7afe7794fcf25ead3
526 Path path =
528 .MoveTo({237.164, 125.003})
529 .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
530 {235.81, 125.538})
531 .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
532 {234.592, 125.977})
533 .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
534 {234.59, 125.977})
535 .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
536 {192.381, 141.429})
537 .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
538 .Close()
539 .TakePath();
540 Entity entity;
541 entity.SetTransform(Matrix::MakeScale(GetContentScale()));
542 entity.SetContents(SolidColorContents::Make(path, Color::Red()));
543 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
544}

◆ TEST_P() [332/450]

impeller::testing::TEST_P ( EntityTest  ,
DecalSpecializationAppliedToMorphologyFilter   
)

Definition at line 2443 of file entity_unittests.cc.

2443 {
2444 auto content_context = GetContentContext();
2445 auto default_color_burn = content_context->GetMorphologyFilterPipeline({
2446 .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2447 });
2448
2449 auto decal_supported = static_cast<Scalar>(
2450 GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2451 std::vector<Scalar> expected_constants = {decal_supported};
2452 ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2453 expected_constants);
2454}

◆ TEST_P() [333/450]

impeller::testing::TEST_P ( EntityTest  ,
DoesNotCullEntitiesByDefault   
)

Definition at line 1496 of file entity_unittests.cc.

1496 {
1497 auto fill = std::make_shared<SolidColorContents>();
1498 fill->SetColor(Color::CornflowerBlue());
1499 fill->SetGeometry(
1500 Geometry::MakeRect(Rect::MakeLTRB(-1000, -1000, -900, -900)));
1501
1502 Entity entity;
1503 entity.SetContents(fill);
1504
1505 // Even though the entity is offscreen, this should still render because we do
1506 // not compute the coverage intersection by default.
1507 EXPECT_TRUE(entity.ShouldRender(Rect::MakeLTRB(0, 0, 100, 100)));
1508}
bool ShouldRender(const std::optional< Rect > &clip_coverage) const
Definition: entity.cc:82

◆ TEST_P() [334/450]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassCanMergeSubpassIntoParent   
)

Definition at line 188 of file entity_unittests.cc.

188 {
189 // Both a red and a blue box should appear if the pass merging has worked
190 // correctly.
191
192 EntityPass pass;
193 auto subpass = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
194 Rect::MakeLTRB(50, 50, 150, 150),
196 pass.AddSubpass(std::move(subpass));
197
198 Entity entity;
199 entity.SetTransform(Matrix::MakeScale(GetContentScale()));
200 auto contents = std::make_unique<SolidColorContents>();
201 contents->SetGeometry(Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
202 contents->SetColor(Color::Blue());
203 entity.SetContents(std::move(contents));
204
205 pass.AddEntity(std::move(entity));
206
207 ASSERT_TRUE(OpenPlaygroundHere(pass));
208}
void AddEntity(Entity entity)
Add an entity to the current entity pass.
Definition: entity_pass.cc:100
EntityPass * AddSubpass(std::unique_ptr< EntityPass > pass)
Appends a given pass as a subpass.
Definition: entity_pass.cc:267
auto CreatePassWithRectPath(Rect rect, std::optional< Rect > bounds_hint, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown, bool collapse=false)

◆ TEST_P() [335/450]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassCoverageRespectsCoverageLimit   
)

Definition at line 210 of file entity_unittests.cc.

210 {
211 // Rect is drawn entirely in negative area.
212 auto pass = CreatePassWithRectPath(Rect::MakeLTRB(-200, -200, -100, -100),
213 std::nullopt);
214
215 // Without coverage limit.
216 {
217 auto pass_coverage = pass->GetElementsCoverage(std::nullopt);
218 ASSERT_TRUE(pass_coverage.has_value());
219 ASSERT_RECT_NEAR(pass_coverage.value(),
220 Rect::MakeLTRB(-200, -200, -100, -100));
221 }
222
223 // With limit that doesn't overlap.
224 {
225 auto pass_coverage =
226 pass->GetElementsCoverage(Rect::MakeLTRB(0, 0, 100, 100));
227 ASSERT_FALSE(pass_coverage.has_value());
228 }
229
230 // With limit that partially overlaps.
231 {
232 auto pass_coverage =
233 pass->GetElementsCoverage(Rect::MakeLTRB(-150, -150, 0, 0));
234 ASSERT_TRUE(pass_coverage.has_value());
235 ASSERT_RECT_NEAR(pass_coverage.value(),
236 Rect::MakeLTRB(-150, -150, -100, -100));
237 }
238}

◆ TEST_P() [336/450]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassRespectsUntrustedSubpassBoundsLimit   
)

Definition at line 125 of file entity_unittests.cc.

125 {
126 EntityPass pass;
127
128 auto subpass0 = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
129 Rect::MakeLTRB(50, 50, 150, 150));
130 auto subpass1 = CreatePassWithRectPath(Rect::MakeLTRB(500, 500, 1000, 1000),
131 Rect::MakeLTRB(800, 800, 900, 900));
132
133 auto subpass0_coverage =
134 pass.GetSubpassCoverage(*subpass0.get(), std::nullopt);
135 ASSERT_TRUE(subpass0_coverage.has_value());
136 ASSERT_RECT_NEAR(subpass0_coverage.value(), Rect::MakeLTRB(50, 50, 100, 100));
137
138 auto subpass1_coverage =
139 pass.GetSubpassCoverage(*subpass1.get(), std::nullopt);
140 ASSERT_TRUE(subpass1_coverage.has_value());
141 ASSERT_RECT_NEAR(subpass1_coverage.value(),
142 Rect::MakeLTRB(800, 800, 900, 900));
143
144 pass.AddSubpass(std::move(subpass0));
145 pass.AddSubpass(std::move(subpass1));
146
147 auto coverage = pass.GetElementsCoverage(std::nullopt);
148 ASSERT_TRUE(coverage.has_value());
149 ASSERT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(50, 50, 900, 900));
150}
std::optional< Rect > GetSubpassCoverage(const EntityPass &subpass, std::optional< Rect > coverage_limit) const
Computes the coverage of a given subpass. This is used to determine the texture size of a given subpa...
Definition: entity_pass.cc:231
std::optional< Rect > GetElementsCoverage(std::optional< Rect > coverage_limit) const
Definition: entity_pass.cc:154

◆ TEST_P() [337/450]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassTrustsSnugSubpassBoundsLimit   
)

Definition at line 152 of file entity_unittests.cc.

152 {
153 EntityPass pass;
154
155 auto subpass0 = //
156 CreatePassWithRectPath(Rect::MakeLTRB(10, 10, 90, 90),
157 Rect::MakeLTRB(5, 5, 95, 95),
158 ContentBoundsPromise::kContainsContents);
159 auto subpass1 = //
160 CreatePassWithRectPath(Rect::MakeLTRB(500, 500, 1000, 1000),
161 Rect::MakeLTRB(495, 495, 1005, 1005),
162 ContentBoundsPromise::kContainsContents);
163
164 auto subpass0_coverage =
165 pass.GetSubpassCoverage(*subpass0.get(), std::nullopt);
166 EXPECT_TRUE(subpass0_coverage.has_value());
167 // Result should be the overridden bounds
168 // (we lied about them being snug, but the property is respected)
169 EXPECT_RECT_NEAR(subpass0_coverage.value(), Rect::MakeLTRB(5, 5, 95, 95));
170
171 auto subpass1_coverage =
172 pass.GetSubpassCoverage(*subpass1.get(), std::nullopt);
173 EXPECT_TRUE(subpass1_coverage.has_value());
174 // Result should be the overridden bounds
175 // (we lied about them being snug, but the property is respected)
176 EXPECT_RECT_NEAR(subpass1_coverage.value(),
177 Rect::MakeLTRB(495, 495, 1005, 1005));
178
179 pass.AddSubpass(std::move(subpass0));
180 pass.AddSubpass(std::move(subpass1));
181
182 auto coverage = pass.GetElementsCoverage(std::nullopt);
183 EXPECT_TRUE(coverage.has_value());
184 // This result should be the union of the overridden bounds
185 EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(5, 5, 1005, 1005));
186}

◆ TEST_P() [338/450]

impeller::testing::TEST_P ( EntityTest  ,
FailOnValidationError   
)

Definition at line 2535 of file entity_unittests.cc.

2535 {
2536 if (GetParam() != PlaygroundBackend::kVulkan) {
2537 GTEST_SKIP() << "Validation is only fatal on Vulkan backend.";
2538 }
2539 EXPECT_DEATH(
2540 // The easiest way to trigger a validation error is to try to compile
2541 // a shader with an unsupported pixel format.
2542 GetContentContext()->GetBlendColorBurnPipeline({
2543 .color_attachment_pixel_format = PixelFormat::kUnknown,
2544 .has_depth_stencil_attachments = false,
2545 }),
2546 "");
2547}
@ kVulkan
Definition: embedder.h:86

◆ TEST_P() [339/450]

impeller::testing::TEST_P ( EntityTest  ,
FillPathGeometryGetPositionBufferReturnsExpectedMode   
)

Definition at line 2501 of file entity_unittests.cc.

2501 {
2504
2505 auto get_result = [this, &mock_pass](const Path& path) {
2506 auto geometry = Geometry::MakeFillPath(
2507 path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
2508 return geometry->GetPositionBuffer(*GetContentContext(), {}, mock_pass);
2509 };
2510
2511 // Convex path
2512 {
2513 GeometryResult result =
2514 get_result(PathBuilder{}
2515 .AddRect(Rect::MakeLTRB(0, 0, 100, 100))
2516 .SetConvexity(Convexity::kConvex)
2517 .TakePath());
2518 EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
2519 }
2520
2521 // Concave path
2522 {
2523 Path path = PathBuilder{}
2524 .MoveTo({0, 0})
2525 .LineTo({100, 0})
2526 .LineTo({100, 100})
2527 .LineTo({50, 50})
2528 .Close()
2529 .TakePath();
2530 GeometryResult result = get_result(path);
2531 EXPECT_EQ(result.mode, GeometryResult::Mode::kNonZero);
2532 }
2533}

◆ TEST_P() [340/450]

impeller::testing::TEST_P ( EntityTest  ,
FilterCoverageRespectsCropRect   
)

Definition at line 240 of file entity_unittests.cc.

240 {
241 auto image = CreateTextureForFixture("boston.jpg");
242 auto filter = ColorFilterContents::MakeBlend(BlendMode::kSoftLight,
244
245 // Without the crop rect (default behavior).
246 {
247 auto actual = filter->GetCoverage({});
248 auto expected = Rect::MakeSize(image->GetSize());
249
250 ASSERT_TRUE(actual.has_value());
251 ASSERT_RECT_NEAR(actual.value(), expected);
252 }
253
254 // With the crop rect.
255 {
256 auto expected = Rect::MakeLTRB(50, 50, 100, 100);
257 filter->SetCoverageHint(expected);
258 auto actual = filter->GetCoverage({});
259
260 ASSERT_TRUE(actual.has_value());
261 ASSERT_RECT_NEAR(actual.value(), expected);
262 }
263}

◆ TEST_P() [341/450]

impeller::testing::TEST_P ( EntityTest  ,
Filters   
)

Definition at line 1027 of file entity_unittests.cc.

1027 {
1028 auto bridge = CreateTextureForFixture("bay_bridge.jpg");
1029 auto boston = CreateTextureForFixture("boston.jpg");
1030 auto kalimba = CreateTextureForFixture("kalimba.jpg");
1031 ASSERT_TRUE(bridge && boston && kalimba);
1032
1033 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1034 auto fi_bridge = FilterInput::Make(bridge);
1035 auto fi_boston = FilterInput::Make(boston);
1036 auto fi_kalimba = FilterInput::Make(kalimba);
1037
1038 std::shared_ptr<FilterContents> blend0 = ColorFilterContents::MakeBlend(
1039 BlendMode::kModulate, {fi_kalimba, fi_boston});
1040
1041 auto blend1 = ColorFilterContents::MakeBlend(
1042 BlendMode::kScreen,
1043 {FilterInput::Make(blend0), fi_bridge, fi_bridge, fi_bridge});
1044
1045 Entity entity;
1046 entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1047 Matrix::MakeTranslation({500, 300}) *
1048 Matrix::MakeScale(Vector2{0.5, 0.5}));
1049 entity.SetContents(blend1);
1050 return entity.Render(context, pass);
1051 };
1052 ASSERT_TRUE(OpenPlaygroundHere(callback));
1053}

◆ TEST_P() [342/450]

impeller::testing::TEST_P ( EntityTest  ,
GaussianBlurFilter   
)

Definition at line 1055 of file entity_unittests.cc.

1055 {
1056 auto boston =
1057 CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true);
1058 ASSERT_TRUE(boston);
1059
1060 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1061 const char* input_type_names[] = {"Texture", "Solid Color"};
1062 const char* blur_type_names[] = {"Image blur", "Mask blur"};
1063 const char* pass_variation_names[] = {"New"};
1064 const char* blur_style_names[] = {"Normal", "Solid", "Outer", "Inner"};
1065 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
1066 const FilterContents::BlurStyle blur_styles[] = {
1068 FilterContents::BlurStyle::kOuter, FilterContents::BlurStyle::kInner};
1069 const Entity::TileMode tile_modes[] = {
1070 Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
1071 Entity::TileMode::kMirror, Entity::TileMode::kDecal};
1072
1073 // UI state.
1074 static int selected_input_type = 0;
1075 static Color input_color = Color::Black();
1076 static int selected_blur_type = 0;
1077 static int selected_pass_variation = 0;
1078 static bool combined_sigma = false;
1079 static float blur_amount_coarse[2] = {0, 0};
1080 static float blur_amount_fine[2] = {10, 10};
1081 static int selected_blur_style = 0;
1082 static int selected_tile_mode = 3;
1083 static Color cover_color(1, 0, 0, 0.2);
1084 static Color bounds_color(0, 1, 0, 0.1);
1085 static float offset[2] = {500, 400};
1086 static float rotation = 0;
1087 static float scale[2] = {0.65, 0.65};
1088 static float skew[2] = {0, 0};
1089 static float path_rect[4] = {0, 0,
1090 static_cast<float>(boston->GetSize().width),
1091 static_cast<float>(boston->GetSize().height)};
1092
1093 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1094 {
1095 ImGui::Combo("Input type", &selected_input_type, input_type_names,
1096 sizeof(input_type_names) / sizeof(char*));
1097 if (selected_input_type == 0) {
1098 ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1099 } else {
1100 ImGui::ColorEdit4("Input color",
1101 reinterpret_cast<float*>(&input_color));
1102 }
1103 ImGui::Combo("Blur type", &selected_blur_type, blur_type_names,
1104 sizeof(blur_type_names) / sizeof(char*));
1105 if (selected_blur_type == 0) {
1106 ImGui::Combo("Pass variation", &selected_pass_variation,
1107 pass_variation_names,
1108 sizeof(pass_variation_names) / sizeof(char*));
1109 }
1110 ImGui::Checkbox("Combined sigma", &combined_sigma);
1111 if (combined_sigma) {
1112 ImGui::SliderFloat("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1113 ImGui::SliderFloat("Sigma (fine)", blur_amount_fine, 0, 10);
1114 blur_amount_coarse[1] = blur_amount_coarse[0];
1115 blur_amount_fine[1] = blur_amount_fine[0];
1116 } else {
1117 ImGui::SliderFloat2("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1118 ImGui::SliderFloat2("Sigma (fine)", blur_amount_fine, 0, 10);
1119 }
1120 ImGui::Combo("Blur style", &selected_blur_style, blur_style_names,
1121 sizeof(blur_style_names) / sizeof(char*));
1122 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1123 sizeof(tile_mode_names) / sizeof(char*));
1124 ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1125 ImGui::ColorEdit4("Bounds color",
1126 reinterpret_cast<float*>(&bounds_color));
1127 ImGui::SliderFloat2("Translation", offset, 0,
1128 pass.GetRenderTargetSize().width);
1129 ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1130 ImGui::SliderFloat2("Scale", scale, 0, 3);
1131 ImGui::SliderFloat2("Skew", skew, -3, 3);
1132 ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1133 }
1134 ImGui::End();
1135
1136 auto blur_sigma_x = Sigma{blur_amount_coarse[0] + blur_amount_fine[0]};
1137 auto blur_sigma_y = Sigma{blur_amount_coarse[1] + blur_amount_fine[1]};
1138
1139 std::shared_ptr<Contents> input;
1140 Size input_size;
1141
1142 auto input_rect =
1143 Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1144 if (selected_input_type == 0) {
1145 auto texture = std::make_shared<TextureContents>();
1146 texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1147 texture->SetDestinationRect(input_rect);
1148 texture->SetTexture(boston);
1149 texture->SetOpacity(input_color.alpha);
1150
1151 input = texture;
1152 input_size = input_rect.GetSize();
1153 } else {
1154 auto fill = std::make_shared<SolidColorContents>();
1155 fill->SetColor(input_color);
1156 fill->SetGeometry(
1157 Geometry::MakeFillPath(PathBuilder{}.AddRect(input_rect).TakePath()));
1158
1159 input = fill;
1160 input_size = input_rect.GetSize();
1161 }
1162
1163 std::shared_ptr<FilterContents> blur;
1164 switch (selected_pass_variation) {
1165 case 0:
1166 blur = std::make_shared<GaussianBlurFilterContents>(
1167 blur_sigma_x.sigma, blur_sigma_y.sigma,
1168 tile_modes[selected_tile_mode], blur_styles[selected_blur_style],
1169 /*geometry=*/nullptr);
1170 blur->SetInputs({FilterInput::Make(input)});
1171 break;
1172 case 1:
1173 blur = FilterContents::MakeGaussianBlur(
1174 FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1175 tile_modes[selected_tile_mode], blur_styles[selected_blur_style]);
1176 break;
1177 };
1178 FML_CHECK(blur);
1179
1180 auto mask_blur = FilterContents::MakeBorderMaskBlur(
1181 FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1182 blur_styles[selected_blur_style]);
1183
1184 auto ctm = Matrix::MakeScale(GetContentScale()) *
1185 Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1186 Matrix::MakeRotationZ(Radians(rotation)) *
1187 Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1188 Matrix::MakeSkew(skew[0], skew[1]) *
1189 Matrix::MakeTranslation(-Point(input_size) / 2);
1190
1191 auto target_contents = selected_blur_type == 0 ? blur : mask_blur;
1192
1193 Entity entity;
1194 entity.SetContents(target_contents);
1195 entity.SetTransform(ctm);
1196
1197 entity.Render(context, pass);
1198
1199 // Renders a red "cover" rectangle that shows the original position of the
1200 // unfiltered input.
1201 Entity cover_entity;
1202 cover_entity.SetContents(SolidColorContents::Make(
1203 PathBuilder{}.AddRect(input_rect).TakePath(), cover_color));
1204 cover_entity.SetTransform(ctm);
1205
1206 cover_entity.Render(context, pass);
1207
1208 // Renders a green bounding rect of the target filter.
1209 Entity bounds_entity;
1210 std::optional<Rect> target_contents_coverage =
1211 target_contents->GetCoverage(entity);
1212 if (target_contents_coverage.has_value()) {
1213 bounds_entity.SetContents(SolidColorContents::Make(
1214 PathBuilder{}
1215 .AddRect(target_contents->GetCoverage(entity).value())
1216 .TakePath(),
1217 bounds_color));
1218 bounds_entity.SetTransform(Matrix());
1219
1220 bounds_entity.Render(context, pass);
1221 }
1222
1223 return true;
1224 };
1225 ASSERT_TRUE(OpenPlaygroundHere(callback));
1226}
SkTileMode TileMode(jint tm)
Definition: Utils.cpp:26

◆ TEST_P() [343/450]

impeller::testing::TEST_P ( EntityTest  ,
GeometryBoundsAreTransformed   
)

Definition at line 293 of file entity_unittests.cc.

293 {
294 auto geometry = Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100));
295 auto transform = Matrix::MakeScale({2.0, 2.0, 2.0});
296
297 ASSERT_RECT_NEAR(geometry->GetCoverage(transform).value(),
298 Rect::MakeXYWH(200, 200, 200, 200));
299}

◆ TEST_P() [344/450]

impeller::testing::TEST_P ( EntityTest  ,
InheritOpacityTest   
)

Definition at line 2125 of file entity_unittests.cc.

2125 {
2126 Entity entity;
2127
2128 // Texture contents can always accept opacity.
2129 auto texture_contents = std::make_shared<TextureContents>();
2130 texture_contents->SetOpacity(0.5);
2131 ASSERT_TRUE(texture_contents->CanInheritOpacity(entity));
2132
2133 texture_contents->SetInheritedOpacity(0.5);
2134 ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2135 texture_contents->SetInheritedOpacity(0.5);
2136 ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2137
2138 // Solid color contents can accept opacity if their geometry
2139 // doesn't overlap.
2140 auto solid_color = std::make_shared<SolidColorContents>();
2141 solid_color->SetGeometry(
2142 Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
2143 solid_color->SetColor(Color::Blue().WithAlpha(0.5));
2144
2145 ASSERT_TRUE(solid_color->CanInheritOpacity(entity));
2146
2147 solid_color->SetInheritedOpacity(0.5);
2148 ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2149 solid_color->SetInheritedOpacity(0.5);
2150 ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2151
2152 // Color source contents can accept opacity if their geometry
2153 // doesn't overlap.
2154 auto tiled_texture = std::make_shared<TiledTextureContents>();
2155 tiled_texture->SetGeometry(
2156 Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
2157 tiled_texture->SetOpacityFactor(0.5);
2158
2159 ASSERT_TRUE(tiled_texture->CanInheritOpacity(entity));
2160
2161 tiled_texture->SetInheritedOpacity(0.5);
2162 ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2163 tiled_texture->SetInheritedOpacity(0.5);
2164 ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2165
2166 // Clips and restores trivially accept opacity.
2167 ASSERT_TRUE(ClipContents().CanInheritOpacity(entity));
2168 ASSERT_TRUE(ClipRestoreContents().CanInheritOpacity(entity));
2169
2170 // Runtime effect contents can't accept opacity.
2171 auto runtime_effect = std::make_shared<RuntimeEffectContents>();
2172 ASSERT_FALSE(runtime_effect->CanInheritOpacity(entity));
2173}

◆ TEST_P() [345/450]

impeller::testing::TEST_P ( EntityTest  ,
LinearGradientContentsIsOpaque   
)

Definition at line 2291 of file entity_unittests.cc.

2291 {
2292 LinearGradientContents contents;
2293 contents.SetColors({Color::CornflowerBlue()});
2294 ASSERT_TRUE(contents.IsOpaque());
2295 contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2296 ASSERT_FALSE(contents.IsOpaque());
2297 contents.SetColors({Color::CornflowerBlue()});
2298 contents.SetTileMode(Entity::TileMode::kDecal);
2299 ASSERT_FALSE(contents.IsOpaque());
2300}
bool IsOpaque() const override
Whether this Contents only emits opaque source colors from the fragment stage. This value does not ac...
void SetTileMode(Entity::TileMode tile_mode)
void SetColors(std::vector< Color > colors)

◆ TEST_P() [346/450]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilter   
)

Definition at line 1755 of file entity_unittests.cc.

1755 {
1756 auto image = CreateTextureForFixture("kalimba.jpg");
1757 ASSERT_TRUE(image);
1758
1759 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1760 auto filtered =
1761 ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(image));
1762
1763 // Define the entity that will serve as the control image as a Gaussian blur
1764 // filter with no filter at all.
1765 Entity entity_left;
1766 entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1767 Matrix::MakeTranslation({100, 300}) *
1768 Matrix::MakeScale(Vector2{0.5, 0.5}));
1769 auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1770 Sigma{0}, Sigma{0});
1771 entity_left.SetContents(unfiltered);
1772
1773 // Define the entity that will be filtered from linear to sRGB.
1774 Entity entity_right;
1775 entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1776 Matrix::MakeTranslation({500, 300}) *
1777 Matrix::MakeScale(Vector2{0.5, 0.5}));
1778 entity_right.SetContents(filtered);
1779 return entity_left.Render(context, pass) &&
1780 entity_right.Render(context, pass);
1781 };
1782
1783 ASSERT_TRUE(OpenPlaygroundHere(callback));
1784}

◆ TEST_P() [347/450]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilterCoverageIsCorrect   
)

Definition at line 1734 of file entity_unittests.cc.

1734 {
1735 // Set up a simple color background.
1736 auto fill = std::make_shared<SolidColorContents>();
1737 fill->SetGeometry(Geometry::MakeFillPath(
1738 PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1739 fill->SetColor(Color::MintCream());
1740
1741 auto filter =
1742 ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(fill));
1743
1744 Entity e;
1745 e.SetTransform(Matrix());
1746
1747 // Confirm that the actual filter coverage matches the expected coverage.
1748 auto actual = filter->GetCoverage(e);
1749 auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1750
1751 ASSERT_TRUE(actual.has_value());
1752 ASSERT_RECT_NEAR(actual.value(), expected);
1753}

◆ TEST_P() [348/450]

impeller::testing::TEST_P ( EntityTest  ,
MorphologyFilter   
)

Definition at line 1228 of file entity_unittests.cc.

1228 {
1229 auto boston = CreateTextureForFixture("boston.jpg");
1230 ASSERT_TRUE(boston);
1231
1232 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1233 const char* morphology_type_names[] = {"Dilate", "Erode"};
1234 const FilterContents::MorphType morphology_types[] = {
1235 FilterContents::MorphType::kDilate, FilterContents::MorphType::kErode};
1236 static Color input_color = Color::Black();
1237 // UI state.
1238 static int selected_morphology_type = 0;
1239 static float radius[2] = {20, 20};
1240 static Color cover_color(1, 0, 0, 0.2);
1241 static Color bounds_color(0, 1, 0, 0.1);
1242 static float offset[2] = {500, 400};
1243 static float rotation = 0;
1244 static float scale[2] = {0.65, 0.65};
1245 static float skew[2] = {0, 0};
1246 static float path_rect[4] = {0, 0,
1247 static_cast<float>(boston->GetSize().width),
1248 static_cast<float>(boston->GetSize().height)};
1249 static float effect_transform_scale = 1;
1250
1251 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1252 {
1253 ImGui::Combo("Morphology type", &selected_morphology_type,
1254 morphology_type_names,
1255 sizeof(morphology_type_names) / sizeof(char*));
1256 ImGui::SliderFloat2("Radius", radius, 0, 200);
1257 ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1258 ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1259 ImGui::ColorEdit4("Bounds color",
1260 reinterpret_cast<float*>(&bounds_color));
1261 ImGui::SliderFloat2("Translation", offset, 0,
1262 pass.GetRenderTargetSize().width);
1263 ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1264 ImGui::SliderFloat2("Scale", scale, 0, 3);
1265 ImGui::SliderFloat2("Skew", skew, -3, 3);
1266 ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1267 ImGui::SliderFloat("Effect transform scale", &effect_transform_scale, 0,
1268 3);
1269 }
1270 ImGui::End();
1271
1272 std::shared_ptr<Contents> input;
1273 Size input_size;
1274
1275 auto input_rect =
1276 Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1277 auto texture = std::make_shared<TextureContents>();
1278 texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1279 texture->SetDestinationRect(input_rect);
1280 texture->SetTexture(boston);
1281 texture->SetOpacity(input_color.alpha);
1282
1283 input = texture;
1284 input_size = input_rect.GetSize();
1285
1286 auto contents = FilterContents::MakeMorphology(
1287 FilterInput::Make(input), Radius{radius[0]}, Radius{radius[1]},
1288 morphology_types[selected_morphology_type]);
1289 contents->SetEffectTransform(Matrix::MakeScale(
1290 Vector2{effect_transform_scale, effect_transform_scale}));
1291
1292 auto ctm = Matrix::MakeScale(GetContentScale()) *
1293 Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1294 Matrix::MakeRotationZ(Radians(rotation)) *
1295 Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1296 Matrix::MakeSkew(skew[0], skew[1]) *
1297 Matrix::MakeTranslation(-Point(input_size) / 2);
1298
1299 Entity entity;
1300 entity.SetContents(contents);
1301 entity.SetTransform(ctm);
1302
1303 entity.Render(context, pass);
1304
1305 // Renders a red "cover" rectangle that shows the original position of the
1306 // unfiltered input.
1307 Entity cover_entity;
1308 cover_entity.SetContents(SolidColorContents::Make(
1309 PathBuilder{}.AddRect(input_rect).TakePath(), cover_color));
1310 cover_entity.SetTransform(ctm);
1311
1312 cover_entity.Render(context, pass);
1313
1314 // Renders a green bounding rect of the target filter.
1315 Entity bounds_entity;
1316 bounds_entity.SetContents(SolidColorContents::Make(
1317 PathBuilder{}.AddRect(contents->GetCoverage(entity).value()).TakePath(),
1318 bounds_color));
1319 bounds_entity.SetTransform(Matrix());
1320
1321 bounds_entity.Render(context, pass);
1322
1323 return true;
1324 };
1325 ASSERT_TRUE(OpenPlaygroundHere(callback));
1326}

◆ TEST_P() [349/450]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldGeometryCoverage   
)

Definition at line 2334 of file entity_unittests.cc.

2334 {
2335 std::vector<Point> points = {{10, 20}, {100, 200}};
2336 auto geometry = Geometry::MakePointField(points, 5.0, false);
2337 ASSERT_EQ(*geometry->GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
2338 ASSERT_EQ(*geometry->GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
2339 Rect::MakeLTRB(35, 15, 135, 205));
2340}

◆ TEST_P() [350/450]

impeller::testing::TEST_P ( EntityTest  ,
RadialGradientContentsIsOpaque   
)

Definition at line 2302 of file entity_unittests.cc.

2302 {
2303 RadialGradientContents contents;
2304 contents.SetColors({Color::CornflowerBlue()});
2305 ASSERT_TRUE(contents.IsOpaque());
2306 contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2307 ASSERT_FALSE(contents.IsOpaque());
2308 contents.SetColors({Color::CornflowerBlue()});
2309 contents.SetTileMode(Entity::TileMode::kDecal);
2310 ASSERT_FALSE(contents.IsOpaque());
2311}
void SetTileMode(Entity::TileMode tile_mode)
bool IsOpaque() const override
Whether this Contents only emits opaque source colors from the fragment stage. This value does not ac...
void SetColors(std::vector< Color > colors)

◆ TEST_P() [351/450]

impeller::testing::TEST_P ( EntityTest  ,
RRectShadowTest   
)

Definition at line 1594 of file entity_unittests.cc.

1594 {
1595 auto callback = [&](ContentContext& context, RenderPass& pass) {
1596 static Color color = Color::Red();
1597 static float corner_radius = 100;
1598 static float blur_radius = 100;
1599 static bool show_coverage = false;
1600 static Color coverage_color = Color::Green().WithAlpha(0.2);
1601
1602 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1603 ImGui::SliderFloat("Corner radius", &corner_radius, 0, 300);
1604 ImGui::SliderFloat("Blur radius", &blur_radius, 0, 300);
1605 ImGui::ColorEdit4("Color", reinterpret_cast<Scalar*>(&color));
1606 ImGui::Checkbox("Show coverage", &show_coverage);
1607 if (show_coverage) {
1608 ImGui::ColorEdit4("Coverage color",
1609 reinterpret_cast<Scalar*>(&coverage_color));
1610 }
1611 ImGui::End();
1612
1613 static PlaygroundPoint top_left_point(Point(200, 200), 30, Color::White());
1614 static PlaygroundPoint bottom_right_point(Point(600, 400), 30,
1615 Color::White());
1616 auto [top_left, bottom_right] =
1617 DrawPlaygroundLine(top_left_point, bottom_right_point);
1618 auto rect =
1619 Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);
1620
1621 auto contents = std::make_unique<SolidRRectBlurContents>();
1622 contents->SetRRect(rect, {corner_radius, corner_radius});
1623 contents->SetColor(color);
1624 contents->SetSigma(Radius(blur_radius));
1625
1626 Entity entity;
1627 entity.SetTransform(Matrix::MakeScale(GetContentScale()));
1628 entity.SetContents(std::move(contents));
1629 entity.Render(context, pass);
1630
1631 auto coverage = entity.GetCoverage();
1632 if (show_coverage && coverage.has_value()) {
1633 auto bounds_contents = std::make_unique<SolidColorContents>();
1634 bounds_contents->SetGeometry(Geometry::MakeFillPath(
1635 PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
1636 bounds_contents->SetColor(coverage_color.Premultiply());
1637 Entity bounds_entity;
1638 bounds_entity.SetContents(std::move(bounds_contents));
1639 bounds_entity.Render(context, pass);
1640 }
1641
1642 return true;
1643 };
1644 ASSERT_TRUE(OpenPlaygroundHere(callback));
1645}
constexpr Color Premultiply() const
Definition: color.h:214

◆ TEST_P() [352/450]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffect   
)

Definition at line 1949 of file entity_unittests.cc.

1949 {
1950 auto runtime_stages =
1951 OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1952 auto runtime_stage =
1953 runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1954 ASSERT_TRUE(runtime_stage);
1955 ASSERT_TRUE(runtime_stage->IsDirty());
1956
1957 bool expect_dirty = true;
1958 Pipeline<PipelineDescriptor>* first_pipeline;
1959 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1960 EXPECT_EQ(runtime_stage->IsDirty(), expect_dirty);
1961
1962 auto contents = std::make_shared<RuntimeEffectContents>();
1963 contents->SetGeometry(Geometry::MakeCover());
1964 contents->SetRuntimeStage(runtime_stage);
1965
1966 struct FragUniforms {
1967 Vector2 iResolution;
1968 Scalar iTime;
1969 } frag_uniforms = {
1970 .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1971 .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1972 };
1973 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1974 uniform_data->resize(sizeof(FragUniforms));
1975 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1976 contents->SetUniformData(uniform_data);
1977
1978 Entity entity;
1979 entity.SetContents(contents);
1980 bool result = contents->Render(context, entity, pass);
1981
1982 if (expect_dirty) {
1983 EXPECT_NE(first_pipeline, pass.GetCommands().back().pipeline.get());
1984 first_pipeline = pass.GetCommands().back().pipeline.get();
1985 } else {
1986 EXPECT_EQ(pass.GetCommands().back().pipeline.get(), first_pipeline);
1987 }
1988
1989 expect_dirty = false;
1990 return result;
1991 };
1992
1993 // Simulate some renders and hot reloading of the shader.
1994 auto content_context = GetContentContext();
1995 {
1997 content_context->GetRenderTargetCache()->CreateOffscreen(
1998 *content_context->GetContext(), {1, 1}, 1u);
1999
2000 testing::MockRenderPass mock_pass(GetContext(), target);
2001 callback(*content_context, mock_pass);
2002 callback(*content_context, mock_pass);
2003
2004 // Dirty the runtime stage.
2005 runtime_stages = OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2006 runtime_stage =
2007 runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2008
2009 ASSERT_TRUE(runtime_stage->IsDirty());
2010 expect_dirty = true;
2011
2012 callback(*content_context, mock_pass);
2013 }
2014}

◆ TEST_P() [353/450]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectCanPrecache   
)

Definition at line 2063 of file entity_unittests.cc.

2063 {
2064 auto runtime_stages =
2065 OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2066 auto runtime_stage =
2067 runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2068 ASSERT_TRUE(runtime_stage);
2069 ASSERT_TRUE(runtime_stage->IsDirty());
2070
2071 auto contents = std::make_shared<RuntimeEffectContents>();
2072 contents->SetRuntimeStage(runtime_stage);
2073
2074 EXPECT_TRUE(contents->BootstrapShader(*GetContentContext()));
2075}

◆ TEST_P() [354/450]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectCanSuccessfullyRender   
)

Definition at line 2016 of file entity_unittests.cc.

2016 {
2017 auto runtime_stages =
2018 OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2019 auto runtime_stage =
2020 runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2021 ASSERT_TRUE(runtime_stage);
2022 ASSERT_TRUE(runtime_stage->IsDirty());
2023
2024 auto contents = std::make_shared<RuntimeEffectContents>();
2025 contents->SetGeometry(Geometry::MakeCover());
2026
2027 contents->SetRuntimeStage(runtime_stage);
2028
2029 struct FragUniforms {
2030 Vector2 iResolution;
2031 Scalar iTime;
2032 } frag_uniforms = {
2033 .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
2034 .iTime = static_cast<Scalar>(GetSecondsElapsed()),
2035 };
2036 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2037 uniform_data->resize(sizeof(FragUniforms));
2038 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2039 contents->SetUniformData(uniform_data);
2040
2041 Entity entity;
2042 entity.SetContents(contents);
2043
2044 // Create a render target with a depth-stencil, similar to how EntityPass
2045 // does.
2047 GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
2048 *GetContext(), {GetWindowSize().width, GetWindowSize().height}, 1,
2049 "RuntimeEffect Texture");
2050 testing::MockRenderPass pass(GetContext(), target);
2051
2052 ASSERT_TRUE(contents->Render(*GetContentContext(), entity, pass));
2053 ASSERT_EQ(pass.GetCommands().size(), 1u);
2054 const auto& command = pass.GetCommands()[0];
2055 ASSERT_TRUE(command.pipeline->GetDescriptor()
2056 .GetDepthStencilAttachmentDescriptor()
2057 .has_value());
2058 ASSERT_TRUE(command.pipeline->GetDescriptor()
2059 .GetFrontStencilAttachmentDescriptor()
2060 .has_value());
2061}
list command
Definition: valgrind.py:24

◆ TEST_P() [355/450]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectSetsRightSizeWhenUniformIsStruct   
)

Definition at line 2077 of file entity_unittests.cc.

2077 {
2078 if (GetBackend() != PlaygroundBackend::kVulkan) {
2079 GTEST_SKIP() << "Test only applies to Vulkan";
2080 }
2081
2082 auto runtime_stages =
2083 OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2084 auto runtime_stage =
2085 runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2086 ASSERT_TRUE(runtime_stage);
2087 ASSERT_TRUE(runtime_stage->IsDirty());
2088
2089 auto contents = std::make_shared<RuntimeEffectContents>();
2090 contents->SetGeometry(Geometry::MakeCover());
2091 contents->SetRuntimeStage(runtime_stage);
2092
2093 struct FragUniforms {
2094 Vector2 iResolution;
2095 Scalar iTime;
2096 } frag_uniforms = {
2097 .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
2098 .iTime = static_cast<Scalar>(GetSecondsElapsed()),
2099 };
2100 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2101 uniform_data->resize(sizeof(FragUniforms));
2102 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2103 contents->SetUniformData(uniform_data);
2104
2105 Entity entity;
2106 entity.SetContents(contents);
2107
2108 auto context = GetContentContext();
2109 RenderTarget target = context->GetRenderTargetCache()->CreateOffscreen(
2110 *context->GetContext(), {1, 1}, 1u);
2111
2112 testing::MockRenderPass pass(GetContext(), target);
2113 ASSERT_TRUE(contents->Render(*context, entity, pass));
2114 ASSERT_EQ(pass.GetCommands().size(), 1u);
2115 const auto& command = pass.GetCommands()[0];
2116 ASSERT_EQ(command.fragment_bindings.buffers.size(), 1u);
2117 // 16 bytes:
2118 // 8 bytes for iResolution
2119 // 4 bytes for iTime
2120 // 4 bytes padding
2121 EXPECT_EQ(command.fragment_bindings.buffers[0].view.resource.range.length,
2122 16u);
2123}

◆ TEST_P() [356/450]

impeller::testing::TEST_P ( EntityTest  ,
SetBlendMode   
)

Definition at line 1328 of file entity_unittests.cc.

1328 {
1329 Entity entity;
1330 ASSERT_EQ(entity.GetBlendMode(), BlendMode::kSourceOver);
1331 entity.SetBlendMode(BlendMode::kClear);
1332 ASSERT_EQ(entity.GetBlendMode(), BlendMode::kClear);
1333}
BlendMode GetBlendMode() const
Definition: entity.cc:119

◆ TEST_P() [357/450]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsIsOpaque   
)

Definition at line 2275 of file entity_unittests.cc.

2275 {
2276 SolidColorContents contents;
2277 contents.SetColor(Color::CornflowerBlue());
2278 ASSERT_TRUE(contents.IsOpaque());
2279 contents.SetColor(Color::CornflowerBlue().WithAlpha(0.5));
2280 ASSERT_FALSE(contents.IsOpaque());
2281}
bool IsOpaque() const override
Whether this Contents only emits opaque source colors from the fragment stage. This value does not ac...

◆ TEST_P() [358/450]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetMiterLimit   
)

Definition at line 842 of file entity_unittests.cc.

842 {
843 {
844 auto geometry = Geometry::MakeStrokePath(Path{});
845 auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
846 ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
847 }
848
849 {
850 auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, /*miter_limit=*/8.0);
851 auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
852 ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 8);
853 }
854
855 {
856 auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, /*miter_limit=*/-1.0);
857 auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
858 ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
859 }
860}
A geometry that is created from a stroked path object.

◆ TEST_P() [359/450]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetStrokeCapsAndJoins   
)

Definition at line 820 of file entity_unittests.cc.

820 {
821 {
822 auto geometry = Geometry::MakeStrokePath(Path{});
823 auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
824 // Defaults.
825 ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kButt);
826 ASSERT_EQ(path_geometry->GetStrokeJoin(), Join::kMiter);
827 }
828
829 {
830 auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kSquare);
831 auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
832 ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kSquare);
833 }
834
835 {
836 auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kRound);
837 auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
838 ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kRound);
839 }
840}

◆ TEST_P() [360/450]

impeller::testing::TEST_P ( EntityTest  ,
SolidFillCoverageIsCorrect   
)

Definition at line 1421 of file entity_unittests.cc.

1421 {
1422 // No transform
1423 {
1424 auto fill = std::make_shared<SolidColorContents>();
1425 fill->SetColor(Color::CornflowerBlue());
1426 auto expected = Rect::MakeLTRB(100, 110, 200, 220);
1427 fill->SetGeometry(
1428 Geometry::MakeFillPath(PathBuilder{}.AddRect(expected).TakePath()));
1429
1430 auto coverage = fill->GetCoverage({});
1431 ASSERT_TRUE(coverage.has_value());
1432 ASSERT_RECT_NEAR(coverage.value(), expected);
1433 }
1434
1435 // Entity transform
1436 {
1437 auto fill = std::make_shared<SolidColorContents>();
1438 fill->SetColor(Color::CornflowerBlue());
1439 fill->SetGeometry(Geometry::MakeFillPath(
1440 PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()));
1441
1442 Entity entity;
1443 entity.SetTransform(Matrix::MakeTranslation(Vector2(4, 5)));
1444 entity.SetContents(std::move(fill));
1445
1446 auto coverage = entity.GetCoverage();
1447 auto expected = Rect::MakeLTRB(104, 115, 204, 225);
1448 ASSERT_TRUE(coverage.has_value());
1449 ASSERT_RECT_NEAR(coverage.value(), expected);
1450 }
1451
1452 // No coverage for fully transparent colors
1453 {
1454 auto fill = std::make_shared<SolidColorContents>();
1455 fill->SetColor(Color::WhiteTransparent());
1456 fill->SetGeometry(Geometry::MakeFillPath(
1457 PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()));
1458
1459 auto coverage = fill->GetCoverage({});
1460 ASSERT_FALSE(coverage.has_value());
1461 }
1462}

◆ TEST_P() [361/450]

impeller::testing::TEST_P ( EntityTest  ,
SolidFillShouldRenderIsCorrect   
)

Definition at line 1464 of file entity_unittests.cc.

1464 {
1465 // No path.
1466 {
1467 auto fill = std::make_shared<SolidColorContents>();
1468 fill->SetColor(Color::CornflowerBlue());
1469 ASSERT_FALSE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1470 ASSERT_FALSE(
1471 fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1472 }
1473
1474 // With path.
1475 {
1476 auto fill = std::make_shared<SolidColorContents>();
1477 fill->SetColor(Color::CornflowerBlue());
1478 fill->SetGeometry(Geometry::MakeFillPath(
1479 PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1480 ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1481 ASSERT_FALSE(
1482 fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1483 }
1484
1485 // With paint cover.
1486 {
1487 auto fill = std::make_shared<SolidColorContents>();
1488 fill->SetColor(Color::CornflowerBlue());
1489 fill->SetGeometry(Geometry::MakeCover());
1490 ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1491 ASSERT_TRUE(
1492 fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1493 }
1494}

◆ TEST_P() [362/450]

impeller::testing::TEST_P ( EntityTest  ,
SolidStrokeCoverageIsCorrect   
)

Definition at line 1341 of file entity_unittests.cc.

1341 {
1342 {
1343 auto geometry = Geometry::MakeStrokePath(
1344 PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1345 Cap::kButt, Join::kBevel);
1346
1347 Entity entity;
1348 auto contents = std::make_unique<SolidColorContents>();
1349 contents->SetGeometry(std::move(geometry));
1350 contents->SetColor(Color::Black());
1351 entity.SetContents(std::move(contents));
1352 auto actual = entity.GetCoverage();
1353 auto expected = Rect::MakeLTRB(-2, -2, 12, 12);
1354 ASSERT_TRUE(actual.has_value());
1355 ASSERT_RECT_NEAR(actual.value(), expected);
1356 }
1357
1358 // Cover the Cap::kSquare case.
1359 {
1360 auto geometry = Geometry::MakeStrokePath(
1361 PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1362 Cap::kSquare, Join::kBevel);
1363
1364 Entity entity;
1365 auto contents = std::make_unique<SolidColorContents>();
1366 contents->SetGeometry(std::move(geometry));
1367 contents->SetColor(Color::Black());
1368 entity.SetContents(std::move(contents));
1369 auto actual = entity.GetCoverage();
1370 auto expected =
1371 Rect::MakeLTRB(-sqrt(8), -sqrt(8), 10 + sqrt(8), 10 + sqrt(8));
1372 ASSERT_TRUE(actual.has_value());
1373 ASSERT_RECT_NEAR(actual.value(), expected);
1374 }
1375
1376 // Cover the Join::kMiter case.
1377 {
1378 auto geometry = Geometry::MakeStrokePath(
1379 PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 2.0,
1380 Cap::kSquare, Join::kMiter);
1381
1382 Entity entity;
1383 auto contents = std::make_unique<SolidColorContents>();
1384 contents->SetGeometry(std::move(geometry));
1385 contents->SetColor(Color::Black());
1386 entity.SetContents(std::move(contents));
1387 auto actual = entity.GetCoverage();
1388 auto expected = Rect::MakeLTRB(-4, -4, 14, 14);
1389 ASSERT_TRUE(actual.has_value());
1390 ASSERT_RECT_NEAR(actual.value(), expected);
1391 }
1392}

◆ TEST_P() [363/450]

impeller::testing::TEST_P ( EntityTest  ,
SpecializationConstantsAreAppliedToVariants   
)

Definition at line 2420 of file entity_unittests.cc.

2420 {
2421 auto content_context = GetContentContext();
2422
2423 auto default_gyph = content_context->GetGlyphAtlasPipeline({
2424 .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2425 .has_depth_stencil_attachments = false,
2426 });
2427 auto alt_gyph = content_context->GetGlyphAtlasPipeline(
2428 {.color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2429 .has_depth_stencil_attachments = true});
2430
2431 EXPECT_NE(default_gyph, alt_gyph);
2432 EXPECT_EQ(default_gyph->GetDescriptor().GetSpecializationConstants(),
2433 alt_gyph->GetDescriptor().GetSpecializationConstants());
2434
2435 auto use_a8 = GetContext()->GetCapabilities()->GetDefaultGlyphAtlasFormat() ==
2436 PixelFormat::kA8UNormInt;
2437
2438 std::vector<Scalar> expected_constants = {static_cast<Scalar>(use_a8)};
2439 EXPECT_EQ(default_gyph->GetDescriptor().GetSpecializationConstants(),
2440 expected_constants);
2441}

◆ TEST_P() [364/450]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilter   
)

Definition at line 1807 of file entity_unittests.cc.

1807 {
1808 auto image = CreateTextureForFixture("embarcadero.jpg");
1809 ASSERT_TRUE(image);
1810
1811 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1812 auto filtered =
1813 ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(image));
1814
1815 // Define the entity that will serve as the control image as a Gaussian blur
1816 // filter with no filter at all.
1817 Entity entity_left;
1818 entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1819 Matrix::MakeTranslation({100, 300}) *
1820 Matrix::MakeScale(Vector2{0.5, 0.5}));
1821 auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1822 Sigma{0}, Sigma{0});
1823 entity_left.SetContents(unfiltered);
1824
1825 // Define the entity that will be filtered from sRGB to linear.
1826 Entity entity_right;
1827 entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1828 Matrix::MakeTranslation({500, 300}) *
1829 Matrix::MakeScale(Vector2{0.5, 0.5}));
1830 entity_right.SetContents(filtered);
1831 return entity_left.Render(context, pass) &&
1832 entity_right.Render(context, pass);
1833 };
1834
1835 ASSERT_TRUE(OpenPlaygroundHere(callback));
1836}

◆ TEST_P() [365/450]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilterCoverageIsCorrect   
)

Definition at line 1786 of file entity_unittests.cc.

1786 {
1787 // Set up a simple color background.
1788 auto fill = std::make_shared<SolidColorContents>();
1789 fill->SetGeometry(Geometry::MakeFillPath(
1790 PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1791 fill->SetColor(Color::DeepPink());
1792
1793 auto filter =
1794 ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(fill));
1795
1796 Entity e;
1797 e.SetTransform(Matrix());
1798
1799 // Confirm that the actual filter coverage matches the expected coverage.
1800 auto actual = filter->GetCoverage(e);
1801 auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1802
1803 ASSERT_TRUE(actual.has_value());
1804 ASSERT_RECT_NEAR(actual.value(), expected);
1805}

◆ TEST_P() [366/450]

impeller::testing::TEST_P ( EntityTest  ,
StrokeCapAndJoinTest   
)

Definition at line 384 of file entity_unittests.cc.

384 {
385 const Point padding(300, 250);
386 const Point margin(140, 180);
387
388 auto callback = [&](ContentContext& context, RenderPass& pass) {
389 // Slightly above sqrt(2) by default, so that right angles are just below
390 // the limit and acute angles are over the limit (causing them to get
391 // beveled).
392 static Scalar miter_limit = 1.41421357;
393 static Scalar width = 30;
394
395 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
396 {
397 ImGui::SliderFloat("Miter limit", &miter_limit, 0, 30);
398 ImGui::SliderFloat("Stroke width", &width, 0, 100);
399 if (ImGui::Button("Reset")) {
400 miter_limit = 1.41421357;
401 width = 30;
402 }
403 }
404 ImGui::End();
405
406 auto world_matrix = Matrix::MakeScale(GetContentScale());
407 auto render_path = [width = width, &context, &pass, &world_matrix](
408 const Path& path, Cap cap, Join join) {
409 auto contents = std::make_unique<SolidColorContents>();
410 contents->SetGeometry(
411 Geometry::MakeStrokePath(path, width, miter_limit, cap, join));
412 contents->SetColor(Color::Red());
413
414 Entity entity;
415 entity.SetTransform(world_matrix);
416 entity.SetContents(std::move(contents));
417
418 auto coverage = entity.GetCoverage();
419 if (coverage.has_value()) {
420 auto bounds_contents = std::make_unique<SolidColorContents>();
421 bounds_contents->SetGeometry(Geometry::MakeFillPath(
422 PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
423 bounds_contents->SetColor(Color::Green().WithAlpha(0.5));
424 Entity bounds_entity;
425 bounds_entity.SetContents(std::move(bounds_contents));
426 bounds_entity.Render(context, pass);
427 }
428
429 entity.Render(context, pass);
430 };
431
432 const Point a_def(0, 0), b_def(0, 100), c_def(150, 0), d_def(150, -100),
433 e_def(75, 75);
434 const Scalar r = 30;
435 // Cap::kButt demo.
436 {
437 Point off = Point(0, 0) * padding + margin;
438 static PlaygroundPoint point_a(off + a_def, r, Color::Black());
439 static PlaygroundPoint point_b(off + b_def, r, Color::White());
440 auto [a, b] = DrawPlaygroundLine(point_a, point_b);
441 static PlaygroundPoint point_c(off + c_def, r, Color::Black());
442 static PlaygroundPoint point_d(off + d_def, r, Color::White());
443 auto [c, d] = DrawPlaygroundLine(point_c, point_d);
444 render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
445 Cap::kButt, Join::kBevel);
446 }
447
448 // Cap::kSquare demo.
449 {
450 Point off = Point(1, 0) * padding + margin;
451 static PlaygroundPoint point_a(off + a_def, r, Color::Black());
452 static PlaygroundPoint point_b(off + b_def, r, Color::White());
453 auto [a, b] = DrawPlaygroundLine(point_a, point_b);
454 static PlaygroundPoint point_c(off + c_def, r, Color::Black());
455 static PlaygroundPoint point_d(off + d_def, r, Color::White());
456 auto [c, d] = DrawPlaygroundLine(point_c, point_d);
457 render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
458 Cap::kSquare, Join::kBevel);
459 }
460
461 // Cap::kRound demo.
462 {
463 Point off = Point(2, 0) * padding + margin;
464 static PlaygroundPoint point_a(off + a_def, r, Color::Black());
465 static PlaygroundPoint point_b(off + b_def, r, Color::White());
466 auto [a, b] = DrawPlaygroundLine(point_a, point_b);
467 static PlaygroundPoint point_c(off + c_def, r, Color::Black());
468 static PlaygroundPoint point_d(off + d_def, r, Color::White());
469 auto [c, d] = DrawPlaygroundLine(point_c, point_d);
470 render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
471 Cap::kRound, Join::kBevel);
472 }
473
474 // Join::kBevel demo.
475 {
476 Point off = Point(0, 1) * padding + margin;
477 static PlaygroundPoint point_a =
478 PlaygroundPoint(off + a_def, r, Color::White());
479 static PlaygroundPoint point_b =
480 PlaygroundPoint(off + e_def, r, Color::White());
481 static PlaygroundPoint point_c =
482 PlaygroundPoint(off + c_def, r, Color::White());
483 Point a = DrawPlaygroundPoint(point_a);
484 Point b = DrawPlaygroundPoint(point_b);
485 Point c = DrawPlaygroundPoint(point_c);
486 render_path(
487 PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
488 Cap::kButt, Join::kBevel);
489 }
490
491 // Join::kMiter demo.
492 {
493 Point off = Point(1, 1) * padding + margin;
494 static PlaygroundPoint point_a(off + a_def, r, Color::White());
495 static PlaygroundPoint point_b(off + e_def, r, Color::White());
496 static PlaygroundPoint point_c(off + c_def, r, Color::White());
497 Point a = DrawPlaygroundPoint(point_a);
498 Point b = DrawPlaygroundPoint(point_b);
499 Point c = DrawPlaygroundPoint(point_c);
500 render_path(
501 PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
502 Cap::kButt, Join::kMiter);
503 }
504
505 // Join::kRound demo.
506 {
507 Point off = Point(2, 1) * padding + margin;
508 static PlaygroundPoint point_a(off + a_def, r, Color::White());
509 static PlaygroundPoint point_b(off + e_def, r, Color::White());
510 static PlaygroundPoint point_c(off + c_def, r, Color::White());
511 Point a = DrawPlaygroundPoint(point_a);
512 Point b = DrawPlaygroundPoint(point_b);
513 Point c = DrawPlaygroundPoint(point_c);
514 render_path(
515 PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
516 Cap::kButt, Join::kRound);
517 }
518
519 return true;
520 };
521 ASSERT_TRUE(OpenPlaygroundHere(callback));
522}
Join
Definition: path.h:24
Cap
Definition: path.h:18

◆ TEST_P() [367/450]

impeller::testing::TEST_P ( EntityTest  ,
StrokeWithTextureContents   
)

Definition at line 320 of file entity_unittests.cc.

320 {
321 auto bridge = CreateTextureForFixture("bay_bridge.jpg");
323 .MoveTo({100, 100})
324 .LineTo({100, 200})
325 .MoveTo({100, 300})
326 .LineTo({100, 400})
327 .MoveTo({100, 500})
328 .LineTo({100, 600})
329 .TakePath();
330
331 Entity entity;
332 entity.SetTransform(Matrix::MakeScale(GetContentScale()));
333 auto contents = std::make_unique<TiledTextureContents>();
334 contents->SetGeometry(Geometry::MakeStrokePath(path, 100.0));
335 contents->SetTexture(bridge);
336 contents->SetTileModes(Entity::TileMode::kClamp, Entity::TileMode::kClamp);
337 entity.SetContents(std::move(contents));
338 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
339}

◆ TEST_P() [368/450]

impeller::testing::TEST_P ( EntityTest  ,
SweepGradientContentsIsOpaque   
)

Definition at line 2313 of file entity_unittests.cc.

2313 {
2314 RadialGradientContents contents;
2315 contents.SetColors({Color::CornflowerBlue()});
2316 ASSERT_TRUE(contents.IsOpaque());
2317 contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2318 ASSERT_FALSE(contents.IsOpaque());
2319 contents.SetColors({Color::CornflowerBlue()});
2320 contents.SetTileMode(Entity::TileMode::kDecal);
2321 ASSERT_FALSE(contents.IsOpaque());
2322}

◆ TEST_P() [369/450]

impeller::testing::TEST_P ( EntityTest  ,
TextContentsCeilsGlyphScaleToDecimal   
)

Definition at line 2362 of file entity_unittests.cc.

2362 {
2363 ASSERT_EQ(TextFrame::RoundScaledFontSize(0.4321111f, 12), 0.43f);
2364 ASSERT_EQ(TextFrame::RoundScaledFontSize(0.5321111f, 12), 0.53f);
2365 ASSERT_EQ(TextFrame::RoundScaledFontSize(2.1f, 12), 2.1f);
2366 ASSERT_EQ(TextFrame::RoundScaledFontSize(0.0f, 12), 0.0f);
2367 ASSERT_EQ(TextFrame::RoundScaledFontSize(100000000.0f, 12), 48.0f);
2368}

◆ TEST_P() [370/450]

impeller::testing::TEST_P ( EntityTest  ,
ThreeStrokesInOnePath   
)

Definition at line 301 of file entity_unittests.cc.

301 {
303 .MoveTo({100, 100})
304 .LineTo({100, 200})
305 .MoveTo({100, 300})
306 .LineTo({100, 400})
307 .MoveTo({100, 500})
308 .LineTo({100, 600})
309 .TakePath();
310
311 Entity entity;
312 entity.SetTransform(Matrix::MakeScale(GetContentScale()));
313 auto contents = std::make_unique<SolidColorContents>();
314 contents->SetGeometry(Geometry::MakeStrokePath(path, 5.0));
315 contents->SetColor(Color::Red());
316 entity.SetContents(std::move(contents));
317 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
318}

◆ TEST_P() [371/450]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsIsOpaque   
)

Definition at line 2324 of file entity_unittests.cc.

2324 {
2325 auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
2326 TiledTextureContents contents;
2327 contents.SetTexture(bay_bridge);
2328 // This is a placeholder test. Images currently never decompress as opaque
2329 // (whether in Flutter or the playground), and so this should currently always
2330 // return false in practice.
2331 ASSERT_FALSE(contents.IsOpaque());
2332}
bool IsOpaque() const override
Whether this Contents only emits opaque source colors from the fragment stage. This value does not ac...
void SetTexture(std::shared_ptr< Texture > texture)

◆ TEST_P() [372/450]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsRendersWithCorrectPipeline   
)

Definition at line 20 of file tiled_texture_contents_unittests.cc.

20 {
21 TextureDescriptor texture_desc;
22 texture_desc.size = {100, 100};
23 texture_desc.type = TextureType::kTexture2D;
24 texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
25 texture_desc.storage_mode = StorageMode::kDevicePrivate;
26 auto texture =
27 GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
28
29 TiledTextureContents contents;
30 contents.SetTexture(texture);
31 contents.SetGeometry(Geometry::MakeCover());
32
33 auto content_context = GetContentContext();
34 auto buffer = content_context->GetContext()->CreateCommandBuffer();
35 auto render_target =
36 GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
37 *content_context->GetContext(), {100, 100},
38 /*mip_count=*/1);
39 auto render_pass = buffer->CreateRenderPass(render_target);
40 auto recording_pass = std::make_shared<RecordingRenderPass>(
41 render_pass, GetContext(), render_target);
42
43 ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *recording_pass));
44 const std::vector<Command>& commands = recording_pass->GetCommands();
45
46 ASSERT_EQ(commands.size(), 1u);
47 EXPECT_TRUE(commands[0].pipeline->GetDescriptor().GetLabel().find(
48 "TextureFill Pipeline") != std::string::npos);
49
50 if (GetParam() == PlaygroundBackend::kMetal) {
51 recording_pass->EncodeCommands();
52 }
53}
void SetGeometry(std::shared_ptr< Geometry > geometry)
Set the geometry that this contents will use to render.
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
dictionary commands
Definition: dom.py:171

◆ TEST_P() [373/450]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsRendersWithCorrectPipelineExternalOES   
)

Definition at line 57 of file tiled_texture_contents_unittests.cc.

57 {
58 if (GetParam() != PlaygroundBackend::kOpenGLES) {
59 GTEST_SKIP_(
60 "External OES textures are only valid for the OpenGLES backend.");
61 }
62
63 TextureDescriptor texture_desc;
64 texture_desc.size = {100, 100};
65 texture_desc.type = TextureType::kTextureExternalOES;
66 texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
67 texture_desc.storage_mode = StorageMode::kDevicePrivate;
68 auto texture =
69 GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
70
71 TiledTextureContents contents;
72 contents.SetTexture(texture);
73 contents.SetGeometry(Geometry::MakeCover());
74
75 auto content_context = GetContentContext();
76 auto buffer = content_context->GetContext()->CreateCommandBuffer();
77 auto render_target =
78 GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
79 *content_context->GetContext(), {100, 100},
80 /*mip_count=*/1);
81 auto render_pass = buffer->CreateRenderPass(render_target);
82
83 ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *render_pass));
84 const std::vector<Command>& commands = render_pass->GetCommands();
85
86 ASSERT_EQ(commands.size(), 1u);
87 EXPECT_TRUE(commands[0].pipeline->GetDescriptor().GetLabel().find(
88 "TiledTextureFillExternal Pipeline") != std::string::npos);
89}

◆ TEST_P() [374/450]

impeller::testing::TEST_P ( EntityTest  ,
TriangleInsideASquare   
)

Definition at line 341 of file entity_unittests.cc.

341 {
342 auto callback = [&](ContentContext& context, RenderPass& pass) {
343 Point offset(100, 100);
344
345 static PlaygroundPoint point_a(Point(10, 10) + offset, 20, Color::White());
346 Point a = DrawPlaygroundPoint(point_a);
347 static PlaygroundPoint point_b(Point(210, 10) + offset, 20, Color::White());
348 Point b = DrawPlaygroundPoint(point_b);
349 static PlaygroundPoint point_c(Point(210, 210) + offset, 20,
350 Color::White());
351 Point c = DrawPlaygroundPoint(point_c);
352 static PlaygroundPoint point_d(Point(10, 210) + offset, 20, Color::White());
353 Point d = DrawPlaygroundPoint(point_d);
354 static PlaygroundPoint point_e(Point(50, 50) + offset, 20, Color::White());
355 Point e = DrawPlaygroundPoint(point_e);
356 static PlaygroundPoint point_f(Point(100, 50) + offset, 20, Color::White());
357 Point f = DrawPlaygroundPoint(point_f);
358 static PlaygroundPoint point_g(Point(50, 150) + offset, 20, Color::White());
359 Point g = DrawPlaygroundPoint(point_g);
361 .MoveTo(a)
362 .LineTo(b)
363 .LineTo(c)
364 .LineTo(d)
365 .Close()
366 .MoveTo(e)
367 .LineTo(f)
368 .LineTo(g)
369 .Close()
370 .TakePath();
371
372 Entity entity;
373 entity.SetTransform(Matrix::MakeScale(GetContentScale()));
374 auto contents = std::make_unique<SolidColorContents>();
375 contents->SetGeometry(Geometry::MakeStrokePath(path, 20.0));
376 contents->SetColor(Color::Red());
377 entity.SetContents(std::move(contents));
378
379 return entity.Render(context, pass);
380 };
381 ASSERT_TRUE(OpenPlaygroundHere(callback));
382}
PathBuilder & Close()
Definition: path_builder.cc:40

◆ TEST_P() [375/450]

impeller::testing::TEST_P ( EntityTest  ,
YUVToRGBFilter   
)

Definition at line 1916 of file entity_unittests.cc.

1916 {
1917 if (GetParam() == PlaygroundBackend::kOpenGLES) {
1918 // TODO(114588) : Support YUV to RGB filter on OpenGLES backend.
1919 GTEST_SKIP_("YUV to RGB filter is not supported on OpenGLES backend yet.");
1920 }
1921
1922 auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1923 YUVColorSpace yuv_color_space_array[2]{YUVColorSpace::kBT601FullRange,
1925 for (int i = 0; i < 2; i++) {
1926 auto yuv_color_space = yuv_color_space_array[i];
1927 auto textures =
1928 CreateTestYUVTextures(GetContext().get(), yuv_color_space);
1929 auto filter_contents = FilterContents::MakeYUVToRGBFilter(
1930 textures[0], textures[1], yuv_color_space);
1931 Entity filter_entity;
1932 filter_entity.SetContents(filter_contents);
1933 auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);
1934
1935 Entity entity;
1936 auto contents = TextureContents::MakeRect(Rect::MakeLTRB(0, 0, 256, 256));
1937 contents->SetTexture(snapshot->texture);
1938 contents->SetSourceRect(Rect::MakeSize(snapshot->texture->GetSize()));
1939 entity.SetContents(contents);
1940 entity.SetTransform(
1941 Matrix::MakeTranslation({static_cast<Scalar>(100 + 400 * i), 300}));
1942 entity.Render(context, pass);
1943 }
1944 return true;
1945 };
1946 ASSERT_TRUE(OpenPlaygroundHere(callback));
1947}
static std::vector< std::shared_ptr< Texture > > CreateTestYUVTextures(Context *context, YUVColorSpace yuv_color_space)
YUVColorSpace
Definition: color.h:55

◆ TEST_P() [376/450]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CalculateUVsSimple   
)

Definition at line 325 of file gaussian_blur_filter_contents_unittests.cc.

325 {
326 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
327 auto filter_input = FilterInput::Make(texture);
328 Entity entity;
329 Quad uvs = GaussianBlurFilterContents::CalculateUVs(
330 filter_input, entity, Rect::MakeSize(ISize(100, 100)), ISize(100, 100));
331 std::optional<Rect> uvs_bounds = Rect::MakePointBounds(uvs);
332 EXPECT_TRUE(uvs_bounds.has_value());
333 if (uvs_bounds.has_value()) {
334 EXPECT_TRUE(RectNear(uvs_bounds.value(), Rect::MakeXYWH(0, 0, 1, 1)));
335 }
336}

◆ TEST_P() [377/450]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CoverageWithEffectTransform   
)

Definition at line 177 of file gaussian_blur_filter_contents_unittests.cc.

177 {
178 Matrix effect_transform = Matrix::MakeScale({2.0, 2.0, 1.0});
179 fml::StatusOr<Scalar> sigma_radius_1 =
180 CalculateSigmaForBlurRadius(1.0, effect_transform);
181 ASSERT_TRUE(sigma_radius_1.ok());
183 /*sigma_x=*/sigma_radius_1.value(),
184 /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
185 FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
186 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
188 Entity entity;
189 entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
190 std::optional<Rect> coverage =
191 contents.GetFilterCoverage(inputs, entity, effect_transform);
192 EXPECT_TRUE(coverage.has_value());
193 if (coverage.has_value()) {
195 Rect::MakeLTRB(100 - 1, 100 - 1, 200 + 1, 200 + 1));
196 }
197}

◆ TEST_P() [378/450]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CoverageWithTexture   
)

Definition at line 156 of file gaussian_blur_filter_contents_unittests.cc.

156 {
157 fml::StatusOr<Scalar> sigma_radius_1 =
158 CalculateSigmaForBlurRadius(1.0, Matrix());
159 ASSERT_TRUE(sigma_radius_1.ok());
161 /*sigma_X=*/sigma_radius_1.value(),
162 /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
163 FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
164 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
166 Entity entity;
167 entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
168 std::optional<Rect> coverage =
169 contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
170
171 EXPECT_TRUE(coverage.has_value());
172 if (coverage.has_value()) {
173 EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
174 }
175}

◆ TEST_P() [379/450]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverage   
)

Definition at line 229 of file gaussian_blur_filter_contents_unittests.cc.

229 {
230 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
231 fml::StatusOr<Scalar> sigma_radius_1 =
232 CalculateSigmaForBlurRadius(1.0, Matrix());
233 ASSERT_TRUE(sigma_radius_1.ok());
234 auto contents = std::make_unique<GaussianBlurFilterContents>(
235 sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
236 FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
237 contents->SetInputs({FilterInput::Make(texture)});
238 std::shared_ptr<ContentContext> renderer = GetContentContext();
239
240 Entity entity;
241 std::optional<Entity> result =
242 contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
243 EXPECT_TRUE(result.has_value());
244 if (result.has_value()) {
245 EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
246 std::optional<Rect> result_coverage = result.value().GetCoverage();
247 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
248 EXPECT_TRUE(result_coverage.has_value());
249 EXPECT_TRUE(contents_coverage.has_value());
250 if (result_coverage.has_value() && contents_coverage.has_value()) {
251 EXPECT_TRUE(RectNear(contents_coverage.value(),
252 Rect::MakeLTRB(-1, -1, 101, 101)));
254 RectNear(result_coverage.value(), Rect::MakeLTRB(-1, -1, 101, 101)));
255 }
256 }
257}

◆ TEST_P() [380/450]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverageRotated   
)

Definition at line 292 of file gaussian_blur_filter_contents_unittests.cc.

293 {
294 std::shared_ptr<Texture> texture = MakeTexture(ISize(400, 300));
295 fml::StatusOr<Scalar> sigma_radius_1 =
296 CalculateSigmaForBlurRadius(1.0, Matrix());
297 auto contents = std::make_unique<GaussianBlurFilterContents>(
298 sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
299 FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
300 contents->SetInputs({FilterInput::Make(texture)});
301 std::shared_ptr<ContentContext> renderer = GetContentContext();
302
303 Entity entity;
304 // Rotate around the top left corner, then push it over to (100, 100).
305 entity.SetTransform(Matrix::MakeTranslation({400, 100, 0}) *
306 Matrix::MakeRotationZ(Degrees(90.0)));
307 std::optional<Entity> result =
308 contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
309 EXPECT_TRUE(result.has_value());
310 if (result.has_value()) {
311 EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
312 std::optional<Rect> result_coverage = result.value().GetCoverage();
313 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
314 EXPECT_TRUE(result_coverage.has_value());
315 EXPECT_TRUE(contents_coverage.has_value());
316 if (result_coverage.has_value() && contents_coverage.has_value()) {
317 EXPECT_TRUE(RectNear(contents_coverage.value(),
318 Rect::MakeLTRB(99, 99, 401, 501)));
320 RectNear(result_coverage.value(), Rect::MakeLTRB(99, 99, 401, 501)));
321 }
322 }
323}

◆ TEST_P() [381/450]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverageTranslate   
)

Definition at line 259 of file gaussian_blur_filter_contents_unittests.cc.

260 {
261 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
262 fml::StatusOr<Scalar> sigma_radius_1 =
263 CalculateSigmaForBlurRadius(1.0, Matrix());
264 ASSERT_TRUE(sigma_radius_1.ok());
265 auto contents = std::make_unique<GaussianBlurFilterContents>(
266 sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
267 FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
268 contents->SetInputs({FilterInput::Make(texture)});
269 std::shared_ptr<ContentContext> renderer = GetContentContext();
270
271 Entity entity;
272 entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
273 std::optional<Entity> result =
274 contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
275
276 EXPECT_TRUE(result.has_value());
277 if (result.has_value()) {
278 EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
279 std::optional<Rect> result_coverage = result.value().GetCoverage();
280 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
281 EXPECT_TRUE(result_coverage.has_value());
282 EXPECT_TRUE(contents_coverage.has_value());
283 if (result_coverage.has_value() && contents_coverage.has_value()) {
284 EXPECT_TRUE(RectNear(contents_coverage.value(),
285 Rect::MakeLTRB(99, 199, 201, 301)));
287 RectNear(result_coverage.value(), Rect::MakeLTRB(99, 199, 201, 301)));
288 }
289 }
290}

◆ TEST_P() [382/450]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRect   
)

Definition at line 338 of file gaussian_blur_filter_contents_unittests.cc.

338 {
339 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
340 auto texture_contents = std::make_shared<TextureContents>();
341 texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
342 texture_contents->SetTexture(texture);
343 texture_contents->SetDestinationRect(Rect::MakeXYWH(
344 50, 40, texture->GetSize().width, texture->GetSize().height));
345
346 fml::StatusOr<Scalar> sigma_radius_1 =
347 CalculateSigmaForBlurRadius(1.0, Matrix());
348 auto contents = std::make_unique<GaussianBlurFilterContents>(
349 sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
350 FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
351 contents->SetInputs({FilterInput::Make(texture_contents)});
352 std::shared_ptr<ContentContext> renderer = GetContentContext();
353
354 Entity entity;
355 std::optional<Entity> result =
356 contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
357 EXPECT_TRUE(result.has_value());
358 if (result.has_value()) {
359 EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
360 std::optional<Rect> result_coverage = result.value().GetCoverage();
361 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
362 EXPECT_TRUE(result_coverage.has_value());
363 EXPECT_TRUE(contents_coverage.has_value());
364 if (result_coverage.has_value() && contents_coverage.has_value()) {
365 EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
366 EXPECT_TRUE(RectNear(result_coverage.value(),
367 Rect::MakeLTRB(49.f, 39.f, 151.f, 141.f)));
368 }
369 }
370}

◆ TEST_P() [383/450]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRectScaled   
)

Definition at line 372 of file gaussian_blur_filter_contents_unittests.cc.

373 {
374 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
375 auto texture_contents = std::make_shared<TextureContents>();
376 texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
377 texture_contents->SetTexture(texture);
378 texture_contents->SetDestinationRect(Rect::MakeXYWH(
379 50, 40, texture->GetSize().width, texture->GetSize().height));
380
381 fml::StatusOr<Scalar> sigma_radius_1 =
382 CalculateSigmaForBlurRadius(1.0, Matrix());
383 auto contents = std::make_unique<GaussianBlurFilterContents>(
384 sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
386 /*mask_geometry=*/nullptr);
387 contents->SetInputs({FilterInput::Make(texture_contents)});
388 std::shared_ptr<ContentContext> renderer = GetContentContext();
389
390 Entity entity;
391 entity.SetTransform(Matrix::MakeScale({2.0, 2.0, 1.0}));
392 std::optional<Entity> result =
393 contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
394 EXPECT_TRUE(result.has_value());
395 if (result.has_value()) {
396 EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
397 std::optional<Rect> result_coverage = result.value().GetCoverage();
398 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
399 EXPECT_TRUE(result_coverage.has_value());
400 EXPECT_TRUE(contents_coverage.has_value());
401 if (result_coverage.has_value() && contents_coverage.has_value()) {
402 EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
403 // Scaling a blurred entity doesn't seem to scale the blur radius linearly
404 // when comparing results with rrect_blur. That's why this is not
405 // Rect::MakeXYWH(98.f, 78.f, 204.0f, 204.f).
406 EXPECT_TRUE(RectNear(contents_coverage.value(),
407 Rect::MakeXYWH(94.f, 74.f, 212.0f, 212.f)));
408 }
409 }
410}

◆ TEST_P() [384/450]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithEffectTransform   
)

Definition at line 412 of file gaussian_blur_filter_contents_unittests.cc.

412 {
413 Matrix effect_transform = Matrix::MakeScale({2.0, 2.0, 1.0});
414 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
415 auto texture_contents = std::make_shared<TextureContents>();
416 texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
417 texture_contents->SetTexture(texture);
418 texture_contents->SetDestinationRect(Rect::MakeXYWH(
419 50, 40, texture->GetSize().width, texture->GetSize().height));
420
421 fml::StatusOr<Scalar> sigma_radius_1 =
422 CalculateSigmaForBlurRadius(1.0, effect_transform);
423 ASSERT_TRUE(sigma_radius_1.ok());
424 auto contents = std::make_unique<GaussianBlurFilterContents>(
425 sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
426 FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
427 contents->SetInputs({FilterInput::Make(texture_contents)});
428 contents->SetEffectTransform(effect_transform);
429 std::shared_ptr<ContentContext> renderer = GetContentContext();
430
431 Entity entity;
432 std::optional<Entity> result =
433 contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
434 EXPECT_TRUE(result.has_value());
435 if (result.has_value()) {
436 EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
437 std::optional<Rect> result_coverage = result.value().GetCoverage();
438 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
439 EXPECT_TRUE(result_coverage.has_value());
440 EXPECT_TRUE(contents_coverage.has_value());
441 if (result_coverage.has_value() && contents_coverage.has_value()) {
442 EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
443 EXPECT_TRUE(RectNear(contents_coverage.value(),
444 Rect::MakeXYWH(49.f, 39.f, 102.f, 102.f)));
445 }
446 }
447}

◆ TEST_P() [385/450]

impeller::testing::TEST_P ( HostBufferTest  ,
CanEmplace   
)

Definition at line 15 of file host_buffer_unittests.cc.

15 {
16 struct Length2 {
17 uint8_t pad[2];
18 };
19 static_assert(sizeof(Length2) == 2u);
20
21 auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
22
23 for (size_t i = 0; i < 12500; i++) {
24 auto view = buffer->Emplace(Length2{});
25 ASSERT_TRUE(view);
26 ASSERT_EQ(view.range, Range(i * sizeof(Length2), 2u));
27 }
28}

◆ TEST_P() [386/450]

impeller::testing::TEST_P ( HostBufferTest  ,
CanEmplaceWithAlignment   
)

Definition at line 30 of file host_buffer_unittests.cc.

30 {
31 struct Length2 {
32 uint8_t pad[2];
33 };
34 static_assert(sizeof(Length2) == 2);
35 struct alignas(16) Align16 {
36 uint8_t pad[2];
37 };
38 static_assert(alignof(Align16) == 16);
39 static_assert(sizeof(Align16) == 16);
40
41 auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
42 ASSERT_TRUE(buffer);
43
44 {
45 auto view = buffer->Emplace(Length2{});
46 ASSERT_TRUE(view);
47 ASSERT_EQ(view.range, Range(0u, 2u));
48 }
49
50 {
51 auto view = buffer->Emplace(Align16{});
52 ASSERT_TRUE(view);
53 ASSERT_EQ(view.range.offset, 16u);
54 ASSERT_EQ(view.range.length, 16u);
55 }
56 {
57 auto view = buffer->Emplace(Length2{});
58 ASSERT_TRUE(view);
59 ASSERT_EQ(view.range, Range(32u, 2u));
60 }
61
62 {
63 auto view = buffer->Emplace(Align16{});
64 ASSERT_TRUE(view);
65 ASSERT_EQ(view.range.offset, 48u);
66 ASSERT_EQ(view.range.length, 16u);
67 }
68}

◆ TEST_P() [387/450]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplaceWithProcIsAligned   
)

Definition at line 149 of file host_buffer_unittests.cc.

149 {
150 auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
151
152 BufferView view = buffer->Emplace(std::array<char, 21>());
153 EXPECT_EQ(view.range, Range(0, 21));
154
155 view = buffer->Emplace(64, 16, [](uint8_t*) {});
156 EXPECT_EQ(view.range, Range(32, 64));
157}

◆ TEST_P() [388/450]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplacingLargerThanBlockSizeCreatesOneOffBuffer   
)

Definition at line 106 of file host_buffer_unittests.cc.

106 {
107 auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
108
109 // Emplace an amount larger than the block size, to verify that the host
110 // buffer does not create a buffer.
111 auto buffer_view = buffer->Emplace(nullptr, 1024000 + 10, 0);
112
113 EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
114 EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
115 EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
116}

◆ TEST_P() [389/450]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback   
)

Definition at line 93 of file host_buffer_unittests.cc.

94 {
95 auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
96
97 // Emplace an amount larger than the block size, to verify that the host
98 // buffer does not create a buffer.
99 auto buffer_view = buffer->Emplace(1024000 + 10, 0, [](uint8_t* data) {});
100
101 EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
102 EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
103 EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
104}

◆ TEST_P() [390/450]

impeller::testing::TEST_P ( HostBufferTest  ,
HostBufferInitialState   
)

Definition at line 70 of file host_buffer_unittests.cc.

70 {
71 auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
72
73 EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
74 EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
75 EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
76}

◆ TEST_P() [391/450]

impeller::testing::TEST_P ( HostBufferTest  ,
ResetIncrementsFrameCounter   
)

Definition at line 78 of file host_buffer_unittests.cc.

78 {
79 auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
80
81 EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
82
83 buffer->Reset();
84 EXPECT_EQ(buffer->GetStateForTest().current_frame, 1u);
85
86 buffer->Reset();
87 EXPECT_EQ(buffer->GetStateForTest().current_frame, 2u);
88
89 buffer->Reset();
90 EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
91}

◆ TEST_P() [392/450]

impeller::testing::TEST_P ( HostBufferTest  ,
UnusedBuffersAreDiscardedWhenResetting   
)

Definition at line 118 of file host_buffer_unittests.cc.

118 {
119 auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
120
121 // Emplace two large allocations to force the allocation of a second buffer.
122 auto buffer_view_a = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
123 auto buffer_view_b = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
124
125 EXPECT_EQ(buffer->GetStateForTest().current_buffer, 1u);
126 EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u);
127 EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
128
129 // Reset until we get back to this frame.
130 for (auto i = 0; i < 3; i++) {
131 buffer->Reset();
132 }
133
134 EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
135 EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u);
136 EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
137
138 // Now when we reset, the buffer should get dropped.
139 // Reset until we get back to this frame.
140 for (auto i = 0; i < 3; i++) {
141 buffer->Reset();
142 }
143
144 EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
145 EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
146 EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
147}

◆ TEST_P() [393/450]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageClippedSubpassScale   
)

Definition at line 180 of file matrix_filter_contents_unittests.cc.

181 {
182 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
183 MatrixFilterContents contents;
185 contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
186 contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
187 contents.SetRenderingMode(
188 Entity::RenderingMode::kSubpassAppendSnapshotTransform);
189
190 Entity entity;
191 entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
192
193 std::shared_ptr<ContentContext> renderer = GetContentContext();
194 std::optional<Entity> result =
195 contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
196 expectRenderCoverageEqual(result, contents.GetCoverage(entity),
197 Rect::MakeXYWH(100, 200, 300, 300));
198}
std::optional< Rect > GetCoverage(const Entity &entity) const override
Get the area of the render pass that will be affected when this contents is rendered.
void SetEffectTransform(const Matrix &effect_transform)
Sets the transform which gets appended to the effect of this filter. Note that this is in addition to...
void SetRenderingMode(Entity::RenderingMode rendering_mode) override
Marks this filter chain as applying in a subpass scenario.

◆ TEST_P() [394/450]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageClippedSubpassTranslate   
)

Definition at line 143 of file matrix_filter_contents_unittests.cc.

144 {
145 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
146 MatrixFilterContents contents;
148 contents.SetMatrix(Matrix::MakeTranslation({50, 100, 0}));
149 contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
150 contents.SetRenderingMode(
151 Entity::RenderingMode::kSubpassAppendSnapshotTransform);
152
153 Entity entity;
154 entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
155
156 std::shared_ptr<ContentContext> renderer = GetContentContext();
157 std::optional<Entity> result =
158 contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
159 expectRenderCoverageEqual(result, contents.GetCoverage(entity),
160 Rect::MakeXYWH(200, 400, 100, 100));
161}

◆ TEST_P() [395/450]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageIdentity   
)

Definition at line 111 of file matrix_filter_contents_unittests.cc.

111 {
112 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
113 MatrixFilterContents contents;
115
116 Entity entity;
117 entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
118
119 std::shared_ptr<ContentContext> renderer = GetContentContext();
120 std::optional<Entity> result =
121 contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
122 expectRenderCoverageEqual(result, contents.GetCoverage(entity),
123 Rect::MakeXYWH(100, 200, 100, 100));
124}

◆ TEST_P() [396/450]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageScale   
)

Definition at line 163 of file matrix_filter_contents_unittests.cc.

163 {
164 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
165 MatrixFilterContents contents;
167 contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
168 contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
169
170 Entity entity;
171 entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
172
173 std::shared_ptr<ContentContext> renderer = GetContentContext();
174 std::optional<Entity> result =
175 contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
176 expectRenderCoverageEqual(result, contents.GetCoverage(entity),
177 Rect::MakeXYWH(100, 200, 300, 300));
178}

◆ TEST_P() [397/450]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageSubpassScale   
)

Definition at line 200 of file matrix_filter_contents_unittests.cc.

200 {
201 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
202 MatrixFilterContents contents;
204 contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
205 contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
206 contents.SetRenderingMode(
207 Entity::RenderingMode::kSubpassPrependSnapshotTransform);
208
209 Entity entity;
210 entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
211
212 std::shared_ptr<ContentContext> renderer = GetContentContext();
213 std::optional<Entity> result =
214 contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
215 expectRenderCoverageEqual(result, contents.GetCoverage(entity),
216 Rect::MakeXYWH(300, 600, 300, 300));
217}

◆ TEST_P() [398/450]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageTranslate   
)

Definition at line 126 of file matrix_filter_contents_unittests.cc.

126 {
127 std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
128 MatrixFilterContents contents;
130 contents.SetMatrix(Matrix::MakeTranslation({50, 100, 0}));
131 contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
132
133 Entity entity;
134 entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
135
136 std::shared_ptr<ContentContext> renderer = GetContentContext();
137 std::optional<Entity> result =
138 contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
139 expectRenderCoverageEqual(result, contents.GetCoverage(entity),
140 Rect::MakeXYWH(150, 300, 100, 100));
141}

◆ TEST_P() [399/450]

impeller::testing::TEST_P ( RendererDartTest  ,
CanCreateRenderPassAndSubmit   
)

Definition at line 302 of file renderer_dart_unittests.cc.

302 {
303 ASSERT_TRUE(RenderDartToPlayground("canCreateRenderPassAndSubmit"));
304}

◆ TEST_P() [400/450]

impeller::testing::TEST_P ( RendererDartTest  ,
CanCreateShaderLibrary   
)

Definition at line 290 of file renderer_dart_unittests.cc.

290 {
291 ASSERT_TRUE(RunDartFunction("canCreateShaderLibrary"));
292}

◆ TEST_P() [401/450]

impeller::testing::TEST_P ( RendererDartTest  ,
CanInstantiateFlutterGPUContext   
)

These test entries correspond to Dart functions located in flutter/impeller/fixtures/dart_tests.dart

Definition at line 286 of file renderer_dart_unittests.cc.

286 {
287 ASSERT_TRUE(RunDartFunction("instantiateDefaultContext"));
288}

◆ TEST_P() [402/450]

impeller::testing::TEST_P ( RendererDartTest  ,
CanReflectUniformStructs   
)

Definition at line 294 of file renderer_dart_unittests.cc.

294 {
295 ASSERT_TRUE(RunDartFunction("canReflectUniformStructs"));
296}

◆ TEST_P() [403/450]

impeller::testing::TEST_P ( RendererDartTest  ,
CanRunDartInPlaygroundFrame   
)

Definition at line 271 of file renderer_dart_unittests.cc.

271 {
272 SinglePassCallback callback = [&](RenderPass& pass) {
273 ImGui::Begin("Dart test", nullptr);
274 ImGui::Text(
275 "This test executes Dart code during the playground frame callback.");
276 ImGui::End();
277
278 return RunDartFunction("sayHi");
279 };
280 ASSERT_TRUE(OpenPlaygroundHere(callback));
281}

◆ TEST_P() [404/450]

impeller::testing::TEST_P ( RendererDartTest  ,
UniformBindFailsForInvalidHostBufferOffset   
)

Definition at line 298 of file renderer_dart_unittests.cc.

298 {
299 ASSERT_TRUE(RunDartFunction("uniformBindFailsForInvalidHostBufferOffset"));
300}

◆ TEST_P() [405/450]

impeller::testing::TEST_P ( RendererTest  ,
ArrayUniforms   
)

Definition at line 997 of file renderer_unittests.cc.

997 {
998 using VS = ArrayVertexShader;
999 using FS = ArrayFragmentShader;
1000
1001 auto context = GetContext();
1002 auto pipeline_descriptor =
1004 ASSERT_TRUE(pipeline_descriptor.has_value());
1005 pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
1006 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1007 auto pipeline =
1008 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1009 ASSERT_TRUE(pipeline && pipeline->IsValid());
1010
1011 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
1012 SinglePassCallback callback = [&](RenderPass& pass) {
1013 auto size = pass.GetRenderTargetSize();
1014
1015 pass.SetPipeline(pipeline);
1016 pass.SetCommandLabel("Google Dots");
1018 builder.AddVertices({{Point()},
1019 {Point(0, size.height)},
1020 {Point(size.width, 0)},
1021 {Point(size.width, 0)},
1022 {Point(0, size.height)},
1023 {Point(size.width, size.height)}});
1024 pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
1025
1026 VS::FrameInfo frame_info;
1027 EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1028 frame_info.mvp =
1029 pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
1030 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1031
1032 auto time = GetSecondsElapsed();
1033 auto y_pos = [&time](float x) {
1034 return 400 + 10 * std::cos(time * 5 + x / 6);
1035 };
1036
1037 FS::FragInfo fs_uniform = {
1038 .circle_positions = {Point(430, y_pos(0)), Point(480, y_pos(1)),
1039 Point(530, y_pos(2)), Point(580, y_pos(3))},
1040 .colors = {Color::MakeRGBA8(66, 133, 244, 255),
1041 Color::MakeRGBA8(219, 68, 55, 255),
1042 Color::MakeRGBA8(244, 180, 0, 255),
1043 Color::MakeRGBA8(15, 157, 88, 255)},
1044 };
1045 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1046
1047 pass.Draw();
1048 host_buffer->Reset();
1049 return true;
1050 };
1051 OpenPlaygroundHere(callback);
1052}

◆ TEST_P() [406/450]

impeller::testing::TEST_P ( RendererTest  ,
BabysFirstTriangle   
)

Definition at line 123 of file renderer_unittests.cc.

123 {
124 auto context = GetContext();
125 ASSERT_TRUE(context);
126
127 // Declare a shorthand for the shaders we are going to use.
128 using VS = BabyVertexShader;
129 using FS = BabyFragmentShader;
130
131 // Create a pipeline descriptor that uses the shaders together and default
132 // initializes the fixed function state.
133 //
134 // If the vertex shader outputs disagree with the fragment shader inputs, this
135 // will be a compile time error.
137 ASSERT_TRUE(desc.has_value());
138
139 // Modify the descriptor for our environment. This is specific to our test.
140 desc->SetSampleCount(SampleCount::kCount4);
141 desc->SetStencilAttachmentDescriptors(std::nullopt);
142
143 // Create a pipeline from our descriptor. This is expensive to do. So just do
144 // it once.
145 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
146
147 // Create a host side buffer to build the vertex and uniform information.
148 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
149
150 // Specify the vertex buffer information.
151 VertexBufferBuilder<VS::PerVertexData> vertex_buffer_builder;
152 vertex_buffer_builder.AddVertices({
153 {{-0.5, -0.5}, Color::Red(), Color::Green()},
154 {{0.0, 0.5}, Color::Green(), Color::Blue()},
155 {{0.5, -0.5}, Color::Blue(), Color::Red()},
156 });
157
158 auto vertex_buffer = vertex_buffer_builder.CreateVertexBuffer(
159 *context->GetResourceAllocator());
160
161 SinglePassCallback callback = [&](RenderPass& pass) {
162 pass.SetPipeline(pipeline);
163 pass.SetVertexBuffer(vertex_buffer);
164
165 FS::FragInfo frag_info;
167
168 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
169 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(frag_info));
170
171 return pass.Draw().ok();
172 };
173 OpenPlaygroundHere(callback);
174}
constexpr double ToSecondsF() const
Definition: time_delta.h:71
TimeDelta ToEpochDelta() const
Definition: time_point.h:52
static TimePoint Now()
Definition: time_point.cc:49
VertexBuffer CreateVertexBuffer(HostBuffer &host_buffer) const
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
guint32 time
Definition: fl_key_event.h:24

◆ TEST_P() [407/450]

impeller::testing::TEST_P ( RendererTest  ,
CachesRenderPassAndFramebuffer   
)

Definition at line 16 of file render_pass_cache_unittests.cc.

16 {
17 if (GetBackend() != PlaygroundBackend::kVulkan) {
18 GTEST_SKIP() << "Test only applies to Vulkan";
19 }
20
21 auto allocator = std::make_shared<RenderTargetAllocator>(
22 GetContext()->GetResourceAllocator());
23
24 auto render_target =
25 allocator->CreateOffscreenMSAA(*GetContext(), {100, 100}, 1);
26 auto resolve_texture =
27 render_target.GetColorAttachments().find(0u)->second.resolve_texture;
28 auto& texture_vk = TextureVK::Cast(*resolve_texture);
29
30 EXPECT_EQ(texture_vk.GetCachedFramebuffer(), nullptr);
31 EXPECT_EQ(texture_vk.GetCachedRenderPass(), nullptr);
32
33 auto buffer = GetContext()->CreateCommandBuffer();
34 auto render_pass = buffer->CreateRenderPass(render_target);
35
36 EXPECT_NE(texture_vk.GetCachedFramebuffer(), nullptr);
37 EXPECT_NE(texture_vk.GetCachedRenderPass(), nullptr);
38
39 render_pass->EncodeCommands();
40 GetContext()->GetCommandQueue()->Submit({buffer});
41
42 // Can be reused without error.
43 auto buffer_2 = GetContext()->CreateCommandBuffer();
44 auto render_pass_2 = buffer_2->CreateRenderPass(render_target);
45
46 EXPECT_TRUE(render_pass_2->EncodeCommands());
47 EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer_2}).ok());
48}

◆ TEST_P() [408/450]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToBuffer   
)

Definition at line 613 of file renderer_unittests.cc.

613 {
614 if (GetBackend() == PlaygroundBackend::kOpenGLES) {
615 GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
616 }
617 auto context = GetContext();
618 ASSERT_TRUE(context);
619
620 using VS = MipmapsVertexShader;
621 using FS = MipmapsFragmentShader;
623 ASSERT_TRUE(desc.has_value());
624 desc->SetSampleCount(SampleCount::kCount4);
625 desc->SetStencilAttachmentDescriptors(std::nullopt);
626 auto mipmaps_pipeline =
627 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
628 ASSERT_TRUE(mipmaps_pipeline);
629
630 auto bridge = CreateTextureForFixture("bay_bridge.jpg");
631 auto boston = CreateTextureForFixture("boston.jpg");
632 ASSERT_TRUE(bridge && boston);
633 const std::unique_ptr<const Sampler>& sampler =
634 context->GetSamplerLibrary()->GetSampler({});
635 ASSERT_TRUE(sampler);
636
637 TextureDescriptor texture_desc;
638 texture_desc.storage_mode = StorageMode::kHostVisible;
639 texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
640 texture_desc.size = bridge->GetTextureDescriptor().size;
641 texture_desc.mip_count = 1u;
642 texture_desc.usage = TextureUsage::kRenderTarget |
643 TextureUsage::kShaderWrite | TextureUsage::kShaderRead;
644 DeviceBufferDescriptor device_buffer_desc;
645 device_buffer_desc.storage_mode = StorageMode::kHostVisible;
646 device_buffer_desc.size =
647 bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
648 auto device_buffer =
649 context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
650
651 // Vertex buffer.
652 VertexBufferBuilder<VS::PerVertexData> vertex_builder;
653 vertex_builder.SetLabel("Box");
654 auto size = Point(boston->GetSize());
655 vertex_builder.AddVertices({
656 {{0, 0}, {0.0, 0.0}}, // 1
657 {{size.x, 0}, {1.0, 0.0}}, // 2
658 {{size.x, size.y}, {1.0, 1.0}}, // 3
659 {{0, 0}, {0.0, 0.0}}, // 1
660 {{size.x, size.y}, {1.0, 1.0}}, // 3
661 {{0, size.y}, {0.0, 1.0}}, // 4
662 });
663 auto vertex_buffer =
664 vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
665 ASSERT_TRUE(vertex_buffer);
666
667 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
668 Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
669 {
670 auto buffer = context->CreateCommandBuffer();
671 if (!buffer) {
672 return false;
673 }
674 buffer->SetLabel("Playground Command Buffer");
675 auto pass = buffer->CreateBlitPass();
676 if (!pass) {
677 return false;
678 }
679 pass->SetLabel("Playground Blit Pass");
680
681 if (render_target.GetColorAttachments().empty()) {
682 return false;
683 }
684
685 // Blit `bridge` to the top left corner of the texture.
686 pass->AddCopy(bridge, device_buffer);
687 pass->EncodeCommands(context->GetResourceAllocator());
688
689 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
690 return false;
691 }
692 }
693
694 {
695 auto buffer = context->CreateCommandBuffer();
696 if (!buffer) {
697 return false;
698 }
699 buffer->SetLabel("Playground Command Buffer");
700
701 auto pass = buffer->CreateRenderPass(render_target);
702 if (!pass) {
703 return false;
704 }
705 pass->SetLabel("Playground Render Pass");
706 {
707 pass->SetCommandLabel("Image");
708 pass->SetPipeline(mipmaps_pipeline);
709 pass->SetVertexBuffer(vertex_buffer);
710
711 VS::FrameInfo frame_info;
712 EXPECT_EQ(pass->GetOrthographicTransform(),
713 Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
714 frame_info.mvp = pass->GetOrthographicTransform() *
715 Matrix::MakeScale(GetContentScale());
716 VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
717
718 FS::FragInfo frag_info;
719 frag_info.lod = 0;
720 FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
721
722 const std::unique_ptr<const Sampler>& sampler =
723 context->GetSamplerLibrary()->GetSampler({});
724 auto buffer_view = DeviceBuffer::AsBufferView(device_buffer);
725 auto texture =
726 context->GetResourceAllocator()->CreateTexture(texture_desc);
727 if (!texture->SetContents(device_buffer->OnGetContents(),
728 buffer_view.range.length)) {
729 VALIDATION_LOG << "Could not upload texture to device memory";
730 return false;
731 }
732 FS::BindTex(*pass, texture, sampler);
733
734 pass->Draw().ok();
735 }
736 pass->EncodeCommands();
737 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
738 return false;
739 }
740 }
741 host_buffer->Reset();
742 return true;
743 };
744 OpenPlaygroundHere(callback);
745}
#define VALIDATION_LOG
Definition: validation.h:73

◆ TEST_P() [409/450]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToTexture   
)

Definition at line 498 of file renderer_unittests.cc.

498 {
499 if (GetBackend() == PlaygroundBackend::kOpenGLES) {
500 GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
501 }
502 auto context = GetContext();
503 ASSERT_TRUE(context);
504
505 using VS = MipmapsVertexShader;
506 using FS = MipmapsFragmentShader;
508 ASSERT_TRUE(desc.has_value());
509 desc->SetSampleCount(SampleCount::kCount4);
510 desc->SetStencilAttachmentDescriptors(std::nullopt);
511 auto mipmaps_pipeline =
512 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
513 ASSERT_TRUE(mipmaps_pipeline);
514
515 TextureDescriptor texture_desc;
516 texture_desc.storage_mode = StorageMode::kHostVisible;
517 texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
518 texture_desc.size = {800, 600};
519 texture_desc.mip_count = 1u;
520 texture_desc.usage = TextureUsage::kRenderTarget | TextureUsage::kShaderRead;
521 auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
522 ASSERT_TRUE(texture);
523
524 auto bridge = CreateTextureForFixture("bay_bridge.jpg");
525 auto boston = CreateTextureForFixture("boston.jpg");
526 ASSERT_TRUE(bridge && boston);
527 const std::unique_ptr<const Sampler>& sampler =
528 context->GetSamplerLibrary()->GetSampler({});
529 ASSERT_TRUE(sampler);
530
531 // Vertex buffer.
532 VertexBufferBuilder<VS::PerVertexData> vertex_builder;
533 vertex_builder.SetLabel("Box");
534 auto size = Point(boston->GetSize());
535 vertex_builder.AddVertices({
536 {{0, 0}, {0.0, 0.0}}, // 1
537 {{size.x, 0}, {1.0, 0.0}}, // 2
538 {{size.x, size.y}, {1.0, 1.0}}, // 3
539 {{0, 0}, {0.0, 0.0}}, // 1
540 {{size.x, size.y}, {1.0, 1.0}}, // 3
541 {{0, size.y}, {0.0, 1.0}}, // 4
542 });
543 auto vertex_buffer =
544 vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
545 ASSERT_TRUE(vertex_buffer);
546
547 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
548 Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
549 auto buffer = context->CreateCommandBuffer();
550 if (!buffer) {
551 return false;
552 }
553 buffer->SetLabel("Playground Command Buffer");
554
555 {
556 auto pass = buffer->CreateBlitPass();
557 if (!pass) {
558 return false;
559 }
560 pass->SetLabel("Playground Blit Pass");
561
562 if (render_target.GetColorAttachments().empty()) {
563 return false;
564 }
565
566 // Blit `bridge` to the top left corner of the texture.
567 pass->AddCopy(bridge, texture);
568
569 if (!pass->EncodeCommands(context->GetResourceAllocator())) {
570 return false;
571 }
572 }
573
574 {
575 auto pass = buffer->CreateRenderPass(render_target);
576 if (!pass) {
577 return false;
578 }
579 pass->SetLabel("Playground Render Pass");
580 {
581 pass->SetCommandLabel("Image");
582 pass->SetPipeline(mipmaps_pipeline);
583 pass->SetVertexBuffer(vertex_buffer);
584
585 VS::FrameInfo frame_info;
586 EXPECT_EQ(pass->GetOrthographicTransform(),
587 Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
588 frame_info.mvp = pass->GetOrthographicTransform() *
589 Matrix::MakeScale(GetContentScale());
590 VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
591
592 FS::FragInfo frag_info;
593 frag_info.lod = 0;
594 FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
595
596 auto& sampler = context->GetSamplerLibrary()->GetSampler({});
597 FS::BindTex(*pass, texture, sampler);
598
599 pass->Draw();
600 }
601 pass->EncodeCommands();
602 }
603
604 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
605 return false;
606 }
607 host_buffer->Reset();
608 return true;
609 };
610 OpenPlaygroundHere(callback);
611}

◆ TEST_P() [410/450]

impeller::testing::TEST_P ( RendererTest  ,
CanCreateBoxPrimitive   
)

Definition at line 54 of file renderer_unittests.cc.

54 {
55 using VS = BoxFadeVertexShader;
56 using FS = BoxFadeFragmentShader;
57 auto context = GetContext();
58 ASSERT_TRUE(context);
59 using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
60 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
61 ASSERT_TRUE(desc.has_value());
62 desc->SetSampleCount(SampleCount::kCount4);
63 desc->SetStencilAttachmentDescriptors(std::nullopt);
64
65 // Vertex buffer.
67 vertex_builder.SetLabel("Box");
68 vertex_builder.AddVertices({
69 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
70 {{800, 100, 0.0}, {1.0, 0.0}}, // 2
71 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
72 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
73 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
74 {{100, 800, 0.0}, {0.0, 1.0}}, // 4
75 });
76 auto bridge = CreateTextureForFixture("bay_bridge.jpg");
77 auto boston = CreateTextureForFixture("boston.jpg");
78 ASSERT_TRUE(bridge && boston);
79 const std::unique_ptr<const Sampler>& sampler =
80 context->GetSamplerLibrary()->GetSampler({});
81 ASSERT_TRUE(sampler);
82
83 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
84 SinglePassCallback callback = [&](RenderPass& pass) {
85 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
86 static bool wireframe;
87 ImGui::Checkbox("Wireframe", &wireframe);
88 ImGui::End();
89
90 desc->SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill);
91 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
92
93 assert(pipeline && pipeline->IsValid());
94
95 pass.SetCommandLabel("Box");
96 pass.SetPipeline(pipeline);
97 pass.SetVertexBuffer(
98 vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator()));
99
100 VS::UniformBuffer uniforms;
101 EXPECT_EQ(pass.GetOrthographicTransform(),
102 Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
103 uniforms.mvp =
104 pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
105 VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
106
107 FS::FrameInfo frame_info;
108 frame_info.current_time = GetSecondsElapsed();
109 frame_info.cursor_position = GetCursorPosition();
110 frame_info.window_size.x = GetWindowSize().width;
111 frame_info.window_size.y = GetWindowSize().height;
112
113 FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
114 FS::BindContents1(pass, boston, sampler);
115 FS::BindContents2(pass, bridge, sampler);
116
117 host_buffer->Reset();
118 return pass.Draw().ok();
119 };
120 OpenPlaygroundHere(callback);
121}
void SetLabel(const std::string &label)

◆ TEST_P() [411/450]

impeller::testing::TEST_P ( RendererTest  ,
CanGenerateMipmaps   
)

Definition at line 747 of file renderer_unittests.cc.

747 {
748 if (GetBackend() == PlaygroundBackend::kOpenGLES) {
749 GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
750 }
751 auto context = GetContext();
752 ASSERT_TRUE(context);
753
754 using VS = MipmapsVertexShader;
755 using FS = MipmapsFragmentShader;
757 ASSERT_TRUE(desc.has_value());
758 desc->SetSampleCount(SampleCount::kCount4);
759 desc->SetStencilAttachmentDescriptors(std::nullopt);
760 auto mipmaps_pipeline =
761 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
762 ASSERT_TRUE(mipmaps_pipeline);
763
764 auto boston = CreateTextureForFixture("boston.jpg", true);
765 ASSERT_TRUE(boston);
766
767 // Vertex buffer.
769 vertex_builder.SetLabel("Box");
770 auto size = Point(boston->GetSize());
771 vertex_builder.AddVertices({
772 {{0, 0}, {0.0, 0.0}}, // 1
773 {{size.x, 0}, {1.0, 0.0}}, // 2
774 {{size.x, size.y}, {1.0, 1.0}}, // 3
775 {{0, 0}, {0.0, 0.0}}, // 1
776 {{size.x, size.y}, {1.0, 1.0}}, // 3
777 {{0, size.y}, {0.0, 1.0}}, // 4
778 });
779 auto vertex_buffer =
780 vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
781 ASSERT_TRUE(vertex_buffer);
782
783 bool first_frame = true;
784 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
785 Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
786 const char* mip_filter_names[] = {"Base", "Nearest", "Linear"};
787 const MipFilter mip_filters[] = {MipFilter::kBase, MipFilter::kNearest,
789 const char* min_filter_names[] = {"Nearest", "Linear"};
790 const MinMagFilter min_filters[] = {MinMagFilter::kNearest,
792
793 // UI state.
794 static int selected_mip_filter = 1;
795 static int selected_min_filter = 0;
796 static float lod = 4.5;
797
798 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
799 ImGui::Combo("Mip filter", &selected_mip_filter, mip_filter_names,
800 sizeof(mip_filter_names) / sizeof(char*));
801 ImGui::Combo("Min filter", &selected_min_filter, min_filter_names,
802 sizeof(min_filter_names) / sizeof(char*));
803 ImGui::SliderFloat("LOD", &lod, 0, boston->GetMipCount() - 1);
804 ImGui::End();
805
806 auto buffer = context->CreateCommandBuffer();
807 if (!buffer) {
808 return false;
809 }
810 buffer->SetLabel("Playground Command Buffer");
811
812 if (first_frame) {
813 auto pass = buffer->CreateBlitPass();
814 if (!pass) {
815 return false;
816 }
817 pass->SetLabel("Playground Blit Pass");
818
819 pass->GenerateMipmap(boston, "Boston Mipmap");
820
821 pass->EncodeCommands(context->GetResourceAllocator());
822 }
823
824 first_frame = false;
825
826 {
827 auto pass = buffer->CreateRenderPass(render_target);
828 if (!pass) {
829 return false;
830 }
831 pass->SetLabel("Playground Render Pass");
832 {
833 pass->SetCommandLabel("Image LOD");
834 pass->SetPipeline(mipmaps_pipeline);
835 pass->SetVertexBuffer(vertex_buffer);
836
837 VS::FrameInfo frame_info;
838 EXPECT_EQ(pass->GetOrthographicTransform(),
839 Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
840 frame_info.mvp = pass->GetOrthographicTransform() *
841 Matrix::MakeScale(GetContentScale());
842 VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
843
844 FS::FragInfo frag_info;
845 frag_info.lod = lod;
846 FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
847
848 SamplerDescriptor sampler_desc;
849 sampler_desc.mip_filter = mip_filters[selected_mip_filter];
850 sampler_desc.min_filter = min_filters[selected_min_filter];
851 const std::unique_ptr<const Sampler>& sampler =
852 context->GetSamplerLibrary()->GetSampler(sampler_desc);
853 FS::BindTex(*pass, boston, sampler);
854
855 pass->Draw();
856 }
857 pass->EncodeCommands();
858 }
859
860 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
861 return false;
862 }
863 host_buffer->Reset();
864 return true;
865 };
866 OpenPlaygroundHere(callback);
867}
MipFilter
Options for selecting and filtering between mipmap levels.
Definition: formats.h:419
MinMagFilter
Describes how the texture should be sampled when the texture is being shrunk (minified) or expanded (...
Definition: formats.h:409

◆ TEST_P() [412/450]

impeller::testing::TEST_P ( RendererTest  ,
CanLookupRenderTargetProperties   
)

Definition at line 1341 of file renderer_unittests.cc.

1341 {
1342 auto context = GetContext();
1343 auto cmd_buffer = context->CreateCommandBuffer();
1344 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1345 GetContext()->GetResourceAllocator());
1346
1347 auto render_target = render_target_cache->CreateOffscreen(
1348 *context, {100, 100}, /*mip_count=*/1);
1349 auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1350
1351 EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1352 EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1353 render_target.GetRenderTargetPixelFormat());
1354 EXPECT_EQ(render_pass->HasStencilAttachment(),
1355 render_target.GetStencilAttachment().has_value());
1356 EXPECT_EQ(render_pass->GetRenderTargetSize(),
1357 render_target.GetRenderTargetSize());
1358 render_pass->EncodeCommands();
1359}

◆ TEST_P() [413/450]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderInstanced   
)

Definition at line 441 of file renderer_unittests.cc.

441 {
442 if (GetParam() == PlaygroundBackend::kOpenGLES) {
443 GTEST_SKIP_("Instancing is not supported on OpenGL.");
444 }
445 using VS = InstancedDrawVertexShader;
446 using FS = InstancedDrawFragmentShader;
447
449 builder.AddVertices({
450 VS::PerVertexData{Point{10, 10}},
451 VS::PerVertexData{Point{10, 110}},
452 VS::PerVertexData{Point{110, 10}},
453 VS::PerVertexData{Point{10, 110}},
454 VS::PerVertexData{Point{110, 10}},
455 VS::PerVertexData{Point{110, 110}},
456 });
457
458 ASSERT_NE(GetContext(), nullptr);
459 auto pipeline =
460 GetContext()
461 ->GetPipelineLibrary()
462 ->GetPipeline(PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(
463 *GetContext())
464 ->SetSampleCount(SampleCount::kCount4)
465 .SetStencilAttachmentDescriptors(std::nullopt))
466
467 .Get();
468 ASSERT_TRUE(pipeline && pipeline->IsValid());
469
470 static constexpr size_t kInstancesCount = 5u;
471 VS::InstanceInfo<kInstancesCount> instances;
472 for (size_t i = 0; i < kInstancesCount; i++) {
473 instances.colors[i] = Color::Random();
474 }
475
476 auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
477 ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool {
478 pass.SetPipeline(pipeline);
479 pass.SetCommandLabel("InstancedDraw");
480
481 VS::FrameInfo frame_info;
482 EXPECT_EQ(pass.GetOrthographicTransform(),
483 Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
484 frame_info.mvp =
485 pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
486 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
487 VS::BindInstanceInfo(pass, host_buffer->EmplaceStorageBuffer(instances));
488 pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
489
490 pass.SetInstanceCount(kInstancesCount);
491 pass.Draw();
492
493 host_buffer->Reset();
494 return true;
495 }));
496}

◆ TEST_P() [414/450]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderMultiplePrimitives   
)

Definition at line 265 of file renderer_unittests.cc.

265 {
266 using VS = BoxFadeVertexShader;
267 using FS = BoxFadeFragmentShader;
268 auto context = GetContext();
269 ASSERT_TRUE(context);
270 using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
271 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
272 ASSERT_TRUE(desc.has_value());
273 desc->SetSampleCount(SampleCount::kCount4);
274 desc->SetStencilAttachmentDescriptors(std::nullopt);
275 auto box_pipeline =
276 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
277 ASSERT_TRUE(box_pipeline);
278
279 // Vertex buffer.
281 vertex_builder.SetLabel("Box");
282 vertex_builder.AddVertices({
283 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
284 {{800, 100, 0.0}, {1.0, 0.0}}, // 2
285 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
286 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
287 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
288 {{100, 800, 0.0}, {0.0, 1.0}}, // 4
289 });
290 auto vertex_buffer =
291 vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
292 ASSERT_TRUE(vertex_buffer);
293
294 auto bridge = CreateTextureForFixture("bay_bridge.jpg");
295 auto boston = CreateTextureForFixture("boston.jpg");
296 ASSERT_TRUE(bridge && boston);
297 const std::unique_ptr<const Sampler>& sampler =
298 context->GetSamplerLibrary()->GetSampler({});
299 ASSERT_TRUE(sampler);
300
301 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
302 SinglePassCallback callback = [&](RenderPass& pass) {
303 for (size_t i = 0; i < 1; i++) {
304 for (size_t j = 0; j < 1; j++) {
305 pass.SetCommandLabel("Box");
306 pass.SetPipeline(box_pipeline);
307 pass.SetVertexBuffer(vertex_buffer);
308
309 FS::FrameInfo frame_info;
310 frame_info.current_time = GetSecondsElapsed();
311 frame_info.cursor_position = GetCursorPosition();
312 frame_info.window_size.x = GetWindowSize().width;
313 frame_info.window_size.y = GetWindowSize().height;
314
315 FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
316 FS::BindContents1(pass, boston, sampler);
317 FS::BindContents2(pass, bridge, sampler);
318
319 VS::UniformBuffer uniforms;
320 EXPECT_EQ(pass.GetOrthographicTransform(),
321 Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
322 uniforms.mvp = pass.GetOrthographicTransform() *
323 Matrix::MakeScale(GetContentScale()) *
324 Matrix::MakeTranslation({i * 50.0f, j * 50.0f, 0.0f});
325 VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
326 if (!pass.Draw().ok()) {
327 return false;
328 }
329 }
330 }
331
332 host_buffer->Reset();
333 return true;
334 };
335 OpenPlaygroundHere(callback);
336}

◆ TEST_P() [415/450]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderPerspectiveCube   
)

Definition at line 176 of file renderer_unittests.cc.

176 {
177 using VS = ColorsVertexShader;
178 using FS = ColorsFragmentShader;
179 auto context = GetContext();
180 ASSERT_TRUE(context);
182 ASSERT_TRUE(desc.has_value());
183 desc->SetCullMode(CullMode::kBackFace);
184 desc->SetWindingOrder(WindingOrder::kCounterClockwise);
185 desc->SetSampleCount(SampleCount::kCount4);
186 desc->SetStencilAttachmentDescriptors(std::nullopt);
187 auto pipeline =
188 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
189 ASSERT_TRUE(pipeline);
190
191 struct Cube {
192 VS::PerVertexData vertices[8] = {
193 // -Z
194 {{-1, -1, -1}, Color::Red()},
195 {{1, -1, -1}, Color::Yellow()},
196 {{1, 1, -1}, Color::Green()},
197 {{-1, 1, -1}, Color::Blue()},
198 // +Z
199 {{-1, -1, 1}, Color::Green()},
200 {{1, -1, 1}, Color::Blue()},
201 {{1, 1, 1}, Color::Red()},
202 {{-1, 1, 1}, Color::Yellow()},
203 };
204 uint16_t indices[36] = {
205 1, 5, 2, 2, 5, 6, // +X
206 4, 0, 7, 7, 0, 3, // -X
207 4, 5, 0, 0, 5, 1, // +Y
208 3, 2, 7, 7, 2, 6, // -Y
209 5, 4, 6, 6, 4, 7, // +Z
210 0, 1, 3, 3, 1, 2, // -Z
211 };
212 } cube;
213
214 VertexBuffer vertex_buffer;
215 {
216 auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
217 reinterpret_cast<uint8_t*>(&cube), sizeof(cube));
218 vertex_buffer.vertex_buffer = {
219 .buffer = device_buffer,
220 .range = Range(offsetof(Cube, vertices), sizeof(Cube::vertices))};
221 vertex_buffer.index_buffer = {
222 .buffer = device_buffer,
223 .range = Range(offsetof(Cube, indices), sizeof(Cube::indices))};
224 vertex_buffer.vertex_count = 36;
225 vertex_buffer.index_type = IndexType::k16bit;
226 }
227
228 const std::unique_ptr<const Sampler>& sampler =
229 context->GetSamplerLibrary()->GetSampler({});
230 ASSERT_TRUE(sampler);
231
232 Vector3 euler_angles;
233 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
234 SinglePassCallback callback = [&](RenderPass& pass) {
235 static Degrees fov_y(60);
236 static Scalar distance = 10;
237
238 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
239 ImGui::SliderFloat("Field of view", &fov_y.degrees, 0, 180);
240 ImGui::SliderFloat("Camera distance", &distance, 0, 30);
241 ImGui::End();
242
243 pass.SetCommandLabel("Perspective Cube");
244 pass.SetPipeline(pipeline);
245 pass.SetVertexBuffer(vertex_buffer);
246
247 VS::UniformBuffer uniforms;
248 Scalar time = GetSecondsElapsed();
249 euler_angles = Vector3(0.19 * time, 0.7 * time, 0.43 * time);
250
251 uniforms.mvp =
252 Matrix::MakePerspective(fov_y, pass.GetRenderTargetSize(), 0, 10) *
253 Matrix::MakeTranslation({0, 0, distance}) *
254 Matrix::MakeRotationX(Radians(euler_angles.x)) *
255 Matrix::MakeRotationY(Radians(euler_angles.y)) *
256 Matrix::MakeRotationZ(Radians(euler_angles.z));
257 VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
258
259 host_buffer->Reset();
260 return pass.Draw().ok();
261 };
262 OpenPlaygroundHere(callback);
263}

◆ TEST_P() [416/450]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderToTexture   
)

Definition at line 338 of file renderer_unittests.cc.

338 {
339 using VS = BoxFadeVertexShader;
340 using FS = BoxFadeFragmentShader;
341 auto context = GetContext();
342 ASSERT_TRUE(context);
343 using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
344 auto pipeline_desc =
345 BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
346 pipeline_desc->SetSampleCount(SampleCount::kCount1);
347 pipeline_desc->ClearDepthAttachment();
348 pipeline_desc->SetStencilPixelFormat(PixelFormat::kS8UInt);
349
350 ASSERT_TRUE(pipeline_desc.has_value());
351 auto box_pipeline =
352 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
353 ASSERT_TRUE(box_pipeline);
354 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
355
357 vertex_builder.SetLabel("Box");
358 vertex_builder.AddVertices({
359 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
360 {{800, 100, 0.0}, {1.0, 0.0}}, // 2
361 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
362 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
363 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
364 {{100, 800, 0.0}, {0.0, 1.0}}, // 4
365 });
366 auto vertex_buffer =
367 vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
368 ASSERT_TRUE(vertex_buffer);
369
370 auto bridge = CreateTextureForFixture("bay_bridge.jpg");
371 auto boston = CreateTextureForFixture("boston.jpg");
372 ASSERT_TRUE(bridge && boston);
373 const std::unique_ptr<const Sampler>& sampler =
374 context->GetSamplerLibrary()->GetSampler({});
375 ASSERT_TRUE(sampler);
376
377 std::shared_ptr<RenderPass> r2t_pass;
378 auto cmd_buffer = context->CreateCommandBuffer();
379 ASSERT_TRUE(cmd_buffer);
380 {
381 ColorAttachment color0;
382 color0.load_action = LoadAction::kClear;
383 color0.store_action = StoreAction::kStore;
384
385 TextureDescriptor texture_descriptor;
386 ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u), nullptr);
387 texture_descriptor.format =
388 pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
389 texture_descriptor.storage_mode = StorageMode::kHostVisible;
390 texture_descriptor.size = {400, 400};
391 texture_descriptor.mip_count = 1u;
392 texture_descriptor.usage = TextureUsage::kRenderTarget;
393
394 color0.texture =
395 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
396
397 ASSERT_TRUE(color0.IsValid());
398
399 color0.texture->SetLabel("r2t_target");
400
401 StencilAttachment stencil0;
402 stencil0.load_action = LoadAction::kClear;
403 stencil0.store_action = StoreAction::kDontCare;
404 TextureDescriptor stencil_texture_desc;
405 stencil_texture_desc.storage_mode = StorageMode::kDeviceTransient;
406 stencil_texture_desc.size = texture_descriptor.size;
407 stencil_texture_desc.format = PixelFormat::kS8UInt;
408 stencil_texture_desc.usage = TextureUsage::kRenderTarget;
409 stencil0.texture =
410 context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
411
412 RenderTarget r2t_desc;
413 r2t_desc.SetColorAttachment(color0, 0u);
414 r2t_desc.SetStencilAttachment(stencil0);
415 r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
416 ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
417 }
418
419 r2t_pass->SetCommandLabel("Box");
420 r2t_pass->SetPipeline(box_pipeline);
421 r2t_pass->SetVertexBuffer(vertex_buffer);
422
423 FS::FrameInfo frame_info;
424 frame_info.current_time = GetSecondsElapsed();
425 frame_info.cursor_position = GetCursorPosition();
426 frame_info.window_size.x = GetWindowSize().width;
427 frame_info.window_size.y = GetWindowSize().height;
428
429 FS::BindFrameInfo(*r2t_pass, host_buffer->EmplaceUniform(frame_info));
430 FS::BindContents1(*r2t_pass, boston, sampler);
431 FS::BindContents2(*r2t_pass, bridge, sampler);
432
433 VS::UniformBuffer uniforms;
434 uniforms.mvp = Matrix::MakeOrthographic(ISize{1024, 768}) *
435 Matrix::MakeTranslation({50.0f, 50.0f, 0.0f});
436 VS::BindUniformBuffer(*r2t_pass, host_buffer->EmplaceUniform(uniforms));
437 ASSERT_TRUE(r2t_pass->Draw().ok());
438 ASSERT_TRUE(r2t_pass->EncodeCommands());
439}

◆ TEST_P() [417/450]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneThenSwizzleWithSubpasses   
)

Definition at line 1489 of file renderer_unittests.cc.

1489 {
1490 // The GLES framebuffer fetch implementation currently does not support this.
1491 // TODO(chinmaygarde): revisit after the GLES framebuffer fetch capabilities
1492 // are clarified.
1493 if (GetParam() == PlaygroundBackend::kOpenGLES) {
1494 GTEST_SKIP_("Not supported on GLES.");
1495 }
1496
1497 // Define shader types
1498 using TextureVS = TextureVertexShader;
1499 using TextureFS = TextureFragmentShader;
1500
1501 using SwizzleVS = SepiaVertexShader;
1502 using SwizzleFS = SwizzleFragmentShader;
1503
1504 using SepiaVS = SepiaVertexShader;
1505 using SepiaFS = SepiaFragmentShader;
1506
1507 auto context = GetContext();
1508 ASSERT_TRUE(context);
1509
1510 if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1511 GTEST_SKIP_(
1512 "This test uses framebuffer fetch and the backend doesn't support it.");
1513 return;
1514 }
1515
1516 // Create pipelines.
1517 auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1518 auto swizzle_pipeline = CreateDefaultPipeline<SwizzleVS, SwizzleFS>(context);
1519 auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1520
1521 ASSERT_TRUE(texture_pipeline);
1522 ASSERT_TRUE(swizzle_pipeline);
1523 ASSERT_TRUE(sepia_pipeline);
1524
1525 // Vertex buffer builders.
1526 VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1527 texture_vtx_builder.AddVertices({
1528 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1529 {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1530 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1531 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1532 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1533 {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1534 });
1535
1536 VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1537 sepia_vtx_builder.AddVertices({
1538 {{100, 100, 0.0}}, // 1
1539 {{800, 100, 0.0}}, // 2
1540 {{800, 800, 0.0}}, // 3
1541 {{100, 100, 0.0}}, // 1
1542 {{800, 800, 0.0}}, // 3
1543 {{100, 800, 0.0}}, // 4
1544 });
1545
1546 auto boston = CreateTextureForFixture("boston.jpg");
1547 ASSERT_TRUE(boston);
1548
1549 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1550 ASSERT_TRUE(sampler);
1551
1552 SinglePassCallback callback = [&](RenderPass& pass) {
1553 auto buffer = HostBuffer::Create(context->GetResourceAllocator());
1554
1555 // Draw the texture.
1556 {
1557 pass.SetPipeline(texture_pipeline);
1558 pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1559 *context->GetResourceAllocator()));
1560 TextureVS::UniformBuffer uniforms;
1561 uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1562 Matrix::MakeScale(GetContentScale());
1563 TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1564 TextureFS::BindTextureContents(pass, boston, sampler);
1565 if (!pass.Draw().ok()) {
1566 return false;
1567 }
1568 }
1569
1570 // Draw the sepia toner.
1571 {
1572 pass.SetPipeline(sepia_pipeline);
1573 pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1574 *context->GetResourceAllocator()));
1575 SepiaVS::UniformBuffer uniforms;
1576 uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1577 Matrix::MakeScale(GetContentScale());
1578 SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1579 if (!pass.Draw().ok()) {
1580 return false;
1581 }
1582 }
1583
1584 // Draw the swizzle.
1585 {
1586 pass.SetPipeline(swizzle_pipeline);
1587 pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1588 *context->GetResourceAllocator()));
1589 SwizzleVS::UniformBuffer uniforms;
1590 uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1591 Matrix::MakeScale(GetContentScale());
1592 SwizzleVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1593 if (!pass.Draw().ok()) {
1594 return false;
1595 }
1596 }
1597
1598 return true;
1599 };
1600 OpenPlaygroundHere(callback);
1601}

◆ TEST_P() [418/450]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneWithSubpasses   
)

Definition at line 1394 of file renderer_unittests.cc.

1394 {
1395 // The GLES framebuffer fetch implementation currently does not support this.
1396 // TODO(chinmaygarde): revisit after the GLES framebuffer fetch capabilities
1397 // are clarified.
1398 if (GetParam() == PlaygroundBackend::kOpenGLES) {
1399 GTEST_SKIP_("Not supported on GLES.");
1400 }
1401
1402 // Define shader types
1403 using TextureVS = TextureVertexShader;
1404 using TextureFS = TextureFragmentShader;
1405
1406 using SepiaVS = SepiaVertexShader;
1407 using SepiaFS = SepiaFragmentShader;
1408
1409 auto context = GetContext();
1410 ASSERT_TRUE(context);
1411
1412 if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1413 GTEST_SKIP_(
1414 "This test uses framebuffer fetch and the backend doesn't support it.");
1415 return;
1416 }
1417
1418 // Create pipelines.
1419 auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1420 auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1421
1422 ASSERT_TRUE(texture_pipeline);
1423 ASSERT_TRUE(sepia_pipeline);
1424
1425 // Vertex buffer builders.
1426 VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1427 texture_vtx_builder.AddVertices({
1428 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1429 {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1430 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1431 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1432 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1433 {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1434 });
1435
1436 VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1437 sepia_vtx_builder.AddVertices({
1438 {{100, 100, 0.0}}, // 1
1439 {{800, 100, 0.0}}, // 2
1440 {{800, 800, 0.0}}, // 3
1441 {{100, 100, 0.0}}, // 1
1442 {{800, 800, 0.0}}, // 3
1443 {{100, 800, 0.0}}, // 4
1444 });
1445
1446 auto boston = CreateTextureForFixture("boston.jpg");
1447 ASSERT_TRUE(boston);
1448
1449 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1450 ASSERT_TRUE(sampler);
1451
1452 SinglePassCallback callback = [&](RenderPass& pass) {
1453 auto buffer = HostBuffer::Create(context->GetResourceAllocator());
1454
1455 // Draw the texture.
1456 {
1457 pass.SetPipeline(texture_pipeline);
1458 pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1459 *context->GetResourceAllocator()));
1460 TextureVS::UniformBuffer uniforms;
1461 uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1462 Matrix::MakeScale(GetContentScale());
1463 TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1464 TextureFS::BindTextureContents(pass, boston, sampler);
1465 if (!pass.Draw().ok()) {
1466 return false;
1467 }
1468 }
1469
1470 // Draw the sepia toner.
1471 {
1472 pass.SetPipeline(sepia_pipeline);
1473 pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1474 *context->GetResourceAllocator()));
1475 SepiaVS::UniformBuffer uniforms;
1476 uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1477 Matrix::MakeScale(GetContentScale());
1478 SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1479 if (!pass.Draw().ok()) {
1480 return false;
1481 }
1482 }
1483
1484 return true;
1485 };
1486 OpenPlaygroundHere(callback);
1487}

◆ TEST_P() [419/450]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexBehavior   
)

Definition at line 1111 of file renderer_unittests.cc.

1111 {
1112 using VS = BoxFadeVertexShader;
1113
1114 // Do not create any index buffer if no indices were provided.
1116 ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::kNone);
1117}
constexpr impeller::IndexType GetIndexType() const
@ kNone
Definition: layer.h:53

◆ TEST_P() [420/450]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexSize   
)

Definition at line 1101 of file renderer_unittests.cc.

1101 {
1102 using VS = BoxFadeVertexShader;
1103
1104 // Default to 16bit index buffer size, as this is a reasonable default and
1105 // supported on all backends without extensions.
1107 vertex_builder.AppendIndex(0u);
1108 ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::k16bit);
1109}
VertexBufferBuilder & AppendIndex(IndexType_ index)

◆ TEST_P() [421/450]

impeller::testing::TEST_P ( RendererTest  ,
InactiveUniforms   
)

Definition at line 1054 of file renderer_unittests.cc.

1054 {
1055 using VS = InactiveUniformsVertexShader;
1056 using FS = InactiveUniformsFragmentShader;
1057
1058 auto context = GetContext();
1059 auto pipeline_descriptor =
1061 ASSERT_TRUE(pipeline_descriptor.has_value());
1062 pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
1063 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1064 auto pipeline =
1065 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1066 ASSERT_TRUE(pipeline && pipeline->IsValid());
1067
1068 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
1069 SinglePassCallback callback = [&](RenderPass& pass) {
1070 auto size = pass.GetRenderTargetSize();
1071
1072 pass.SetPipeline(pipeline);
1073 pass.SetCommandLabel("Inactive Uniform");
1074
1076 builder.AddVertices({{Point()},
1077 {Point(0, size.height)},
1078 {Point(size.width, 0)},
1079 {Point(size.width, 0)},
1080 {Point(0, size.height)},
1081 {Point(size.width, size.height)}});
1082 pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
1083
1084 VS::FrameInfo frame_info;
1085 EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1086 frame_info.mvp =
1087 pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
1088 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1089
1090 FS::FragInfo fs_uniform = {.unused_color = Color::Red(),
1091 .color = Color::Green()};
1092 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1093
1094 pass.Draw().ok();
1095 host_buffer->Reset();
1096 return true;
1097 };
1098 OpenPlaygroundHere(callback);
1099}

◆ TEST_P() [422/450]

impeller::testing::TEST_P ( RendererTest  ,
Planet   
)

Definition at line 931 of file renderer_unittests.cc.

931 {
932 using VS = PlanetVertexShader;
933 using FS = PlanetFragmentShader;
934
935 auto context = GetContext();
936 auto pipeline_descriptor =
938 ASSERT_TRUE(pipeline_descriptor.has_value());
939 pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
940 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
941 auto pipeline =
942 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
943 ASSERT_TRUE(pipeline && pipeline->IsValid());
944
945 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
946
947 SinglePassCallback callback = [&](RenderPass& pass) {
948 static Scalar speed = 0.1;
949 static Scalar planet_size = 550.0;
950 static bool show_normals = false;
951 static bool show_noise = false;
952 static Scalar seed_value = 42.0;
953
954 auto size = pass.GetRenderTargetSize();
955
956 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
957 ImGui::SliderFloat("Speed", &speed, 0.0, 10.0);
958 ImGui::SliderFloat("Planet Size", &planet_size, 0.1, 1000);
959 ImGui::Checkbox("Show Normals", &show_normals);
960 ImGui::Checkbox("Show Noise", &show_noise);
961 ImGui::InputFloat("Seed Value", &seed_value);
962 ImGui::End();
963
964 pass.SetPipeline(pipeline);
965 pass.SetCommandLabel("Planet scene");
967 builder.AddVertices({{Point()},
968 {Point(0, size.height)},
969 {Point(size.width, 0)},
970 {Point(size.width, 0)},
971 {Point(0, size.height)},
972 {Point(size.width, size.height)}});
973 pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
974
975 VS::FrameInfo frame_info;
976 EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
977 frame_info.mvp = pass.GetOrthographicTransform();
978 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
979
980 FS::FragInfo fs_uniform;
981 fs_uniform.resolution = Point(size);
982 fs_uniform.time = GetSecondsElapsed();
983 fs_uniform.speed = speed;
984 fs_uniform.planet_size = planet_size;
985 fs_uniform.show_normals = show_normals ? 1.0 : 0.0;
986 fs_uniform.show_noise = show_noise ? 1.0 : 0.0;
987 fs_uniform.seed_value = seed_value;
988 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
989
990 pass.Draw().ok();
991 host_buffer->Reset();
992 return true;
993 };
994 OpenPlaygroundHere(callback);
995}

◆ TEST_P() [423/450]

impeller::testing::TEST_P ( RendererTest  ,
RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat   
)

Definition at line 1361 of file renderer_unittests.cc.

1362 {
1363 auto context = GetContext();
1364 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1365 GetContext()->GetResourceAllocator());
1366
1367 RenderTarget render_target = render_target_cache->CreateOffscreenMSAA(
1368 *context, {100, 100}, /*mip_count=*/1);
1369 EXPECT_EQ(render_target.GetDepthAttachment()
1370 ->texture->GetTextureDescriptor()
1371 .format,
1372 GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
1373}

◆ TEST_P() [424/450]

impeller::testing::TEST_P ( RendererTest  ,
StencilMask   
)

Definition at line 1189 of file renderer_unittests.cc.

1189 {
1190 using VS = BoxFadeVertexShader;
1191 using FS = BoxFadeFragmentShader;
1192 auto context = GetContext();
1193 ASSERT_TRUE(context);
1194 using BoxFadePipelineBuilder = PipelineBuilder<VS, FS>;
1195 auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1196 ASSERT_TRUE(desc.has_value());
1197
1198 // Vertex buffer.
1200 vertex_builder.SetLabel("Box");
1201 vertex_builder.AddVertices({
1202 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1203 {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1204 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1205 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1206 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1207 {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1208 });
1209 auto vertex_buffer =
1210 vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
1211 ASSERT_TRUE(vertex_buffer);
1212
1213 desc->SetSampleCount(SampleCount::kCount4);
1214 desc->SetStencilAttachmentDescriptors(std::nullopt);
1215
1216 auto bridge = CreateTextureForFixture("bay_bridge.jpg");
1217 auto boston = CreateTextureForFixture("boston.jpg");
1218 ASSERT_TRUE(bridge && boston);
1219 const std::unique_ptr<const Sampler>& sampler =
1220 context->GetSamplerLibrary()->GetSampler({});
1221 ASSERT_TRUE(sampler);
1222
1223 static bool mirror = false;
1224 static int stencil_reference_write = 0xFF;
1225 static int stencil_reference_read = 0x1;
1226 std::vector<uint8_t> stencil_contents;
1227 static int last_stencil_contents_reference_value = 0;
1228 static int current_front_compare =
1229 CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1230 static int current_back_compare =
1231 CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1232
1233 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
1234 Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
1235 auto buffer = context->CreateCommandBuffer();
1236 if (!buffer) {
1237 return false;
1238 }
1239 buffer->SetLabel("Playground Command Buffer");
1240
1241 {
1242 // Configure the stencil attachment for the test.
1243 RenderTarget::AttachmentConfig stencil_config;
1244 stencil_config.load_action = LoadAction::kLoad;
1245 stencil_config.store_action = StoreAction::kDontCare;
1246 stencil_config.storage_mode = StorageMode::kHostVisible;
1247 render_target.SetupDepthStencilAttachments(
1248 *context, *context->GetResourceAllocator(),
1249 render_target.GetRenderTargetSize(), true, "stencil", stencil_config);
1250 // Fill the stencil buffer with an checkerboard pattern.
1251 const auto target_width = render_target.GetRenderTargetSize().width;
1252 const auto target_height = render_target.GetRenderTargetSize().height;
1253 const size_t target_size = target_width * target_height;
1254 if (stencil_contents.size() != target_size ||
1255 last_stencil_contents_reference_value != stencil_reference_write) {
1256 stencil_contents.resize(target_size);
1257 last_stencil_contents_reference_value = stencil_reference_write;
1258 for (int y = 0; y < target_height; y++) {
1259 for (int x = 0; x < target_width; x++) {
1260 const auto index = y * target_width + x;
1261 const auto kCheckSize = 64;
1262 const auto value =
1263 (((y / kCheckSize) + (x / kCheckSize)) % 2 == 0) *
1264 stencil_reference_write;
1265 stencil_contents[index] = value;
1266 }
1267 }
1268 }
1269 if (!render_target.GetStencilAttachment()->texture->SetContents(
1270 stencil_contents.data(), stencil_contents.size(), 0, false)) {
1271 VALIDATION_LOG << "Could not upload stencil contents to device memory";
1272 return false;
1273 }
1274 auto pass = buffer->CreateRenderPass(render_target);
1275 if (!pass) {
1276 return false;
1277 }
1278 pass->SetLabel("Stencil Buffer");
1279 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1280 ImGui::SliderInt("Stencil Write Value", &stencil_reference_write, 0,
1281 0xFF);
1282 ImGui::SliderInt("Stencil Compare Value", &stencil_reference_read, 0,
1283 0xFF);
1284 ImGui::Checkbox("Back face mode", &mirror);
1285 ImGui::ListBox("Front face compare function", &current_front_compare,
1286 CompareFunctionUI().labels(), CompareFunctionUI().size());
1287 ImGui::ListBox("Back face compare function", &current_back_compare,
1288 CompareFunctionUI().labels(), CompareFunctionUI().size());
1289 ImGui::End();
1290
1291 StencilAttachmentDescriptor front;
1292 front.stencil_compare =
1293 CompareFunctionUI().FunctionOf(current_front_compare);
1294 StencilAttachmentDescriptor back;
1295 back.stencil_compare =
1296 CompareFunctionUI().FunctionOf(current_back_compare);
1297 desc->SetStencilAttachmentDescriptors(front, back);
1298 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1299
1300 assert(pipeline && pipeline->IsValid());
1301
1302 pass->SetCommandLabel("Box");
1303 pass->SetPipeline(pipeline);
1304 pass->SetStencilReference(stencil_reference_read);
1305 pass->SetVertexBuffer(vertex_buffer);
1306
1307 VS::UniformBuffer uniforms;
1308 EXPECT_EQ(pass->GetOrthographicTransform(),
1309 Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
1310 uniforms.mvp = pass->GetOrthographicTransform() *
1311 Matrix::MakeScale(GetContentScale());
1312 if (mirror) {
1313 uniforms.mvp = Matrix::MakeScale(Vector2(-1, 1)) * uniforms.mvp;
1314 }
1315 VS::BindUniformBuffer(*pass, host_buffer->EmplaceUniform(uniforms));
1316
1317 FS::FrameInfo frame_info;
1318 frame_info.current_time = GetSecondsElapsed();
1319 frame_info.cursor_position = GetCursorPosition();
1320 frame_info.window_size.x = GetWindowSize().width;
1321 frame_info.window_size.y = GetWindowSize().height;
1322
1323 FS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
1324 FS::BindContents1(*pass, boston, sampler);
1325 FS::BindContents2(*pass, bridge, sampler);
1326 if (!pass->Draw().ok()) {
1327 return false;
1328 }
1329 pass->EncodeCommands();
1330 }
1331
1332 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
1333 return false;
1334 }
1335 host_buffer->Reset();
1336 return true;
1337 };
1338 OpenPlaygroundHere(callback);
1339}
static unsigned mirror(SkFixed fx, int max)
CompareFunction FunctionOf(int index) const
int IndexOf(CompareFunction func) const
static const CompareFunctionUIData & CompareFunctionUI()

◆ TEST_P() [425/450]

impeller::testing::TEST_P ( RendererTest  ,
TheImpeller   
)

Definition at line 869 of file renderer_unittests.cc.

869 {
870 using VS = ImpellerVertexShader;
871 using FS = ImpellerFragmentShader;
872
873 auto context = GetContext();
874 auto pipeline_descriptor =
876 ASSERT_TRUE(pipeline_descriptor.has_value());
877 pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
878 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
879 auto pipeline =
880 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
881 ASSERT_TRUE(pipeline && pipeline->IsValid());
882
883 auto blue_noise = CreateTextureForFixture("blue_noise.png");
884 SamplerDescriptor noise_sampler_desc;
885 noise_sampler_desc.width_address_mode = SamplerAddressMode::kRepeat;
886 noise_sampler_desc.height_address_mode = SamplerAddressMode::kRepeat;
887 const std::unique_ptr<const Sampler>& noise_sampler =
888 context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
889
890 auto cube_map = CreateTextureCubeForFixture(
891 {"table_mountain_px.png", "table_mountain_nx.png",
892 "table_mountain_py.png", "table_mountain_ny.png",
893 "table_mountain_pz.png", "table_mountain_nz.png"});
894 const std::unique_ptr<const Sampler>& cube_map_sampler =
895 context->GetSamplerLibrary()->GetSampler({});
896 auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
897
898 SinglePassCallback callback = [&](RenderPass& pass) {
899 auto size = pass.GetRenderTargetSize();
900
901 pass.SetPipeline(pipeline);
902 pass.SetCommandLabel("Impeller SDF scene");
903 VertexBufferBuilder<VS::PerVertexData> builder;
904 builder.AddVertices({{Point()},
905 {Point(0, size.height)},
906 {Point(size.width, 0)},
907 {Point(size.width, 0)},
908 {Point(0, size.height)},
909 {Point(size.width, size.height)}});
910 pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
911
912 VS::FrameInfo frame_info;
913 EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
914 frame_info.mvp = pass.GetOrthographicTransform();
915 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
916
917 FS::FragInfo fs_uniform;
918 fs_uniform.texture_size = Point(size);
919 fs_uniform.time = GetSecondsElapsed();
920 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
921 FS::BindBlueNoise(pass, blue_noise, noise_sampler);
922 FS::BindCubeMap(pass, cube_map, cube_map_sampler);
923
924 pass.Draw().ok();
925 host_buffer->Reset();
926 return true;
927 };
928 OpenPlaygroundHere(callback);
929}
SamplerAddressMode width_address_mode
SamplerAddressMode height_address_mode

◆ TEST_P() [426/450]

impeller::testing::TEST_P ( RendererTest  ,
VertexBufferBuilder   
)

Definition at line 1119 of file renderer_unittests.cc.

1119 {
1120 // Does not create index buffer if one is provided.
1121 using VS = BoxFadeVertexShader;
1123 vertex_builder.SetLabel("Box");
1124 vertex_builder.AddVertices({
1125 {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1126 {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1127 {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1128 {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1129 });
1130 vertex_builder.AppendIndex(0);
1131 vertex_builder.AppendIndex(1);
1132 vertex_builder.AppendIndex(2);
1133 vertex_builder.AppendIndex(1);
1134 vertex_builder.AppendIndex(2);
1135 vertex_builder.AppendIndex(3);
1136
1137 ASSERT_EQ(vertex_builder.GetIndexCount(), 6u);
1138 ASSERT_EQ(vertex_builder.GetVertexCount(), 4u);
1139}

◆ TEST_P() [427/450]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachedTextureGetsNewAttachmentConfig   
)

Definition at line 90 of file render_target_cache_unittests.cc.

90 {
91 auto render_target_cache =
92 RenderTargetCache(GetContext()->GetResourceAllocator());
93
94 render_target_cache.Start();
95 RenderTarget::AttachmentConfig color_attachment_config =
96 RenderTarget::kDefaultColorAttachmentConfig;
97 RenderTarget target1 = render_target_cache.CreateOffscreen(
98 *GetContext(), {100, 100}, 1, "Offscreen1", color_attachment_config);
99 render_target_cache.End();
100
101 render_target_cache.Start();
102 color_attachment_config.clear_color = Color::Red();
103 RenderTarget target2 = render_target_cache.CreateOffscreen(
104 *GetContext(), {100, 100}, 1, "Offscreen2", color_attachment_config);
105 render_target_cache.End();
106
107 auto color1 = target1.GetColorAttachments().find(0)->second;
108 auto color2 = target2.GetColorAttachments().find(0)->second;
109 // The second color attachment should reuse the first attachment's texture
110 // but with attributes from the second AttachmentConfig.
111 EXPECT_EQ(color2.texture, color1.texture);
112 EXPECT_EQ(color2.clear_color, Color::Red());
113}
An implementation of the [RenderTargetAllocator] that caches all allocated texture data for one frame...

◆ TEST_P() [428/450]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachesUsedTexturesAcrossFrames   
)

Definition at line 51 of file render_target_cache_unittests.cc.

51 {
52 auto render_target_cache =
53 RenderTargetCache(GetContext()->GetResourceAllocator());
54
55 render_target_cache.Start();
56 // Create two render targets of the same exact size/shape. Both should be
57 // marked as used this frame, so the cached data set will contain two.
58 render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
59 render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
60
61 EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
62
63 render_target_cache.End();
64 render_target_cache.Start();
65
66 // Next frame, only create one texture. The set will still contain two,
67 // but one will be removed at the end of the frame.
68 render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
69 EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
70
71 render_target_cache.End();
72 EXPECT_EQ(render_target_cache.CachedTextureCount(), 1u);
73}

◆ TEST_P() [429/450]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CreateWithEmptySize   
)

Definition at line 115 of file render_target_cache_unittests.cc.

115 {
116 auto render_target_cache =
117 RenderTargetCache(GetContext()->GetResourceAllocator());
118
119 render_target_cache.Start();
120 RenderTarget empty_target =
121 render_target_cache.CreateOffscreen(*GetContext(), {100, 0}, 1);
122 RenderTarget empty_target_msaa =
123 render_target_cache.CreateOffscreenMSAA(*GetContext(), {0, 0}, 1);
124 render_target_cache.End();
125
126 {
127 ScopedValidationDisable disable_validation;
128 EXPECT_FALSE(empty_target.IsValid());
129 EXPECT_FALSE(empty_target_msaa.IsValid());
130 }
131}

◆ TEST_P() [430/450]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
DoesNotPersistFailedAllocations   
)

Definition at line 75 of file render_target_cache_unittests.cc.

75 {
77 auto allocator = std::make_shared<TestAllocator>();
78 auto render_target_cache = RenderTargetCache(allocator);
79
80 render_target_cache.Start();
81 allocator->should_fail = true;
82
83 auto render_target =
84 render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
85
86 EXPECT_FALSE(render_target.IsValid());
87 EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
88}

◆ TEST_P() [431/450]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanCreatePipelineFromRuntimeStage   
)

Definition at line 314 of file runtime_stage_unittests.cc.

314 {
315 auto stages = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
316 auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
317
318 ASSERT_TRUE(stage);
319 ASSERT_NE(stage, nullptr);
320 ASSERT_TRUE(RegisterStage(*stage));
321 auto library = GetContext()->GetShaderLibrary();
322 using VS = RuntimeEffectVertexShader;
324 desc.SetLabel("Runtime Stage InkSparkle");
325 desc.AddStageEntrypoint(
326 library->GetFunction(VS::kEntrypointName, ShaderStage::kVertex));
327 desc.AddStageEntrypoint(
328 library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment));
329 auto vertex_descriptor = std::make_shared<VertexDescriptor>();
330 vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs,
331 VS::kInterleavedBufferLayout);
332
333 std::array<DescriptorSetLayout, 2> descriptor_set_layouts = {
334 VS::kDescriptorSetLayouts[0],
336 .binding = 64u,
337 .descriptor_type = DescriptorType::kUniformBuffer,
338 .shader_stage = ShaderStage::kFragment,
339 },
340 };
341 vertex_descriptor->RegisterDescriptorSetLayouts(descriptor_set_layouts);
342
343 desc.SetVertexDescriptor(std::move(vertex_descriptor));
344 ColorAttachmentDescriptor color0;
345 color0.format = GetContext()->GetCapabilities()->GetDefaultColorFormat();
346 StencilAttachmentDescriptor stencil0;
347 stencil0.stencil_compare = CompareFunction::kEqual;
348 desc.SetColorAttachmentDescriptor(0u, color0);
349 desc.SetStencilAttachmentDescriptors(stencil0);
350 const auto stencil_fmt =
351 GetContext()->GetCapabilities()->GetDefaultStencilFormat();
352 desc.SetStencilPixelFormat(stencil_fmt);
353 auto pipeline = GetContext()->GetPipelineLibrary()->GetPipeline(desc).Get();
354 ASSERT_NE(pipeline, nullptr);
355}

◆ TEST_P() [432/450]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniforms   
)

Definition at line 55 of file runtime_stage_unittests.cc.

55 {
56 const std::shared_ptr<fml::Mapping> fixture =
57 flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
58 ASSERT_TRUE(fixture);
59 ASSERT_GT(fixture->GetSize(), 0u);
60 auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
61 auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
62
63 ASSERT_TRUE(stage->IsValid());
64 switch (GetBackend()) {
66 [[fallthrough]];
67 case PlaygroundBackend::kOpenGLES: {
68 ASSERT_EQ(stage->GetUniforms().size(), 17u);
69 {
70 auto uni = stage->GetUniform("u_color");
71 ASSERT_NE(uni, nullptr);
72 EXPECT_EQ(uni->dimensions.rows, 4u);
73 EXPECT_EQ(uni->dimensions.cols, 1u);
74 EXPECT_EQ(uni->location, 0u);
75 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
76 }
77 {
78 auto uni = stage->GetUniform("u_alpha");
79 ASSERT_NE(uni, nullptr);
80 EXPECT_EQ(uni->dimensions.rows, 1u);
81 EXPECT_EQ(uni->dimensions.cols, 1u);
82 EXPECT_EQ(uni->location, 1u);
83 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
84 }
85 {
86 auto uni = stage->GetUniform("u_sparkle_color");
87 ASSERT_NE(uni, nullptr);
88 EXPECT_EQ(uni->dimensions.rows, 4u);
89 EXPECT_EQ(uni->dimensions.cols, 1u);
90 EXPECT_EQ(uni->location, 2u);
91 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
92 }
93 {
94 auto uni = stage->GetUniform("u_sparkle_alpha");
95 ASSERT_NE(uni, nullptr);
96 EXPECT_EQ(uni->dimensions.rows, 1u);
97 EXPECT_EQ(uni->dimensions.cols, 1u);
98 EXPECT_EQ(uni->location, 3u);
99 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
100 }
101 {
102 auto uni = stage->GetUniform("u_blur");
103 ASSERT_NE(uni, nullptr);
104 EXPECT_EQ(uni->dimensions.rows, 1u);
105 EXPECT_EQ(uni->dimensions.cols, 1u);
106 EXPECT_EQ(uni->location, 4u);
107 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
108 }
109 {
110 auto uni = stage->GetUniform("u_radius_scale");
111 ASSERT_NE(uni, nullptr);
112 EXPECT_EQ(uni->dimensions.rows, 1u);
113 EXPECT_EQ(uni->dimensions.cols, 1u);
114 EXPECT_EQ(uni->location, 6u);
115 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
116 }
117 {
118 auto uni = stage->GetUniform("u_max_radius");
119 ASSERT_NE(uni, nullptr);
120 EXPECT_EQ(uni->dimensions.rows, 1u);
121 EXPECT_EQ(uni->dimensions.cols, 1u);
122 EXPECT_EQ(uni->location, 7u);
123 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
124 }
125 {
126 auto uni = stage->GetUniform("u_resolution_scale");
127 ASSERT_NE(uni, nullptr);
128 EXPECT_EQ(uni->dimensions.rows, 2u);
129 EXPECT_EQ(uni->dimensions.cols, 1u);
130 EXPECT_EQ(uni->location, 8u);
131 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
132 }
133 {
134 auto uni = stage->GetUniform("u_noise_scale");
135 ASSERT_NE(uni, nullptr);
136 EXPECT_EQ(uni->dimensions.rows, 2u);
137 EXPECT_EQ(uni->dimensions.cols, 1u);
138 EXPECT_EQ(uni->location, 9u);
139 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
140 }
141 {
142 auto uni = stage->GetUniform("u_noise_phase");
143 ASSERT_NE(uni, nullptr);
144 EXPECT_EQ(uni->dimensions.rows, 1u);
145 EXPECT_EQ(uni->dimensions.cols, 1u);
146 EXPECT_EQ(uni->location, 10u);
147 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
148 }
149
150 {
151 auto uni = stage->GetUniform("u_circle1");
152 ASSERT_NE(uni, nullptr);
153 EXPECT_EQ(uni->dimensions.rows, 2u);
154 EXPECT_EQ(uni->dimensions.cols, 1u);
155 EXPECT_EQ(uni->location, 11u);
156 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
157 }
158 {
159 auto uni = stage->GetUniform("u_circle2");
160 ASSERT_NE(uni, nullptr);
161 EXPECT_EQ(uni->dimensions.rows, 2u);
162 EXPECT_EQ(uni->dimensions.cols, 1u);
163 EXPECT_EQ(uni->location, 12u);
164 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
165 }
166 {
167 auto uni = stage->GetUniform("u_circle3");
168 ASSERT_NE(uni, nullptr);
169 EXPECT_EQ(uni->dimensions.rows, 2u);
170 EXPECT_EQ(uni->dimensions.cols, 1u);
171 EXPECT_EQ(uni->location, 13u);
172 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
173 }
174 {
175 auto uni = stage->GetUniform("u_rotation1");
176 ASSERT_NE(uni, nullptr);
177 EXPECT_EQ(uni->dimensions.rows, 2u);
178 EXPECT_EQ(uni->dimensions.cols, 1u);
179 EXPECT_EQ(uni->location, 14u);
180 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
181 }
182 {
183 auto uni = stage->GetUniform("u_rotation2");
184 ASSERT_NE(uni, nullptr);
185 EXPECT_EQ(uni->dimensions.rows, 2u);
186 EXPECT_EQ(uni->dimensions.cols, 1u);
187 EXPECT_EQ(uni->location, 15u);
188 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
189 }
190 {
191 auto uni = stage->GetUniform("u_rotation3");
192 ASSERT_NE(uni, nullptr);
193 EXPECT_EQ(uni->dimensions.rows, 2u);
194 EXPECT_EQ(uni->dimensions.cols, 1u);
195 EXPECT_EQ(uni->location, 16u);
196 EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
197 }
198 break;
199 }
201 EXPECT_EQ(stage->GetUniforms().size(), 1u);
202 auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
203 ASSERT_TRUE(uni);
204 EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
205 EXPECT_EQ(uni->struct_float_count, 32u);
206
207 // There are 36 4 byte chunks in the UBO: 32 for the 32 floats, and 4 for
208 // padding. Initialize a vector as if they'll all be floats, then manually
209 // set the few padding bytes. If the shader changes, the padding locations
210 // will change as well. For example, if `u_alpha` was moved to the end,
211 // three bytes of padding could potentially be dropped - or if some of the
212 // scalar floats were changed to vec2 or vec4s, or if any vec3s are
213 // introduced.
214 // This means 36 * 4 = 144 bytes total.
215
216 EXPECT_EQ(uni->GetSize(), 144u);
217 std::vector<uint8_t> layout(uni->GetSize() / sizeof(float), 1);
218 layout[5] = 0;
219 layout[6] = 0;
220 layout[7] = 0;
221 layout[23] = 0;
222
223 EXPECT_THAT(uni->struct_layout, ::testing::ElementsAreArray(layout));
224 break;
225 }
226 }
227}

◆ TEST_P() [433/450]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniformsSamplerAfterUBO   
)

Definition at line 254 of file runtime_stage_unittests.cc.

254 {
255 if (GetBackend() != PlaygroundBackend::kVulkan) {
256 GTEST_SKIP() << "Test only relevant for Vulkan";
257 }
258 const std::shared_ptr<fml::Mapping> fixture =
260 "uniforms_and_sampler_2.frag.iplr");
261 ASSERT_TRUE(fixture);
262 ASSERT_GT(fixture->GetSize(), 0u);
263 auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
264 auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
265
266 EXPECT_EQ(stage->GetUniforms().size(), 2u);
267 auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
268 ASSERT_TRUE(uni);
269 // Struct must be offset at 45.
270 EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
271 EXPECT_EQ(uni->binding, 64u);
272 // Sampler should be offset at 64 but due to current bug
273 // has offset of 0, the correct offset is computed at runtime.
274 auto sampler_uniform = stage->GetUniform("u_texture");
275 EXPECT_EQ(sampler_uniform->type, RuntimeUniformType::kSampledImage);
276 EXPECT_EQ(sampler_uniform->binding, 65u);
277}

◆ TEST_P() [434/450]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniformsSamplerBeforeUBO   
)

Definition at line 229 of file runtime_stage_unittests.cc.

229 {
230 if (GetBackend() != PlaygroundBackend::kVulkan) {
231 GTEST_SKIP() << "Test only relevant for Vulkan";
232 }
233 const std::shared_ptr<fml::Mapping> fixture =
235 "uniforms_and_sampler_1.frag.iplr");
236 ASSERT_TRUE(fixture);
237 ASSERT_GT(fixture->GetSize(), 0u);
238 auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
239 auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
240
241 EXPECT_EQ(stage->GetUniforms().size(), 2u);
242 auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
243 ASSERT_TRUE(uni);
244 // Struct must be offset at 65.
245 EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
246 EXPECT_EQ(uni->binding, 65u);
247 // Sampler should be offset at 64 but due to current bug
248 // has offset of 0, the correct offset is computed at runtime.
249 auto sampler_uniform = stage->GetUniform("u_texture");
250 EXPECT_EQ(sampler_uniform->type, RuntimeUniformType::kSampledImage);
251 EXPECT_EQ(sampler_uniform->binding, 64u);
252}

◆ TEST_P() [435/450]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadValidBlob   
)

Definition at line 29 of file runtime_stage_unittests.cc.

29 {
30 const std::shared_ptr<fml::Mapping> fixture =
31 flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
32 ASSERT_TRUE(fixture);
33 ASSERT_GT(fixture->GetSize(), 0u);
34 auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
35 auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
36 ASSERT_TRUE(stage->IsValid());
37 ASSERT_EQ(stage->GetShaderStage(), RuntimeShaderStage::kFragment);
38}

◆ TEST_P() [436/450]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanRegisterStage   
)

Definition at line 279 of file runtime_stage_unittests.cc.

279 {
280 const std::shared_ptr<fml::Mapping> fixture =
281 flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
282 ASSERT_TRUE(fixture);
283 ASSERT_GT(fixture->GetSize(), 0u);
284 auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
285 auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
286 ASSERT_TRUE(stage->IsValid());
287 std::promise<bool> registration;
288 auto future = registration.get_future();
289 auto library = GetContext()->GetShaderLibrary();
290 library->RegisterFunction(
291 stage->GetEntrypoint(), //
292 ToShaderStage(stage->GetShaderStage()), //
293 stage->GetCodeMapping(), //
294 fml::MakeCopyable([reg = std::move(registration)](bool result) mutable {
295 reg.set_value(result);
296 }));
297 ASSERT_TRUE(future.get());
298 {
299 auto function =
300 library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
301 ASSERT_NE(function, nullptr);
302 }
303
304 // Check if unregistering works.
305
306 library->UnregisterFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
307 {
308 auto function =
309 library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
310 ASSERT_EQ(function, nullptr);
311 }
312}
internal::CopyableLambda< T > MakeCopyable(T lambda)
Definition: make_copyable.h:57
constexpr ShaderStage ToShaderStage(RuntimeShaderStage stage)
Definition: shader_types.h:29

◆ TEST_P() [437/450]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanRejectInvalidBlob   
)

Definition at line 40 of file runtime_stage_unittests.cc.

40 {
41 ScopedValidationDisable disable_validation;
42 const std::shared_ptr<fml::Mapping> fixture =
43 flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
44 ASSERT_TRUE(fixture);
45 auto junk_allocation = std::make_shared<Allocation>();
46 ASSERT_TRUE(junk_allocation->Truncate(fixture->GetSize(), false));
47 // Not meant to be secure. Just reject obviously bad blobs using magic
48 // numbers.
49 ::memset(junk_allocation->GetBuffer(), 127, junk_allocation->GetLength());
50 auto stages = RuntimeStage::DecodeRuntimeStages(
51 CreateMappingFromAllocation(junk_allocation));
52 ASSERT_FALSE(stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())]);
53}
std::shared_ptr< fml::Mapping > CreateMappingFromAllocation(const std::shared_ptr< Allocation > &allocation)
Definition: allocation.cc:99

◆ TEST_P() [438/450]

impeller::testing::TEST_P ( RuntimeStageTest  ,
ContainsExpectedShaderTypes   
)

Definition at line 357 of file runtime_stage_unittests.cc.

357 {
358 auto stages = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
359 // Right now, SkSL gets implicitly bundled regardless of what the build rule
360 // for this test requested. After
361 // https://github.com/flutter/flutter/issues/138919, this may require a build
362 // rule change or a new test.
363 EXPECT_TRUE(stages[RuntimeStageBackend::kSkSL]);
364
365 EXPECT_TRUE(stages[RuntimeStageBackend::kOpenGLES]);
368}

◆ TEST_P() [439/450]

impeller::testing::TEST_P ( TypographerTest  ,
CanConvertTextBlob   
)

Definition at line 65 of file typographer_unittests.cc.

65 {
68 "the quick brown fox jumped over the lazy dog.", font);
69 ASSERT_TRUE(blob);
71 ASSERT_EQ(frame->GetRunCount(), 1u);
72 for (const auto& run : frame->GetRuns()) {
73 ASSERT_TRUE(run.IsValid());
74 ASSERT_EQ(run.GetGlyphCount(), 45u);
75 }
76}
font
Font Metadata and Metrics.
Definition: run.py:1

◆ TEST_P() [440/450]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateGlyphAtlas   
)

Definition at line 83 of file typographer_unittests.cc.

83 {
84 auto context = TypographerContextSkia::Make();
85 auto atlas_context =
86 context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
87 auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
88 ASSERT_TRUE(context && context->IsValid());
90 auto blob = SkTextBlob::MakeFromString("hello", sk_font);
91 ASSERT_TRUE(blob);
92 auto atlas =
93 CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
94 GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
96 ASSERT_NE(atlas, nullptr);
97 ASSERT_NE(atlas->GetTexture(), nullptr);
98 ASSERT_EQ(atlas->GetType(), GlyphAtlas::Type::kAlphaBitmap);
99 ASSERT_EQ(atlas->GetGlyphCount(), 4llu);
100
101 std::optional<impeller::ScaledFont> first_scaled_font;
102 std::optional<impeller::SubpixelGlyph> first_glyph;
103 Rect first_rect;
104 atlas->IterateGlyphs([&](const ScaledFont& scaled_font,
105 const SubpixelGlyph& glyph,
106 const Rect& rect) -> bool {
107 first_scaled_font = scaled_font;
108 first_glyph = glyph;
109 first_rect = rect;
110 return false;
111 });
112
113 ASSERT_TRUE(first_scaled_font.has_value());
114 ASSERT_TRUE(atlas
115 ->FindFontGlyphBounds(
116 {first_scaled_font.value(), first_glyph.value()})
117 .has_value());
118}
static std::shared_ptr< GlyphAtlas > CreateGlyphAtlas(Context &context, const TypographerContext *typographer_context, HostBuffer &host_buffer, GlyphAtlas::Type type, Scalar scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const std::vector< std::shared_ptr< TextFrame > > &frames, const std::vector< GlyphProperties > &properties)
A font and a scale. Used as a key that represents a typeface within a glyph atlas.
A glyph and its subpixel position.

◆ TEST_P() [441/450]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateRenderContext   
)

Definition at line 78 of file typographer_unittests.cc.

78 {
79 auto context = TypographerContextSkia::Make();
80 ASSERT_TRUE(context && context->IsValid());
81}

◆ TEST_P() [442/450]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasIsRecycledIfUnchanged   
)

Definition at line 179 of file typographer_unittests.cc.

179 {
180 auto context = TypographerContextSkia::Make();
181 auto atlas_context =
182 context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
183 auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
184 ASSERT_TRUE(context && context->IsValid());
186 auto blob = SkTextBlob::MakeFromString("spooky skellingtons", sk_font);
187 ASSERT_TRUE(blob);
188 auto atlas =
189 CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
190 GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
192 ASSERT_NE(atlas, nullptr);
193 ASSERT_NE(atlas->GetTexture(), nullptr);
194 ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
195
196 // now attempt to re-create an atlas with the same text blob.
197
198 auto next_atlas =
199 CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
200 GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
202 ASSERT_EQ(atlas, next_atlas);
203 ASSERT_EQ(atlas_context->GetGlyphAtlas(), atlas);
204}

◆ TEST_P() [443/450]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureIsRecycledIfUnchanged   
)

Definition at line 253 of file typographer_unittests.cc.

253 {
254 auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
255 auto context = TypographerContextSkia::Make();
256 auto atlas_context =
257 context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
258 ASSERT_TRUE(context && context->IsValid());
260 auto blob = SkTextBlob::MakeFromString("spooky 1", sk_font);
261 ASSERT_TRUE(blob);
262 auto atlas =
263 CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
264 GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
266 auto old_packer = atlas_context->GetRectPacker();
267
268 ASSERT_NE(atlas, nullptr);
269 ASSERT_NE(atlas->GetTexture(), nullptr);
270 ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
271
272 auto* first_texture = atlas->GetTexture().get();
273
274 // Now create a new glyph atlas with a nearly identical blob.
275
276 auto blob2 = SkTextBlob::MakeFromString("spooky 2", sk_font);
277 auto next_atlas =
278 CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
279 GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
281 ASSERT_EQ(atlas, next_atlas);
282 auto* second_texture = next_atlas->GetTexture().get();
283
284 auto new_packer = atlas_context->GetRectPacker();
285
286 ASSERT_EQ(second_texture, first_texture);
287 ASSERT_EQ(old_packer, new_packer);
288}

◆ TEST_P() [444/450]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureWillGrowTilMaxTextureSize   
)

Definition at line 419 of file typographer_unittests.cc.

419 {
420 if (GetBackend() == PlaygroundBackend::kOpenGLES) {
421 GTEST_SKIP() << "Atlas growth isn't supported for OpenGLES currently.";
422 }
423
424 auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
425 auto context = TypographerContextSkia::Make();
426 auto atlas_context =
427 context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
428 ASSERT_TRUE(context && context->IsValid());
430 auto blob = SkTextBlob::MakeFromString("A", sk_font);
431 ASSERT_TRUE(blob);
432 auto atlas =
433 CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
434 GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
436 // Continually append new glyphs until the glyph size grows to the maximum.
437 // Note that the sizes here are more or less experimentally determined, but
438 // the important expectation is that the atlas size will shrink again after
439 // growing to the maximum size.
440 constexpr ISize expected_sizes[13] = {
441 {4096, 4096}, //
442 {4096, 4096}, //
443 {4096, 8192}, //
444 {4096, 8192}, //
445 {4096, 8192}, //
446 {4096, 8192}, //
447 {4096, 16384}, //
448 {4096, 16384}, //
449 {4096, 16384}, //
450 {4096, 16384}, //
451 {4096, 16384}, //
452 {4096, 16384}, //
453 {4096, 4096} // Shrinks!
454 };
455
456 for (int i = 0; i < 13; i++) {
458 auto blob = SkTextBlob::MakeFromString("A", sk_font);
459
460 atlas =
461 CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
462 GlyphAtlas::Type::kAlphaBitmap, 50 + i, atlas_context,
464 ASSERT_TRUE(!!atlas);
465 EXPECT_EQ(atlas->GetTexture()->GetTextureDescriptor().size,
466 expected_sizes[i]);
467 }
468}

◆ TEST_P() [445/450]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithLotsOfdUniqueGlyphSize   
)

Definition at line 206 of file typographer_unittests.cc.

206 {
207 auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
208 auto context = TypographerContextSkia::Make();
209 auto atlas_context =
210 context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
211 ASSERT_TRUE(context && context->IsValid());
212
213 const char* test_string =
214 "QWERTYUIOPASDFGHJKLZXCVBNMqewrtyuiopasdfghjklzxcvbnm,.<>[]{};':"
215 "2134567890-=!@#$%^&*()_+"
216 "œ∑´®†¥¨ˆøπ““‘‘åß∂ƒ©˙∆˚¬…æ≈ç√∫˜µ≤≥≥≥≥÷¡™£¢∞§¶•ªº–≠⁄€‹›fifl‡°·‚—±Œ„´‰Á¨Ø∏”’/"
217 "* Í˝ */¸˛Ç◊ı˜Â¯˘¿";
218
220 auto blob = SkTextBlob::MakeFromString(test_string, sk_font);
221 ASSERT_TRUE(blob);
222
223 FontGlyphMap font_glyph_map;
224 size_t size_count = 8;
225 for (size_t index = 0; index < size_count; index += 1) {
226 MakeTextFrameFromTextBlobSkia(blob)->CollectUniqueFontGlyphPairs(
227 font_glyph_map, 0.6 * index, {0, 0}, {});
228 };
229 auto atlas =
230 context->CreateGlyphAtlas(*GetContext(), GlyphAtlas::Type::kAlphaBitmap,
231 *host_buffer, atlas_context, font_glyph_map);
232 ASSERT_NE(atlas, nullptr);
233 ASSERT_NE(atlas->GetTexture(), nullptr);
234
235 std::set<uint16_t> unique_glyphs;
236 std::vector<uint16_t> total_glyphs;
237 atlas->IterateGlyphs([&](const ScaledFont& scaled_font,
238 const SubpixelGlyph& glyph, const Rect& rect) {
239 unique_glyphs.insert(glyph.glyph.index);
240 total_glyphs.push_back(glyph.glyph.index);
241 return true;
242 });
243
244 // These numbers may be different due to subpixel positions.
245 EXPECT_LE(unique_glyphs.size() * size_count, atlas->GetGlyphCount());
246 EXPECT_EQ(total_glyphs.size(), atlas->GetGlyphCount());
247
248 EXPECT_TRUE(atlas->GetGlyphCount() > 0);
249 EXPECT_TRUE(atlas->GetTexture()->GetSize().width > 0);
250 EXPECT_TRUE(atlas->GetTexture()->GetSize().height > 0);
251}
int width() const
Definition: SkImage.h:285
int height() const
Definition: SkImage.h:291

◆ TEST_P() [446/450]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithOddUniqueGlyphSize   
)

Definition at line 159 of file typographer_unittests.cc.

159 {
160 auto context = TypographerContextSkia::Make();
161 auto atlas_context =
162 context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
163 auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
164 ASSERT_TRUE(context && context->IsValid());
166 auto blob = SkTextBlob::MakeFromString("AGH", sk_font);
167 ASSERT_TRUE(blob);
168 auto atlas =
169 CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
170 GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
172 ASSERT_NE(atlas, nullptr);
173 ASSERT_NE(atlas->GetTexture(), nullptr);
174
175 EXPECT_EQ(atlas->GetTexture()->GetSize().width, 4096u);
176 EXPECT_EQ(atlas->GetTexture()->GetSize().height, 1024u);
177}

◆ TEST_P() [447/450]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphColorIsIgnoredForNonEmojiFonts   
)

Definition at line 324 of file typographer_unittests.cc.

324 {
325 auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
327 sk_sp<SkTypeface> typeface =
328 font_mgr->matchFamilyStyle("Arial", SkFontStyle::Normal());
329 SkFont sk_font(typeface, 0.5f);
330
331 auto context = TypographerContextSkia::Make();
332 auto atlas_context =
333 context->CreateGlyphAtlasContext(GlyphAtlas::Type::kColorBitmap);
334
335 // Create two frames with the same character and a different color, but as a
336 // non-emoji font the text frame constructor will ignore it.
337 auto frame =
339 auto frame_2 =
341 auto properties = {
344 };
345
346 auto next_atlas =
347 CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
348 GlyphAtlas::Type::kColorBitmap, 1.0f, atlas_context,
349 {frame, frame_2}, properties);
350
351 EXPECT_EQ(next_atlas->GetGlyphCount(), 1u);
352}
sk_sp< SkTypeface > matchFamilyStyle(const char familyName[], const SkFontStyle &) const
Definition: SkFontMgr.cpp:109
static constexpr SkFontStyle Normal()
Definition: SkFontStyle.h:66

◆ TEST_P() [448/450]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphColorIsPartOfCacheKey   
)

Definition at line 290 of file typographer_unittests.cc.

290 {
291 auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
292#if FML_OS_MACOSX
293 auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc");
294#else
295 auto mapping = flutter::testing::OpenFixtureAsSkData("NotoColorEmoji.ttf");
296#endif
297 ASSERT_TRUE(mapping);
299 SkFont emoji_font(font_mgr->makeFromData(mapping), 50.0);
300
301 auto context = TypographerContextSkia::Make();
302 auto atlas_context =
303 context->CreateGlyphAtlasContext(GlyphAtlas::Type::kColorBitmap);
304
305 // Create two frames with the same character and a different color, expect
306 // that it adds a character.
308 SkTextBlob::MakeFromString("😂", emoji_font));
309 auto frame_2 = MakeTextFrameFromTextBlobSkia(
310 SkTextBlob::MakeFromString("😂", emoji_font));
311 auto properties = {
312 GlyphProperties{.color = Color::Red()},
313 GlyphProperties{.color = Color::Blue()},
314 };
315
316 auto next_atlas =
317 CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
318 GlyphAtlas::Type::kColorBitmap, 1.0f, atlas_context,
319 {frame, frame_2}, properties);
320
321 EXPECT_EQ(next_atlas->GetGlyphCount(), 2u);
322}

◆ TEST_P() [449/450]

impeller::testing::TEST_P ( TypographerTest  ,
LazyAtlasTracksColor   
)

Definition at line 120 of file typographer_unittests.cc.

120 {
121 auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
122#if FML_OS_MACOSX
123 auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc");
124#else
125 auto mapping = flutter::testing::OpenFixtureAsSkData("NotoColorEmoji.ttf");
126#endif
127 ASSERT_TRUE(mapping);
129 SkFont emoji_font(font_mgr->makeFromData(mapping), 50.0);
131
132 auto blob = SkTextBlob::MakeFromString("hello", sk_font);
133 ASSERT_TRUE(blob);
135
136 ASSERT_FALSE(frame->GetAtlasType() == GlyphAtlas::Type::kColorBitmap);
137
139
140 lazy_atlas.AddTextFrame(*frame, 1.0f, {0, 0}, {});
141
143 SkTextBlob::MakeFromString("😀 ", emoji_font));
144
145 ASSERT_TRUE(frame->GetAtlasType() == GlyphAtlas::Type::kColorBitmap);
146
147 lazy_atlas.AddTextFrame(*frame, 1.0f, {0, 0}, {});
148
149 // Creates different atlases for color and red bitmap.
150 auto color_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
151 *GetContext(), *host_buffer, GlyphAtlas::Type::kColorBitmap);
152
153 auto bitmap_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
154 *GetContext(), *host_buffer, GlyphAtlas::Type::kAlphaBitmap);
155
156 ASSERT_FALSE(color_atlas == bitmap_atlas);
157}

◆ TEST_P() [450/450]

impeller::testing::TEST_P ( TypographerTest  ,
RectanglePackerAddsNonoverlapingRectangles   
)

Definition at line 354 of file typographer_unittests.cc.

354 {
355 auto packer = RectanglePacker::Factory(200, 100);
356 ASSERT_NE(packer, nullptr);
357 ASSERT_EQ(packer->PercentFull(), 0);
358
359 const SkIRect packer_area = SkIRect::MakeXYWH(0, 0, 200, 100);
360
361 IPoint16 first_output = {-1, -1}; // Fill with sentinel values
362 ASSERT_TRUE(packer->AddRect(20, 20, &first_output));
363 // Make sure the rectangle is placed such that it is inside the bounds of
364 // the packer's area.
365 const SkIRect first_rect =
366 SkIRect::MakeXYWH(first_output.x(), first_output.y(), 20, 20);
367 ASSERT_TRUE(SkIRect::Intersects(packer_area, first_rect));
368
369 // Initial area was 200 x 100 = 20_000
370 // We added 20x20 = 400. 400 / 20_000 == 0.02 == 2%
371 ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.02));
372
373 IPoint16 second_output = {-1, -1};
374 ASSERT_TRUE(packer->AddRect(140, 90, &second_output));
375 const SkIRect second_rect =
376 SkIRect::MakeXYWH(second_output.x(), second_output.y(), 140, 90);
377 // Make sure the rectangle is placed such that it is inside the bounds of
378 // the packer's area but not in the are of the first rectangle.
379 ASSERT_TRUE(SkIRect::Intersects(packer_area, second_rect));
380 ASSERT_FALSE(SkIRect::Intersects(first_rect, second_rect));
381
382 // We added another 90 x 140 = 12_600 units, now taking us to 13_000
383 // 13_000 / 20_000 == 0.65 == 65%
384 ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.65));
385
386 // There's enough area to add this rectangle, but no space big enough for
387 // the 50 units of width.
388 IPoint16 output;
389 ASSERT_FALSE(packer->AddRect(50, 50, &output));
390 // Should be unchanged.
391 ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.65));
392
393 packer->Reset();
394 // Should be empty now.
395 ASSERT_EQ(packer->PercentFull(), 0);
396}
bool NumberNear(double a, double b)
Definition: assertions.h:13
Definition: SkRect.h:32
static bool Intersects(const SkIRect &a, const SkIRect &b)
Definition: SkRect.h:535

◆ toColor()

flutter::DlColor impeller::testing::toColor ( const float *  components)

Definition at line 41 of file dl_unittests.cc.

41 {
42 return flutter::DlColor(Color::ToIColor(
43 Color(components[0], components[1], components[2], components[3])));
44}

Variable Documentation

◆ g_extensions

std::vector<const unsigned char*> impeller::testing::g_extensions
static

Definition at line 24 of file mock_gles.cc.

◆ g_mock_gles

std::weak_ptr<MockGLES> impeller::testing::g_mock_gles
static

Definition at line 20 of file mock_gles.cc.

◆ g_resolver

ProcTableGLES::Resolver impeller::testing::g_resolver
static

Definition at line 22 of file mock_gles.cc.

◆ g_test_lock

std::mutex impeller::testing::g_test_lock
static

Definition at line 18 of file mock_gles.cc.

◆ g_version

const unsigned char* impeller::testing::g_version
static

Definition at line 26 of file mock_gles.cc.

◆ golden_cubic_and_quad_points

std::vector<Point> impeller::testing::golden_cubic_and_quad_points

Definition at line 16 of file golden_paths.h.

◆ kExtensions

auto const impeller::testing::kExtensions
Initial value:
= std::vector<const unsigned char*>{
(unsigned char*)"GL_KHR_debug"
}

Definition at line 46 of file mock_gles.cc.

◆ kFontFixture

constexpr std::string_view impeller::testing::kFontFixture
staticconstexpr
Initial value:
=
"NotoColorEmoji.ttf"

Definition at line 728 of file aiks_unittests.cc.

◆ kMockResolverGLES

const ProcTableGLES::Resolver impeller::testing::kMockResolverGLES
Initial value:
= [](const char* name) {
if (strcmp(name, "glPopDebugGroupKHR") == 0) {
return reinterpret_cast<void*>(&mockPopDebugGroupKHR);
} else if (strcmp(name, "glPushDebugGroupKHR") == 0) {
return reinterpret_cast<void*>(&mockPushDebugGroupKHR);
} else if (strcmp(name, "glGetString") == 0) {
return reinterpret_cast<void*>(&mockGetString);
} else if (strcmp(name, "glGetStringi") == 0) {
return reinterpret_cast<void*>(&mockGetStringi);
} else if (strcmp(name, "glGetIntegerv") == 0) {
return reinterpret_cast<void*>(&mockGetIntegerv);
} else if (strcmp(name, "glGetError") == 0) {
return reinterpret_cast<void*>(&mockGetError);
} else if (strcmp(name, "glGenQueriesEXT") == 0) {
return reinterpret_cast<void*>(&mockGenQueriesEXT);
} else if (strcmp(name, "glBeginQueryEXT") == 0) {
return reinterpret_cast<void*>(&mockBeginQueryEXT);
} else if (strcmp(name, "glEndQueryEXT") == 0) {
return reinterpret_cast<void*>(&mockEndQueryEXT);
} else if (strcmp(name, "glDeleteQueriesEXT") == 0) {
return reinterpret_cast<void*>(&mockDeleteQueriesEXT);
} else if (strcmp(name, "glGetQueryObjectui64vEXT") == 0) {
return reinterpret_cast<void*>(mockGetQueryObjectui64vEXT);
} else if (strcmp(name, "glGetQueryObjectuivEXT") == 0) {
return reinterpret_cast<void*>(mockGetQueryObjectuivEXT);
} else {
return reinterpret_cast<void*>(&doNothing);
}
}
void mockDeleteQueriesEXT(GLsizei size, const GLuint *queries)
Definition: mock_gles.cc:159
void mockGetQueryObjectuivEXT(GLuint id, GLenum target, GLuint *result)
Definition: mock_gles.cc:143
GLenum mockGetError()
Definition: mock_gles.cc:95
void mockPopDebugGroupKHR()
Definition: mock_gles.cc:102
const unsigned char * mockGetStringi(GLenum name, GLuint index)
Definition: mock_gles.cc:66
void mockGetIntegerv(GLenum name, int *value)
Definition: mock_gles.cc:78
void mockGetQueryObjectui64vEXT(GLuint id, GLenum target, GLuint64 *result)
Definition: mock_gles.cc:151
void mockPushDebugGroupKHR(GLenum source, GLuint id, GLsizei length, const GLchar *message)
Definition: mock_gles.cc:109
void mockEndQueryEXT(GLuint id)
Definition: mock_gles.cc:136
void mockGenQueriesEXT(GLsizei n, GLuint *ids)
Definition: mock_gles.cc:119
const unsigned char * mockGetString(GLenum name)
Definition: mock_gles.cc:50
void mockBeginQueryEXT(GLenum target, GLuint id)
Definition: mock_gles.cc:129

Definition at line 180 of file mock_gles.cc.

◆ kMockShadingLanguageVersion

const auto impeller::testing::kMockShadingLanguageVersion = (unsigned char*)"GLSL ES 1.0"

Definition at line 45 of file mock_gles.cc.

◆ kMockVendor

auto const impeller::testing::kMockVendor = (unsigned char*)"MockGLES"

Definition at line 44 of file mock_gles.cc.

◆ kPaintVariations

const std::map<std::string, MaskBlurTestConfig> impeller::testing::kPaintVariations
static

Definition at line 378 of file aiks_blur_unittests.cc.