blob: a356a434d821ab63060560c0c59ff64baa3cdb3c [file] [log] [blame]
// Copyright 2019 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 "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h"
#include "cc/layers/layer.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/geometry_as_json.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
#include "third_party/blink/renderer/platform/wtf/text/text_stream.h"
namespace blink {
namespace {
String PointerAsString(const void* ptr) {
WTF::TextStream ts;
ts << ptr;
return ts.Release();
}
} // namespace
// Create a JSON version of the specified |layer|.
std::unique_ptr<JSONObject> CCLayerAsJSON(const cc::Layer& layer,
LayerTreeFlags flags) {
auto json = std::make_unique<JSONObject>();
if (flags & kLayerTreeIncludesDebugInfo) {
json->SetString("this", PointerAsString(&layer));
json->SetInteger("ccLayerId", layer.id());
}
json->SetString("name", String(layer.DebugName().c_str()));
if (layer.offset_to_transform_parent() != gfx::Vector2dF()) {
json->SetArray(
"position",
PointAsJSONArray(FloatPoint(layer.offset_to_transform_parent())));
}
// This is testing against gfx::Size(), *not* whether the size is empty.
if (layer.bounds() != gfx::Size())
json->SetArray("bounds", SizeAsJSONArray(IntSize(layer.bounds())));
if (layer.contents_opaque())
json->SetBoolean("contentsOpaque", true);
else if (layer.contents_opaque_for_text())
json->SetBoolean("contentsOpaqueForText", true);
if (!layer.DrawsContent())
json->SetBoolean("drawsContent", false);
if (layer.should_check_backface_visibility())
json->SetString("backfaceVisibility", "hidden");
if (Color(layer.background_color()).Alpha()) {
json->SetString("backgroundColor",
Color(layer.background_color()).NameForLayoutTreeAsText());
}
if (flags &
(kLayerTreeIncludesDebugInfo | kLayerTreeIncludesCompositingReasons)) {
if (layer.debug_info()) {
auto compositing_reasons_json = std::make_unique<JSONArray>();
for (const char* name : layer.debug_info()->compositing_reasons)
compositing_reasons_json->PushString(name);
json->SetArray("compositingReasons", std::move(compositing_reasons_json));
}
}
return json;
}
LayersAsJSON::LayersAsJSON(LayerTreeFlags flags)
: flags_(flags),
next_transform_id_(1),
layers_json_(std::make_unique<JSONArray>()),
transforms_json_(std::make_unique<JSONArray>()) {}
int LayersAsJSON::AddTransformJSON(
const TransformPaintPropertyNode& transform) {
auto it = transform_id_map_.find(&transform);
if (it != transform_id_map_.end())
return it->value;
int parent_id = 0;
if (transform.Parent())
parent_id = AddTransformJSON(*transform.UnaliasedParent());
if (transform.IsIdentity() && !transform.RenderingContextId()) {
transform_id_map_.Set(&transform, parent_id);
return parent_id;
}
auto transform_json = std::make_unique<JSONObject>();
int transform_id = next_transform_id_++;
transform_id_map_.Set(&transform, transform_id);
transform_json->SetInteger("id", transform_id);
if (parent_id)
transform_json->SetInteger("parent", parent_id);
if (!transform.IsIdentity()) {
transform_json->SetArray("transform",
TransformAsJSONArray(transform.SlowMatrix()));
}
if (!transform.IsIdentityOr2DTranslation() &&
!transform.Matrix().IsIdentityOrTranslation())
transform_json->SetArray("origin", PointAsJSONArray(transform.Origin()));
if (!transform.FlattensInheritedTransform())
transform_json->SetBoolean("flattenInheritedTransform", false);
if (auto rendering_context = transform.RenderingContextId()) {
auto context_lookup_result = rendering_context_map_.find(rendering_context);
int rendering_id = rendering_context_map_.size() + 1;
if (context_lookup_result == rendering_context_map_.end())
rendering_context_map_.Set(rendering_context, rendering_id);
else
rendering_id = context_lookup_result->value;
transform_json->SetInteger("renderingContext", rendering_id);
}
transforms_json_->PushObject(std::move(transform_json));
return transform_id;
}
void LayersAsJSON::AddLayer(const cc::Layer& layer,
const TransformPaintPropertyNode& transform,
const LayerAsJSONClient* json_client) {
if (!(flags_ & kLayerTreeIncludesAllLayers) && !layer.DrawsContent() &&
(layer.DebugName() == "LayoutView #document" ||
layer.DebugName() == "Inner Viewport Scroll Layer" ||
layer.DebugName() == "Scrolling Contents Layer"))
return;
auto layer_json = CCLayerAsJSON(layer, flags_);
if (json_client) {
json_client->AppendAdditionalInfoAsJSON(flags_, layer, *(layer_json.get()));
}
int transform_id = AddTransformJSON(transform);
if (transform_id)
layer_json->SetInteger("transform", transform_id);
layers_json_->PushObject(std::move(layer_json));
}
std::unique_ptr<JSONObject> LayersAsJSON::Finalize() {
auto json = std::make_unique<JSONObject>();
json->SetArray("layers", std::move(layers_json_));
if (transforms_json_->size())
json->SetArray("transforms", std::move(transforms_json_));
return json;
}
} // namespace blink