Index: third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp |
diff --git a/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp |
index 15fb79b3c8df7d58edebe9b394d98c8483bb7497..74db7214b11d60e66608042996b2e5326ee9cca0 100644 |
--- a/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp |
+++ b/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp |
@@ -7,7 +7,9 @@ |
#include "platform/graphics/GraphicsContext.h" |
#include "platform/graphics/GraphicsLayer.h" |
#include "platform/graphics/paint/CompositingDisplayItem.h" |
+#include "platform/graphics/paint/DrawingRecorder.h" |
#include "platform/graphics/paint/PaintController.h" |
+#include "platform/graphics/paint/SkPictureBuilder.h" |
namespace blink { |
@@ -30,7 +32,40 @@ void CompositingRecorder::beginCompositing(GraphicsContext& graphicsContext, con |
void CompositingRecorder::endCompositing(GraphicsContext& graphicsContext, const DisplayItemClient& client) |
{ |
- graphicsContext.getPaintController().endItem<EndCompositingDisplayItem>(client); |
+ // If the end of the current display list is of the form [BeginCompositingDisplayItem] [DrawingDisplayItem], |
+ // then fold the BeginCompositingDisplayItem into a new DrawingDisplayItem that replaces them both. This allows |
+ // Skia to optimize for the case when the BeginCompositingDisplayItem represents a simple opacity/color that can be merged into |
+ // the opacity/color of the drawing. See crbug.com/628831 for more details. |
+ PaintController& paintController = graphicsContext.getPaintController(); |
wkorman
2016/07/26 18:41:08
Need to turn off caching.
chrishtr
2016/07/26 18:49:45
Done.
|
+ const DisplayItem* lastDisplayItem = paintController.lastDisplayItem(0); |
+ const DisplayItem* secondToLastDisplayItem = paintController.lastDisplayItem(1); |
wkorman
2016/07/26 18:41:08
fun: opportunity to use 'penultimate' vs 'secondTo
chrishtr
2016/07/26 18:49:45
Acknowledged.
|
+ if (lastDisplayItem && secondToLastDisplayItem && lastDisplayItem->drawsContent() && secondToLastDisplayItem->isBeginCompositingDisplayItem()) { |
+ FloatRect cullRect(((DrawingDisplayItem*)lastDisplayItem)->picture()->cullRect()); |
+ const DisplayItemClient& displayItemClient = lastDisplayItem->client(); |
+ DisplayItem::Type displayItemType = lastDisplayItem->getType(); |
+ |
+ // Re-record the last two DisplayItems into a new SkPicture. |
+ SkPictureBuilder pictureBuilder(cullRect, nullptr, &graphicsContext); |
+ { |
+ DrawingRecorder newRecorder(pictureBuilder.context(), displayItemClient, displayItemType, cullRect); |
f(malita)
2016/07/26 19:03:15
Why is this inner DrawingRecording needed? Wouldn
chrishtr
2016/07/26 19:54:24
SkPictureBuilder doesn't start a recording of a sp
|
+ DCHECK(!DrawingRecorder::useCachedDrawingIfPossible(pictureBuilder.context(), displayItemClient, displayItemType)); |
+ |
+ secondToLastDisplayItem->replay(pictureBuilder.context()); |
+ lastDisplayItem->replay(pictureBuilder.context()); |
+ EndCompositingDisplayItem(client).replay(pictureBuilder.context()); |
+ } |
+ |
+ paintController.removeLastDisplayItem(); // Remove the DrawingDisplayItem. |
+ paintController.removeLastDisplayItem(); // Remove the BeginCompositingDisplayItem. |
+ |
+ { |
+ // Replay the new SKPicture into a new DrawingDisplayItem in the original DisplayItemList. |
+ DrawingRecorder newRecorder(graphicsContext, displayItemClient, displayItemType, cullRect); |
+ pictureBuilder.endRecording()->playback(graphicsContext.canvas()); |
+ } |
+ } else { |
+ graphicsContext.getPaintController().endItem<EndCompositingDisplayItem>(client); |
+ } |
} |
} // namespace blink |