Changeset 235165 in webkit
- Timestamp:
- Aug 22, 2018 5:14:14 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ChangeLog
r235118 r235165 1 2018-08-22 Zan Dobersek <zdobersek@igalia.com> 2 3 [CoordGraphics] Switch to Nicosia::CompositionLayer state tracking 4 https://bugs.webkit.org/show_bug.cgi?id=188693 5 6 Reviewed by Carlos Garcia Campos. 7 8 * Source/cmake/OptionsGTK.cmake: Enable USE_NICOSIA alongside 9 USE_COORDINATED_GRAPHICS and USE_COORDINATED_GRAPHICS_THREADED. 10 * Source/cmake/OptionsWPE.cmake: Ditto. 11 1 12 2018-08-21 Adrian Perez de Castro <aperez@igalia.com> 2 13 -
trunk/Source/WebCore/ChangeLog
r235164 r235165 1 2018-08-22 Zan Dobersek <zdobersek@igalia.com> 2 3 [CoordGraphics] Switch to Nicosia::CompositionLayer state tracking 4 https://bugs.webkit.org/show_bug.cgi?id=188693 5 6 Reviewed by Carlos Garcia Campos. 7 8 Populate Nicosia::CompositionLayer with additional LayerState member 9 objects. For now we're using pending, staging and committed states, 10 though it might be possible to narrow down these to just two. 11 12 Pending state contains state that will be moved to staging during the 13 final steps of the next layer flush. flushState() method accumulates all 14 state changes in the staging state, and also allows the caller to 15 additionally perform flushing operations that are specific to backing 16 store, image backing or content layer containers. 17 18 commitState() method moves staging state over into the committed state, 19 again allowing user to pass a functor that receives the just-committed 20 state and apply it to their composition engine. 21 22 Changes in state objects are done under a thread-safe lock. This might 23 not be completely necessary at this point, but will be useful when 24 additonal layer state updates will be coming from e.g. the scrolling 25 thread. It might also make sense to tie in this lock use with the 26 Nicosia::Scene lock in the future. 27 28 Nicosia::ContentLayerTextureMapperImpl is modified slightly to allow 29 determining during flushes whether an update is pending. This is 30 necessary for a special case in ThreadedCompositor where content (i.e. 31 platform) layers like WebGL or video require an additional level of 32 scene update coordination. This complete special case has to go through 33 another review to see whether it's still necessary. Ideally we would be 34 able to remove it. 35 36 CoordinatedGraphicsLayer is finally switched over to using 37 Nicosia layer objects for state updates of any kind. This patch only 38 adds all the necessary bits, but doesn't yet remove any of the existing 39 code (but rather disables it temporarily, before it's removed). 40 41 Updating of simple state values is already in place. For backing stores, 42 the flushCompositingStateForThisLayerOnly() method now takes care of 43 preparing the backing store object if necessary as per layer state, 44 while the updateContentBuffers() method is switched to operate with 45 TiledBackingStore objects now kept on the BackingStoreTextureMapperImpl 46 instance associated with that backing store. Helper methods like 47 adjustContentsScale() and createBackingStore(), only called from the 48 updateContentBuffers() method, are removed and the code there inlined. 49 50 For image-backed layers, the update is now done directly in 51 the flushCompositingStateForThisLayerOnly() method, if necessary. The 52 helper syncImageBacking() method is commented out in order to prevent 53 double-painting of image buffers for now, but all this (along with the 54 CoordinatedImageBacking logic in CompositingCoordinator) will be removed 55 later. 56 57 For layers backed by platform layer objects, integration is relatively 58 simple. setContentsToPlatformLayer() is changed to properly handle any 59 passed-in platform layer object, and updatePlatformLayer() invokes the 60 swapBuffersIfNeeded() method on the ContentLayerTextureMapperImpl object 61 during each flush, if necessary. 62 63 In order to ensure any Nicosia-specific state update properly triggers 64 a composition update, m_nicosia.performLayerUpdate is added and flipped 65 to true during the flush in case of any state change. This then triggers 66 a layer sync in the CompositingCoordinator object when the 67 syncPendingStateChangesIncludingSubLayers() method is called. While no 68 old-style layer state update is provided, it causes the necessary 69 synchronization step that properly picks up the Nicosia-provided state 70 changes. Once the old-style layer state tracking is removed, this method 71 of update triggering will have to be updated as well. 72 73 * platform/graphics/nicosia/NicosiaPlatformLayer.h: 74 (Nicosia::CompositionLayer::flushState): 75 (Nicosia::CompositionLayer::commitState): 76 (Nicosia::CompositionLayer::accessCommitted): 77 * platform/graphics/nicosia/NicosiaScene.h: 78 * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp: 79 (Nicosia::ContentLayerTextureMapperImpl::flushUpdate): 80 * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.h: 81 * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp: 82 (WebCore::CoordinatedGraphicsLayer::~CoordinatedGraphicsLayer): 83 (WebCore::CoordinatedGraphicsLayer::setContentsNeedsDisplay): 84 (WebCore::CoordinatedGraphicsLayer::setContentsToPlatformLayer): 85 (WebCore::CoordinatedGraphicsLayer::updatePlatformLayer): 86 (WebCore::CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly): 87 (WebCore::CoordinatedGraphicsLayer::syncPendingStateChangesIncludingSubLayers): 88 (WebCore::CoordinatedGraphicsLayer::updateContentBuffers): 89 (WebCore::CoordinatedGraphicsLayer::purgeBackingStores): 90 (WebCore::CoordinatedGraphicsLayer::adjustContentsScale): Deleted. 91 (WebCore::CoordinatedGraphicsLayer::createBackingStore): Deleted. 92 * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h: 93 1 94 2018-08-22 David Kilzer <ddkilzer@apple.com> 2 95 -
trunk/Source/WebCore/platform/graphics/nicosia/NicosiaPlatformLayer.h
r234594 r235165 181 181 } 182 182 183 template<typename T> 184 void flushState(const T& functor) 185 { 186 LockHolder locker(PlatformLayer::m_state.lock); 187 auto& pending = m_state.pending; 188 auto& staging = m_state.staging; 189 190 staging.delta.value |= pending.delta.value; 191 192 if (pending.delta.positionChanged) 193 staging.position = pending.position; 194 if (pending.delta.anchorPointChanged) 195 staging.anchorPoint = pending.anchorPoint; 196 if (pending.delta.sizeChanged) 197 staging.size = pending.size; 198 199 if (pending.delta.transformChanged) 200 staging.transform = pending.transform; 201 if (pending.delta.childrenTransformChanged) 202 staging.childrenTransform = pending.childrenTransform; 203 204 if (pending.delta.contentsRectChanged) 205 staging.contentsRect = pending.contentsRect; 206 if (pending.delta.contentsTilingChanged) { 207 staging.contentsTilePhase = pending.contentsTilePhase; 208 staging.contentsTileSize = pending.contentsTileSize; 209 } 210 211 if (pending.delta.opacityChanged) 212 staging.opacity = pending.opacity; 213 if (pending.delta.solidColorChanged) 214 staging.solidColor = pending.solidColor; 215 216 if (pending.delta.filtersChanged) 217 staging.filters = pending.filters; 218 if (pending.delta.animationsChanged) 219 staging.animations = pending.animations; 220 221 if (pending.delta.childrenChanged) 222 staging.children = pending.children; 223 if (pending.delta.maskChanged) 224 staging.mask = pending.mask; 225 if (pending.delta.replicaChanged) 226 staging.replica = pending.replica; 227 228 if (pending.delta.flagsChanged) 229 staging.flags.value = pending.flags.value; 230 231 if (pending.delta.repaintCounterChanged) 232 staging.repaintCounter = pending.repaintCounter; 233 if (pending.delta.debugBorderChanged) 234 staging.debugBorder = pending.debugBorder; 235 236 if (pending.delta.backingStoreChanged) 237 staging.backingStore = pending.backingStore; 238 if (pending.delta.contentLayerChanged) 239 staging.contentLayer = pending.contentLayer; 240 if (pending.delta.imageBackingChanged) 241 staging.imageBacking = pending.imageBacking; 242 243 pending.delta = { }; 244 245 functor(staging); 246 } 247 248 template<typename T> 249 void commitState(const T& functor) 250 { 251 LockHolder locker(PlatformLayer::m_state.lock); 252 m_state.committed = m_state.staging; 253 m_state.staging.delta = { }; 254 255 functor(m_state.committed); 256 } 257 258 template<typename T> 259 void accessCommitted(const T& functor) 260 { 261 LockHolder locker(PlatformLayer::m_state.lock); 262 functor(m_state.committed); 263 } 264 183 265 private: 184 266 CompositionLayer(uint64_t, const Impl::Factory&); … … 188 270 struct { 189 271 LayerState pending; 272 LayerState staging; 273 LayerState committed; 190 274 } m_state; 191 275 }; -
trunk/Source/WebCore/platform/graphics/nicosia/NicosiaScene.h
r234593 r235165 52 52 53 53 uint32_t id { 0 }; 54 // FIXME: This is needed for a ThreadedCompositor oddity that might not even be 55 // necessary anymore. It that has to be checked and ideally removed. 56 // https://bugs.webkit.org/show_bug.cgi?id=188839 57 bool platformLayerUpdated { false }; 54 58 HashSet<RefPtr<Nicosia::CompositionLayer>> layers; 55 59 RefPtr<Nicosia::CompositionLayer> rootLayer; -
trunk/Source/WebCore/platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp
r234643 r235165 64 64 } 65 65 66 bool ContentLayerTextureMapperImpl::flushUpdate() 67 { 68 LockHolder locker(m_client.lock); 69 return std::exchange(m_client.pendingUpdate, false); 70 } 71 66 72 void ContentLayerTextureMapperImpl::swapBuffersIfNeeded() 67 73 { -
trunk/Source/WebCore/platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.h
r234643 r235165 57 57 void invalidateClient(); 58 58 59 bool flushUpdate(); 60 59 61 WebCore::TextureMapperPlatformLayerProxy& proxy() const { return m_proxy; } 60 62 void swapBuffersIfNeeded(); … … 65 67 Lock lock; 66 68 Client* client { nullptr }; 69 bool pendingUpdate { true }; // Starts off with a pending update. 67 70 } m_client; 68 71 }; -
trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp
r234688 r235165 31 31 #include "GraphicsLayer.h" 32 32 #include "GraphicsLayerFactory.h" 33 #include "NicosiaBackingStoreTextureMapperImpl.h" 33 34 #include "NicosiaCompositionLayerTextureMapperImpl.h" 35 #include "NicosiaContentLayerTextureMapperImpl.h" 36 #include "NicosiaImageBackingTextureMapperImpl.h" 37 #include "NicosiaPaintingContext.h" 34 38 #include "NicosiaPaintingEngine.h" 35 39 #include "ScrollableArea.h" … … 161 165 ASSERT(!m_coordinatedImageBacking); 162 166 ASSERT(!m_mainBackingStore); 167 ASSERT(!m_nicosia.imageBacking); 168 ASSERT(!m_nicosia.backingStore); 163 169 willBeDestroyed(); 164 170 } … … 422 428 { 423 429 #if USE(COORDINATED_GRAPHICS_THREADED) 430 #if USE(NICOSIA) 431 if (m_nicosia.contentLayer) 432 m_shouldUpdatePlatformLayer = true; 433 #else 424 434 if (m_platformLayer) 425 435 m_shouldUpdatePlatformLayer = true; 426 436 #endif 437 #endif 427 438 428 439 notifyFlushRequired(); … … 434 445 #if USE(COORDINATED_GRAPHICS_THREADED) 435 446 #if USE(NICOSIA) 447 auto* contentLayer = downcast<Nicosia::ContentLayer>(platformLayer); 448 if (m_nicosia.contentLayer != contentLayer) { 449 m_shouldSyncPlatformLayer = true; 450 m_nicosia.contentLayer = contentLayer; 451 m_nicosia.delta.contentLayerChanged = true; 452 } 436 453 #else 437 454 if (m_platformLayer != platformLayer) … … 768 785 #if USE(COORDINATED_GRAPHICS_THREADED) 769 786 #if USE(NICOSIA) 787 if (m_nicosia.contentLayer) 788 downcast<Nicosia::ContentLayerTextureMapperImpl>(m_nicosia.contentLayer->impl()).swapBuffersIfNeeded(); 770 789 #else 771 790 m_layerState.platformLayerUpdated = true; … … 786 805 computePixelAlignment(m_adjustedPosition, m_adjustedSize, m_adjustedAnchorPoint, m_pixelAlignmentOffset); 787 806 788 syncImageBacking(); 807 // FIXME: this is commented out to immediately disable any old-way image updates. 808 // It will soon be removed in a larger cleanup. 809 // syncImageBacking(); 810 789 811 syncLayerState(); 790 812 syncAnimations(); … … 798 820 if (!hasActiveTransformAnimation) 799 821 m_movingVisibleRect = false; 822 823 // Determine the backing store presence. Content is painted later, in the updateContentBuffers() traversal. 824 if (shouldHaveBackingStore()) { 825 if (!m_nicosia.backingStore) { 826 m_nicosia.backingStore = Nicosia::BackingStore::create(Nicosia::BackingStoreTextureMapperImpl::createFactory()); 827 m_nicosia.delta.backingStoreChanged = true; 828 } 829 } else if (m_nicosia.backingStore) { 830 auto& layerState = downcast<Nicosia::BackingStoreTextureMapperImpl>(m_nicosia.backingStore->impl()).layerState(); 831 layerState.isPurging = true; 832 layerState.mainBackingStore = nullptr; 833 layerState.previousBackingStore = nullptr; 834 835 m_nicosia.backingStore = nullptr; 836 m_nicosia.delta.backingStoreChanged = true; 837 } 838 839 // Determine image backing presence according to the composited image source. 840 if (m_compositedNativeImagePtr) { 841 ASSERT(m_compositedImage); 842 auto& image = *m_compositedImage; 843 uintptr_t imageID = reinterpret_cast<uintptr_t>(&image); 844 uintptr_t nativeImageID = reinterpret_cast<uintptr_t>(m_compositedNativeImagePtr.get()); 845 846 // Respawn the ImageBacking object if the underlying image changed. 847 if (m_nicosia.imageBacking) { 848 auto& impl = downcast<Nicosia::ImageBackingTextureMapperImpl>(m_nicosia.imageBacking->impl()); 849 if (impl.layerState().imageID != imageID) { 850 impl.layerState().update = Nicosia::ImageBackingTextureMapperImpl::Update { }; 851 m_nicosia.imageBacking = nullptr; 852 } 853 } 854 if (!m_nicosia.imageBacking) { 855 m_nicosia.imageBacking = Nicosia::ImageBacking::create(Nicosia::ImageBackingTextureMapperImpl::createFactory()); 856 m_nicosia.delta.imageBackingChanged = true; 857 } 858 859 // Update the image contents only when the image layer is visible and the native image changed. 860 auto& impl = downcast<Nicosia::ImageBackingTextureMapperImpl>(m_nicosia.imageBacking->impl()); 861 auto& layerState = impl.layerState(); 862 layerState.imageID = imageID; 863 layerState.update.isVisible = transformedVisibleRect().intersects(IntRect(contentsRect())); 864 if (layerState.update.isVisible && layerState.nativeImageID != nativeImageID) { 865 auto buffer = Nicosia::Buffer::create(IntSize(image.size()), 866 !image.currentFrameKnownToBeOpaque() ? Nicosia::Buffer::SupportsAlpha : Nicosia::Buffer::NoFlags); 867 Nicosia::PaintingContext::paint(buffer, 868 [&image](GraphicsContext& context) 869 { 870 IntRect rect { { }, IntSize { image.size() } }; 871 context.drawImage(image, rect, rect, ImagePaintingOptions(CompositeCopy)); 872 }); 873 layerState.nativeImageID = nativeImageID; 874 layerState.update.buffer = WTFMove(buffer); 875 m_nicosia.delta.imageBackingChanged = true; 876 } 877 } else if (m_nicosia.imageBacking) { 878 auto& layerState = downcast<Nicosia::ImageBackingTextureMapperImpl>(m_nicosia.imageBacking->impl()).layerState(); 879 layerState.update = Nicosia::ImageBackingTextureMapperImpl::Update { }; 880 m_nicosia.imageBacking = nullptr; 881 m_nicosia.delta.imageBackingChanged = true; 882 } 800 883 801 884 { … … 868 951 if (localDelta.debugBorderChanged) 869 952 state.debugBorder = m_nicosia.debugBorder; 953 954 if (localDelta.backingStoreChanged) 955 state.backingStore = m_nicosia.backingStore; 956 if (localDelta.contentLayerChanged) 957 state.contentLayer = m_nicosia.contentLayer; 958 if (localDelta.imageBackingChanged) 959 state.imageBacking = m_nicosia.imageBacking; 870 960 }); 961 m_nicosia.performLayerSync = !!m_nicosia.delta.value; 871 962 m_nicosia.delta = { }; 872 963 } … … 875 966 void CoordinatedGraphicsLayer::syncPendingStateChangesIncludingSubLayers() 876 967 { 877 if (m_layerState.hasPendingChanges()) { 968 // FIXME: For now the best way for layer state changes to trigger an update is to use 969 // the CoordinatedGraphicsLayerClient::syncLayerState() method. This should be simplified 970 // once the m_layerState member object is removed. 971 if (m_nicosia.performLayerSync || m_layerState.hasPendingChanges()) { 878 972 m_coordinator->syncLayerState(m_id, m_layerState); 879 973 resetLayerState(); 880 974 } 975 m_nicosia.performLayerSync = false; 881 976 882 977 if (maskLayer()) … … 922 1017 { 923 1018 return selfOrAncestorHaveNonAffineTransforms() ? 1 : deviceScaleFactor() * pageScaleFactor(); 924 }925 926 void CoordinatedGraphicsLayer::adjustContentsScale()927 {928 ASSERT(shouldHaveBackingStore());929 if (!m_mainBackingStore || m_mainBackingStore->contentsScale() == effectiveContentsScale())930 return;931 932 // Between creating the new backing store and painting the content,933 // we do not want to drop the previous one as that might result in934 // briefly seeing flickering as the old tiles may be dropped before935 // something replaces them.936 m_previousBackingStore = WTFMove(m_mainBackingStore);937 938 // No reason to save the previous backing store for non-visible areas.939 m_previousBackingStore->removeAllNonVisibleTiles(transformedVisibleRect(), IntRect(0, 0, size().width(), size().height()));940 }941 942 void CoordinatedGraphicsLayer::createBackingStore()943 {944 m_mainBackingStore = std::make_unique<TiledBackingStore>(*this, effectiveContentsScale());945 1019 } 946 1020 … … 1025 1099 void CoordinatedGraphicsLayer::updateContentBuffers() 1026 1100 { 1027 if (!shouldHaveBackingStore()) { 1028 m_mainBackingStore = nullptr; 1029 m_previousBackingStore = nullptr; 1030 return; 1031 } 1032 1101 if (!m_nicosia.backingStore) 1102 return; 1103 1104 // Prepare for painting on the impl-contained backing store. isFlushing is used there 1105 // for internal sanity checks. 1106 auto& impl = downcast<Nicosia::BackingStoreTextureMapperImpl>(m_nicosia.backingStore->impl()); 1107 auto& layerState = impl.layerState(); 1108 layerState.isFlushing = true; 1109 1110 // Helper lambda that finished the flush update and determines layer sync necessity. 1111 auto finishUpdate = 1112 [this, &layerState] { 1113 auto& update = layerState.update; 1114 m_nicosia.performLayerSync = !update.tilesToCreate.isEmpty() 1115 || !update.tilesToRemove.isEmpty() || !update.tilesToUpdate.isEmpty(); 1116 layerState.isFlushing = false; 1117 }; 1118 1119 // Address the content scale adjustment. 1120 // FIXME: the previousBackingStore logic is likely possible to remove. 1121 // https://bugs.webkit.org/show_bug.cgi?id=188693 1033 1122 if (m_pendingContentsScaleAdjustment) { 1034 adjustContentsScale(); 1123 if (layerState.mainBackingStore && layerState.mainBackingStore->contentsScale() != effectiveContentsScale()) { 1124 // Between creating the new backing store and painting the content, we do not 1125 // want to drop the previous one as that might result in briefly seeing flickering 1126 // as the old tiles may be dropped before something replaces them. 1127 layerState.previousBackingStore = WTFMove(layerState.mainBackingStore); 1128 1129 // No reason to save the previous backing store for non-visible areas. 1130 layerState.previousBackingStore->removeAllNonVisibleTiles(transformedVisibleRect(), IntRect(0, 0, size().width(), size().height())); 1131 } 1035 1132 m_pendingContentsScaleAdjustment = false; 1036 1133 } 1037 1134 1038 // This is the only place we (re)create the main tiled backing store, once we 1039 // have a remote client and we are ready to send our data to the UI process. 1040 if (!m_mainBackingStore) { 1041 createBackingStore(); 1135 // Ensure the TiledBackingStore object, and enforce a complete repaint if it's not been present yet. 1136 if (!layerState.mainBackingStore) { 1137 layerState.mainBackingStore = std::make_unique<TiledBackingStore>(impl, effectiveContentsScale()); 1042 1138 m_pendingVisibleRectAdjustment = true; 1043 1139 } 1044 1140 1045 if (!m_pendingVisibleRectAdjustment && !m_needsDisplay.completeLayer && m_needsDisplay.rects.isEmpty()) 1046 return; 1141 // Bail if there's no painting recorded or enforced. 1142 if (!m_pendingVisibleRectAdjustment && !m_needsDisplay.completeLayer && m_needsDisplay.rects.isEmpty()) { 1143 finishUpdate(); 1144 return; 1145 } 1047 1146 1048 1147 if (!m_needsDisplay.completeLayer) { 1049 1148 for (auto& rect : m_needsDisplay.rects) 1050 m_mainBackingStore->invalidate(IntRect { rect });1149 layerState.mainBackingStore->invalidate(IntRect { rect }); 1051 1150 } else 1052 m_mainBackingStore->invalidate({ { }, IntSize { m_size } });1151 layerState.mainBackingStore->invalidate({ { }, IntSize { m_size } }); 1053 1152 1054 1153 m_needsDisplay.completeLayer = false; … … 1057 1156 if (m_pendingVisibleRectAdjustment) { 1058 1157 m_pendingVisibleRectAdjustment = false; 1059 m_mainBackingStore->createTilesIfNeeded(transformedVisibleRect(), IntRect(0, 0, size().width(), size().height()));1158 layerState.mainBackingStore->createTilesIfNeeded(transformedVisibleRect(), IntRect(0, 0, m_size.width(), m_size.height())); 1060 1159 } 1061 1160 1062 1161 ASSERT(m_coordinator && m_coordinator->isFlushingLayerChanges()); 1063 1162 1064 auto dirtyTiles = m_mainBackingStore->dirtyTiles(); 1163 // With all the affected tiles created and/or invalidated, we can finally paint them. 1164 auto dirtyTiles = layerState.mainBackingStore->dirtyTiles(); 1065 1165 if (!dirtyTiles.isEmpty()) { 1066 1166 bool didUpdateTiles = false; … … 1080 1180 1081 1181 if (!m_coordinator->paintingEngine().paint(*this, WTFMove(coordinatedBuffer), 1082 dirtyRect, m_mainBackingStore->mapToContents(dirtyRect),1083 IntRect { { 0, 0 }, dirtyRect.size() }, m_mainBackingStore->contentsScale()))1182 dirtyRect, layerState.mainBackingStore->mapToContents(dirtyRect), 1183 IntRect { { 0, 0 }, dirtyRect.size() }, layerState.mainBackingStore->contentsScale())) 1084 1184 continue; 1085 1185 1086 updateTile(tile.tileID(), updateInfo, tileRect);1186 impl.updateTile(tile.tileID(), updateInfo, tileRect); 1087 1187 1088 1188 tile.markClean(); … … 1097 1197 // removing the existing tiles and painting the new ones. The first time 1098 1198 // the visibleRect is full painted we remove the previous backing store. 1099 if (m_previousBackingStore && m_mainBackingStore->visibleAreaIsCovered()) 1100 m_previousBackingStore = nullptr; 1199 if (layerState.previousBackingStore && layerState.mainBackingStore->visibleAreaIsCovered()) 1200 layerState.previousBackingStore = nullptr; 1201 1202 // Request a second update immediately if some tiles are still pending creation. 1203 if (layerState.hasPendingTileCreation) { 1204 setNeedsVisibleRectAdjustment(); 1205 notifyFlushRequired(); 1206 } 1207 1208 finishUpdate(); 1101 1209 } 1102 1210 … … 1108 1216 m_mainBackingStore = nullptr; 1109 1217 m_previousBackingStore = nullptr; 1218 if (m_nicosia.backingStore) { 1219 auto& layerState = downcast<Nicosia::BackingStoreTextureMapperImpl>(m_nicosia.backingStore->impl()).layerState(); 1220 layerState.isPurging = true; 1221 layerState.mainBackingStore = nullptr; 1222 layerState.previousBackingStore = nullptr; 1223 1224 m_nicosia.backingStore = nullptr; 1225 } 1110 1226 1111 1227 releaseImageBackingIfNeeded(); -
trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h
r233910 r235165 111 111 void suspendAnimations(MonotonicTime) override; 112 112 void resumeAnimations() override; 113 bool usesContentsLayer() const override { return m_platformLayer || m_ compositedImage; }113 bool usesContentsLayer() const override { return m_platformLayer || m_nicosia.contentLayer || m_compositedImage; } 114 114 115 115 void syncPendingStateChangesIncludingSubLayers(); … … 162 162 void updateContentBuffers(); 163 163 164 void createBackingStore();165 164 void releaseImageBackingIfNeeded(); 166 165 … … 172 171 bool selfOrAncestorHasActiveTransformAnimation() const; 173 172 bool selfOrAncestorHaveNonAffineTransforms(); 174 void adjustContentsScale();175 173 176 174 void setShouldUpdateVisibleRect(); … … 232 230 Nicosia::CompositionLayer::LayerState::RepaintCounter repaintCounter; 233 231 Nicosia::CompositionLayer::LayerState::DebugBorder debugBorder; 232 bool performLayerSync { false }; 233 234 RefPtr<Nicosia::BackingStore> backingStore; 235 RefPtr<Nicosia::ContentLayer> contentLayer; 236 RefPtr<Nicosia::ImageBacking> imageBacking; 234 237 } m_nicosia; 235 238 }; -
trunk/Source/WebKit/ChangeLog
r235158 r235165 1 2018-08-22 Zan Dobersek <zdobersek@igalia.com> 2 3 [CoordGraphics] Switch to Nicosia::CompositionLayer state tracking 4 https://bugs.webkit.org/show_bug.cgi?id=188693 5 6 Reviewed by Carlos Garcia Campos. 7 8 Switch CoordinatedGraphicsScene to utilizing Nicosia::CompositionLayer 9 objects for state updates of the TextureMapper layer tree. 10 11 CoordinatedGraphicsScene::paintToCurrentGLContext() now calls 12 updateSceneState() at the beginning. This is a new method that manages 13 all updates for a given Nicosia::Scene instance. Any removed layers 14 have their composition-side state cleaned up, and the current set of 15 layers is then iterated to ensure and update the corresponding 16 TextureMapperLayer objects. 17 18 Layers with any backing (painted backing store, platform-layer or image 19 content) are temporarly stored for updating outside of mutex-controlled 20 scene update. Performing all other state updates outside of this mutex 21 area will be investigated at a later point. 22 23 We then iterate over vectors for each layer backing, gathering any 24 affected CoordinatedBackingStore or TextureMapperPlatformLayerProxy 25 objects that we have to update. 26 27 This drops a bunch of member variables and helper methods off the 28 CoordinatedGraphicsScene class. The applyStateChanges() method will be 29 further simplified in the future. coordinateUpdateCompletionWithClient 30 logic in ThreadedCompositor should be checked to see whether it still 31 addresses any real-life problem, because at the moment it imposes a few 32 additional operations in terms of scene updates that we could really do 33 without. This will be checked later and removed if possible. 34 35 * Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp: 36 (WebKit::CoordinatedGraphicsScene::applyStateChanges): 37 (WebKit::CoordinatedGraphicsScene::paintToCurrentGLContext): 38 (WebKit::compositionLayerImpl): 39 (WebKit::contentLayerImpl): 40 (WebKit::backingStoreImpl): 41 (WebKit::imageBackingImpl): 42 (WebKit::texmapLayer): 43 (WebKit::updateBackingStore): 44 (WebKit::updateImageBacking): 45 (WebKit::removeLayer): 46 (WebKit::CoordinatedGraphicsScene::commitSceneState): 47 (WebKit::CoordinatedGraphicsScene::updateSceneState): 48 (WebKit::CoordinatedGraphicsScene::purgeGLResources): 49 (WebKit::CoordinatedGraphicsScene::syncPlatformLayerIfNeeded): Deleted. 50 (WebKit::CoordinatedGraphicsScene::setLayerChildrenIfNeeded): Deleted. 51 (WebKit::CoordinatedGraphicsScene::setLayerFiltersIfNeeded): Deleted. 52 (WebKit::CoordinatedGraphicsScene::setLayerState): Deleted. 53 (WebKit::CoordinatedGraphicsScene::getLayerByIDIfExists): Deleted. 54 (WebKit::CoordinatedGraphicsScene::createLayers): Deleted. 55 (WebKit::CoordinatedGraphicsScene::createLayer): Deleted. 56 (WebKit::CoordinatedGraphicsScene::deleteLayers): Deleted. 57 (WebKit::CoordinatedGraphicsScene::deleteLayer): Deleted. 58 (WebKit::CoordinatedGraphicsScene::setRootLayerID): Deleted. 59 (WebKit::CoordinatedGraphicsScene::prepareContentBackingStore): Deleted. 60 (WebKit::CoordinatedGraphicsScene::createBackingStoreIfNeeded): Deleted. 61 (WebKit::CoordinatedGraphicsScene::removeBackingStoreIfNeeded): Deleted. 62 (WebKit::CoordinatedGraphicsScene::resetBackingStoreSizeToLayerSize): Deleted. 63 (WebKit::CoordinatedGraphicsScene::createTilesIfNeeded): Deleted. 64 (WebKit::CoordinatedGraphicsScene::removeTilesIfNeeded): Deleted. 65 (WebKit::CoordinatedGraphicsScene::updateTilesIfNeeded): Deleted. 66 (WebKit::CoordinatedGraphicsScene::syncImageBackings): Deleted. 67 (WebKit::CoordinatedGraphicsScene::createImageBacking): Deleted. 68 (WebKit::CoordinatedGraphicsScene::updateImageBacking): Deleted. 69 (WebKit::CoordinatedGraphicsScene::clearImageBackingContents): Deleted. 70 (WebKit::CoordinatedGraphicsScene::removeImageBacking): Deleted. 71 (WebKit::CoordinatedGraphicsScene::assignImageBackingToLayer): Deleted. 72 (WebKit::CoordinatedGraphicsScene::setLayerAnimationsIfNeeded): Deleted. 73 * Shared/CoordinatedGraphics/CoordinatedGraphicsScene.h: 74 (WebKit::CoordinatedGraphicsScene::layerByID): Deleted. 75 * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp: 76 (WebKit::ThreadedCompositor::renderLayerTree): 77 * WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp: 78 (WebKit::CompositingCoordinator::flushPendingLayerChanges): 79 1 80 2018-08-21 Ryosuke Niwa <rniwa@webkit.org> 2 81 -
trunk/Source/WebKit/Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp
r234455 r235165 26 26 27 27 #include <WebCore/CoordinatedBackingStore.h> 28 #include <WebCore/NicosiaBackingStoreTextureMapperImpl.h> 28 29 #include <WebCore/NicosiaBuffer.h> 30 #include <WebCore/NicosiaCompositionLayerTextureMapperImpl.h> 31 #include <WebCore/NicosiaContentLayerTextureMapperImpl.h> 32 #include <WebCore/NicosiaImageBackingTextureMapperImpl.h> 33 #include <WebCore/NicosiaScene.h> 29 34 #include <WebCore/TextureMapper.h> 30 35 #include <WebCore/TextureMapperBackingStore.h> … … 58 63 59 64 for (auto& state : states) 60 commitSceneState(state );65 commitSceneState(state.nicosia); 61 66 } 62 67 63 68 void CoordinatedGraphicsScene::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, const Color& backgroundColor, bool drawsBackground, TextureMapper::PaintFlags PaintFlags) 64 69 { 70 updateSceneState(); 71 65 72 TextureMapperLayer* currentRootLayer = rootLayer(); 66 73 if (!currentRootLayer) 67 74 return; 68 69 #if USE(COORDINATED_GRAPHICS_THREADED)70 for (auto& proxy : m_platformLayerProxies.values())71 proxy->swapBuffer();72 #endif73 75 74 76 currentRootLayer->setTextureMapper(m_textureMapper.get()); … … 105 107 } 106 108 107 void CoordinatedGraphicsScene::syncPlatformLayerIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)108 {109 #if USE(COORDINATED_GRAPHICS_THREADED)110 if (!state.platformLayerChanged)111 return;112 113 if (state.platformLayerProxy) {114 m_platformLayerProxies.set(layer, state.platformLayerProxy);115 state.platformLayerProxy->activateOnCompositingThread(this, layer);116 } else117 m_platformLayerProxies.remove(layer);118 #else119 UNUSED_PARAM(layer);120 UNUSED_PARAM(state);121 #endif122 }123 124 109 #if USE(COORDINATED_GRAPHICS_THREADED) 125 110 void CoordinatedGraphicsScene::onNewBufferAvailable() … … 129 114 #endif 130 115 131 void CoordinatedGraphicsScene::setLayerChildrenIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state) 132 { 133 if (!state.childrenChanged) 134 return; 135 136 Vector<TextureMapperLayer*> children; 137 children.reserveCapacity(state.children.size()); 138 for (auto& child : state.children) 139 children.append(layerByID(child)); 140 141 layer->setChildren(children); 142 } 143 144 void CoordinatedGraphicsScene::setLayerFiltersIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state) 145 { 146 if (!state.filtersChanged) 147 return; 148 149 layer->setFilters(state.filters); 150 } 151 152 void CoordinatedGraphicsScene::setLayerState(CoordinatedLayerID id, const CoordinatedGraphicsLayerState& layerState, CommitScope& commitScope) 153 { 154 ASSERT(m_rootLayerID != InvalidCoordinatedLayerID); 155 TextureMapperLayer* layer = layerByID(id); 156 157 if (layerState.positionChanged) 158 layer->setPosition(layerState.pos); 159 160 if (layerState.anchorPointChanged) 161 layer->setAnchorPoint(layerState.anchorPoint); 162 163 if (layerState.sizeChanged) 164 layer->setSize(layerState.size); 165 166 if (layerState.transformChanged) 167 layer->setTransform(layerState.transform); 168 169 if (layerState.childrenTransformChanged) 170 layer->setChildrenTransform(layerState.childrenTransform); 171 172 if (layerState.contentsRectChanged) 173 layer->setContentsRect(layerState.contentsRect); 174 175 if (layerState.contentsTilingChanged) { 176 layer->setContentsTilePhase(layerState.contentsTilePhase); 177 layer->setContentsTileSize(layerState.contentsTileSize); 178 } 179 180 if (layerState.opacityChanged) 181 layer->setOpacity(layerState.opacity); 182 183 if (layerState.solidColorChanged) 184 layer->setSolidColor(layerState.solidColor); 185 186 if (layerState.debugVisualsChanged) 187 layer->setDebugVisuals(layerState.debugVisuals.showDebugBorders, layerState.debugVisuals.debugBorderColor, layerState.debugVisuals.debugBorderWidth); 188 if (layerState.repaintCountChanged) 189 layer->setRepaintCounter(layerState.repaintCount.showRepaintCounter, layerState.repaintCount.count); 190 191 if (layerState.replicaChanged) 192 layer->setReplicaLayer(getLayerByIDIfExists(layerState.replica)); 193 194 if (layerState.maskChanged) 195 layer->setMaskLayer(getLayerByIDIfExists(layerState.mask)); 196 197 if (layerState.imageChanged) 198 assignImageBackingToLayer(layer, layerState.imageID); 199 200 if (layerState.flagsChanged) { 201 layer->setContentsOpaque(layerState.contentsOpaque); 202 layer->setDrawsContent(layerState.drawsContent); 203 layer->setContentsVisible(layerState.contentsVisible); 204 layer->setBackfaceVisibility(layerState.backfaceVisible); 205 206 // Never clip the root layer. 207 layer->setMasksToBounds(id == m_rootLayerID ? false : layerState.masksToBounds); 208 layer->setPreserves3D(layerState.preserves3D); 209 } 210 211 // Apply Operations. 212 setLayerChildrenIfNeeded(layer, layerState); 213 setLayerFiltersIfNeeded(layer, layerState); 214 setLayerAnimationsIfNeeded(layer, layerState); 215 prepareContentBackingStore(layer, commitScope); 216 createTilesIfNeeded(layer, layerState); 217 removeTilesIfNeeded(layer, layerState, commitScope); 218 updateTilesIfNeeded(layer, layerState, commitScope); 219 syncPlatformLayerIfNeeded(layer, layerState); 220 } 221 222 TextureMapperLayer* CoordinatedGraphicsScene::getLayerByIDIfExists(CoordinatedLayerID id) 223 { 224 return (id != InvalidCoordinatedLayerID) ? layerByID(id) : 0; 225 } 226 227 void CoordinatedGraphicsScene::createLayers(const Vector<CoordinatedLayerID>& layerIDs) 228 { 229 for (auto& layerID : layerIDs) 230 createLayer(layerID); 231 } 232 233 void CoordinatedGraphicsScene::createLayer(CoordinatedLayerID id) 234 { 235 std::unique_ptr<TextureMapperLayer> newLayer = std::make_unique<TextureMapperLayer>(); 236 newLayer->setID(id); 237 m_layers.add(id, WTFMove(newLayer)); 238 } 239 240 void CoordinatedGraphicsScene::deleteLayers(const Vector<CoordinatedLayerID>& layerIDs) 241 { 242 for (auto& layerID : layerIDs) 243 deleteLayer(layerID); 244 } 245 246 void CoordinatedGraphicsScene::deleteLayer(CoordinatedLayerID layerID) 247 { 248 std::unique_ptr<TextureMapperLayer> layer = m_layers.take(layerID); 249 ASSERT(layer); 250 251 m_backingStores.remove(layer.get()); 252 #if USE(COORDINATED_GRAPHICS_THREADED) 253 if (auto platformLayerProxy = m_platformLayerProxies.take(layer.get())) 254 platformLayerProxy->invalidate(); 255 #endif 256 } 257 258 void CoordinatedGraphicsScene::setRootLayerID(CoordinatedLayerID layerID) 259 { 260 ASSERT(layerID != InvalidCoordinatedLayerID); 261 ASSERT(m_rootLayerID == InvalidCoordinatedLayerID); 262 263 m_rootLayerID = layerID; 264 265 TextureMapperLayer* layer = layerByID(layerID); 266 ASSERT(m_rootLayer->children().isEmpty()); 267 m_rootLayer->addChild(layer); 268 } 269 270 void CoordinatedGraphicsScene::prepareContentBackingStore(TextureMapperLayer* layer, CommitScope& commitScope) 271 { 272 if (!layerShouldHaveBackingStore(layer)) { 273 removeBackingStoreIfNeeded(layer); 274 return; 275 } 276 277 createBackingStoreIfNeeded(layer); 278 resetBackingStoreSizeToLayerSize(layer, commitScope); 279 } 280 281 void CoordinatedGraphicsScene::createBackingStoreIfNeeded(TextureMapperLayer* layer) 282 { 283 if (m_backingStores.contains(layer)) 284 return; 285 286 auto backingStore = CoordinatedBackingStore::create(); 287 m_backingStores.add(layer, backingStore.copyRef()); 288 layer->setBackingStore(backingStore.ptr()); 289 } 290 291 void CoordinatedGraphicsScene::removeBackingStoreIfNeeded(TextureMapperLayer* layer) 292 { 293 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.take(layer); 294 if (!backingStore) 295 return; 296 297 layer->setBackingStore(nullptr); 298 } 299 300 void CoordinatedGraphicsScene::resetBackingStoreSizeToLayerSize(TextureMapperLayer* layer, CommitScope& commitScope) 301 { 302 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer); 303 ASSERT(backingStore); 304 backingStore->setSize(layer->size()); 305 commitScope.backingStoresWithPendingBuffers.add(backingStore); 306 } 307 308 void CoordinatedGraphicsScene::createTilesIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state) 309 { 310 if (state.tilesToCreate.isEmpty()) 311 return; 312 313 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer); 314 ASSERT(backingStore || !layerShouldHaveBackingStore(layer)); 315 if (!backingStore) 316 return; 317 318 for (auto& tile : state.tilesToCreate) 319 backingStore->createTile(tile.tileID, tile.scale); 320 } 321 322 void CoordinatedGraphicsScene::removeTilesIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state, CommitScope& commitScope) 323 { 324 if (state.tilesToRemove.isEmpty()) 325 return; 326 327 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer); 328 if (!backingStore) 329 return; 330 331 for (auto& tile : state.tilesToRemove) 332 backingStore->removeTile(tile); 333 334 commitScope.backingStoresWithPendingBuffers.add(backingStore); 335 } 336 337 void CoordinatedGraphicsScene::updateTilesIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state, CommitScope& commitScope) 338 { 339 if (state.tilesToUpdate.isEmpty()) 340 return; 341 342 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer); 343 ASSERT(backingStore || !layerShouldHaveBackingStore(layer)); 344 if (!backingStore) 345 return; 346 347 for (auto& tile : state.tilesToUpdate) { 348 const SurfaceUpdateInfo& surfaceUpdateInfo = tile.updateInfo; 349 350 backingStore->updateTile(tile.tileID, surfaceUpdateInfo.updateRect, tile.tileRect, surfaceUpdateInfo.buffer.copyRef(), { 0, 0 }); 351 commitScope.backingStoresWithPendingBuffers.add(backingStore); 352 } 353 } 354 355 void CoordinatedGraphicsScene::syncImageBackings(const CoordinatedGraphicsState& state, CommitScope& commitScope) 356 { 357 for (auto& image : state.imagesToRemove) 358 removeImageBacking(image, commitScope); 359 360 for (auto& image : state.imagesToCreate) 361 createImageBacking(image); 362 363 for (auto& image : state.imagesToUpdate) 364 updateImageBacking(image.first, image.second.copyRef(), commitScope); 365 366 for (auto& image : state.imagesToClear) 367 clearImageBackingContents(image, commitScope); 368 } 369 370 void CoordinatedGraphicsScene::createImageBacking(CoordinatedImageBackingID imageID) 371 { 372 ASSERT(!m_imageBackings.contains(imageID)); 373 m_imageBackings.add(imageID, CoordinatedBackingStore::create()); 374 } 375 376 void CoordinatedGraphicsScene::updateImageBacking(CoordinatedImageBackingID imageID, RefPtr<Nicosia::Buffer>&& buffer, CommitScope& commitScope) 377 { 378 ASSERT(m_imageBackings.contains(imageID)); 379 auto it = m_imageBackings.find(imageID); 380 RefPtr<CoordinatedBackingStore> backingStore = it->value; 381 382 // CoordinatedImageBacking is realized to CoordinatedBackingStore with only one tile in UI Process. 383 backingStore->createTile(1 /* id */, 1 /* scale */); 384 IntRect rect(IntPoint::zero(), buffer->size()); 385 // See CoordinatedGraphicsLayer::shouldDirectlyCompositeImage() 116 Nicosia::CompositionLayerTextureMapperImpl& compositionLayerImpl(Nicosia::CompositionLayer& compositionLayer) 117 { 118 return downcast<Nicosia::CompositionLayerTextureMapperImpl>(compositionLayer.impl()); 119 } 120 121 Nicosia::ContentLayerTextureMapperImpl& contentLayerImpl(Nicosia::ContentLayer& contentLayer) 122 { 123 return downcast<Nicosia::ContentLayerTextureMapperImpl>(contentLayer.impl()); 124 } 125 126 Nicosia::BackingStoreTextureMapperImpl& backingStoreImpl(Nicosia::BackingStore& backingStore) 127 { 128 return downcast<Nicosia::BackingStoreTextureMapperImpl>(backingStore.impl()); 129 } 130 131 Nicosia::ImageBackingTextureMapperImpl& imageBackingImpl(Nicosia::ImageBacking& imageBacking) 132 { 133 return downcast<Nicosia::ImageBackingTextureMapperImpl>(imageBacking.impl()); 134 } 135 136 TextureMapperLayer& texmapLayer(Nicosia::CompositionLayer& compositionLayer) 137 { 138 auto& compositionState = compositionLayerImpl(compositionLayer).compositionState(); 139 if (!compositionState.layer) { 140 compositionState.layer = std::make_unique<TextureMapperLayer>(); 141 compositionState.layer->setID(compositionLayer.id()); 142 } 143 return *compositionState.layer; 144 } 145 146 void updateBackingStore(TextureMapperLayer& layer, 147 Nicosia::BackingStoreTextureMapperImpl::CompositionState& compositionState, 148 const Nicosia::BackingStoreTextureMapperImpl::TileUpdate& update) 149 { 150 if (!layerShouldHaveBackingStore(&layer)) { 151 layer.setBackingStore(nullptr); 152 compositionState.backingStore = nullptr; 153 return; 154 } 155 156 if (!compositionState.backingStore) 157 compositionState.backingStore = CoordinatedBackingStore::create(); 158 auto& backingStore = *compositionState.backingStore; 159 160 layer.setBackingStore(&backingStore); 161 backingStore.setSize(layer.size()); 162 163 for (auto& tile : update.tilesToCreate) 164 backingStore.createTile(tile.tileID, tile.scale); 165 for (auto& tile : update.tilesToRemove) 166 backingStore.removeTile(tile.tileID); 167 for (auto& tile : update.tilesToUpdate) { 168 backingStore.updateTile(tile.tileID, tile.updateInfo.updateRect, 169 tile.tileRect, tile.updateInfo.buffer.copyRef(), { 0, 0 }); 170 } 171 } 172 173 void updateImageBacking(TextureMapperLayer& layer, 174 Nicosia::ImageBackingTextureMapperImpl::CompositionState& compositionState, 175 Nicosia::ImageBackingTextureMapperImpl::Update& update) 176 { 177 if (!update.isVisible) { 178 layer.setBackingStore(nullptr); 179 return; 180 } 181 182 if (!compositionState.backingStore) 183 compositionState.backingStore = CoordinatedBackingStore::create(); 184 auto& backingStore = *compositionState.backingStore; 185 layer.setContentsLayer(&backingStore); 186 187 if (!update.buffer) 188 return; 189 190 backingStore.createTile(1, 1.0); 191 WebCore::IntRect rect { { }, update.buffer->size() }; 386 192 ASSERT(2000 >= std::max(rect.width(), rect.height())); 387 backingStore->setSize(rect.size()); 388 backingStore->updateTile(1 /* id */, rect, rect, WTFMove(buffer), rect.location()); 389 390 commitScope.backingStoresWithPendingBuffers.add(backingStore); 391 } 392 393 void CoordinatedGraphicsScene::clearImageBackingContents(CoordinatedImageBackingID imageID, CommitScope& commitScope) 394 { 395 ASSERT(m_imageBackings.contains(imageID)); 396 auto it = m_imageBackings.find(imageID); 397 RefPtr<CoordinatedBackingStore> backingStore = it->value; 398 backingStore->removeAllTiles(); 399 commitScope.backingStoresWithPendingBuffers.add(backingStore); 400 } 401 402 void CoordinatedGraphicsScene::removeImageBacking(CoordinatedImageBackingID imageID, CommitScope& commitScope) 403 { 404 ASSERT(m_imageBackings.contains(imageID)); 405 406 // We don't want TextureMapperLayer refers a dangling pointer. 407 commitScope.releasedImageBackings.append(m_imageBackings.take(imageID)); 408 } 409 410 void CoordinatedGraphicsScene::assignImageBackingToLayer(TextureMapperLayer* layer, CoordinatedImageBackingID imageID) 411 { 412 if (imageID == InvalidCoordinatedImageBackingID) { 413 layer->setContentsLayer(0); 414 return; 415 } 416 417 auto it = m_imageBackings.find(imageID); 418 ASSERT(it != m_imageBackings.end()); 419 layer->setContentsLayer(it->value.get()); 420 } 421 422 void CoordinatedGraphicsScene::commitSceneState(const CoordinatedGraphicsState& state) 193 backingStore.setSize(rect.size()); 194 backingStore.updateTile(1, rect, rect, WTFMove(update.buffer), rect.location()); 195 } 196 197 void removeLayer(Nicosia::CompositionLayer& layer) 198 { 199 layer.accessCommitted( 200 [](const Nicosia::CompositionLayer::LayerState& committed) 201 { 202 if (committed.backingStore) { 203 auto& compositionState = backingStoreImpl(*committed.backingStore).compositionState(); 204 compositionState.backingStore = nullptr; 205 } 206 207 if (committed.contentLayer) 208 contentLayerImpl(*committed.contentLayer).proxy().invalidate(); 209 210 if (committed.imageBacking) { 211 auto& compositionState = imageBackingImpl(*committed.imageBacking).compositionState(); 212 compositionState.backingStore = nullptr; 213 } 214 }); 215 216 auto& compositionState = compositionLayerImpl(layer).compositionState(); 217 compositionState.layer = nullptr; 218 } 219 220 void CoordinatedGraphicsScene::commitSceneState(const CoordinatedGraphicsState::NicosiaState& state) 423 221 { 424 222 if (!m_client) 425 223 return; 426 224 427 m_nicosia = state.nicosia; 428 // FIXME: Start using the Nicosia layer state for updates. 429 430 CommitScope commitScope; 431 432 createLayers(state.layersToCreate); 433 deleteLayers(state.layersToRemove); 434 435 if (state.rootCompositingLayer != m_rootLayerID) 436 setRootLayerID(state.rootCompositingLayer); 437 438 syncImageBackings(state, commitScope); 439 440 for (auto& layer : state.layersToUpdate) 441 setLayerState(layer.first, layer.second, commitScope); 442 443 for (auto& backingStore : commitScope.backingStoresWithPendingBuffers) 225 m_nicosia.scene = state.scene; 226 } 227 228 void CoordinatedGraphicsScene::updateSceneState() 229 { 230 if (!m_nicosia.scene) 231 return; 232 233 // Store layer and impl references along with the corresponding update 234 // for each type of possible layer backing. 235 struct { 236 struct BackingStore { 237 std::reference_wrapper<TextureMapperLayer> layer; 238 std::reference_wrapper<Nicosia::BackingStoreTextureMapperImpl> backingStore; 239 Nicosia::BackingStoreTextureMapperImpl::TileUpdate update; 240 }; 241 Vector<BackingStore> backingStore; 242 243 struct ContentLayer { 244 std::reference_wrapper<TextureMapperLayer> layer; 245 std::reference_wrapper<TextureMapperPlatformLayerProxy> proxy; 246 bool needsActivation { false }; 247 }; 248 Vector<ContentLayer> contentLayer; 249 250 struct ImageBacking { 251 std::reference_wrapper<TextureMapperLayer> layer; 252 std::reference_wrapper<Nicosia::ImageBackingTextureMapperImpl> imageBacking; 253 Nicosia::ImageBackingTextureMapperImpl::Update update; 254 }; 255 Vector<ImageBacking> imageBacking; 256 } layersByBacking; 257 258 // Access the scene state and perform state update for each layer. 259 m_nicosia.scene->accessState( 260 [this, &layersByBacking](Nicosia::Scene::State& state) 261 { 262 // Bail if the scene didn't change. 263 if (state.id == m_nicosia.state.id) 264 return; 265 266 // Handle the root layer, adding it to the TextureMapperLayer tree 267 // on the first update. No such change is expected later. 268 { 269 auto& rootLayer = texmapLayer(*state.rootLayer); 270 if (rootLayer.id() != m_rootLayerID) { 271 m_rootLayerID = rootLayer.id(); 272 RELEASE_ASSERT(m_rootLayer->children().isEmpty()); 273 m_rootLayer->addChild(&rootLayer); 274 } 275 } 276 277 // Gather all the to-be-removed layers so that composition-side state 278 // can be properly purged after the current state's set of layers is adopted. 279 HashSet<RefPtr<Nicosia::CompositionLayer>> removedLayers; 280 for (auto& layer : m_nicosia.state.layers) { 281 if (!state.layers.contains(layer)) 282 removedLayers.add(layer); 283 } 284 285 m_nicosia.state = state; 286 287 for (auto& layer : removedLayers) 288 removeLayer(*layer); 289 removedLayers = { }; 290 291 // Iterate the current state's set of layers, updating state values according to 292 // the incoming state changes. Layer backings are stored so that the updates 293 // (possibly time-consuming) can be done outside of this scene update. 294 for (auto& compositionLayer : m_nicosia.state.layers) { 295 auto& layer = texmapLayer(*compositionLayer); 296 compositionLayer->commitState( 297 [this, &layer, &compositionLayer, &layersByBacking] 298 (const Nicosia::CompositionLayer::LayerState& layerState) 299 { 300 if (layerState.delta.positionChanged) 301 layer.setPosition(layerState.position); 302 if (layerState.delta.anchorPointChanged) 303 layer.setAnchorPoint(layerState.anchorPoint); 304 if (layerState.delta.sizeChanged) 305 layer.setSize(layerState.size); 306 307 if (layerState.delta.transformChanged) 308 layer.setTransform(layerState.transform); 309 if (layerState.delta.childrenTransformChanged) 310 layer.setChildrenTransform(layerState.childrenTransform); 311 312 if (layerState.delta.contentsRectChanged) 313 layer.setContentsRect(layerState.contentsRect); 314 if (layerState.delta.contentsTilingChanged) { 315 layer.setContentsTilePhase(layerState.contentsTilePhase); 316 layer.setContentsTileSize(layerState.contentsTileSize); 317 } 318 319 if (layerState.delta.opacityChanged) 320 layer.setOpacity(layerState.opacity); 321 if (layerState.delta.solidColorChanged) 322 layer.setSolidColor(layerState.solidColor); 323 324 if (layerState.delta.filtersChanged) 325 layer.setFilters(layerState.filters); 326 if (layerState.delta.animationsChanged) 327 layer.setAnimations(layerState.animations); 328 329 if (layerState.delta.childrenChanged) { 330 layer.setChildren(WTF::map(layerState.children, 331 [](auto& child) { return &texmapLayer(*child); })); 332 } 333 334 if (layerState.delta.maskChanged) 335 layer.setMaskLayer(layerState.mask ? &texmapLayer(*layerState.mask) : nullptr); 336 if (layerState.delta.replicaChanged) 337 layer.setReplicaLayer(layerState.replica ? &texmapLayer(*layerState.replica) : nullptr); 338 339 if (layerState.delta.flagsChanged) { 340 layer.setContentsOpaque(layerState.flags.contentsOpaque); 341 layer.setDrawsContent(layerState.flags.drawsContent); 342 layer.setContentsVisible(layerState.flags.contentsVisible); 343 layer.setBackfaceVisibility(layerState.flags.backfaceVisible); 344 layer.setMasksToBounds(layerState.flags.masksToBounds); 345 layer.setPreserves3D(layerState.flags.preserves3D); 346 } 347 348 if (layerState.backingStore) { 349 auto& impl = backingStoreImpl(*layerState.backingStore); 350 layersByBacking.backingStore.append( 351 { std::ref(layer), std::ref(impl), impl.takeUpdate() }); 352 } else 353 layer.setBackingStore(nullptr); 354 355 if (layerState.contentLayer) { 356 auto& impl = contentLayerImpl(*layerState.contentLayer); 357 layersByBacking.contentLayer.append( 358 { std::ref(layer), std::ref(impl.proxy()), layerState.delta.contentLayerChanged }); 359 } else if (layerState.imageBacking) { 360 auto& impl = imageBackingImpl(*layerState.imageBacking); 361 layersByBacking.imageBacking.append( 362 { std::ref(layer), std::ref(impl), impl.takeUpdate() }); 363 } else 364 layer.setContentsLayer(nullptr); 365 }); 366 } 367 }); 368 369 // Iterate through each backing type of layers and gather backing store 370 // or proxy objects that need an update. 371 // FIXME: HashSet<std::reference_wrapper<>> would be ideal, but doesn't work (yet). 372 HashSet<Ref<WebCore::CoordinatedBackingStore>> backingStoresWithPendingBuffers; 373 HashSet<Ref<WebCore::TextureMapperPlatformLayerProxy>> proxiesForSwapping; 374 375 { 376 for (auto& entry : layersByBacking.backingStore) { 377 auto& compositionState = entry.backingStore.get().compositionState(); 378 updateBackingStore(entry.layer.get(), compositionState, entry.update); 379 380 if (compositionState.backingStore) 381 backingStoresWithPendingBuffers.add(makeRef(*compositionState.backingStore)); 382 } 383 384 layersByBacking.backingStore = { }; 385 } 386 387 { 388 for (auto& entry : layersByBacking.contentLayer) { 389 auto& proxy = entry.proxy.get(); 390 if (entry.needsActivation) 391 proxy.activateOnCompositingThread(this, &entry.layer.get()); 392 proxiesForSwapping.add(makeRef(proxy)); 393 } 394 395 layersByBacking.contentLayer = { }; 396 } 397 398 { 399 for (auto& entry : layersByBacking.imageBacking) { 400 auto& compositionState = entry.imageBacking.get().compositionState(); 401 updateImageBacking(entry.layer.get(), compositionState, entry.update); 402 403 if (compositionState.backingStore) 404 backingStoresWithPendingBuffers.add(makeRef(*compositionState.backingStore)); 405 } 406 407 layersByBacking.imageBacking = { }; 408 } 409 410 for (auto& backingStore : backingStoresWithPendingBuffers) 444 411 backingStore->commitTileOperations(*m_textureMapper); 412 413 for (auto& proxy : proxiesForSwapping) 414 proxy->swapBuffer(); 445 415 } 446 416 … … 466 436 ASSERT(!m_client); 467 437 468 m_imageBackings.clear(); 469 #if USE(COORDINATED_GRAPHICS_THREADED) 470 for (auto& proxy : m_platformLayerProxies.values()) 471 proxy->invalidate(); 472 m_platformLayerProxies.clear(); 473 #endif 438 if (m_nicosia.scene) { 439 m_nicosia.scene->accessState( 440 [this](const Nicosia::Scene::State& state) 441 { 442 ASSERT(state.id == m_nicosia.state.id); 443 for (auto& layer : m_nicosia.state.layers) 444 removeLayer(*layer); 445 m_nicosia.state.layers = { }; 446 m_nicosia.state.rootLayer = nullptr; 447 }); 448 m_nicosia.scene = nullptr; 449 } 474 450 475 451 m_rootLayer = nullptr; 476 452 m_rootLayerID = InvalidCoordinatedLayerID; 477 m_layers.clear();478 453 m_textureMapper = nullptr; 479 m_backingStores.clear();480 }481 482 void CoordinatedGraphicsScene::setLayerAnimationsIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)483 {484 if (!state.animationsChanged)485 return;486 487 layer->setAnimations(state.animations);488 454 } 489 455 -
trunk/Source/WebKit/Shared/CoordinatedGraphics/CoordinatedGraphicsScene.h
r234455 r235165 82 82 void setActive(bool active) { m_isActive = active; } 83 83 84 void commitSceneState(const WebCore::CoordinatedGraphicsState&);85 86 84 void setViewBackgroundColor(const WebCore::Color& color) { m_viewBackgroundColor = color; } 87 85 WebCore::Color viewBackgroundColor() const { return m_viewBackgroundColor; } 88 86 89 87 private: 90 struct CommitScope { 91 CommitScope() = default; 92 CommitScope(CommitScope&) = delete; 93 CommitScope& operator=(const CommitScope&) = delete; 88 void commitSceneState(const WebCore::CoordinatedGraphicsState::NicosiaState&); 89 void updateSceneState(); 94 90 95 Vector<RefPtr<WebCore::CoordinatedBackingStore>> releasedImageBackings;96 HashSet<RefPtr<WebCore::CoordinatedBackingStore>> backingStoresWithPendingBuffers;97 };98 99 void setRootLayerID(WebCore::CoordinatedLayerID);100 void createLayers(const Vector<WebCore::CoordinatedLayerID>&);101 void deleteLayers(const Vector<WebCore::CoordinatedLayerID>&);102 void setLayerState(WebCore::CoordinatedLayerID, const WebCore::CoordinatedGraphicsLayerState&, CommitScope&);103 void setLayerChildrenIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&);104 void updateTilesIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&, CommitScope&);105 void createTilesIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&);106 void removeTilesIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&, CommitScope&);107 void setLayerFiltersIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&);108 void setLayerAnimationsIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&);109 void syncPlatformLayerIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&);110 111 void syncImageBackings(const WebCore::CoordinatedGraphicsState&, CommitScope&);112 void createImageBacking(WebCore::CoordinatedImageBackingID);113 void updateImageBacking(WebCore::CoordinatedImageBackingID, RefPtr<Nicosia::Buffer>&&, CommitScope&);114 void clearImageBackingContents(WebCore::CoordinatedImageBackingID, CommitScope&);115 void removeImageBacking(WebCore::CoordinatedImageBackingID, CommitScope&);116 117 WebCore::TextureMapperLayer* layerByID(WebCore::CoordinatedLayerID id)118 {119 ASSERT(m_layers.contains(id));120 ASSERT(id != WebCore::InvalidCoordinatedLayerID);121 return m_layers.get(id);122 }123 WebCore::TextureMapperLayer* getLayerByIDIfExists(WebCore::CoordinatedLayerID);124 91 WebCore::TextureMapperLayer* rootLayer() { return m_rootLayer.get(); } 125 92 126 93 void updateViewport(); 127 94 128 void createLayer(WebCore::CoordinatedLayerID);129 void deleteLayer(WebCore::CoordinatedLayerID);130 131 void assignImageBackingToLayer(WebCore::TextureMapperLayer*, WebCore::CoordinatedImageBackingID);132 95 void ensureRootLayer(); 133 134 void prepareContentBackingStore(WebCore::TextureMapperLayer*, CommitScope&);135 void createBackingStoreIfNeeded(WebCore::TextureMapperLayer*);136 void removeBackingStoreIfNeeded(WebCore::TextureMapperLayer*);137 void resetBackingStoreSizeToLayerSize(WebCore::TextureMapperLayer*, CommitScope&);138 96 139 97 #if USE(COORDINATED_GRAPHICS_THREADED) … … 141 99 #endif 142 100 143 WebCore::CoordinatedGraphicsState::NicosiaState m_nicosia; 101 struct { 102 RefPtr<Nicosia::Scene> scene; 103 Nicosia::Scene::State state; 104 } m_nicosia; 144 105 145 106 std::unique_ptr<WebCore::TextureMapper> m_textureMapper; 146 147 HashMap<WebCore::CoordinatedImageBackingID, RefPtr<WebCore::CoordinatedBackingStore>> m_imageBackings;148 HashMap<WebCore::TextureMapperLayer*, RefPtr<WebCore::CoordinatedBackingStore>> m_backingStores;149 150 #if USE(COORDINATED_GRAPHICS_THREADED)151 HashMap<WebCore::TextureMapperLayer*, RefPtr<WebCore::TextureMapperPlatformLayerProxy>> m_platformLayerProxies;152 #endif153 107 154 108 // Below two members are accessed by only the main thread. The painting thread must lock the main thread to access both members. … … 158 112 std::unique_ptr<WebCore::TextureMapperLayer> m_rootLayer; 159 113 160 HashMap<WebCore::CoordinatedLayerID, std::unique_ptr<WebCore::TextureMapperLayer>> m_layers;161 114 WebCore::CoordinatedLayerID m_rootLayerID { WebCore::InvalidCoordinatedLayerID }; 162 115 WebCore::Color m_viewBackgroundColor { WebCore::Color::white }; -
trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp
r235111 r235165 216 216 // But do not change coordinateUpdateCompletionWithClient while in force repaint because that 217 217 // demands immediate scene update completion regardless of platform layers. 218 // FIXME: Check whether we still need all this coordinateUpdateCompletionWithClient logic. 219 // https://bugs.webkit.org/show_bug.cgi?id=188839 220 // Relatedly, we should only ever operate with a single Nicosia::Scene object, not with a Vector 221 // of CoordinatedGraphicsState instances (which at this time will all contain RefPtr to the same 222 // Nicosia::State object anyway). 218 223 if (!m_inForceRepaint) { 219 224 bool coordinateUpdate = false; 220 for (auto& state : states) 221 coordinateUpdate |= std::any_of(state.layersToUpdate.begin(), state.layersToUpdate.end(), 222 [](auto& it) { return it.second.platformLayerChanged || it.second.platformLayerUpdated; }); 225 for (auto& state : states) { 226 state.nicosia.scene->accessState( 227 [&coordinateUpdate](Nicosia::Scene::State& state) 228 { 229 coordinateUpdate |= state.platformLayerUpdated; 230 state.platformLayerUpdated = false; 231 }); 232 } 223 233 m_attributes.coordinateUpdateCompletionWithClient = coordinateUpdate; 224 234 } -
trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp
r234593 r235165 36 36 #include <WebCore/GraphicsContext.h> 37 37 #include <WebCore/InspectorController.h> 38 #include <WebCore/NicosiaBackingStoreTextureMapperImpl.h> 39 #include <WebCore/NicosiaContentLayerTextureMapperImpl.h> 40 #include <WebCore/NicosiaImageBackingTextureMapperImpl.h> 38 41 #include <WebCore/NicosiaPaintingEngine.h> 39 42 #include <WebCore/Page.h> … … 131 134 [this](Nicosia::Scene::State& state) 132 135 { 136 bool platformLayerUpdated = false; 137 for (auto& compositionLayer : m_nicosia.state.layers) { 138 compositionLayer->flushState( 139 [&platformLayerUpdated] 140 (const Nicosia::CompositionLayer::LayerState& state) 141 { 142 if (state.backingStore) { 143 auto& impl = downcast<Nicosia::BackingStoreTextureMapperImpl>(state.backingStore->impl()); 144 impl.flushUpdate(); 145 } 146 147 if (state.imageBacking) { 148 auto& impl = downcast<Nicosia::ImageBackingTextureMapperImpl>(state.imageBacking->impl()); 149 impl.flushUpdate(); 150 } 151 152 if (state.contentLayer) { 153 auto& impl = downcast<Nicosia::ContentLayerTextureMapperImpl>(state.contentLayer->impl()); 154 platformLayerUpdated |= impl.flushUpdate(); 155 } 156 }); 157 } 158 133 159 ++state.id; 160 state.platformLayerUpdated = platformLayerUpdated; 134 161 state.layers = m_nicosia.state.layers; 135 162 state.rootLayer = m_nicosia.state.rootLayer; -
trunk/Source/cmake/OptionsGTK.cmake
r234362 r235165 278 278 SET_AND_EXPOSE_TO_BUILD(USE_COORDINATED_GRAPHICS TRUE) 279 279 SET_AND_EXPOSE_TO_BUILD(USE_COORDINATED_GRAPHICS_THREADED TRUE) 280 SET_AND_EXPOSE_TO_BUILD(USE_NICOSIA TRUE) 280 281 endif () 281 282 -
trunk/Source/cmake/OptionsWPE.cmake
r235118 r235165 135 135 SET_AND_EXPOSE_TO_BUILD(USE_COORDINATED_GRAPHICS TRUE) 136 136 SET_AND_EXPOSE_TO_BUILD(USE_COORDINATED_GRAPHICS_THREADED TRUE) 137 SET_AND_EXPOSE_TO_BUILD(USE_NICOSIA TRUE) 137 138 138 139 set(FORWARDING_HEADERS_DIR ${DERIVED_SOURCES_DIR}/ForwardingHeaders)
Note: See TracChangeset
for help on using the changeset viewer.