paint_filter.cc 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "cc/paint/paint_filter.h"
  5. #include <string>
  6. #include <utility>
  7. #include <vector>
  8. #include "base/memory/values_equivalent.h"
  9. #include "base/no_destructor.h"
  10. #include "base/notreached.h"
  11. #include "base/stl_util.h"
  12. #include "build/build_config.h"
  13. #include "cc/paint/draw_image.h"
  14. #include "cc/paint/filter_operations.h"
  15. #include "cc/paint/image_provider.h"
  16. #include "cc/paint/paint_image_builder.h"
  17. #include "cc/paint/paint_op_writer.h"
  18. #include "cc/paint/paint_record.h"
  19. #include "cc/paint/scoped_raster_flags.h"
  20. #include "third_party/skia/include/core/SkColorFilter.h"
  21. #include "third_party/skia/include/core/SkColorSpace.h"
  22. #include "third_party/skia/include/core/SkMath.h"
  23. #include "third_party/skia/include/core/SkString.h"
  24. #include "third_party/skia/include/effects/SkImageFilters.h"
  25. #include "third_party/skia/include/effects/SkPerlinNoiseShader.h"
  26. #include "third_party/skia/include/effects/SkRuntimeEffect.h"
  27. #include "third_party/skia/src/effects/imagefilters/SkRuntimeImageFilter.h"
  28. namespace cc {
  29. namespace {
  30. const bool kHasNoDiscardableImages = false;
  31. #if BUILDFLAG(IS_ANDROID)
  32. struct StretchShaderUniforms {
  33. // multiplier to apply to scale effect
  34. float uMaxStretchIntensity;
  35. // Maximum percentage to stretch beyond bounds of target
  36. float uStretchAffectedDistX;
  37. float uStretchAffectedDistY;
  38. // Distance stretched as a function of the normalized overscroll times
  39. // scale intensity
  40. float uDistanceStretchedX;
  41. float uDistanceStretchedY;
  42. float uInverseDistanceStretchedX;
  43. float uInverseDistanceStretchedY;
  44. float uDistDiffX;
  45. // Difference between the peak stretch amount and overscroll amount normalized
  46. float uDistDiffY;
  47. // Horizontal offset represented as a ratio of pixels divided by the target
  48. // width
  49. float uScrollX;
  50. // Vertical offset represented as a ratio of pixels divided by the target
  51. // height
  52. float uScrollY;
  53. // Normalized overscroll amount in the horizontal direction
  54. float uOverscrollX;
  55. // Normalized overscroll amount in the vertical direction
  56. float uOverscrollY;
  57. float viewportWidth; // target height in pixels
  58. float viewportHeight; // target width in pixels
  59. // uInterpolationStrength is the intensity of the interpolation.
  60. // if uInterpolationStrength is 0, then the stretch is constant for all the
  61. // uStretchAffectedDist. if uInterpolationStrength is 1, then stretch
  62. // intensity is interpolated based on the pixel position in the
  63. // uStretchAffectedDist area; The closer we are from the scroll anchor point,
  64. // the more it stretches, and the other way around.
  65. float uInterpolationStrength;
  66. };
  67. const char* kStretchShader = R"(
  68. uniform shader uContentTexture;
  69. // multiplier to apply to scale effect
  70. uniform float uMaxStretchIntensity;
  71. // Maximum percentage to stretch beyond bounds of target
  72. uniform float uStretchAffectedDistX;
  73. uniform float uStretchAffectedDistY;
  74. // Distance stretched as a function of the normalized overscroll times
  75. // scale intensity
  76. uniform float uDistanceStretchedX;
  77. uniform float uDistanceStretchedY;
  78. uniform float uInverseDistanceStretchedX;
  79. uniform float uInverseDistanceStretchedY;
  80. uniform float uDistDiffX;
  81. // Difference between the peak stretch amount and overscroll amount
  82. // normalized
  83. uniform float uDistDiffY;
  84. // Horizontal offset represented as a ratio of pixels divided by the target
  85. // width
  86. uniform float uScrollX;
  87. // Vertical offset represented as a ratio of pixels divided by the target
  88. // height
  89. uniform float uScrollY;
  90. // Normalized overscroll amount in the horizontal direction
  91. uniform float uOverscrollX;
  92. // Normalized overscroll amount in the vertical direction
  93. uniform float uOverscrollY;
  94. uniform float viewportWidth; // target height in pixels
  95. uniform float viewportHeight; // target width in pixels
  96. // uInterpolationStrength is the intensity of the interpolation.
  97. // if uInterpolationStrength is 0, then the stretch is constant for all the
  98. // uStretchAffectedDist. if uInterpolationStrength is 1, then stretch
  99. // intensity is interpolated based on the pixel position in the
  100. // uStretchAffectedDist area; The closer we are from the scroll anchor
  101. // point, the more it stretches, and the other way around.
  102. uniform float uInterpolationStrength;
  103. float easeInCubic(float t, float d) {
  104. float tmp = t * d;
  105. return tmp * tmp * tmp;
  106. }
  107. float computeOverscrollStart(
  108. float inPos,
  109. float overscroll,
  110. float uStretchAffectedDist,
  111. float uInverseStretchAffectedDist,
  112. float distanceStretched,
  113. float interpolationStrength
  114. ) {
  115. float offsetPos = uStretchAffectedDist - inPos;
  116. float posBasedVariation = mix(
  117. 1. ,easeInCubic(offsetPos, uInverseStretchAffectedDist),
  118. interpolationStrength);
  119. float stretchIntensity = overscroll * posBasedVariation;
  120. return distanceStretched - (offsetPos / (1. + stretchIntensity));
  121. }
  122. float computeOverscrollEnd(
  123. float inPos,
  124. float overscroll,
  125. float reverseStretchDist,
  126. float uStretchAffectedDist,
  127. float uInverseStretchAffectedDist,
  128. float distanceStretched,
  129. float interpolationStrength
  130. ) {
  131. float offsetPos = inPos - reverseStretchDist;
  132. float posBasedVariation = mix(
  133. 1. ,easeInCubic(offsetPos, uInverseStretchAffectedDist),
  134. interpolationStrength);
  135. float stretchIntensity = (-overscroll) * posBasedVariation;
  136. return 1 - (distanceStretched - (offsetPos / (1. + stretchIntensity)));
  137. }
  138. // Prefer usage of return values over out parameters as it enables
  139. // SKSL to properly inline method calls and works around potential GPU
  140. // driver issues on Wembly. See b/182566543 for details
  141. float computeOverscroll(
  142. float inPos,
  143. float overscroll,
  144. float uStretchAffectedDist,
  145. float uInverseStretchAffectedDist,
  146. float distanceStretched,
  147. float distanceDiff,
  148. float interpolationStrength
  149. ) {
  150. float outPos = inPos;
  151. if (overscroll > 0) {
  152. if (inPos <= uStretchAffectedDist) {
  153. outPos = computeOverscrollStart(
  154. inPos,
  155. overscroll,
  156. uStretchAffectedDist,
  157. uInverseStretchAffectedDist,
  158. distanceStretched,
  159. interpolationStrength
  160. );
  161. } else if (inPos >= distanceStretched) {
  162. outPos = distanceDiff + inPos;
  163. }
  164. }
  165. if (overscroll < 0) {
  166. float stretchAffectedDist = 1. - uStretchAffectedDist;
  167. if (inPos >= stretchAffectedDist) {
  168. outPos = computeOverscrollEnd(
  169. inPos,
  170. overscroll,
  171. stretchAffectedDist,
  172. uStretchAffectedDist,
  173. uInverseStretchAffectedDist,
  174. distanceStretched,
  175. interpolationStrength
  176. );
  177. } else if (inPos < stretchAffectedDist) {
  178. outPos = -distanceDiff + inPos;
  179. }
  180. }
  181. return outPos;
  182. }
  183. vec4 main(vec2 coord) {
  184. // Normalize SKSL pixel coordinate into a unit vector
  185. float inU = coord.x / viewportWidth;
  186. float inV = coord.y / viewportHeight;
  187. float outU;
  188. float outV;
  189. float stretchIntensity;
  190. // Add the normalized scroll position within scrolling list
  191. inU += uScrollX;
  192. inV += uScrollY;
  193. outU = inU;
  194. outV = inV;
  195. outU = computeOverscroll(
  196. inU,
  197. uOverscrollX,
  198. uStretchAffectedDistX,
  199. uInverseDistanceStretchedX,
  200. uDistanceStretchedX,
  201. uDistDiffX,
  202. uInterpolationStrength
  203. );
  204. outV = computeOverscroll(
  205. inV,
  206. uOverscrollY,
  207. uStretchAffectedDistY,
  208. uInverseDistanceStretchedY,
  209. uDistanceStretchedY,
  210. uDistDiffY,
  211. uInterpolationStrength
  212. );
  213. coord.x = outU * viewportWidth;
  214. coord.y = outV * viewportHeight;
  215. return uContentTexture.eval(coord);
  216. })";
  217. static const float CONTENT_DISTANCE_STRETCHED = 1.f;
  218. static const float INTERPOLATION_STRENGTH_VALUE = 0.7f;
  219. sk_sp<SkRuntimeEffect> getStretchEffect() {
  220. static base::NoDestructor<SkRuntimeEffect::Result> effect(
  221. SkRuntimeEffect::MakeForShader(SkString(kStretchShader)));
  222. return effect->effect;
  223. }
  224. #endif
  225. bool AreScalarsEqual(SkScalar one, SkScalar two) {
  226. return PaintOp::AreEqualEvenIfNaN(one, two);
  227. }
  228. bool HasDiscardableImages(const sk_sp<PaintFilter>& filter) {
  229. return filter ? filter->has_discardable_images() : false;
  230. }
  231. bool HasDiscardableImages(const sk_sp<PaintFilter>* const filters, int count) {
  232. for (int i = 0; i < count; ++i) {
  233. if (filters[i] && filters[i]->has_discardable_images())
  234. return true;
  235. }
  236. return false;
  237. }
  238. sk_sp<PaintFilter> Snapshot(const sk_sp<PaintFilter>& filter,
  239. ImageProvider* image_provider) {
  240. if (!filter)
  241. return nullptr;
  242. return filter->SnapshotWithImages(image_provider);
  243. }
  244. } // namespace
  245. PaintFilter::PaintFilter(Type type,
  246. const CropRect* crop_rect,
  247. bool has_discardable_images)
  248. : type_(type), has_discardable_images_(has_discardable_images) {
  249. if (crop_rect)
  250. crop_rect_.emplace(*crop_rect);
  251. }
  252. PaintFilter::~PaintFilter() = default;
  253. // static
  254. std::string PaintFilter::TypeToString(Type type) {
  255. switch (type) {
  256. case Type::kNullFilter:
  257. return "kNullFilter";
  258. case Type::kColorFilter:
  259. return "kColorFilter";
  260. case Type::kBlur:
  261. return "kBlur";
  262. case Type::kDropShadow:
  263. return "kDropShadow";
  264. case Type::kMagnifier:
  265. return "kMagnifier";
  266. case Type::kCompose:
  267. return "kCompose";
  268. case Type::kAlphaThreshold:
  269. return "kAlphaThreshold";
  270. case Type::kXfermode:
  271. return "kXfermode";
  272. case Type::kArithmetic:
  273. return "kArithmetic";
  274. case Type::kMatrixConvolution:
  275. return "kMatrixConvolution";
  276. case Type::kDisplacementMapEffect:
  277. return "kDisplacementMapEffect";
  278. case Type::kImage:
  279. return "kImage";
  280. case Type::kPaintRecord:
  281. return "kPaintRecord";
  282. case Type::kMerge:
  283. return "kMerge";
  284. case Type::kMorphology:
  285. return "kMorphology";
  286. case Type::kOffset:
  287. return "kOffset";
  288. case Type::kTile:
  289. return "kTile";
  290. case Type::kTurbulence:
  291. return "kTurbulence";
  292. case Type::kShader:
  293. return "kShader";
  294. case Type::kMatrix:
  295. return "kMatrix";
  296. case Type::kLightingDistant:
  297. return "kLightingDistant";
  298. case Type::kLightingPoint:
  299. return "kLightingPoint";
  300. case Type::kLightingSpot:
  301. return "kLightingSpot";
  302. case Type::kStretch:
  303. return "kStretch";
  304. }
  305. NOTREACHED();
  306. return "Unknown";
  307. }
  308. const PaintFilter::CropRect* PaintFilter::GetCropRect() const {
  309. return base::OptionalOrNullptr(crop_rect_);
  310. }
  311. size_t PaintFilter::GetFilterSize(const PaintFilter* filter) {
  312. // A null type is used to indicate no filter.
  313. if (!filter)
  314. return sizeof(uint32_t);
  315. return filter->SerializedSize() + PaintOpWriter::Alignment();
  316. }
  317. size_t PaintFilter::BaseSerializedSize() const {
  318. size_t total_size = 0u;
  319. // Filter type.
  320. total_size += sizeof(uint32_t);
  321. // Bool to indicate whether crop exists.
  322. total_size += sizeof(uint32_t);
  323. if (crop_rect_) {
  324. // CropRect.
  325. total_size += sizeof(*crop_rect_);
  326. }
  327. return total_size;
  328. }
  329. sk_sp<PaintFilter> PaintFilter::SnapshotWithImages(
  330. ImageProvider* image_provider) const {
  331. if (!has_discardable_images_)
  332. return sk_ref_sp<PaintFilter>(this);
  333. return SnapshotWithImagesInternal(image_provider);
  334. }
  335. bool PaintFilter::operator==(const PaintFilter& other) const {
  336. if (type_ != other.type_)
  337. return false;
  338. if (!!crop_rect_ != !!other.crop_rect_)
  339. return false;
  340. if (crop_rect_) {
  341. if (!PaintOp::AreSkRectsEqual(*crop_rect_, *other.crop_rect_)) {
  342. return false;
  343. }
  344. }
  345. switch (type_) {
  346. case Type::kNullFilter:
  347. return true;
  348. case Type::kColorFilter:
  349. return *static_cast<const ColorFilterPaintFilter*>(this) ==
  350. static_cast<const ColorFilterPaintFilter&>(other);
  351. case Type::kBlur:
  352. return *static_cast<const BlurPaintFilter*>(this) ==
  353. static_cast<const BlurPaintFilter&>(other);
  354. case Type::kDropShadow:
  355. return *static_cast<const DropShadowPaintFilter*>(this) ==
  356. static_cast<const DropShadowPaintFilter&>(other);
  357. case Type::kMagnifier:
  358. return *static_cast<const MagnifierPaintFilter*>(this) ==
  359. static_cast<const MagnifierPaintFilter&>(other);
  360. case Type::kCompose:
  361. return *static_cast<const ComposePaintFilter*>(this) ==
  362. static_cast<const ComposePaintFilter&>(other);
  363. case Type::kAlphaThreshold:
  364. return *static_cast<const AlphaThresholdPaintFilter*>(this) ==
  365. static_cast<const AlphaThresholdPaintFilter&>(other);
  366. case Type::kXfermode:
  367. return *static_cast<const XfermodePaintFilter*>(this) ==
  368. static_cast<const XfermodePaintFilter&>(other);
  369. case Type::kArithmetic:
  370. return *static_cast<const ArithmeticPaintFilter*>(this) ==
  371. static_cast<const ArithmeticPaintFilter&>(other);
  372. case Type::kMatrixConvolution:
  373. return *static_cast<const MatrixConvolutionPaintFilter*>(this) ==
  374. static_cast<const MatrixConvolutionPaintFilter&>(other);
  375. case Type::kDisplacementMapEffect:
  376. return *static_cast<const DisplacementMapEffectPaintFilter*>(this) ==
  377. static_cast<const DisplacementMapEffectPaintFilter&>(other);
  378. case Type::kImage:
  379. return *static_cast<const ImagePaintFilter*>(this) ==
  380. static_cast<const ImagePaintFilter&>(other);
  381. case Type::kPaintRecord:
  382. return *static_cast<const RecordPaintFilter*>(this) ==
  383. static_cast<const RecordPaintFilter&>(other);
  384. case Type::kMerge:
  385. return *static_cast<const MergePaintFilter*>(this) ==
  386. static_cast<const MergePaintFilter&>(other);
  387. case Type::kMorphology:
  388. return *static_cast<const MorphologyPaintFilter*>(this) ==
  389. static_cast<const MorphologyPaintFilter&>(other);
  390. case Type::kOffset:
  391. return *static_cast<const OffsetPaintFilter*>(this) ==
  392. static_cast<const OffsetPaintFilter&>(other);
  393. case Type::kTile:
  394. return *static_cast<const TilePaintFilter*>(this) ==
  395. static_cast<const TilePaintFilter&>(other);
  396. case Type::kTurbulence:
  397. return *static_cast<const TurbulencePaintFilter*>(this) ==
  398. static_cast<const TurbulencePaintFilter&>(other);
  399. case Type::kShader:
  400. return *static_cast<const ShaderPaintFilter*>(this) ==
  401. static_cast<const ShaderPaintFilter&>(other);
  402. case Type::kMatrix:
  403. return *static_cast<const MatrixPaintFilter*>(this) ==
  404. static_cast<const MatrixPaintFilter&>(other);
  405. case Type::kLightingDistant:
  406. return *static_cast<const LightingDistantPaintFilter*>(this) ==
  407. static_cast<const LightingDistantPaintFilter&>(other);
  408. case Type::kLightingPoint:
  409. return *static_cast<const LightingPointPaintFilter*>(this) ==
  410. static_cast<const LightingPointPaintFilter&>(other);
  411. case Type::kLightingSpot:
  412. return *static_cast<const LightingSpotPaintFilter*>(this) ==
  413. static_cast<const LightingSpotPaintFilter&>(other);
  414. case Type::kStretch:
  415. return *static_cast<const StretchPaintFilter*>(this) ==
  416. static_cast<const StretchPaintFilter&>(other);
  417. }
  418. NOTREACHED();
  419. return true;
  420. }
  421. ColorFilterPaintFilter::ColorFilterPaintFilter(
  422. sk_sp<SkColorFilter> color_filter,
  423. sk_sp<PaintFilter> input,
  424. const CropRect* crop_rect)
  425. : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
  426. color_filter_(std::move(color_filter)),
  427. input_(std::move(input)) {
  428. DCHECK(color_filter_);
  429. cached_sk_filter_ = SkImageFilters::ColorFilter(
  430. color_filter_, GetSkFilter(input_.get()), crop_rect);
  431. }
  432. ColorFilterPaintFilter::~ColorFilterPaintFilter() = default;
  433. size_t ColorFilterPaintFilter::SerializedSize() const {
  434. base::CheckedNumeric<size_t> total_size = 0u;
  435. total_size += BaseSerializedSize();
  436. total_size += PaintOpWriter::GetFlattenableSize(color_filter_.get());
  437. total_size += GetFilterSize(input_.get());
  438. return total_size.ValueOrDefault(0u);
  439. }
  440. sk_sp<PaintFilter> ColorFilterPaintFilter::SnapshotWithImagesInternal(
  441. ImageProvider* image_provider) const {
  442. return sk_make_sp<ColorFilterPaintFilter>(
  443. color_filter_, Snapshot(input_, image_provider), GetCropRect());
  444. }
  445. bool ColorFilterPaintFilter::operator==(
  446. const ColorFilterPaintFilter& other) const {
  447. return PaintOp::AreSkFlattenablesEqual(color_filter_.get(),
  448. other.color_filter_.get()) &&
  449. base::ValuesEquivalent(input_.get(), other.input_.get());
  450. }
  451. BlurPaintFilter::BlurPaintFilter(SkScalar sigma_x,
  452. SkScalar sigma_y,
  453. SkTileMode tile_mode,
  454. sk_sp<PaintFilter> input,
  455. const CropRect* crop_rect)
  456. : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
  457. sigma_x_(sigma_x),
  458. sigma_y_(sigma_y),
  459. tile_mode_(tile_mode),
  460. input_(std::move(input)) {
  461. cached_sk_filter_ = SkImageFilters::Blur(
  462. sigma_x, sigma_y, tile_mode_, GetSkFilter(input_.get()), crop_rect);
  463. }
  464. BlurPaintFilter::~BlurPaintFilter() = default;
  465. size_t BlurPaintFilter::SerializedSize() const {
  466. base::CheckedNumeric<size_t> total_size =
  467. BaseSerializedSize() + sizeof(sigma_x_) + sizeof(sigma_y_) +
  468. sizeof(tile_mode_);
  469. total_size += GetFilterSize(input_.get());
  470. return total_size.ValueOrDefault(0u);
  471. }
  472. sk_sp<PaintFilter> BlurPaintFilter::SnapshotWithImagesInternal(
  473. ImageProvider* image_provider) const {
  474. return sk_make_sp<BlurPaintFilter>(sigma_x_, sigma_y_, tile_mode_,
  475. Snapshot(input_, image_provider),
  476. GetCropRect());
  477. }
  478. bool BlurPaintFilter::operator==(const BlurPaintFilter& other) const {
  479. return PaintOp::AreEqualEvenIfNaN(sigma_x_, other.sigma_x_) &&
  480. PaintOp::AreEqualEvenIfNaN(sigma_y_, other.sigma_y_) &&
  481. tile_mode_ == other.tile_mode_ &&
  482. base::ValuesEquivalent(input_.get(), other.input_.get());
  483. }
  484. DropShadowPaintFilter::DropShadowPaintFilter(SkScalar dx,
  485. SkScalar dy,
  486. SkScalar sigma_x,
  487. SkScalar sigma_y,
  488. SkColor4f color,
  489. ShadowMode shadow_mode,
  490. sk_sp<PaintFilter> input,
  491. const CropRect* crop_rect)
  492. : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
  493. dx_(dx),
  494. dy_(dy),
  495. sigma_x_(sigma_x),
  496. sigma_y_(sigma_y),
  497. color_(color),
  498. shadow_mode_(shadow_mode),
  499. input_(std::move(input)) {
  500. if (shadow_mode == ShadowMode::kDrawShadowOnly) {
  501. // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
  502. cached_sk_filter_ = SkImageFilters::DropShadowOnly(
  503. dx_, dy_, sigma_x_, sigma_y_, color_.toSkColor(),
  504. GetSkFilter(input_.get()), crop_rect);
  505. } else {
  506. // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
  507. cached_sk_filter_ = SkImageFilters::DropShadow(
  508. dx_, dy_, sigma_x_, sigma_y_, color_.toSkColor(),
  509. GetSkFilter(input_.get()), crop_rect);
  510. }
  511. }
  512. DropShadowPaintFilter::~DropShadowPaintFilter() = default;
  513. size_t DropShadowPaintFilter::SerializedSize() const {
  514. base::CheckedNumeric<size_t> total_size =
  515. BaseSerializedSize() + sizeof(dx_) + sizeof(dy_) + sizeof(sigma_x_) +
  516. sizeof(sigma_y_) + sizeof(color_) + sizeof(shadow_mode_);
  517. total_size += GetFilterSize(input_.get());
  518. return total_size.ValueOrDefault(0u);
  519. }
  520. sk_sp<PaintFilter> DropShadowPaintFilter::SnapshotWithImagesInternal(
  521. ImageProvider* image_provider) const {
  522. return sk_make_sp<DropShadowPaintFilter>(
  523. dx_, dy_, sigma_x_, sigma_y_, color_, shadow_mode_,
  524. Snapshot(input_, image_provider), GetCropRect());
  525. }
  526. bool DropShadowPaintFilter::operator==(
  527. const DropShadowPaintFilter& other) const {
  528. return PaintOp::AreEqualEvenIfNaN(dx_, other.dx_) &&
  529. PaintOp::AreEqualEvenIfNaN(dy_, other.dy_) &&
  530. PaintOp::AreEqualEvenIfNaN(sigma_x_, other.sigma_x_) &&
  531. PaintOp::AreEqualEvenIfNaN(sigma_y_, other.sigma_y_) &&
  532. color_ == other.color_ && shadow_mode_ == other.shadow_mode_ &&
  533. base::ValuesEquivalent(input_.get(), other.input_.get());
  534. }
  535. MagnifierPaintFilter::MagnifierPaintFilter(const SkRect& src_rect,
  536. SkScalar inset,
  537. sk_sp<PaintFilter> input,
  538. const CropRect* crop_rect)
  539. : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
  540. src_rect_(src_rect),
  541. inset_(inset),
  542. input_(std::move(input)) {
  543. cached_sk_filter_ = SkImageFilters::Magnifier(
  544. src_rect_, inset_, GetSkFilter(input_.get()), crop_rect);
  545. }
  546. MagnifierPaintFilter::~MagnifierPaintFilter() = default;
  547. size_t MagnifierPaintFilter::SerializedSize() const {
  548. base::CheckedNumeric<size_t> total_size =
  549. BaseSerializedSize() + sizeof(src_rect_) + sizeof(inset_);
  550. total_size += GetFilterSize(input_.get());
  551. return total_size.ValueOrDefault(0u);
  552. }
  553. sk_sp<PaintFilter> MagnifierPaintFilter::SnapshotWithImagesInternal(
  554. ImageProvider* image_provider) const {
  555. return sk_make_sp<MagnifierPaintFilter>(
  556. src_rect_, inset_, Snapshot(input_, image_provider), GetCropRect());
  557. }
  558. bool MagnifierPaintFilter::operator==(const MagnifierPaintFilter& other) const {
  559. return PaintOp::AreSkRectsEqual(src_rect_, other.src_rect_) &&
  560. PaintOp::AreEqualEvenIfNaN(inset_, other.inset_) &&
  561. base::ValuesEquivalent(input_.get(), other.input_.get());
  562. }
  563. ComposePaintFilter::ComposePaintFilter(sk_sp<PaintFilter> outer,
  564. sk_sp<PaintFilter> inner)
  565. : PaintFilter(Type::kCompose,
  566. nullptr,
  567. HasDiscardableImages(outer) || HasDiscardableImages(inner)),
  568. outer_(std::move(outer)),
  569. inner_(std::move(inner)) {
  570. cached_sk_filter_ = SkImageFilters::Compose(GetSkFilter(outer_.get()),
  571. GetSkFilter(inner_.get()));
  572. }
  573. ComposePaintFilter::~ComposePaintFilter() = default;
  574. size_t ComposePaintFilter::SerializedSize() const {
  575. base::CheckedNumeric<size_t> total_size = BaseSerializedSize();
  576. total_size += GetFilterSize(outer_.get());
  577. total_size += GetFilterSize(inner_.get());
  578. return total_size.ValueOrDefault(0u);
  579. }
  580. sk_sp<PaintFilter> ComposePaintFilter::SnapshotWithImagesInternal(
  581. ImageProvider* image_provider) const {
  582. return sk_make_sp<ComposePaintFilter>(Snapshot(outer_, image_provider),
  583. Snapshot(inner_, image_provider));
  584. }
  585. bool ComposePaintFilter::operator==(const ComposePaintFilter& other) const {
  586. return base::ValuesEquivalent(outer_.get(), other.outer_.get()) &&
  587. base::ValuesEquivalent(inner_.get(), other.inner_.get());
  588. }
  589. AlphaThresholdPaintFilter::AlphaThresholdPaintFilter(const SkRegion& region,
  590. SkScalar inner_min,
  591. SkScalar outer_max,
  592. sk_sp<PaintFilter> input,
  593. const CropRect* crop_rect)
  594. : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
  595. region_(region),
  596. inner_min_(inner_min),
  597. outer_max_(outer_max),
  598. input_(std::move(input)) {
  599. cached_sk_filter_ = SkImageFilters::AlphaThreshold(
  600. region_, inner_min_, outer_max_, GetSkFilter(input_.get()), crop_rect);
  601. }
  602. AlphaThresholdPaintFilter::~AlphaThresholdPaintFilter() = default;
  603. size_t AlphaThresholdPaintFilter::SerializedSize() const {
  604. size_t region_size = region_.writeToMemory(nullptr);
  605. base::CheckedNumeric<size_t> total_size;
  606. total_size = BaseSerializedSize() + sizeof(uint64_t) +
  607. base::bits::AlignUp(region_size, PaintOpWriter::Alignment()) +
  608. sizeof(inner_min_) + sizeof(outer_max_);
  609. total_size += GetFilterSize(input_.get());
  610. return total_size.ValueOrDefault(0u);
  611. }
  612. sk_sp<PaintFilter> AlphaThresholdPaintFilter::SnapshotWithImagesInternal(
  613. ImageProvider* image_provider) const {
  614. return sk_make_sp<AlphaThresholdPaintFilter>(region_, inner_min_, outer_max_,
  615. Snapshot(input_, image_provider),
  616. GetCropRect());
  617. }
  618. bool AlphaThresholdPaintFilter::operator==(
  619. const AlphaThresholdPaintFilter& other) const {
  620. return region_ == other.region_ &&
  621. PaintOp::AreEqualEvenIfNaN(inner_min_, other.inner_min_) &&
  622. PaintOp::AreEqualEvenIfNaN(outer_max_, other.outer_max_) &&
  623. base::ValuesEquivalent(input_.get(), other.input_.get());
  624. }
  625. XfermodePaintFilter::XfermodePaintFilter(SkBlendMode blend_mode,
  626. sk_sp<PaintFilter> background,
  627. sk_sp<PaintFilter> foreground,
  628. const CropRect* crop_rect)
  629. : PaintFilter(
  630. kType,
  631. crop_rect,
  632. HasDiscardableImages(background) || HasDiscardableImages(foreground)),
  633. blend_mode_(blend_mode),
  634. background_(std::move(background)),
  635. foreground_(std::move(foreground)) {
  636. cached_sk_filter_ =
  637. SkImageFilters::Blend(blend_mode_, GetSkFilter(background_.get()),
  638. GetSkFilter(foreground_.get()), crop_rect);
  639. }
  640. XfermodePaintFilter::~XfermodePaintFilter() = default;
  641. size_t XfermodePaintFilter::SerializedSize() const {
  642. base::CheckedNumeric<size_t> total_size =
  643. BaseSerializedSize() + sizeof(blend_mode_);
  644. total_size += GetFilterSize(background_.get());
  645. total_size += GetFilterSize(foreground_.get());
  646. return total_size.ValueOrDefault(0u);
  647. }
  648. sk_sp<PaintFilter> XfermodePaintFilter::SnapshotWithImagesInternal(
  649. ImageProvider* image_provider) const {
  650. return sk_make_sp<XfermodePaintFilter>(
  651. blend_mode_, Snapshot(background_, image_provider),
  652. Snapshot(foreground_, image_provider), GetCropRect());
  653. }
  654. bool XfermodePaintFilter::operator==(const XfermodePaintFilter& other) const {
  655. return blend_mode_ == other.blend_mode_ &&
  656. base::ValuesEquivalent(background_.get(), other.background_.get()) &&
  657. base::ValuesEquivalent(foreground_.get(), other.foreground_.get());
  658. }
  659. ArithmeticPaintFilter::ArithmeticPaintFilter(float k1,
  660. float k2,
  661. float k3,
  662. float k4,
  663. bool enforce_pm_color,
  664. sk_sp<PaintFilter> background,
  665. sk_sp<PaintFilter> foreground,
  666. const CropRect* crop_rect)
  667. : PaintFilter(
  668. kType,
  669. crop_rect,
  670. HasDiscardableImages(background) || HasDiscardableImages(foreground)),
  671. k1_(k1),
  672. k2_(k2),
  673. k3_(k3),
  674. k4_(k4),
  675. enforce_pm_color_(enforce_pm_color),
  676. background_(std::move(background)),
  677. foreground_(std::move(foreground)) {
  678. cached_sk_filter_ = SkImageFilters::Arithmetic(
  679. k1_, k2_, k3_, k4_, enforce_pm_color_, GetSkFilter(background_.get()),
  680. GetSkFilter(foreground_.get()), crop_rect);
  681. }
  682. ArithmeticPaintFilter::~ArithmeticPaintFilter() = default;
  683. size_t ArithmeticPaintFilter::SerializedSize() const {
  684. base::CheckedNumeric<size_t> total_size =
  685. BaseSerializedSize() + sizeof(k1_) + sizeof(k2_) + sizeof(k3_) +
  686. sizeof(k4_) + sizeof(enforce_pm_color_);
  687. total_size += GetFilterSize(background_.get());
  688. total_size += GetFilterSize(foreground_.get());
  689. return total_size.ValueOrDefault(0u);
  690. }
  691. sk_sp<PaintFilter> ArithmeticPaintFilter::SnapshotWithImagesInternal(
  692. ImageProvider* image_provider) const {
  693. return sk_make_sp<ArithmeticPaintFilter>(
  694. k1_, k2_, k3_, k4_, enforce_pm_color_,
  695. Snapshot(background_, image_provider),
  696. Snapshot(foreground_, image_provider), GetCropRect());
  697. }
  698. bool ArithmeticPaintFilter::operator==(
  699. const ArithmeticPaintFilter& other) const {
  700. return PaintOp::AreEqualEvenIfNaN(k1_, other.k1_) &&
  701. PaintOp::AreEqualEvenIfNaN(k2_, other.k2_) &&
  702. PaintOp::AreEqualEvenIfNaN(k3_, other.k3_) &&
  703. PaintOp::AreEqualEvenIfNaN(k4_, other.k4_) &&
  704. enforce_pm_color_ == other.enforce_pm_color_ &&
  705. base::ValuesEquivalent(background_.get(), other.background_.get()) &&
  706. base::ValuesEquivalent(foreground_.get(), other.foreground_.get());
  707. }
  708. MatrixConvolutionPaintFilter::MatrixConvolutionPaintFilter(
  709. const SkISize& kernel_size,
  710. const SkScalar* kernel,
  711. SkScalar gain,
  712. SkScalar bias,
  713. const SkIPoint& kernel_offset,
  714. SkTileMode tile_mode,
  715. bool convolve_alpha,
  716. sk_sp<PaintFilter> input,
  717. const CropRect* crop_rect)
  718. : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
  719. kernel_size_(kernel_size),
  720. gain_(gain),
  721. bias_(bias),
  722. kernel_offset_(kernel_offset),
  723. tile_mode_(tile_mode),
  724. convolve_alpha_(convolve_alpha),
  725. input_(std::move(input)) {
  726. auto len = static_cast<size_t>(
  727. sk_64_mul(kernel_size_.width(), kernel_size_.height()));
  728. kernel_->reserve(len);
  729. for (size_t i = 0; i < len; ++i)
  730. kernel_->push_back(kernel[i]);
  731. cached_sk_filter_ = SkImageFilters::MatrixConvolution(
  732. kernel_size_, kernel, gain_, bias_, kernel_offset_, tile_mode_,
  733. convolve_alpha_, GetSkFilter(input_.get()), crop_rect);
  734. }
  735. MatrixConvolutionPaintFilter::~MatrixConvolutionPaintFilter() = default;
  736. size_t MatrixConvolutionPaintFilter::SerializedSize() const {
  737. base::CheckedNumeric<size_t> total_size =
  738. BaseSerializedSize() + sizeof(kernel_size_) + sizeof(size_t) +
  739. kernel_->size() * sizeof(SkScalar) + sizeof(gain_) + sizeof(bias_) +
  740. sizeof(kernel_offset_) + sizeof(tile_mode_) + sizeof(convolve_alpha_);
  741. total_size += GetFilterSize(input_.get());
  742. return total_size.ValueOrDefault(0u);
  743. }
  744. sk_sp<PaintFilter> MatrixConvolutionPaintFilter::SnapshotWithImagesInternal(
  745. ImageProvider* image_provider) const {
  746. return sk_make_sp<MatrixConvolutionPaintFilter>(
  747. kernel_size_, &kernel_[0], gain_, bias_, kernel_offset_, tile_mode_,
  748. convolve_alpha_, Snapshot(input_, image_provider), GetCropRect());
  749. }
  750. bool MatrixConvolutionPaintFilter::operator==(
  751. const MatrixConvolutionPaintFilter& other) const {
  752. return kernel_size_ == other.kernel_size_ &&
  753. std::equal(kernel_.container().begin(), kernel_.container().end(),
  754. other.kernel_.container().begin(), AreScalarsEqual) &&
  755. PaintOp::AreEqualEvenIfNaN(gain_, other.gain_) &&
  756. PaintOp::AreEqualEvenIfNaN(bias_, other.bias_) &&
  757. kernel_offset_ == other.kernel_offset_ &&
  758. tile_mode_ == other.tile_mode_ &&
  759. convolve_alpha_ == other.convolve_alpha_ &&
  760. base::ValuesEquivalent(input_.get(), other.input_.get());
  761. }
  762. DisplacementMapEffectPaintFilter::DisplacementMapEffectPaintFilter(
  763. SkColorChannel channel_x,
  764. SkColorChannel channel_y,
  765. SkScalar scale,
  766. sk_sp<PaintFilter> displacement,
  767. sk_sp<PaintFilter> color,
  768. const CropRect* crop_rect)
  769. : PaintFilter(
  770. kType,
  771. crop_rect,
  772. HasDiscardableImages(displacement) || HasDiscardableImages(color)),
  773. channel_x_(channel_x),
  774. channel_y_(channel_y),
  775. scale_(scale),
  776. displacement_(std::move(displacement)),
  777. color_(std::move(color)) {
  778. cached_sk_filter_ = SkImageFilters::DisplacementMap(
  779. channel_x_, channel_y_, scale_, GetSkFilter(displacement_.get()),
  780. GetSkFilter(color_.get()), crop_rect);
  781. }
  782. DisplacementMapEffectPaintFilter::~DisplacementMapEffectPaintFilter() = default;
  783. size_t DisplacementMapEffectPaintFilter::SerializedSize() const {
  784. base::CheckedNumeric<size_t> total_size = BaseSerializedSize() +
  785. sizeof(channel_x_) +
  786. sizeof(channel_y_) + sizeof(scale_);
  787. total_size += GetFilterSize(displacement_.get());
  788. total_size += GetFilterSize(color_.get());
  789. return total_size.ValueOrDefault(0u);
  790. }
  791. sk_sp<PaintFilter> DisplacementMapEffectPaintFilter::SnapshotWithImagesInternal(
  792. ImageProvider* image_provider) const {
  793. return sk_make_sp<DisplacementMapEffectPaintFilter>(
  794. channel_x_, channel_y_, scale_, Snapshot(displacement_, image_provider),
  795. Snapshot(color_, image_provider), GetCropRect());
  796. }
  797. bool DisplacementMapEffectPaintFilter::operator==(
  798. const DisplacementMapEffectPaintFilter& other) const {
  799. return channel_x_ == other.channel_x_ && channel_y_ == other.channel_y_ &&
  800. PaintOp::AreEqualEvenIfNaN(scale_, other.scale_) &&
  801. base::ValuesEquivalent(displacement_.get(),
  802. other.displacement_.get()) &&
  803. base::ValuesEquivalent(color_.get(), other.color_.get());
  804. }
  805. ImagePaintFilter::ImagePaintFilter(PaintImage image,
  806. const SkRect& src_rect,
  807. const SkRect& dst_rect,
  808. PaintFlags::FilterQuality filter_quality)
  809. : PaintFilter(kType, nullptr, !image.IsTextureBacked()),
  810. image_(std::move(image)),
  811. src_rect_(src_rect),
  812. dst_rect_(dst_rect),
  813. filter_quality_(filter_quality) {
  814. SkSamplingOptions sampling(
  815. PaintFlags::FilterQualityToSkSamplingOptions(filter_quality));
  816. cached_sk_filter_ = SkImageFilters::Image(image_.GetSkImage(), src_rect_,
  817. dst_rect_, sampling);
  818. }
  819. ImagePaintFilter::~ImagePaintFilter() = default;
  820. size_t ImagePaintFilter::SerializedSize() const {
  821. base::CheckedNumeric<size_t> total_size =
  822. BaseSerializedSize() + sizeof(src_rect_) + sizeof(dst_rect_) +
  823. sizeof(filter_quality_);
  824. total_size += PaintOpWriter::GetImageSize(image_);
  825. return total_size.ValueOrDefault(0u);
  826. }
  827. sk_sp<PaintFilter> ImagePaintFilter::SnapshotWithImagesInternal(
  828. ImageProvider* image_provider) const {
  829. DrawImage draw_image(image_, false,
  830. SkIRect::MakeWH(image_.width(), image_.height()),
  831. filter_quality_, SkM44());
  832. auto scoped_result = image_provider->GetRasterContent(draw_image);
  833. if (!scoped_result)
  834. return nullptr;
  835. auto decoded_sk_image = sk_ref_sp<SkImage>(
  836. const_cast<SkImage*>(scoped_result.decoded_image().image().get()));
  837. PaintImage decoded_paint_image =
  838. PaintImageBuilder::WithDefault()
  839. .set_id(image_.stable_id())
  840. .set_texture_image(decoded_sk_image, PaintImage::GetNextContentId())
  841. .TakePaintImage();
  842. return sk_make_sp<ImagePaintFilter>(std::move(decoded_paint_image), src_rect_,
  843. dst_rect_, filter_quality_);
  844. }
  845. bool ImagePaintFilter::operator==(const ImagePaintFilter& other) const {
  846. return !!image_ == !!other.image_ &&
  847. PaintOp::AreSkRectsEqual(src_rect_, other.src_rect_) &&
  848. PaintOp::AreSkRectsEqual(dst_rect_, other.dst_rect_) &&
  849. filter_quality_ == other.filter_quality_;
  850. }
  851. RecordPaintFilter::RecordPaintFilter(sk_sp<PaintRecord> record,
  852. const SkRect& record_bounds,
  853. const gfx::SizeF& raster_scale,
  854. ScalingBehavior scaling_behavior)
  855. : RecordPaintFilter(std::move(record),
  856. record_bounds,
  857. raster_scale,
  858. scaling_behavior,
  859. nullptr) {}
  860. RecordPaintFilter::RecordPaintFilter(sk_sp<PaintRecord> record,
  861. const SkRect& record_bounds,
  862. const gfx::SizeF& raster_scale,
  863. ScalingBehavior scaling_behavior,
  864. ImageProvider* image_provider)
  865. : PaintFilter(kType, nullptr, record->HasDiscardableImages()),
  866. record_(std::move(record)),
  867. record_bounds_(record_bounds),
  868. raster_scale_(raster_scale),
  869. scaling_behavior_(scaling_behavior) {
  870. DCHECK(raster_scale_.width() > 0.f && raster_scale_.height() > 0.f);
  871. DCHECK(scaling_behavior == ScalingBehavior::kFixedScale ||
  872. (raster_scale_.width() == 1.f && raster_scale_.height() == 1.f));
  873. sk_sp<SkPicture> picture =
  874. ToSkPicture(record_, record_bounds_, image_provider);
  875. if (scaling_behavior == ScalingBehavior::kRasterAtScale ||
  876. record_bounds_.isEmpty()) {
  877. cached_sk_filter_ = SkImageFilters::Picture(std::move(picture));
  878. } else {
  879. DCHECK(scaling_behavior == ScalingBehavior::kFixedScale);
  880. // Convert the record to an image at the scaled resolution, but draw it in
  881. // the filter DAG at the original record bounds.
  882. int width = SkScalarCeilToInt(record_bounds.width());
  883. int height = SkScalarCeilToInt(record_bounds.height());
  884. SkMatrix originAdjust =
  885. SkMatrix::Translate(-record_bounds.fLeft, -record_bounds.fTop);
  886. auto image = SkImage::MakeFromPicture(
  887. std::move(picture), SkISize::Make(width, height), &originAdjust,
  888. nullptr, SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB());
  889. // Must account for the raster scale when drawing the picture image,
  890. SkRect src = SkRect::MakeWH(record_bounds.width(), record_bounds.height());
  891. SkScalar inv_x = 1.f / raster_scale_.width();
  892. SkScalar inv_y = 1.f / raster_scale_.height();
  893. SkRect dst = {inv_x * record_bounds.fLeft, inv_y * record_bounds.fTop,
  894. inv_x * record_bounds.fRight, inv_y * record_bounds.fBottom};
  895. // Use Mitchell cubic filter, matching historic
  896. // PaintFlags::FilterQuality::kHigh
  897. SkSamplingOptions sampling(SkCubicResampler::Mitchell());
  898. cached_sk_filter_ =
  899. SkImageFilters::Image(std::move(image), src, dst, sampling);
  900. }
  901. }
  902. RecordPaintFilter::~RecordPaintFilter() = default;
  903. sk_sp<RecordPaintFilter> RecordPaintFilter::CreateScaledPaintRecord(
  904. const SkMatrix& ctm,
  905. int max_texture_size) const {
  906. // If this is already fixed scale, then this is already good to go, and if
  907. // the bounds are empty the filter produces no output so keep it as-is.
  908. if (scaling_behavior_ == ScalingBehavior::kFixedScale ||
  909. record_bounds_.isEmpty()) {
  910. return sk_ref_sp<RecordPaintFilter>(this);
  911. }
  912. // For creating a deserialized RecordPaintFilter, extract the scale factor at
  913. // which it would have been rasterized at for the given ctm. This is modeled
  914. // after PaintShader::CreateScaledPaintRecord.
  915. SkRect scaled_record_bounds =
  916. PaintRecord::GetFixedScaleBounds(ctm, record_bounds_, max_texture_size);
  917. gfx::SizeF raster_scale = {
  918. scaled_record_bounds.width() / record_bounds_.width(),
  919. scaled_record_bounds.height() / record_bounds_.height()};
  920. if (raster_scale.IsEmpty())
  921. return nullptr;
  922. return sk_make_sp<RecordPaintFilter>(record_, scaled_record_bounds,
  923. raster_scale,
  924. ScalingBehavior::kFixedScale);
  925. }
  926. size_t RecordPaintFilter::SerializedSize() const {
  927. base::CheckedNumeric<size_t> total_size =
  928. BaseSerializedSize() + sizeof(record_bounds_) + sizeof(raster_scale_) +
  929. sizeof(scaling_behavior_) + sizeof(bool);
  930. total_size += PaintOpWriter::GetRecordSize(record_.get());
  931. return total_size.ValueOrDefault(0u);
  932. }
  933. sk_sp<PaintFilter> RecordPaintFilter::SnapshotWithImagesInternal(
  934. ImageProvider* image_provider) const {
  935. return sk_sp<RecordPaintFilter>(
  936. new RecordPaintFilter(record_, record_bounds_, raster_scale_,
  937. scaling_behavior_, image_provider));
  938. }
  939. bool RecordPaintFilter::operator==(const RecordPaintFilter& other) const {
  940. return !!record_ == !!other.record_ &&
  941. scaling_behavior_ == other.scaling_behavior_ &&
  942. raster_scale_ == other.raster_scale_ &&
  943. PaintOp::AreSkRectsEqual(record_bounds_, other.record_bounds_);
  944. }
  945. MergePaintFilter::MergePaintFilter(const sk_sp<PaintFilter>* const filters,
  946. int count,
  947. const CropRect* crop_rect)
  948. : MergePaintFilter(filters, count, crop_rect, nullptr) {}
  949. MergePaintFilter::MergePaintFilter(const sk_sp<PaintFilter>* const filters,
  950. int count,
  951. const CropRect* crop_rect,
  952. ImageProvider* image_provider)
  953. : PaintFilter(kType, crop_rect, HasDiscardableImages(filters, count)) {
  954. std::vector<sk_sp<SkImageFilter>> sk_filters;
  955. sk_filters.reserve(count);
  956. for (int i = 0; i < count; ++i) {
  957. auto filter =
  958. image_provider ? Snapshot(filters[i], image_provider) : filters[i];
  959. inputs_->push_back(std::move(filter));
  960. sk_filters.push_back(GetSkFilter(inputs_->back().get()));
  961. }
  962. cached_sk_filter_ = SkImageFilters::Merge(
  963. static_cast<sk_sp<SkImageFilter>*>(sk_filters.data()), count, crop_rect);
  964. }
  965. MergePaintFilter::~MergePaintFilter() = default;
  966. size_t MergePaintFilter::SerializedSize() const {
  967. base::CheckedNumeric<size_t> total_size = 0u;
  968. for (size_t i = 0; i < input_count(); ++i)
  969. total_size += GetFilterSize(input_at(i));
  970. total_size += BaseSerializedSize();
  971. total_size += sizeof(input_count());
  972. return total_size.ValueOrDefault(0u);
  973. }
  974. sk_sp<PaintFilter> MergePaintFilter::SnapshotWithImagesInternal(
  975. ImageProvider* image_provider) const {
  976. return sk_sp<MergePaintFilter>(new MergePaintFilter(
  977. &inputs_[0], inputs_->size(), GetCropRect(), image_provider));
  978. }
  979. bool MergePaintFilter::operator==(const MergePaintFilter& other) const {
  980. if (inputs_->size() != other.inputs_->size())
  981. return false;
  982. for (size_t i = 0; i < inputs_->size(); ++i) {
  983. if (!base::ValuesEquivalent(inputs_[i].get(), other.inputs_[i].get()))
  984. return false;
  985. }
  986. return true;
  987. }
  988. MorphologyPaintFilter::MorphologyPaintFilter(MorphType morph_type,
  989. float radius_x,
  990. float radius_y,
  991. sk_sp<PaintFilter> input,
  992. const CropRect* crop_rect)
  993. : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
  994. morph_type_(morph_type),
  995. radius_x_(radius_x),
  996. radius_y_(radius_y),
  997. input_(std::move(input)) {
  998. switch (morph_type_) {
  999. case MorphType::kDilate:
  1000. cached_sk_filter_ = SkImageFilters::Dilate(
  1001. radius_x_, radius_y_, GetSkFilter(input_.get()), crop_rect);
  1002. break;
  1003. case MorphType::kErode:
  1004. cached_sk_filter_ = SkImageFilters::Erode(
  1005. radius_x_, radius_y_, GetSkFilter(input_.get()), crop_rect);
  1006. break;
  1007. }
  1008. }
  1009. MorphologyPaintFilter::~MorphologyPaintFilter() = default;
  1010. size_t MorphologyPaintFilter::SerializedSize() const {
  1011. base::CheckedNumeric<size_t> total_size =
  1012. BaseSerializedSize() + sizeof(morph_type_) + sizeof(radius_x_) +
  1013. sizeof(radius_y_);
  1014. total_size += GetFilterSize(input_.get());
  1015. return total_size.ValueOrDefault(0u);
  1016. }
  1017. sk_sp<PaintFilter> MorphologyPaintFilter::SnapshotWithImagesInternal(
  1018. ImageProvider* image_provider) const {
  1019. return sk_make_sp<MorphologyPaintFilter>(morph_type_, radius_x_, radius_y_,
  1020. Snapshot(input_, image_provider),
  1021. GetCropRect());
  1022. }
  1023. bool MorphologyPaintFilter::operator==(
  1024. const MorphologyPaintFilter& other) const {
  1025. return morph_type_ == other.morph_type_ && radius_x_ == other.radius_x_ &&
  1026. radius_y_ == other.radius_y_ &&
  1027. base::ValuesEquivalent(input_.get(), other.input_.get());
  1028. }
  1029. OffsetPaintFilter::OffsetPaintFilter(SkScalar dx,
  1030. SkScalar dy,
  1031. sk_sp<PaintFilter> input,
  1032. const CropRect* crop_rect)
  1033. : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
  1034. dx_(dx),
  1035. dy_(dy),
  1036. input_(std::move(input)) {
  1037. cached_sk_filter_ =
  1038. SkImageFilters::Offset(dx_, dy_, GetSkFilter(input_.get()), crop_rect);
  1039. }
  1040. OffsetPaintFilter::~OffsetPaintFilter() = default;
  1041. size_t OffsetPaintFilter::SerializedSize() const {
  1042. base::CheckedNumeric<size_t> total_size =
  1043. BaseSerializedSize() + sizeof(dx_) + sizeof(dy_);
  1044. total_size += GetFilterSize(input_.get());
  1045. return total_size.ValueOrDefault(0u);
  1046. }
  1047. sk_sp<PaintFilter> OffsetPaintFilter::SnapshotWithImagesInternal(
  1048. ImageProvider* image_provider) const {
  1049. return sk_make_sp<OffsetPaintFilter>(
  1050. dx_, dy_, Snapshot(input_, image_provider), GetCropRect());
  1051. }
  1052. bool OffsetPaintFilter::operator==(const OffsetPaintFilter& other) const {
  1053. return PaintOp::AreEqualEvenIfNaN(dx_, other.dx_) &&
  1054. PaintOp::AreEqualEvenIfNaN(dy_, other.dy_) &&
  1055. base::ValuesEquivalent(input_.get(), other.input_.get());
  1056. }
  1057. TilePaintFilter::TilePaintFilter(const SkRect& src,
  1058. const SkRect& dst,
  1059. sk_sp<PaintFilter> input)
  1060. : PaintFilter(kType, nullptr, HasDiscardableImages(input)),
  1061. src_(src),
  1062. dst_(dst),
  1063. input_(std::move(input)) {
  1064. cached_sk_filter_ =
  1065. SkImageFilters::Tile(src_, dst_, GetSkFilter(input_.get()));
  1066. }
  1067. TilePaintFilter::~TilePaintFilter() = default;
  1068. size_t TilePaintFilter::SerializedSize() const {
  1069. base::CheckedNumeric<size_t> total_size =
  1070. BaseSerializedSize() + sizeof(src_) + sizeof(dst_);
  1071. total_size += GetFilterSize(input_.get());
  1072. return total_size.ValueOrDefault(0u);
  1073. }
  1074. sk_sp<PaintFilter> TilePaintFilter::SnapshotWithImagesInternal(
  1075. ImageProvider* image_provider) const {
  1076. return sk_make_sp<TilePaintFilter>(src_, dst_,
  1077. Snapshot(input_, image_provider));
  1078. }
  1079. bool TilePaintFilter::operator==(const TilePaintFilter& other) const {
  1080. return PaintOp::AreSkRectsEqual(src_, other.src_) &&
  1081. PaintOp::AreSkRectsEqual(dst_, other.dst_) &&
  1082. base::ValuesEquivalent(input_.get(), other.input_.get());
  1083. }
  1084. TurbulencePaintFilter::TurbulencePaintFilter(TurbulenceType turbulence_type,
  1085. SkScalar base_frequency_x,
  1086. SkScalar base_frequency_y,
  1087. int num_octaves,
  1088. SkScalar seed,
  1089. const SkISize* tile_size,
  1090. const CropRect* crop_rect)
  1091. : PaintFilter(kType, crop_rect, kHasNoDiscardableImages),
  1092. turbulence_type_(turbulence_type),
  1093. base_frequency_x_(base_frequency_x),
  1094. base_frequency_y_(base_frequency_y),
  1095. num_octaves_(num_octaves),
  1096. seed_(seed),
  1097. tile_size_(tile_size ? *tile_size : SkISize::MakeEmpty()) {
  1098. sk_sp<SkShader> shader;
  1099. switch (turbulence_type_) {
  1100. case TurbulenceType::kTurbulence:
  1101. shader = SkPerlinNoiseShader::MakeTurbulence(
  1102. base_frequency_x_, base_frequency_y_, num_octaves_, seed_,
  1103. &tile_size_);
  1104. break;
  1105. case TurbulenceType::kFractalNoise:
  1106. shader = SkPerlinNoiseShader::MakeFractalNoise(
  1107. base_frequency_x_, base_frequency_y_, num_octaves_, seed_,
  1108. &tile_size_);
  1109. break;
  1110. }
  1111. cached_sk_filter_ = SkImageFilters::Shader(std::move(shader), crop_rect);
  1112. }
  1113. TurbulencePaintFilter::~TurbulencePaintFilter() = default;
  1114. size_t TurbulencePaintFilter::SerializedSize() const {
  1115. return BaseSerializedSize() + sizeof(turbulence_type_) +
  1116. sizeof(base_frequency_x_) + sizeof(base_frequency_y_) +
  1117. sizeof(num_octaves_) + sizeof(seed_) + sizeof(tile_size_);
  1118. }
  1119. sk_sp<PaintFilter> TurbulencePaintFilter::SnapshotWithImagesInternal(
  1120. ImageProvider* image_provider) const {
  1121. return sk_make_sp<TurbulencePaintFilter>(turbulence_type_, base_frequency_x_,
  1122. base_frequency_y_, num_octaves_,
  1123. seed_, &tile_size_, GetCropRect());
  1124. }
  1125. bool TurbulencePaintFilter::operator==(
  1126. const TurbulencePaintFilter& other) const {
  1127. return turbulence_type_ == other.turbulence_type_ &&
  1128. PaintOp::AreEqualEvenIfNaN(base_frequency_x_,
  1129. other.base_frequency_x_) &&
  1130. PaintOp::AreEqualEvenIfNaN(base_frequency_y_,
  1131. other.base_frequency_y_) &&
  1132. num_octaves_ == other.num_octaves_ &&
  1133. PaintOp::AreEqualEvenIfNaN(seed_, other.seed_) &&
  1134. tile_size_ == other.tile_size_;
  1135. }
  1136. ShaderPaintFilter::ShaderPaintFilter(sk_sp<PaintShader> shader,
  1137. uint8_t alpha,
  1138. PaintFlags::FilterQuality filter_quality,
  1139. SkImageFilters::Dither dither,
  1140. const CropRect* crop_rect)
  1141. : PaintFilter(kType, crop_rect, shader->has_discardable_images()),
  1142. shader_(std::move(shader)),
  1143. alpha_(alpha),
  1144. filter_quality_(filter_quality),
  1145. dither_(dither) {
  1146. sk_sp<SkShader> sk_shader = shader_->GetSkShader(filter_quality_);
  1147. // Combine the alpha multiply into the SkShader if it's not opaque
  1148. if (alpha < 255) {
  1149. // The blend effectively produces (shader * alpha), the rgb of the secondary
  1150. // color are ignored.
  1151. SkColor4f color{1.0f, 1.0f, 1.0f, alpha / 255.0f};
  1152. // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
  1153. sk_shader = SkShaders::Blend(SkBlendMode::kDstIn, std::move(sk_shader),
  1154. SkShaders::Color(color.toSkColor()));
  1155. }
  1156. cached_sk_filter_ =
  1157. SkImageFilters::Shader(std::move(sk_shader), dither, crop_rect);
  1158. }
  1159. ShaderPaintFilter::~ShaderPaintFilter() = default;
  1160. size_t ShaderPaintFilter::SerializedSize() const {
  1161. base::CheckedNumeric<size_t> total_size = BaseSerializedSize();
  1162. total_size += PaintShader::GetSerializedSize(shader_.get());
  1163. total_size += sizeof(alpha_);
  1164. total_size += sizeof(filter_quality_); // filter quality
  1165. total_size += sizeof(dither_);
  1166. return total_size.ValueOrDefault(0u);
  1167. }
  1168. sk_sp<PaintFilter> ShaderPaintFilter::SnapshotWithImagesInternal(
  1169. ImageProvider* image_provider) const {
  1170. PaintFlags orig_flags;
  1171. orig_flags.setShader(shader_);
  1172. orig_flags.setAlpha(alpha_);
  1173. orig_flags.setFilterQuality(filter_quality_);
  1174. orig_flags.setDither(dither_ == SkImageFilters::Dither::kYes);
  1175. ScopedRasterFlags raster_flags(&orig_flags, image_provider, SkMatrix::I(), 0,
  1176. 1.0f);
  1177. const PaintFlags* snapshot = raster_flags.flags();
  1178. if (snapshot) {
  1179. // Ref the updated paint shader so that it can outlive ScopedRasterFlags
  1180. return sk_make_sp<ShaderPaintFilter>(
  1181. sk_ref_sp(snapshot->getShader()), snapshot->getAlpha(),
  1182. snapshot->getFilterQuality(),
  1183. snapshot->isDither() ? Dither::kYes : Dither::kNo, GetCropRect());
  1184. } else {
  1185. // If decode failed, then just fallback to the solid color
  1186. return sk_make_sp<ShaderPaintFilter>(nullptr, alpha_, filter_quality_,
  1187. dither_, GetCropRect());
  1188. }
  1189. }
  1190. bool ShaderPaintFilter::operator==(const ShaderPaintFilter& other) const {
  1191. DCHECK(shader_ && other.shader_);
  1192. return alpha_ == other.alpha_ && filter_quality_ == other.filter_quality_ &&
  1193. dither_ == other.dither_ && *shader_ == *other.shader_;
  1194. }
  1195. MatrixPaintFilter::MatrixPaintFilter(const SkMatrix& matrix,
  1196. PaintFlags::FilterQuality filter_quality,
  1197. sk_sp<PaintFilter> input)
  1198. : PaintFilter(Type::kMatrix, nullptr, HasDiscardableImages(input)),
  1199. matrix_(matrix),
  1200. filter_quality_(filter_quality),
  1201. input_(std::move(input)) {
  1202. cached_sk_filter_ = SkImageFilters::MatrixTransform(
  1203. matrix_, PaintFlags::FilterQualityToSkSamplingOptions(filter_quality_),
  1204. GetSkFilter(input_.get()));
  1205. }
  1206. MatrixPaintFilter::~MatrixPaintFilter() = default;
  1207. size_t MatrixPaintFilter::SerializedSize() const {
  1208. base::CheckedNumeric<size_t> total_size =
  1209. BaseSerializedSize() + sizeof(matrix_) + sizeof(filter_quality_);
  1210. total_size += GetFilterSize(input_.get());
  1211. return total_size.ValueOrDefault(0u);
  1212. }
  1213. sk_sp<PaintFilter> MatrixPaintFilter::SnapshotWithImagesInternal(
  1214. ImageProvider* image_provider) const {
  1215. return sk_make_sp<MatrixPaintFilter>(matrix_, filter_quality_,
  1216. Snapshot(input_, image_provider));
  1217. }
  1218. bool MatrixPaintFilter::operator==(const MatrixPaintFilter& other) const {
  1219. return PaintOp::AreSkMatricesEqual(matrix_, other.matrix_) &&
  1220. filter_quality_ == other.filter_quality_ &&
  1221. base::ValuesEquivalent(input_.get(), other.input_.get());
  1222. }
  1223. LightingDistantPaintFilter::LightingDistantPaintFilter(
  1224. LightingType lighting_type,
  1225. const SkPoint3& direction,
  1226. SkColor4f light_color,
  1227. SkScalar surface_scale,
  1228. SkScalar kconstant,
  1229. SkScalar shininess,
  1230. sk_sp<PaintFilter> input,
  1231. const CropRect* crop_rect)
  1232. : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
  1233. lighting_type_(lighting_type),
  1234. direction_(direction),
  1235. light_color_(light_color),
  1236. surface_scale_(surface_scale),
  1237. kconstant_(kconstant),
  1238. shininess_(shininess),
  1239. input_(std::move(input)) {
  1240. switch (lighting_type_) {
  1241. case LightingType::kDiffuse:
  1242. // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
  1243. cached_sk_filter_ = SkImageFilters::DistantLitDiffuse(
  1244. direction_, light_color_.toSkColor(), surface_scale_, kconstant_,
  1245. GetSkFilter(input_.get()), crop_rect);
  1246. break;
  1247. case LightingType::kSpecular:
  1248. // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
  1249. cached_sk_filter_ = SkImageFilters::DistantLitSpecular(
  1250. direction_, light_color_.toSkColor(), surface_scale_, kconstant_,
  1251. shininess_, GetSkFilter(input_.get()), crop_rect);
  1252. break;
  1253. }
  1254. }
  1255. LightingDistantPaintFilter::~LightingDistantPaintFilter() = default;
  1256. size_t LightingDistantPaintFilter::SerializedSize() const {
  1257. base::CheckedNumeric<size_t> total_size =
  1258. BaseSerializedSize() + sizeof(lighting_type_) + sizeof(direction_) +
  1259. sizeof(light_color_) + sizeof(surface_scale_) + sizeof(kconstant_) +
  1260. sizeof(shininess_);
  1261. total_size += GetFilterSize(input_.get());
  1262. return total_size.ValueOrDefault(0u);
  1263. }
  1264. sk_sp<PaintFilter> LightingDistantPaintFilter::SnapshotWithImagesInternal(
  1265. ImageProvider* image_provider) const {
  1266. return sk_make_sp<LightingDistantPaintFilter>(
  1267. lighting_type_, direction_, light_color_, surface_scale_, kconstant_,
  1268. shininess_, Snapshot(input_, image_provider), GetCropRect());
  1269. }
  1270. bool LightingDistantPaintFilter::operator==(
  1271. const LightingDistantPaintFilter& other) const {
  1272. return lighting_type_ == other.lighting_type_ &&
  1273. PaintOp::AreSkPoint3sEqual(direction_, other.direction_) &&
  1274. light_color_ == other.light_color_ &&
  1275. PaintOp::AreEqualEvenIfNaN(surface_scale_, other.surface_scale_) &&
  1276. PaintOp::AreEqualEvenIfNaN(kconstant_, other.kconstant_) &&
  1277. PaintOp::AreEqualEvenIfNaN(shininess_, other.shininess_) &&
  1278. base::ValuesEquivalent(input_.get(), other.input_.get());
  1279. }
  1280. LightingPointPaintFilter::LightingPointPaintFilter(LightingType lighting_type,
  1281. const SkPoint3& location,
  1282. SkColor4f light_color,
  1283. SkScalar surface_scale,
  1284. SkScalar kconstant,
  1285. SkScalar shininess,
  1286. sk_sp<PaintFilter> input,
  1287. const CropRect* crop_rect)
  1288. : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
  1289. lighting_type_(lighting_type),
  1290. location_(location),
  1291. light_color_(light_color),
  1292. surface_scale_(surface_scale),
  1293. kconstant_(kconstant),
  1294. shininess_(shininess),
  1295. input_(std::move(input)) {
  1296. switch (lighting_type_) {
  1297. case LightingType::kDiffuse:
  1298. // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
  1299. cached_sk_filter_ = SkImageFilters::PointLitDiffuse(
  1300. location_, light_color_.toSkColor(), surface_scale_, kconstant_,
  1301. GetSkFilter(input_.get()), crop_rect);
  1302. break;
  1303. case LightingType::kSpecular:
  1304. // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
  1305. cached_sk_filter_ = SkImageFilters::PointLitSpecular(
  1306. location_, light_color_.toSkColor(), surface_scale_, kconstant_,
  1307. shininess_, GetSkFilter(input_.get()), crop_rect);
  1308. break;
  1309. }
  1310. }
  1311. LightingPointPaintFilter::~LightingPointPaintFilter() = default;
  1312. size_t LightingPointPaintFilter::SerializedSize() const {
  1313. base::CheckedNumeric<size_t> total_size =
  1314. BaseSerializedSize() + sizeof(lighting_type_) + sizeof(location_) +
  1315. sizeof(light_color_) + sizeof(surface_scale_) + sizeof(kconstant_) +
  1316. sizeof(shininess_);
  1317. total_size += GetFilterSize(input_.get());
  1318. return total_size.ValueOrDefault(0u);
  1319. }
  1320. sk_sp<PaintFilter> LightingPointPaintFilter::SnapshotWithImagesInternal(
  1321. ImageProvider* image_provider) const {
  1322. return sk_make_sp<LightingPointPaintFilter>(
  1323. lighting_type_, location_, light_color_, surface_scale_, kconstant_,
  1324. shininess_, Snapshot(input_, image_provider), GetCropRect());
  1325. }
  1326. bool LightingPointPaintFilter::operator==(
  1327. const LightingPointPaintFilter& other) const {
  1328. return lighting_type_ == other.lighting_type_ &&
  1329. PaintOp::AreSkPoint3sEqual(location_, other.location_) &&
  1330. light_color_ == other.light_color_ &&
  1331. PaintOp::AreEqualEvenIfNaN(surface_scale_, other.surface_scale_) &&
  1332. PaintOp::AreEqualEvenIfNaN(kconstant_, other.kconstant_) &&
  1333. PaintOp::AreEqualEvenIfNaN(shininess_, other.shininess_) &&
  1334. base::ValuesEquivalent(input_.get(), other.input_.get());
  1335. }
  1336. LightingSpotPaintFilter::LightingSpotPaintFilter(LightingType lighting_type,
  1337. const SkPoint3& location,
  1338. const SkPoint3& target,
  1339. SkScalar specular_exponent,
  1340. SkScalar cutoff_angle,
  1341. SkColor4f light_color,
  1342. SkScalar surface_scale,
  1343. SkScalar kconstant,
  1344. SkScalar shininess,
  1345. sk_sp<PaintFilter> input,
  1346. const CropRect* crop_rect)
  1347. : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
  1348. lighting_type_(lighting_type),
  1349. location_(location),
  1350. target_(target),
  1351. specular_exponent_(specular_exponent),
  1352. cutoff_angle_(cutoff_angle),
  1353. light_color_(light_color),
  1354. surface_scale_(surface_scale),
  1355. kconstant_(kconstant),
  1356. shininess_(shininess),
  1357. input_(std::move(input)) {
  1358. switch (lighting_type_) {
  1359. case LightingType::kDiffuse:
  1360. // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
  1361. cached_sk_filter_ = SkImageFilters::SpotLitDiffuse(
  1362. location_, target_, specular_exponent_, cutoff_angle_,
  1363. light_color_.toSkColor(), surface_scale_, kconstant_,
  1364. GetSkFilter(input_.get()), crop_rect);
  1365. break;
  1366. case LightingType::kSpecular:
  1367. // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f.
  1368. cached_sk_filter_ = SkImageFilters::SpotLitSpecular(
  1369. location_, target_, specular_exponent_, cutoff_angle_,
  1370. light_color_.toSkColor(), surface_scale_, kconstant_, shininess_,
  1371. GetSkFilter(input_.get()), crop_rect);
  1372. break;
  1373. }
  1374. }
  1375. LightingSpotPaintFilter::~LightingSpotPaintFilter() = default;
  1376. size_t LightingSpotPaintFilter::SerializedSize() const {
  1377. base::CheckedNumeric<size_t> total_size =
  1378. BaseSerializedSize() + sizeof(lighting_type_) + sizeof(location_) +
  1379. sizeof(target_) + sizeof(specular_exponent_) + sizeof(cutoff_angle_) +
  1380. sizeof(light_color_) + sizeof(surface_scale_) + sizeof(kconstant_) +
  1381. sizeof(shininess_);
  1382. total_size += GetFilterSize(input_.get());
  1383. return total_size.ValueOrDefault(0u);
  1384. }
  1385. sk_sp<PaintFilter> LightingSpotPaintFilter::SnapshotWithImagesInternal(
  1386. ImageProvider* image_provider) const {
  1387. return sk_make_sp<LightingSpotPaintFilter>(
  1388. lighting_type_, location_, target_, specular_exponent_, cutoff_angle_,
  1389. light_color_, surface_scale_, kconstant_, shininess_,
  1390. Snapshot(input_, image_provider), GetCropRect());
  1391. }
  1392. bool LightingSpotPaintFilter::operator==(
  1393. const LightingSpotPaintFilter& other) const {
  1394. return lighting_type_ == other.lighting_type_ &&
  1395. PaintOp::AreSkPoint3sEqual(location_, other.location_) &&
  1396. PaintOp::AreSkPoint3sEqual(target_, other.target_) &&
  1397. PaintOp::AreEqualEvenIfNaN(specular_exponent_,
  1398. other.specular_exponent_) &&
  1399. PaintOp::AreEqualEvenIfNaN(cutoff_angle_, other.cutoff_angle_) &&
  1400. light_color_ == other.light_color_ &&
  1401. PaintOp::AreEqualEvenIfNaN(surface_scale_, other.surface_scale_) &&
  1402. PaintOp::AreEqualEvenIfNaN(kconstant_, other.kconstant_) &&
  1403. PaintOp::AreEqualEvenIfNaN(shininess_, other.shininess_) &&
  1404. base::ValuesEquivalent(input_.get(), other.input_.get());
  1405. }
  1406. StretchPaintFilter::StretchPaintFilter(SkScalar stretch_x,
  1407. SkScalar stretch_y,
  1408. SkScalar width,
  1409. SkScalar height,
  1410. sk_sp<PaintFilter> input,
  1411. const CropRect* crop_rect)
  1412. : PaintFilter(kType, crop_rect, HasDiscardableImages(input)),
  1413. stretch_x_(stretch_x),
  1414. stretch_y_(stretch_y),
  1415. width_(width),
  1416. height_(height),
  1417. input_(std::move(input)) {
  1418. #if BUILDFLAG(IS_ANDROID)
  1419. float normOverScrollDistX = stretch_x_;
  1420. float normOverScrollDistY = stretch_y_;
  1421. float distanceStretchedX =
  1422. CONTENT_DISTANCE_STRETCHED / (1 + std::abs(normOverScrollDistX));
  1423. float distanceStretchedY =
  1424. CONTENT_DISTANCE_STRETCHED / (1 + std::abs(normOverScrollDistY));
  1425. float inverseDistanceStretchedX = 1.f / CONTENT_DISTANCE_STRETCHED;
  1426. float inverseDistanceStretchedY = 1.f / CONTENT_DISTANCE_STRETCHED;
  1427. float diffX = distanceStretchedX - CONTENT_DISTANCE_STRETCHED;
  1428. float diffY = distanceStretchedY - CONTENT_DISTANCE_STRETCHED;
  1429. StretchShaderUniforms uniforms;
  1430. uniforms.uInterpolationStrength = INTERPOLATION_STRENGTH_VALUE;
  1431. uniforms.uStretchAffectedDistX = CONTENT_DISTANCE_STRETCHED;
  1432. uniforms.uStretchAffectedDistY = CONTENT_DISTANCE_STRETCHED;
  1433. uniforms.uDistanceStretchedX = distanceStretchedX;
  1434. uniforms.uDistanceStretchedY = distanceStretchedY;
  1435. uniforms.uInverseDistanceStretchedX = inverseDistanceStretchedX;
  1436. uniforms.uInverseDistanceStretchedY = inverseDistanceStretchedY;
  1437. uniforms.uDistDiffX = diffX;
  1438. uniforms.uDistDiffY = diffY;
  1439. uniforms.uOverscrollX = normOverScrollDistX;
  1440. uniforms.uOverscrollY = normOverScrollDistY;
  1441. uniforms.uScrollX = 0;
  1442. uniforms.uScrollY = 0;
  1443. uniforms.viewportWidth = width;
  1444. uniforms.viewportHeight = height;
  1445. sk_sp<SkData> uniformVals = SkData::MakeWithCopy(&uniforms, sizeof(uniforms));
  1446. cached_sk_filter_ = SkMakeRuntimeImageFilter(getStretchEffect(), uniformVals,
  1447. GetSkFilter(input_.get()));
  1448. #else // BUILDFLAG(IS_ANDROID)
  1449. // Stretch filter is only used on android and removed from other platforms
  1450. // to reduce size. See https://crbug.com/1226170.
  1451. #endif // BUILDFLAG(IS_ANDROID)
  1452. }
  1453. StretchPaintFilter::~StretchPaintFilter() = default;
  1454. size_t StretchPaintFilter::SerializedSize() const {
  1455. base::CheckedNumeric<size_t> total_size =
  1456. BaseSerializedSize() + sizeof(stretch_x_) + sizeof(stretch_y_) +
  1457. sizeof(width_) + sizeof(height_);
  1458. total_size += GetFilterSize(input_.get());
  1459. return total_size.ValueOrDefault(0u);
  1460. }
  1461. sk_sp<PaintFilter> StretchPaintFilter::SnapshotWithImagesInternal(
  1462. ImageProvider* image_provider) const {
  1463. return sk_make_sp<StretchPaintFilter>(stretch_x_, stretch_y_, width_, height_,
  1464. Snapshot(input_, image_provider),
  1465. GetCropRect());
  1466. }
  1467. bool StretchPaintFilter::operator==(const StretchPaintFilter& other) const {
  1468. return PaintOp::AreEqualEvenIfNaN(stretch_x_, other.stretch_x_) &&
  1469. PaintOp::AreEqualEvenIfNaN(stretch_y_, other.stretch_y_) &&
  1470. PaintOp::AreEqualEvenIfNaN(width_, other.width_) &&
  1471. PaintOp::AreEqualEvenIfNaN(height_, other.height_) &&
  1472. base::ValuesEquivalent(input_.get(), other.input_.get());
  1473. }
  1474. } // namespace cc