blob: cba46c93c644fee1aca004d1585fb2f31ad69609 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "platform/graphics/paint/PaintArtifact.h"
#include "platform/TraceEvent.h"
#include "platform/geometry/IntRect.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/graphics/paint/DrawingDisplayItem.h"
#include "public/platform/WebDisplayItemList.h"
#include "third_party/skia/include/core/SkRegion.h"
namespace blink {
namespace {
void computeChunkBoundsAndOpaqueness(const DisplayItemList& displayItems,
Vector<PaintChunk>& paintChunks) {
for (PaintChunk& chunk : paintChunks) {
FloatRect bounds;
SkRegion knownToBeOpaqueRegion;
for (const DisplayItem& item : displayItems.itemsInPaintChunk(chunk)) {
bounds.unite(FloatRect(item.client().visualRect()));
if (!item.isDrawing())
continue;
const auto& drawing = static_cast<const DrawingDisplayItem&>(item);
if (const SkPicture* picture = drawing.picture()) {
if (drawing.knownToBeOpaque()) {
// TODO(pdr): It may be too conservative to round in to the
// enclosedIntRect.
SkIRect conservativelyRoundedPictureRect;
const SkRect& pictureRect = picture->cullRect();
pictureRect.roundIn(&conservativelyRoundedPictureRect);
knownToBeOpaqueRegion.op(conservativelyRoundedPictureRect,
SkRegion::kUnion_Op);
}
}
}
chunk.bounds = bounds;
if (knownToBeOpaqueRegion.contains(enclosingIntRect(bounds)))
chunk.knownToBeOpaque = true;
}
}
} // namespace
PaintArtifact::PaintArtifact()
: m_displayItemList(0), m_isSuitableForGpuRasterization(true) {}
PaintArtifact::PaintArtifact(DisplayItemList displayItems,
Vector<PaintChunk> paintChunks,
bool isSuitableForGpuRasterizationArg)
: m_displayItemList(std::move(displayItems)),
m_paintChunks(std::move(paintChunks)),
m_isSuitableForGpuRasterization(isSuitableForGpuRasterizationArg) {
computeChunkBoundsAndOpaqueness(m_displayItemList, m_paintChunks);
}
PaintArtifact::PaintArtifact(PaintArtifact&& source)
: m_displayItemList(std::move(source.m_displayItemList)),
m_paintChunks(std::move(source.m_paintChunks)),
m_isSuitableForGpuRasterization(source.m_isSuitableForGpuRasterization) {}
PaintArtifact::~PaintArtifact() {}
PaintArtifact& PaintArtifact::operator=(PaintArtifact&& source) {
m_displayItemList = std::move(source.m_displayItemList);
m_paintChunks = std::move(source.m_paintChunks);
m_isSuitableForGpuRasterization = source.m_isSuitableForGpuRasterization;
return *this;
}
void PaintArtifact::reset() {
m_displayItemList.clear();
m_paintChunks.clear();
}
size_t PaintArtifact::approximateUnsharedMemoryUsage() const {
return sizeof(*this) + m_displayItemList.memoryUsageInBytes() +
m_paintChunks.capacity() * sizeof(m_paintChunks[0]);
}
void PaintArtifact::replay(GraphicsContext& graphicsContext) const {
TRACE_EVENT0("blink,benchmark", "PaintArtifact::replay");
for (const DisplayItem& displayItem : m_displayItemList)
displayItem.replay(graphicsContext);
}
void PaintArtifact::appendToWebDisplayItemList(WebDisplayItemList* list) const {
TRACE_EVENT0("blink,benchmark", "PaintArtifact::appendToWebDisplayItemList");
size_t visualRectIndex = 0;
for (const DisplayItem& displayItem : m_displayItemList) {
displayItem.appendToWebDisplayItemList(
m_displayItemList.visualRect(visualRectIndex), list);
visualRectIndex++;
}
list->setIsSuitableForGpuRasterization(isSuitableForGpuRasterization());
}
} // namespace blink