Commit c9794c06 authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

Remove some internals.layerTreeAsText flags

These flags were used just for a few tests for checking internal data
of composited layers. We should check them with unit tests.

Removed tests:
- compositing/layer-tree.html: just tested LAYER_TREE_INCLUDES_ROOT_LAYER
  which is not important.
- compositing/overflow/composited-scrolling-paint-phases and
  compositing/update-paint-phases.html: The tested functionality is
  already tested by unit test
  CompositedLayerMappingTest.ScrollingContentsAndForegroundLayerPaintingPhase
- compositing/animation/hidden-composited.html: now tested with unit test
  CompositedLayerMappingTest.CompositedHiddenAnimatingLayer.

Change-Id: I148b4480020b41f241cd7ab854c31f96528cf89b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1927187Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#717682}
parent cd154d77
......@@ -824,7 +824,7 @@ String LocalFrame::GetLayerTreeAsTextForTesting(unsigned flags) const {
} else {
if (const auto* root_layer =
ContentLayoutObject()->Compositor()->RootGraphicsLayer()) {
if (flags & kLayerTreeIncludesRootLayer && IsMainFrame()) {
if (flags & kLayerTreeIncludesAllLayers && IsMainFrame()) {
while (root_layer->Parent())
root_layer = root_layer->Parent();
}
......
......@@ -18,6 +18,9 @@
namespace blink {
// TODO(wangxianzhu): Though these tests don't directly apply in
// CompositeAfterPaint, we should ensure the cases are tested in
// CompositeAfterPaint mode if applicable.
class CompositedLayerMappingTest : public RenderingTest {
public:
CompositedLayerMappingTest()
......@@ -999,12 +1002,12 @@ TEST_F(CompositedLayerMappingTest,
true);
SetBodyInnerHTML(R"HTML(
<div id='container' style='position: relative; z-index: 1; overflow:
scroll; width: 300px; height: 300px'>
<div id='negative-composited-child' style='background-color: red;
width: 1px; height: 1px; position: absolute; backface-visibility:
hidden; z-index: -1'></div>
<div style='background-color: blue; width: 2000px; height: 2000px;
position: relative; top: 10px'></div>
scroll; width: 300px; height: 300px'>
<div id='negative-composited-child' style='background-color: red;
width: 1px; height: 1px; position: absolute;
backface-visibility: hidden; z-index: -1'></div>
<div style='background-color: blue; width: 2000px; height: 2000px;
position: relative; top: 10px'></div>
</div>
)HTML");
......@@ -1513,8 +1516,6 @@ TEST_F(CompositedLayerMappingTest, ScrollLayerSizingSubpixelAccumulation) {
}
TEST_F(CompositedLayerMappingTest, SquashingScroll) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML(R"HTML(
<style>
* { margin: 0 }
......@@ -1536,8 +1537,6 @@ TEST_F(CompositedLayerMappingTest, SquashingScroll) {
}
TEST_F(CompositedLayerMappingTest, SquashingScrollInterestRect) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML(R"HTML(
<style>
* { margin: 0 }
......@@ -1562,9 +1561,6 @@ TEST_F(CompositedLayerMappingTest, SquashingScrollInterestRect) {
TEST_F(CompositedLayerMappingTest,
SquashingBoundsUnderCompositedScrollingWithTransform) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML(R"HTML(
<div id=scroller style="will-change: transform; overflow: scroll;
width: 200px; height: 400px;">
......@@ -1597,9 +1593,6 @@ TEST_F(CompositedLayerMappingTest,
}
TEST_F(CompositedLayerMappingTest, ContentsNotOpaqueWithForegroundLayer) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML(R"HTML(
<style>
div {
......@@ -1622,9 +1615,6 @@ TEST_F(CompositedLayerMappingTest, ContentsNotOpaqueWithForegroundLayer) {
}
TEST_F(CompositedLayerMappingTest, EmptyBoundsDoesntDrawContent) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML(R"HTML(
<style>
div {
......@@ -1644,9 +1634,6 @@ TEST_F(CompositedLayerMappingTest, EmptyBoundsDoesntDrawContent) {
}
TEST_F(CompositedLayerMappingTest, TouchActionRectsWithoutContent) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML(
"<div id='target' style='will-change: transform; width: 100px;"
" height: 100px; touch-action: none;'></div>");
......@@ -1666,9 +1653,6 @@ TEST_F(CompositedLayerMappingTest, TouchActionRectsWithoutContent) {
}
TEST_F(CompositedLayerMappingTest, ContentsOpaque) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML(R"HTML(
<style>
div {
......@@ -1690,9 +1674,6 @@ TEST_F(CompositedLayerMappingTest, ContentsOpaque) {
}
TEST_F(CompositedLayerMappingTest, NullOverflowControlsHostLayer) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML("<div id='target' style='will-change: transform'></div>");
CompositedLayerMapping* mapping =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))
......@@ -1701,4 +1682,43 @@ TEST_F(CompositedLayerMappingTest, NullOverflowControlsHostLayer) {
EXPECT_FALSE(mapping->DetachLayerForOverflowControls());
}
TEST_F(CompositedLayerMappingTest, CompositedHiddenAnimatingLayer) {
SetHtmlInnerHTML(R"HTML(
<style>
@keyframes slide {
0% { transform: translate3d(0px, 0px, 0px); }
100% { transform: translate3d(100px, 0px, 1px); }
}
div {
width: 123px;
height: 234px;
animation-duration: 2s;
animation-name: slide;
animation-iteration-count: infinite;
animation-direction: alternate;
}
</style>
<div id="animated"></div>
)HTML");
PaintLayer* animated =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("animated"))->Layer();
CompositedLayerMapping* mapping = animated->GetCompositedLayerMapping();
ASSERT_TRUE(mapping);
EXPECT_TRUE(mapping->MainGraphicsLayer()->GetCompositingReasons() &
CompositingReason::kActiveTransformAnimation);
// We still composite the animated layer even if visibility: hidden.
// TODO(crbug.com/937573): Is this necessary?
GetDocument()
.getElementById("animated")
->setAttribute(html_names::kStyleAttr, "visibility: hidden");
UpdateAllLifecyclePhasesForTest();
mapping = animated->GetCompositedLayerMapping();
ASSERT_TRUE(mapping);
EXPECT_TRUE(mapping->MainGraphicsLayer()->GetCompositingReasons() &
CompositingReason::kActiveTransformAnimation);
}
} // namespace blink
......@@ -190,14 +190,10 @@
readonly attribute InternalRuntimeFlags runtimeFlags;
readonly attribute unsigned long workerThreadCount;
// Flags for layerTreeAsText.
// The values of these constants must be kept in sync with the values of LayerTreeFlags in layers_as_json.h.
const unsigned short LAYER_TREE_INCLUDES_DEBUG_INFO = 1;
// Flag for layerTreeAsText.
// The value must be kept in sync with the value of LayerTreeFlags in layers_as_json.h.
// Other flags in LayerTreeFlags are not supported in internals API.
const unsigned short LAYER_TREE_INCLUDES_PAINT_INVALIDATIONS = 2;
const unsigned short LAYER_TREE_INCLUDES_PAINTING_PHASES = 4;
const unsigned short LAYER_TREE_INCLUDES_ROOT_LAYER = 8;
const unsigned short LAYER_TREE_INCLUDES_COMPOSITING_REASONS = 32;
const unsigned short LAYER_TREE_INCLUDES_PAINT_RECORDS = 64;
[RaisesException] DOMString layerTreeAsText(Document document, optional unsigned short flags);
......
......@@ -130,10 +130,12 @@ void LayersAsJSON::AddLayer(const cc::Layer& layer,
const FloatPoint& offset,
const TransformPaintPropertyNode& transform,
const LayerAsJSONClient* json_client) {
auto layer_json = CCLayerAsJSON(&layer, Flags(), offset);
if (!(flags_ & kLayerTreeIncludesAllLayers) && !layer.DrawsContent())
return;
auto layer_json = CCLayerAsJSON(&layer, flags_, offset);
if (json_client) {
json_client->AppendAdditionalInfoAsJSON(Flags(), layer,
*(layer_json.get()));
json_client->AppendAdditionalInfoAsJSON(flags_, layer, *(layer_json.get()));
}
int transform_id = AddTransformJSON(transform);
if (transform_id)
......
......@@ -29,7 +29,7 @@ enum {
kLayerTreeIncludesDebugInfo = 1 << 0,
kLayerTreeIncludesPaintInvalidations = 1 << 1,
kLayerTreeIncludesPaintingPhases = 1 << 2,
kLayerTreeIncludesRootLayer = 1 << 3,
kLayerTreeIncludesAllLayers = 1 << 3,
kLayerTreeIncludesCompositingReasons = 1 << 5,
kLayerTreeIncludesPaintRecords = 1 << 6,
// Outputs all layers as a layer tree. The default is output children
......@@ -49,8 +49,6 @@ class PLATFORM_EXPORT LayersAsJSON {
public:
LayersAsJSON(LayerTreeFlags);
LayerTreeFlags Flags() const { return flags_; }
void AddLayer(const cc::Layer& layer,
const FloatPoint& offset,
const TransformPaintPropertyNode& transform,
......
......@@ -83,11 +83,7 @@ std::unique_ptr<JSONObject> PaintArtifactCompositor::GetLayersAsJSON(
paint_artifact);
LayersAsJSON layers_as_json(flags);
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
if (!tracks_raster_invalidations_)
flags &= ~kLayerTreeIncludesPaintInvalidations;
for (const auto& layer : root_layer_->children()) {
if (!layer->DrawsContent() && !(flags & kLayerTreeIncludesRootLayer))
continue;
const LayerAsJSONClient* json_client = nullptr;
const TransformPaintPropertyNode* transform = nullptr;
for (const auto& client : content_layer_clients_) {
......@@ -120,12 +116,10 @@ std::unique_ptr<JSONObject> PaintArtifactCompositor::GetLayersAsJSON(
const auto& foreign_layer_display_item =
static_cast<const ForeignLayerDisplayItem&>(display_item);
cc::Layer* layer = foreign_layer_display_item.GetLayer();
if ((layer->DrawsContent()) || (flags & kLayerTreeIncludesRootLayer)) {
layers_as_json.AddLayer(
*layer, foreign_layer_display_item.Offset(),
paint_chunk.properties.Transform(),
foreign_layer_display_item.GetLayerAsJSONClient());
}
layers_as_json.AddLayer(
*layer, foreign_layer_display_item.Offset(),
paint_chunk.properties.Transform(),
foreign_layer_display_item.GetLayerAsJSONClient());
}
}
return layers_as_json.Finalize();
......
Verifies hidden, compositor-animated layers still get composited
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS successfullyParsed is true
TEST COMPLETE
PASS hiddenLayerIsComposited(documentLayerTree) is true
<!DOCTYPE HTML>
<style>
@keyframes slide {
0% { transform: translate3d(0px, 0px, 0px); }
100% { transform: translate3d(100px, 0px, 1px); }
}
div {
width: 100px;
height: 100px;
background: green;
animation-duration: 2s;
animation-name: slide;
animation-iteration-count: infinite;
animation-direction: alternate;
}
</style>
<div id="animated"></div>
<script src='../../resources/js-test.js'></script>
<script>
description('Verifies hidden, compositor-animated layers still get composited');
if (window.internals)
internals.settings.setPreferCompositingToLCDTextEnabled(true);
function hiddenLayerIsComposited(layers) {
var found = false;
layers["layers"].forEach(function(layer) {
if (layer.bounds[0] == 100 && layer.bounds[1] == 100) {
for (var j = 0; j < layer.compositingReasons.length; j++) {
if (layer.compositingReasons[j].includes('active accelerated transform animation'))
found = true;
}
}
});
return found;
}
onload = function() {
if (!window.internals)
return;
document.getElementById('animated').style.visibility = 'hidden';
internals.forceCompositingUpdate(document);
documentLayerTree = JSON.parse(internals.layerTreeAsText(
document, window.internals.LAYER_TREE_INCLUDES_COMPOSITING_REASONS));
shouldBe('hiddenLayerIsComposited(documentLayerTree)', 'true');
};
</script>
Layer list
{
"layers": [
{
"name": "Inner Viewport Scroll Layer",
"bounds": [800, 600],
"drawsContent": false
},
{
"name": "LayoutView #document",
"bounds": [800, 600],
"drawsContent": false,
"backgroundColor": "#FFFFFF"
},
{
"name": "Scrolling Contents Layer",
"bounds": [1200, 900],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "Horizontal Scrollbar Layer",
"position": [0, 580],
"bounds": [780, 20]
},
{
"name": "Vertical Scrollbar Layer",
"position": [780, 0],
"bounds": [20, 580]
},
{
"name": "Scroll Corner Layer",
"position": [780, 580],
"bounds": [20, 20]
}
]
}
<!DOCTYPE html>
<!--
This test dumps the full composited layer tree on a blank page with overflow.
-->
<style>
html { overflow: scroll; width: 1200px; height: 900px; }
/* Fixed scrollbar thickness for consistency across platforms. */
::-webkit-scrollbar { width: 20px; height: 20px; }
::-webkit-scrollbar-thumb { background-color: blue; }
</style>
<script>
testRunner.dumpAsText();
testRunner.setCustomTextOutput(
"Layer list\n" +
internals.layerTreeAsText(document,
internals.LAYER_TREE_INCLUDES_ROOT_LAYER));
</script>
{
"layers": [
{
"name": "LayoutNGBlockFlow HTML",
"bounds": [800, 242],
"paintingPhases": [
"GraphicsLayerPaintBackground",
"GraphicsLayerPaintMask",
"GraphicsLayerPaintDecoration"
]
},
{
"name": "LayoutNGBlockFlow (relative positioned) DIV class='composited'",
"bounds": [80, 10],
"contentsOpaque": true,
"backgroundColor": "#008000",
"paintingPhases": [
"GraphicsLayerPaintBackground",
"GraphicsLayerPaintForeground",
"GraphicsLayerPaintMask",
"GraphicsLayerPaintDecoration"
],
"transform": 2
},
{
"name": "LayoutNGBlockFlow HTML (foreground) Layer",
"bounds": [800, 242],
"paintingPhases": [
"GraphicsLayerPaintForeground"
]
},
{
"name": "LayoutNGBlockFlow DIV class='container'",
"bounds": [202, 202],
"paintingPhases": [
"GraphicsLayerPaintBackground",
"GraphicsLayerPaintMask",
"GraphicsLayerPaintCompositedScroll",
"GraphicsLayerPaintDecoration"
],
"transform": 1
},
{
"name": "Scrolling Contents Layer",
"position": [1, 1],
"bounds": [185, 715],
"paintingPhases": [
"GraphicsLayerPaintForeground",
"GraphicsLayerPaintOverflowContents",
"GraphicsLayerPaintCompositedScroll"
],
"transform": 1
},
{
"name": "ContentsLayer for Horizontal Scrollbar Layer",
"position": [1, 186],
"bounds": [185, 15],
"transform": 1
},
{
"name": "ContentsLayer for Vertical Scrollbar Layer",
"position": [186, 1],
"bounds": [15, 185],
"transform": 1
},
{
"name": "Scroll Corner Layer",
"position": [186, 186],
"bounds": [15, 15],
"paintingPhases": [
"GraphicsLayerPaintBackground",
"GraphicsLayerPaintForeground",
"GraphicsLayerPaintMask",
"GraphicsLayerPaintDecoration"
],
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[28, 20, 0, 1]
]
},
{
"id": 2,
"parent": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[1, 11, 0, 1]
]
}
]
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Composited scrolling paint phases</title>
<style type="text/css" media="screen">
.container {
width: 200px;
height: 200px;
overflow: scroll;
margin: 20px;
border: 1px solid black;
}
.composited {
width: 80px;
height: 10px;
position: relative;
top: 10px;
will-change: transform;
background-color: green;
z-index: -1;
}
.not-composited {
width: 80px;
height: 20px;
margin: 5px;
background-color: blue;
}
</style>
<script>
if (window.testRunner)
testRunner.dumpAsText();
if (window.internals)
internals.settings.setPreferCompositingToLCDTextEnabled(true);
function write(str)
{
var pre = document.getElementById('console');
var text = document.createTextNode(str + '\n');
pre.appendChild(text);
}
function doTest()
{
write(internals.layerTreeAsText(document, window.internals.LAYER_TREE_INCLUDES_PAINTING_PHASES));
if (window.testRunner)
testRunner.notifyDone();
}
window.addEventListener('load', doTest, false);
if (window.testRunner)
testRunner.waitUntilDone();
</script>
</head>
<body>
<div class="container">
<div class="composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
<div class="not-composited"></div>
</div>
<pre id="console"></pre>
</body>
</html>
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF",
"paintingPhases": [
"GraphicsLayerPaintForeground",
"GraphicsLayerPaintOverflowContents",
"GraphicsLayerPaintCompositedScroll"
]
},
{
"name": "LayoutNGBlockFlow DIV class='scroller'",
"bounds": [102, 102],
"paintingPhases": [
"GraphicsLayerPaintBackground",
"GraphicsLayerPaintMask",
"GraphicsLayerPaintCompositedScroll",
"GraphicsLayerPaintDecoration"
],
"transform": 1
},
{
"name": "Scrolling Contents Layer",
"position": [1, 1],
"bounds": [85, 120],
"paintingPhases": [
"GraphicsLayerPaintForeground",
"GraphicsLayerPaintOverflowContents",
"GraphicsLayerPaintCompositedScroll"
],
"transform": 1
},
{
"name": "ContentsLayer for Horizontal Scrollbar Layer",
"position": [1, 86],
"bounds": [85, 15],
"transform": 1
},
{
"name": "ContentsLayer for Vertical Scrollbar Layer",
"position": [86, 1],
"bounds": [15, 85],
"transform": 1
},
{
"name": "Scroll Corner Layer",
"position": [86, 86],
"bounds": [15, 15],
"paintingPhases": [
"GraphicsLayerPaintBackground",
"GraphicsLayerPaintForeground",
"GraphicsLayerPaintMask",
"GraphicsLayerPaintDecoration"
],
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[8, 8, 0, 1]
]
}
]
}
<!DOCTYPE HTML>
<style>
.scroller {
width: 100px;
height: 100px;
border: 1px solid black;
overflow: scroll;
}
.scrolled {
width: 40px;
height: 40px;
background: green;
}
.neg-zorder {
position: relative;
z-index: -1;
will-change: transform;
background: blue;
}
</style>
<script>
if (window.internals) {
internals.settings.setPreferCompositingToLCDTextEnabled(true);
}
</script>
<div class="scroller">
<div class="scrolled neg-zorder" id="to-modify"></div>
<div class="scrolled"></div>
<div class="scrolled"></div>
<div class="scrolled"></div>
</div>
<script>
if (window.testRunner)
testRunner.dumpAsText();
if (window.internals) {
internals.forceCompositingUpdate(document);
internals.startTrackingRepaints(document);
}
document.querySelector('style').appendChild(document.createTextNode('#to-modify { display: none }'));
if (window.internals) {
var layerTree = document.createElement('pre');
layerTree.innerHTML = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_PAINTING_PHASES);
internals.stopTrackingRepaints(document);
document.body.appendChild(layerTree);
}
</script>
Layer list
{
"layers": [
{
"name": "LayoutView #document",
"bounds": [780, 580],
"drawsContent": false
},
{
"name": "Scrolling background of LayoutView #document",
"bounds": [1200, 900],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutCustomScrollbarPart (anonymous)",
"bounds": [800, 600],
"backgroundColor": "#0000FF"
}
]
}
{
"layers": [
{
"name": "Scrolling background of LayoutView #document",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutNGBlockFlow (relative positioned) DIV class='composited'",
"bounds": [80, 10],
"contentsOpaque": true,
"backgroundColor": "#008000",
"transform": 2
},
{
"name": "LayoutNGBlockFlow DIV class='container'",
"bounds": [202, 202],
"transform": 1
},
{
"name": "HorizontalScrollbar",
"position": [1, 186],
"bounds": [185, 15],
"transform": 1
},
{
"name": "VerticalScrollbar",
"position": [186, 1],
"bounds": [15, 185],
"transform": 1
},
{
"name": "LayoutNGBlockFlow DIV class='container'",
"bounds": [202, 202],
"transform": 1
},
{
"name": "LayoutNGBlockFlow DIV class='container'",
"position": [6, 16],
"bounds": [80, 695],
"backgroundColor": "#0000FF",
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[28, 20, 0, 1]
]
},
{
"id": 2,
"parent": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[1, 11, 0, 1]
]
}
]
}
{
"layers": [
{
"name": "Scrolling background of LayoutView #document",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "HorizontalScrollbar",
"position": [1, 86],
"bounds": [85, 15],
"transform": 1
},
{
"name": "VerticalScrollbar",
"position": [86, 1],
"bounds": [15, 85],
"transform": 1
},
{
"name": "LayoutNGBlockFlow DIV class='scroller'",
"bounds": [102, 102],
"transform": 1
},
{
"name": "LayoutNGBlockFlow DIV class='scroller'",
"position": [1, 1],
"bounds": [40, 120],
"contentsOpaque": true,
"backgroundColor": "#008000",
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[8, 8, 0, 1]
]
}
]
}
{
"layers": [
{
"name": "LayoutBlockFlow HTML",
"bounds": [800, 242],
"paintingPhases": [
"GraphicsLayerPaintBackground",
"GraphicsLayerPaintMask",
"GraphicsLayerPaintDecoration"
]
},
{
"name": "LayoutBlockFlow (relative positioned) DIV class='composited'",
"bounds": [80, 10],
"contentsOpaque": true,
"backgroundColor": "#008000",
"paintingPhases": [
"GraphicsLayerPaintBackground",
"GraphicsLayerPaintForeground",
"GraphicsLayerPaintMask",
"GraphicsLayerPaintDecoration"
],
"transform": 2
},
{
"name": "LayoutBlockFlow HTML (foreground) Layer",
"bounds": [800, 242],
"paintingPhases": [
"GraphicsLayerPaintForeground"
]
},
{
"name": "LayoutBlockFlow DIV class='container'",
"bounds": [202, 202],
"paintingPhases": [
"GraphicsLayerPaintBackground",
"GraphicsLayerPaintMask",
"GraphicsLayerPaintCompositedScroll",
"GraphicsLayerPaintDecoration"
],
"transform": 1
},
{
"name": "Scrolling Contents Layer",
"position": [1, 1],
"bounds": [185, 715],
"paintingPhases": [
"GraphicsLayerPaintForeground",
"GraphicsLayerPaintOverflowContents",
"GraphicsLayerPaintCompositedScroll"
],
"transform": 1
},
{
"name": "ContentsLayer for Horizontal Scrollbar Layer",
"position": [1, 186],
"bounds": [185, 15],
"transform": 1
},
{
"name": "ContentsLayer for Vertical Scrollbar Layer",
"position": [186, 1],
"bounds": [15, 185],
"transform": 1
},
{
"name": "Scroll Corner Layer",
"position": [186, 186],
"bounds": [15, 15],
"paintingPhases": [
"GraphicsLayerPaintBackground",
"GraphicsLayerPaintForeground",
"GraphicsLayerPaintMask",
"GraphicsLayerPaintDecoration"
],
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[28, 20, 0, 1]
]
},
{
"id": 2,
"parent": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[1, 11, 0, 1]
]
}
]
}
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF",
"paintingPhases": [
"GraphicsLayerPaintForeground",
"GraphicsLayerPaintOverflowContents",
"GraphicsLayerPaintCompositedScroll"
]
},
{
"name": "LayoutBlockFlow DIV class='scroller'",
"bounds": [102, 102],
"paintingPhases": [
"GraphicsLayerPaintBackground",
"GraphicsLayerPaintMask",
"GraphicsLayerPaintCompositedScroll",
"GraphicsLayerPaintDecoration"
],
"transform": 1
},
{
"name": "Scrolling Contents Layer",
"position": [1, 1],
"bounds": [85, 120],
"paintingPhases": [
"GraphicsLayerPaintForeground",
"GraphicsLayerPaintOverflowContents",
"GraphicsLayerPaintCompositedScroll"
],
"transform": 1
},
{
"name": "ContentsLayer for Horizontal Scrollbar Layer",
"position": [1, 86],
"bounds": [85, 15],
"transform": 1
},
{
"name": "ContentsLayer for Vertical Scrollbar Layer",
"position": [86, 1],
"bounds": [15, 85],
"transform": 1
},
{
"name": "Scroll Corner Layer",
"position": [86, 86],
"bounds": [15, 15],
"paintingPhases": [
"GraphicsLayerPaintBackground",
"GraphicsLayerPaintForeground",
"GraphicsLayerPaintMask",
"GraphicsLayerPaintDecoration"
],
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[8, 8, 0, 1]
]
}
]
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment