Changeset 275570 in webkit
- Timestamp:
- Apr 6, 2021 4:36:25 PM (3 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r275565 r275570 1 2021-04-06 Said Abou-Hallawa <said@apple.com> 2 3 Replace the Optional metadata of ImageSource by a single OptionSet and the underlying metadata 4 https://bugs.webkit.org/show_bug.cgi?id=224202 5 6 Reviewed by Simon Fraser. 7 8 Encapsulating the metadata in a Optionals adds extra memory cost. Replace 9 these Optionals by the underlying metadata and an OptionSet to tell which 10 ones are cached. 11 12 * platform/graphics/ImageSource.cpp: 13 (WebCore::ImageSource::ImageSource): 14 (WebCore::ImageSource::frameAtIndexCacheIfNeeded): 15 Instead of assertion index < m_frames.size(), we can return defaultFrame(). 16 This will used in many callers which checks the size before calling it. 17 18 (WebCore::ImageSource::clearMetadata): 19 20 (WebCore::ImageSource::metadataCacheIfNeeded): 21 (WebCore::ImageSource::firstFrameMetadataCacheIfNeeded): 22 These two template functions will be used to return and cache, if needed, 23 the image metadata. The first function uses the ImageDecoder while the 24 second one uses the first ImageFrame of the image. 25 26 (WebCore::ImageSource::encodedDataStatus): 27 (WebCore::ImageSource::frameCount): 28 (WebCore::ImageSource::repetitionCount): 29 (WebCore::ImageSource::uti): 30 (WebCore::ImageSource::filenameExtension): 31 (WebCore::ImageSource::accessibilityDescription): 32 (WebCore::ImageSource::hotSpot): 33 (WebCore::ImageSource::orientation): 34 (WebCore::ImageSource::densityCorrectedSize): 35 (WebCore::ImageSource::sourceSize): 36 (WebCore::ImageSource::singlePixelSolidColor): 37 (WebCore::ImageSource::maximumSubsamplingLevel): 38 (WebCore::ImageSource::frameDecodingStatusAtIndex): 39 (WebCore::ImageSource::frameHasAlphaAtIndex): 40 (WebCore::ImageSource::frameHasFullSizeNativeImageAtIndex): 41 (WebCore::ImageSource::frameHasDecodedNativeImageCompatibleWithOptionsAtIndex): 42 (WebCore::ImageSource::frameSubsamplingLevelAtIndex): 43 (WebCore::ImageSource::frameSizeAtIndex): 44 (WebCore::ImageSource::frameBytesAtIndex): 45 (WebCore::ImageSource::frameDurationAtIndex): 46 (WebCore::ImageSource::frameOrientationAtIndex): 47 (WebCore::ImageSource::frameImageAtIndex): 48 (WebCore::ImageSource::frameImageAtIndexCacheIfNeeded): 49 (WebCore::ImageSource::metadata): Deleted. 50 (WebCore::ImageSource::frameMetadataAtIndex): Deleted. 51 (WebCore::ImageSource::frameMetadataAtIndexCacheIfNeeded): Deleted. 52 * platform/graphics/ImageSource.h: 53 (WebCore::ImageSource::frameAtIndex): 54 1 55 2021-04-06 Myles C. Maxfield <mmaxfield@apple.com> 2 56 -
trunk/Source/WebCore/platform/graphics/ImageSource.cpp
r273214 r275570 1 1 /* 2 * Copyright (C) 2016-20 17Apple Inc. All rights reserved.2 * Copyright (C) 2016-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 55 55 m_frameCount = 1; 56 56 m_encodedDataStatus = EncodedDataStatus::Complete; 57 m_cachedMetadata.add({ MetadataType::EncodedDataStatus, MetadataType::FrameCount }); 57 58 growFrames(); 58 59 … … 63 64 m_size = m_frames[0].size(); 64 65 m_orientation = ImageOrientation(ImageOrientation::None); 66 m_cachedMetadata.add({ MetadataType::Orientation, MetadataType::Size }); 65 67 } 66 68 … … 436 438 const ImageFrame& ImageSource::frameAtIndexCacheIfNeeded(size_t index, ImageFrame::Caching caching, const Optional<SubsamplingLevel>& subsamplingLevel) 437 439 { 438 ASSERT(index < m_frames.size()); 440 if (index >= m_frames.size()) 441 return ImageFrame::defaultFrame(); 442 439 443 ImageFrame& frame = m_frames[index]; 440 444 if (!isDecoderAvailable() || frameIsBeingDecodedAndIsCompatibleWithOptionsAtIndex(index, DecodingOptions(DecodingMode::Asynchronous))) … … 467 471 void ImageSource::clearMetadata() 468 472 { 469 m_frameCount = WTF::nullopt; 470 m_repetitionCount = WTF::nullopt; 471 m_singlePixelSolidColor = WTF::nullopt; 472 m_encodedDataStatus = WTF::nullopt; 473 m_uti = WTF::nullopt; 473 m_cachedMetadata.remove({ 474 MetadataType::EncodedDataStatus, 475 MetadataType::FrameCount, 476 MetadataType::RepetitionCount, 477 MetadataType::SinglePixelSolidColor, 478 MetadataType::UTI 479 }); 474 480 } 475 481 … … 489 495 } 490 496 491 template<typename T , T (ImageDecoder::*functor)() const>492 T ImageSource::metadata (const T& defaultValue, Optional<T>* cachedValue)493 { 494 if ( cachedValue && *cachedValue)495 return cachedValue ->value();497 template<typename T> 498 T ImageSource::metadataCacheIfNeeded(T& cachedValue, const T& defaultValue, MetadataType metadataType, T (ImageDecoder::*functor)() const) 499 { 500 if (m_cachedMetadata.contains(metadataType)) 501 return cachedValue; 496 502 497 503 if (!isDecoderAvailable() || !m_decoder->isSizeAvailable()) 498 504 return defaultValue; 499 505 500 if (!cachedValue) 501 return (*m_decoder.*functor)(); 502 503 *cachedValue = (*m_decoder.*functor)(); 506 cachedValue = (*m_decoder.*functor)(); 507 m_cachedMetadata.add(metadataType); 504 508 didDecodeProperties(m_decoder->bytesDecodedToDetermineProperties()); 505 return cachedValue->value(); 506 } 507 508 template<typename T, typename... Args> 509 T ImageSource::frameMetadataAtIndex(size_t index, T (ImageFrame::*functor)(Args...) const, Args&&... args) 510 { 511 const ImageFrame& frame = index < m_frames.size() ? m_frames[index] : ImageFrame::defaultFrame(); 512 return (frame.*functor)(std::forward<Args>(args)...); 513 } 514 515 template<typename T, typename... Args> 516 T ImageSource::frameMetadataAtIndexCacheIfNeeded(size_t index, T (ImageFrame::*functor)() const, Optional<T>* cachedValue, Args&&... args) 517 { 518 if (cachedValue && *cachedValue) 519 return cachedValue->value(); 520 521 const ImageFrame& frame = index < m_frames.size() ? frameAtIndexCacheIfNeeded(index, std::forward<Args>(args)...) : ImageFrame::defaultFrame(); 509 return cachedValue; 510 } 511 512 template<typename T> 513 T ImageSource::firstFrameMetadataCacheIfNeeded(T& cachedValue, MetadataType metadataType, T (ImageFrame::*functor)() const, ImageFrame::Caching caching, const Optional<SubsamplingLevel>& subsamplingLevel) 514 { 515 if (m_cachedMetadata.contains(metadataType)) 516 return cachedValue; 517 518 const ImageFrame& frame = frameAtIndexCacheIfNeeded(0, caching, subsamplingLevel); 522 519 523 520 // Don't cache any unavailable frame metadata. 524 if (!frame.hasMetadata() || !cachedValue)521 if (!frame.hasMetadata()) 525 522 return (frame.*functor)(); 526 523 527 *cachedValue = (frame.*functor)(); 528 return cachedValue->value(); 524 cachedValue = (frame.*functor)(); 525 m_cachedMetadata.add(metadataType); 526 return cachedValue; 529 527 } 530 528 531 529 EncodedDataStatus ImageSource::encodedDataStatus() 532 530 { 533 return metadata <EncodedDataStatus, (&ImageDecoder::encodedDataStatus)>(EncodedDataStatus::Unknown, &m_encodedDataStatus);531 return metadataCacheIfNeeded(m_encodedDataStatus, EncodedDataStatus::Unknown, MetadataType::EncodedDataStatus, &ImageDecoder::encodedDataStatus); 534 532 } 535 533 536 534 size_t ImageSource::frameCount() 537 535 { 538 return metadata <size_t, (&ImageDecoder::frameCount)>(m_frames.size(), &m_frameCount);536 return metadataCacheIfNeeded(m_frameCount, m_frames.size(), MetadataType::FrameCount, &ImageDecoder::frameCount); 539 537 } 540 538 541 539 RepetitionCount ImageSource::repetitionCount() 542 540 { 543 return metadata <RepetitionCount, (&ImageDecoder::repetitionCount)>(RepetitionCountNone, &m_repetitionCount);541 return metadataCacheIfNeeded(m_repetitionCount, static_cast<RepetitionCount>(RepetitionCountNone), MetadataType::RepetitionCount, &ImageDecoder::repetitionCount); 544 542 } 545 543 … … 547 545 { 548 546 #if USE(CG) 549 return metadata <String, (&ImageDecoder::uti)>(String(), &m_uti);547 return metadataCacheIfNeeded(m_uti, String(), MetadataType::UTI, &ImageDecoder::uti); 550 548 #else 551 549 return String(); … … 555 553 String ImageSource::filenameExtension() 556 554 { 557 return metadata <String, (&ImageDecoder::filenameExtension)>(String(), &m_filenameExtension);555 return metadataCacheIfNeeded(m_filenameExtension, String(), MetadataType::FileNameExtension, &ImageDecoder::filenameExtension); 558 556 } 559 557 560 558 String ImageSource::accessibilityDescription() 561 559 { 562 return metadata <String, (&ImageDecoder::accessibilityDescription)>(String(), &m_accessibilityDescription);560 return metadataCacheIfNeeded(m_accessibilityDescription, String(), MetadataType::AccessibilityDescription, &ImageDecoder::accessibilityDescription); 563 561 } 564 562 565 563 Optional<IntPoint> ImageSource::hotSpot() 566 564 { 567 return metadata <Optional<IntPoint>, (&ImageDecoder::hotSpot)>(WTF::nullopt, &m_hotSpot);565 return metadataCacheIfNeeded(m_hotSpot, { }, MetadataType::HotSpot, &ImageDecoder::hotSpot); 568 566 } 569 567 570 568 ImageOrientation ImageSource::orientation() 571 569 { 572 return f rameMetadataAtIndexCacheIfNeeded<ImageOrientation>(0, (&ImageFrame::orientation), &m_orientation, ImageFrame::Caching::Metadata);570 return firstFrameMetadataCacheIfNeeded(m_orientation, MetadataType::Orientation, &ImageFrame::orientation, ImageFrame::Caching::Metadata); 573 571 } 574 572 575 573 Optional<IntSize> ImageSource::densityCorrectedSize(ImageOrientation orientation) 576 574 { 577 auto size = f rameMetadataAtIndexCacheIfNeeded<Optional<IntSize>>(0, &ImageFrame::densityCorrectedSize, &m_densityCorrectedSize, ImageFrame::Caching::Metadata);575 auto size = firstFrameMetadataCacheIfNeeded(m_densityCorrectedSize, MetadataType::DensityCorrectedSize, &ImageFrame::densityCorrectedSize, ImageFrame::Caching::Metadata); 578 576 if (!size) 579 577 return WTF::nullopt; … … 601 599 else 602 600 #endif 603 size = f rameMetadataAtIndexCacheIfNeeded<IntSize>(0, (&ImageFrame::size), &m_size, ImageFrame::Caching::Metadata, SubsamplingLevel::Default);601 size = firstFrameMetadataCacheIfNeeded(m_size, MetadataType::Size, &ImageFrame::size, ImageFrame::Caching::Metadata, SubsamplingLevel::Default); 604 602 605 603 if (orientation == ImageOrientation::FromImage) … … 611 609 Color ImageSource::singlePixelSolidColor() 612 610 { 613 if (!m_ singlePixelSolidColor && (size() != IntSize(1, 1) || frameCount() != 1))611 if (!m_cachedMetadata.contains(MetadataType::SinglePixelSolidColor) && (size() != IntSize(1, 1) || frameCount() != 1)) { 614 612 m_singlePixelSolidColor = Color(); 615 616 if (m_singlePixelSolidColor) 617 return m_singlePixelSolidColor.value(); 618 619 return frameMetadataAtIndexCacheIfNeeded<Color>(0, (&ImageFrame::singlePixelSolidColor), &m_singlePixelSolidColor, ImageFrame::Caching::MetadataAndImage); 613 m_cachedMetadata.add(MetadataType::SinglePixelSolidColor); 614 } 615 616 return firstFrameMetadataCacheIfNeeded(m_singlePixelSolidColor, MetadataType::SinglePixelSolidColor, &ImageFrame::singlePixelSolidColor, ImageFrame::Caching::MetadataAndImage); 620 617 } 621 618 622 619 SubsamplingLevel ImageSource::maximumSubsamplingLevel() 623 620 { 624 if (m_ maximumSubsamplingLevel)625 return m_maximumSubsamplingLevel .value();621 if (m_cachedMetadata.contains(MetadataType::MaximumSubsamplingLevel)) 622 return m_maximumSubsamplingLevel; 626 623 627 624 if (!isDecoderAvailable() || !m_decoder->frameAllowSubsamplingAtIndex(0)) … … 640 637 641 638 m_maximumSubsamplingLevel = level; 642 return m_maximumSubsamplingLevel.value(); 639 m_cachedMetadata.add(MetadataType::MaximumSubsamplingLevel); 640 return m_maximumSubsamplingLevel; 643 641 } 644 642 … … 653 651 DecodingStatus ImageSource::frameDecodingStatusAtIndex(size_t index) 654 652 { 655 return frame MetadataAtIndexCacheIfNeeded<DecodingStatus>(index, (&ImageFrame::decodingStatus), nullptr, ImageFrame::Caching::Metadata);653 return frameAtIndexCacheIfNeeded(index, ImageFrame::Caching::Metadata).decodingStatus(); 656 654 } 657 655 658 656 bool ImageSource::frameHasAlphaAtIndex(size_t index) 659 657 { 660 return frame MetadataAtIndex<bool>(index, (&ImageFrame::hasAlpha));658 return frameAtIndex(index).hasAlpha(); 661 659 } 662 660 663 661 bool ImageSource::frameHasFullSizeNativeImageAtIndex(size_t index, const Optional<SubsamplingLevel>& subsamplingLevel) 664 662 { 665 return frame MetadataAtIndex<bool>(index, (&ImageFrame::hasFullSizeNativeImage),subsamplingLevel);663 return frameAtIndex(index).hasFullSizeNativeImage(subsamplingLevel); 666 664 } 667 665 668 666 bool ImageSource::frameHasDecodedNativeImageCompatibleWithOptionsAtIndex(size_t index, const Optional<SubsamplingLevel>& subsamplingLevel, const DecodingOptions& decodingOptions) 669 667 { 670 return frame MetadataAtIndex<bool>(index, (&ImageFrame::hasDecodedNativeImageCompatibleWithOptions),subsamplingLevel, decodingOptions);668 return frameAtIndex(index).hasDecodedNativeImageCompatibleWithOptions(subsamplingLevel, decodingOptions); 671 669 } 672 670 673 671 SubsamplingLevel ImageSource::frameSubsamplingLevelAtIndex(size_t index) 674 672 { 675 return frame MetadataAtIndex<SubsamplingLevel>(index, (&ImageFrame::subsamplingLevel));673 return frameAtIndex(index).subsamplingLevel(); 676 674 } 677 675 678 676 IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel) 679 677 { 680 return frame MetadataAtIndexCacheIfNeeded<IntSize>(index, (&ImageFrame::size), nullptr, ImageFrame::Caching::Metadata, subsamplingLevel);678 return frameAtIndexCacheIfNeeded(index, ImageFrame::Caching::Metadata, subsamplingLevel).size(); 681 679 } 682 680 683 681 unsigned ImageSource::frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel) 684 682 { 685 return frame MetadataAtIndexCacheIfNeeded<unsigned>(index, (&ImageFrame::frameBytes), nullptr, ImageFrame::Caching::Metadata, subsamplingLevel);683 return frameAtIndexCacheIfNeeded(index, ImageFrame::Caching::Metadata, subsamplingLevel).frameBytes(); 686 684 } 687 685 688 686 Seconds ImageSource::frameDurationAtIndex(size_t index) 689 687 { 690 return frame MetadataAtIndexCacheIfNeeded<Seconds>(index, (&ImageFrame::duration), nullptr, ImageFrame::Caching::Metadata);688 return frameAtIndexCacheIfNeeded(index, ImageFrame::Caching::Metadata).duration(); 691 689 } 692 690 693 691 ImageOrientation ImageSource::frameOrientationAtIndex(size_t index) 694 692 { 695 return frame MetadataAtIndexCacheIfNeeded<ImageOrientation>(index, (&ImageFrame::orientation), nullptr, ImageFrame::Caching::Metadata);693 return frameAtIndexCacheIfNeeded(index, ImageFrame::Caching::Metadata).orientation(); 696 694 } 697 695 … … 713 711 RefPtr<NativeImage> ImageSource::frameImageAtIndex(size_t index) 714 712 { 715 return frame MetadataAtIndex<RefPtr<NativeImage>>(index, (&ImageFrame::nativeImage));713 return frameAtIndex(index).nativeImage(); 716 714 } 717 715 718 716 RefPtr<NativeImage> ImageSource::frameImageAtIndexCacheIfNeeded(size_t index, SubsamplingLevel subsamplingLevel) 719 717 { 720 return frame MetadataAtIndexCacheIfNeeded<RefPtr<NativeImage>>(index, (&ImageFrame::nativeImage), nullptr, ImageFrame::Caching::MetadataAndImage, subsamplingLevel);718 return frameAtIndexCacheIfNeeded(index, ImageFrame::Caching::MetadataAndImage, subsamplingLevel).nativeImage(); 721 719 } 722 720 -
trunk/Source/WebCore/platform/graphics/ImageSource.h
r273214 r275570 1 1 /* 2 * Copyright (C) 2016-20 17Apple Inc. All rights reserved.2 * Copyright (C) 2016-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 135 135 ImageSource(RefPtr<NativeImage>&&); 136 136 137 template<typename T, T (ImageDecoder::*functor)() const> 138 T metadata(const T& defaultValue, Optional<T>* cachedValue = nullptr); 139 140 template<typename T, typename... Args> 141 T frameMetadataAtIndex(size_t, T (ImageFrame::*functor)(Args...) const, Args&&...); 142 143 template<typename T, typename... Args> 144 T frameMetadataAtIndexCacheIfNeeded(size_t, T (ImageFrame::*functor)() const, Optional<T>* cachedValue, Args&&...); 137 enum class MetadataType { 138 AccessibilityDescription = 1 << 0, 139 DensityCorrectedSize = 1 << 1, 140 EncodedDataStatus = 1 << 2, 141 FileNameExtension = 1 << 3, 142 FrameCount = 1 << 4, 143 HotSpot = 1 << 5, 144 MaximumSubsamplingLevel = 1 << 6, 145 Orientation = 1 << 7, 146 RepetitionCount = 1 << 8, 147 SinglePixelSolidColor = 1 << 9, 148 Size = 1 << 10, 149 UTI = 1 << 11 150 }; 151 152 template<typename T> 153 T metadataCacheIfNeeded(T& cachedValue, const T& defaultValue, MetadataType, T (ImageDecoder::*functor)() const); 154 155 template<typename T> 156 T firstFrameMetadataCacheIfNeeded(T& cachedValue, MetadataType, T (ImageFrame::*functor)() const, ImageFrame::Caching, const Optional<SubsamplingLevel>& = { }); 145 157 146 158 bool ensureDecoderAvailable(SharedBuffer* data); … … 164 176 SynchronizedFixedQueue<ImageFrameRequest, BufferSize>& frameRequestQueue(); 165 177 178 const ImageFrame& frameAtIndex(size_t index) { return index < m_frames.size() ? m_frames[index] : ImageFrame::defaultFrame(); } 166 179 const ImageFrame& frameAtIndexCacheIfNeeded(size_t, ImageFrame::Caching, const Optional<SubsamplingLevel>& = { }); 167 180 … … 196 209 197 210 // Image metadata. 198 Optional<EncodedDataStatus> m_encodedDataStatus;199 Optional<size_t> m_frameCount;200 Optional<RepetitionCount> m_repetitionCount;201 Optional<String>m_uti;202 Optional<String>m_filenameExtension;203 Optional<String>m_accessibilityDescription;204 Optional< Optional<IntPoint>> m_hotSpot;211 EncodedDataStatus m_encodedDataStatus { EncodedDataStatus::Unknown }; 212 size_t m_frameCount { 0 }; 213 RepetitionCount m_repetitionCount { RepetitionCountNone }; 214 String m_uti; 215 String m_filenameExtension; 216 String m_accessibilityDescription; 217 Optional<IntPoint> m_hotSpot; 205 218 206 219 // Image metadata which is calculated from the first ImageFrame. 207 Optional<IntSize> m_size; 208 Optional<ImageOrientation> m_orientation; 209 Optional<Optional<IntSize>> m_densityCorrectedSize; 210 Optional<Color> m_singlePixelSolidColor; 211 Optional<SubsamplingLevel> m_maximumSubsamplingLevel; 220 IntSize m_size; 221 Optional<IntSize> m_densityCorrectedSize; 222 ImageOrientation m_orientation; 223 Color m_singlePixelSolidColor; 224 SubsamplingLevel m_maximumSubsamplingLevel { SubsamplingLevel::Default }; 225 226 OptionSet<MetadataType> m_cachedMetadata; 212 227 213 228 RunLoop& m_runLoop;
Note: See TracChangeset
for help on using the changeset viewer.