Added protobuf to gather layer info.

Use protobuf to gather information about the layers. This change also
uses protobuf for the layer dumpsys.

Test: Ran dumpsys for layers to confirm the data was correct.

Change-Id: Iec474e57a4fb9de1e548440d6a08685505947278
This commit is contained in:
chaviw 2017-09-27 12:19:28 -07:00
parent a039340cac
commit 1d04428c3c
16 changed files with 809 additions and 10 deletions

1
include/layerproto Symbolic link
View file

@ -0,0 +1 @@
../services/surfaceflinger/layerproto/include/layerproto/

View file

@ -5,4 +5,4 @@ cc_library_static {
export_static_lib_headers = ["libserviceutils"],
}
subdirs = ["tests/fakehwc"]
subdirs = ["tests/fakehwc", "layerproto"]

View file

@ -39,6 +39,7 @@ LOCAL_SRC_FILES := \
RenderEngine/RenderEngine.cpp \
RenderEngine/Texture.cpp \
RenderEngine/GLES20RenderEngine.cpp \
LayerProtoHelper.cpp \
LOCAL_MODULE := libsurfaceflinger
LOCAL_C_INCLUDES := \
@ -98,7 +99,8 @@ LOCAL_SHARED_LIBRARIES := \
libsync \
libprotobuf-cpp-lite \
libbase \
android.hardware.power@1.0
android.hardware.power@1.0 \
liblayers_proto
LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
android.hardware.graphics.allocator@2.0 \
@ -145,7 +147,8 @@ LOCAL_SHARED_LIBRARIES := \
libutils \
libui \
libgui \
libdl
libdl \
liblayers_proto
LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
LOCAL_STATIC_LIBRARIES := libtrace_proto \

View file

@ -56,6 +56,7 @@
#include "RenderEngine/RenderEngine.h"
#include <mutex>
#include "LayerProtoHelper.h"
#define DEBUG_RESIZE 0
@ -2826,6 +2827,82 @@ void Layer::commitChildList() {
mDrawingParent = mCurrentParent;
}
void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) {
const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
const State& state = useDrawing ? mDrawingState : mCurrentState;
Transform requestedTransform = state.active.transform;
Transform transform = getTransform();
layerInfo->set_id(sequence);
layerInfo->set_name(getName().c_str());
layerInfo->set_type(String8(getTypeId()));
for (const auto& child : children) {
layerInfo->add_children(child->sequence);
}
for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
sp<Layer> strongRelative = weakRelative.promote();
if (strongRelative != nullptr) {
layerInfo->add_relatives(strongRelative->sequence);
}
}
LayerProtoHelper::writeToProto(state.activeTransparentRegion,
layerInfo->mutable_transparent_region());
LayerProtoHelper::writeToProto(visibleRegion, layerInfo->mutable_visible_region());
LayerProtoHelper::writeToProto(surfaceDamageRegion, layerInfo->mutable_damage_region());
layerInfo->set_layer_stack(getLayerStack());
layerInfo->set_z(state.z);
PositionProto* position = layerInfo->mutable_position();
position->set_x(transform.tx());
position->set_y(transform.ty());
PositionProto* requestedPosition = layerInfo->mutable_requested_position();
requestedPosition->set_x(requestedTransform.tx());
requestedPosition->set_y(requestedTransform.ty());
SizeProto* size = layerInfo->mutable_size();
size->set_w(state.active.w);
size->set_h(state.active.h);
LayerProtoHelper::writeToProto(state.crop, layerInfo->mutable_crop());
LayerProtoHelper::writeToProto(state.finalCrop, layerInfo->mutable_final_crop());
layerInfo->set_is_opaque(isOpaque(state));
layerInfo->set_invalidate(contentDirty);
layerInfo->set_dataspace(dataspaceDetails(getDataSpace()));
layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat()));
LayerProtoHelper::writeToProto(getColor(), layerInfo->mutable_color());
LayerProtoHelper::writeToProto(state.color, layerInfo->mutable_requested_color());
layerInfo->set_flags(state.flags);
LayerProtoHelper::writeToProto(transform, layerInfo->mutable_transform());
LayerProtoHelper::writeToProto(requestedTransform, layerInfo->mutable_requested_transform());
auto parent = getParent();
if (parent != nullptr) {
layerInfo->set_parent(parent->sequence);
}
auto zOrderRelativeOf = state.zOrderRelativeOf.promote();
if (zOrderRelativeOf != nullptr) {
layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence);
}
auto activeBuffer = getActiveBuffer();
if (activeBuffer != nullptr) {
LayerProtoHelper::writeToProto(activeBuffer, layerInfo->mutable_active_buffer());
}
layerInfo->set_queued_frames(getQueuedFrameCount());
layerInfo->set_refresh_pending(isBufferLatched());
}
// ---------------------------------------------------------------------------
}; // namespace android

View file

@ -49,9 +49,12 @@
#include "DisplayHardware/HWComposerBufferCache.h"
#include "RenderEngine/Mesh.h"
#include "RenderEngine/Texture.h"
#include <layerproto/LayerProtoHeader.h>
#include <math/vec4.h>
using namespace android::surfaceflinger;
namespace android {
// ---------------------------------------------------------------------------
@ -303,6 +306,8 @@ public:
*/
virtual bool isFixedSize() const;
void writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing);
protected:
/*
* onDraw - draws the surface.

View file

@ -0,0 +1,63 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LayerProtoHelper.h"
namespace android {
namespace surfaceflinger {
void LayerProtoHelper::writeToProto(const Region& region, RegionProto* regionProto) {
Region::const_iterator head = region.begin();
Region::const_iterator const tail = region.end();
uint64_t address = reinterpret_cast<uint64_t>(&region);
regionProto->set_id(address);
while (head != tail) {
RectProto* rectProto = regionProto->add_rect();
writeToProto(*head, rectProto);
head++;
}
}
void LayerProtoHelper::writeToProto(const Rect& rect, RectProto* rectProto) {
rectProto->set_left(rect.left);
rectProto->set_top(rect.top);
rectProto->set_bottom(rect.bottom);
rectProto->set_right(rect.right);
}
void LayerProtoHelper::writeToProto(const half4 color, ColorProto* colorProto) {
colorProto->set_r(color.r);
colorProto->set_g(color.g);
colorProto->set_b(color.b);
colorProto->set_a(color.a);
}
void LayerProtoHelper::writeToProto(const Transform& transform, TransformProto* transformProto) {
transformProto->set_dsdx(transform[0][0]);
transformProto->set_dtdx(transform[0][1]);
transformProto->set_dsdy(transform[1][0]);
transformProto->set_dtdy(transform[1][1]);
}
void LayerProtoHelper::writeToProto(const sp<GraphicBuffer>& buffer,
ActiveBufferProto* activeBufferProto) {
activeBufferProto->set_width(buffer->getWidth());
activeBufferProto->set_height(buffer->getHeight());
activeBufferProto->set_stride(buffer->getStride());
activeBufferProto->set_format(buffer->format);
}
} // namespace surfaceflinger
} // namespace android

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <layerproto/LayerProtoHeader.h>
#include <ui/GraphicBuffer.h>
#include <ui/Rect.h>
#include <ui/Region.h>
#include <Transform.h>
#include <math/vec4.h>
namespace android {
namespace surfaceflinger {
class LayerProtoHelper {
public:
static void writeToProto(const Rect& rect, RectProto* rectProto);
static void writeToProto(const Region& region, RegionProto* regionProto);
static void writeToProto(const half4 color, ColorProto* colorProto);
static void writeToProto(const Transform& transform, TransformProto* transformProto);
static void writeToProto(const sp<GraphicBuffer>& buffer, ActiveBufferProto* activeBufferProto);
};
} // namespace surfaceflinger
} // namespace android

View file

@ -90,6 +90,8 @@
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <configstore/Utils.h>
#include <layerproto/LayerProtoParser.h>
#define DISPLAY_COUNT 1
/*
@ -3532,6 +3534,13 @@ status_t SurfaceFlinger::doDump(int fd, const Vector<String16>& args) {
dumpWideColorInfo(result);
dumpAll = false;
}
if ((index < numArgs) && (args[index] == String16("--proto"))) {
index++;
LayersProto layersProto = dumpProtoInfo();
result.append(layersProto.SerializeAsString().c_str(), layersProto.ByteSize());
dumpAll = false;
}
}
if (dumpAll) {
@ -3727,6 +3736,16 @@ void SurfaceFlinger::dumpWideColorInfo(String8& result) const {
result.append("\n");
}
LayersProto SurfaceFlinger::dumpProtoInfo() const {
LayersProto layersProto;
mCurrentState.traverseInZOrder([&](Layer* layer) {
LayerProto* layerProto = layersProto.add_layers();
layer->writeToProto(layerProto, LayerVector::StateSet::Current);
});
return layersProto;
}
void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
String8& result) const
{
@ -3791,9 +3810,10 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
colorizer.bold(result);
result.appendFormat("Visible layers (count = %zu)\n", mNumLayers);
colorizer.reset(result);
mCurrentState.traverseInZOrder([&](Layer* layer) {
result.append(to_string(layer->getLayerDebugInfo()).c_str());
});
LayersProto layersProto = dumpProtoInfo();
auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
result.append(LayerProtoParser::layersToString(layerTree).c_str());
/*
* Dump Display state

View file

@ -78,6 +78,10 @@
#include <thread>
#include <utility>
#include <layerproto/LayerProtoHeader.h>
using namespace android::surfaceflinger;
namespace android {
// ---------------------------------------------------------------------------
@ -622,6 +626,7 @@ private:
std::vector<OccupancyTracker::Segment>&& history);
void dumpBufferingStats(String8& result) const;
void dumpWideColorInfo(String8& result) const;
LayersProto dumpProtoInfo() const;
bool isLayerTripleBufferingDisabled() const {
return this->mLayerTripleBufferingDisabled;

View file

@ -87,6 +87,8 @@
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <configstore/Utils.h>
#include <layerproto/LayerProtoParser.h>
#define DISPLAY_COUNT 1
/*
@ -3073,6 +3075,13 @@ status_t SurfaceFlinger::doDump(int fd, const Vector<String16>& args)
dumpFrameEventsLocked(result);
dumpAll = false;
}
if ((index < numArgs) && (args[index] == String16("--proto"))) {
index++;
LayersProto layersProto = dumpProtoInfo();
result.append(layersProto.SerializeAsString().c_str(), layersProto.ByteSize());
dumpAll = false;
}
}
if (dumpAll) {
@ -3243,6 +3252,16 @@ void SurfaceFlinger::dumpBufferingStats(String8& result) const {
result.append("\n");
}
LayersProto SurfaceFlinger::dumpProtoInfo() const {
LayersProto layersProto;
mCurrentState.traverseInZOrder([&](Layer* layer) {
LayerProto* layerProto = layersProto.add_layers();
layer->writeToProto(layerProto, LayerVector::StateSet::Current);
});
return layersProto;
}
void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
String8& result) const
{
@ -3302,9 +3321,10 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
colorizer.bold(result);
result.appendFormat("Visible layers (count = %zu)\n", mNumLayers);
colorizer.reset(result);
mCurrentState.traverseInZOrder([&](Layer* layer) {
result.append(to_string(layer->getLayerDebugInfo()).c_str());
});
LayersProto layersProto = dumpProtoInfo();
auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
result.append(LayerProtoParser::layersToString(layerTree).c_str());
/*
* Dump Display state

View file

@ -0,0 +1,35 @@
cc_library_shared {
name: "liblayers_proto",
vendor_available: true,
export_include_dirs: ["include"],
srcs: [
"LayerProtoParser.cpp",
"layers.proto",
],
shared_libs: [
"libui",
"libprotobuf-cpp-lite",
"libbase",
],
proto: {
export_proto_headers: true,
},
cppflags: [
"-Werror",
"-Wno-unused-parameter",
"-Wno-format",
"-Wno-c++98-compat-pedantic",
"-Wno-float-conversion",
"-Wno-disabled-macro-expansion",
"-Wno-float-equal",
"-Wno-sign-conversion",
"-Wno-padded",
"-Wno-old-style-cast",
"-Wno-undef",
],
}

View file

@ -0,0 +1,223 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <layerproto/LayerProtoParser.h>
namespace android {
namespace surfaceflinger {
bool sortLayers(const LayerProtoParser::Layer* lhs, const LayerProtoParser::Layer* rhs) {
uint32_t ls = lhs->layerStack;
uint32_t rs = rhs->layerStack;
if (ls != rs) return ls < rs;
uint32_t lz = lhs->z;
uint32_t rz = rhs->z;
if (lz != rz) return lz < rz;
return lhs->id < rhs->id;
}
std::vector<const LayerProtoParser::Layer*> LayerProtoParser::generateLayerTree(
const LayersProto& layersProto) {
auto layerMap = generateMap(layersProto);
std::vector<const Layer*> layers;
std::for_each(layerMap.begin(), layerMap.end(),
[&](const std::pair<const int32_t, Layer*>& ref) {
if (ref.second->parent == nullptr) {
// only save top level layers
layers.push_back(ref.second);
}
});
std::sort(layers.begin(), layers.end(), sortLayers);
return layers;
}
std::unordered_map<int32_t, LayerProtoParser::Layer*> LayerProtoParser::generateMap(
const LayersProto& layersProto) {
std::unordered_map<int32_t, Layer*> layerMap;
for (int i = 0; i < layersProto.layers_size(); i++) {
const LayerProto& layerProto = layersProto.layers(i);
layerMap[layerProto.id()] = generateLayer(layerProto);
}
for (int i = 0; i < layersProto.layers_size(); i++) {
const LayerProto& layerProto = layersProto.layers(i);
updateChildrenAndRelative(layerProto, layerMap);
}
return layerMap;
}
LayerProtoParser::Layer* LayerProtoParser::generateLayer(const LayerProto& layerProto) {
Layer* layer = new Layer();
layer->id = layerProto.id();
layer->name = layerProto.name();
layer->type = layerProto.type();
layer->transparentRegion = generateRegion(layerProto.transparent_region());
layer->visibleRegion = generateRegion(layerProto.visible_region());
layer->damageRegion = generateRegion(layerProto.damage_region());
layer->layerStack = layerProto.layer_stack();
layer->z = layerProto.z();
layer->position = {layerProto.position().x(), layerProto.position().y()};
layer->requestedPosition = {layerProto.requested_position().x(),
layerProto.requested_position().y()};
layer->size = {layerProto.size().w(), layerProto.size().h()};
layer->crop = generateRect(layerProto.crop());
layer->finalCrop = generateRect(layerProto.final_crop());
layer->isOpaque = layerProto.is_opaque();
layer->invalidate = layerProto.invalidate();
layer->dataspace = layerProto.dataspace();
layer->pixelFormat = layerProto.pixel_format();
layer->color = {layerProto.color().r(), layerProto.color().g(), layerProto.color().b(),
layerProto.color().a()};
layer->requestedColor = {layerProto.requested_color().r(), layerProto.requested_color().g(),
layerProto.requested_color().b(), layerProto.requested_color().a()};
layer->flags = layerProto.flags();
layer->transform = generateTransform(layerProto.transform());
layer->requestedTransform = generateTransform(layerProto.requested_transform());
layer->activeBuffer = generateActiveBuffer(layerProto.active_buffer());
layer->queuedFrames = layerProto.queued_frames();
layer->refreshPending = layerProto.refresh_pending();
return layer;
}
LayerProtoParser::Region LayerProtoParser::generateRegion(const RegionProto& regionProto) {
LayerProtoParser::Region region;
region.id = regionProto.id();
for (int i = 0; i < regionProto.rect_size(); i++) {
const RectProto& rectProto = regionProto.rect(i);
region.rects.push_back(generateRect(rectProto));
}
return region;
}
LayerProtoParser::Rect LayerProtoParser::generateRect(const RectProto& rectProto) {
LayerProtoParser::Rect rect;
rect.left = rectProto.left();
rect.top = rectProto.top();
rect.right = rectProto.right();
rect.bottom = rectProto.bottom();
return rect;
}
LayerProtoParser::Transform LayerProtoParser::generateTransform(
const TransformProto& transformProto) {
LayerProtoParser::Transform transform;
transform.dsdx = transformProto.dsdx();
transform.dtdx = transformProto.dtdx();
transform.dsdy = transformProto.dsdy();
transform.dtdy = transformProto.dtdy();
return transform;
}
LayerProtoParser::ActiveBuffer LayerProtoParser::generateActiveBuffer(
const ActiveBufferProto& activeBufferProto) {
LayerProtoParser::ActiveBuffer activeBuffer;
activeBuffer.width = activeBufferProto.width();
activeBuffer.height = activeBufferProto.height();
activeBuffer.stride = activeBufferProto.stride();
activeBuffer.format = activeBufferProto.format();
return activeBuffer;
}
void LayerProtoParser::updateChildrenAndRelative(const LayerProto& layerProto,
std::unordered_map<int32_t, Layer*>& layerMap) {
auto currLayer = layerMap[layerProto.id()];
for (int i = 0; i < layerProto.children_size(); i++) {
if (layerMap.count(layerProto.children(i)) > 0) {
auto childLayer = layerMap[layerProto.children(i)];
currLayer->children.push_back(childLayer);
}
}
for (int i = 0; i < layerProto.relatives_size(); i++) {
if (layerMap.count(layerProto.relatives(i)) > 0) {
auto relativeLayer = layerMap[layerProto.relatives(i)];
currLayer->relatives.push_back(relativeLayer);
}
}
if (layerProto.has_parent()) {
if (layerMap.count(layerProto.parent()) > 0) {
auto parentLayer = layerMap[layerProto.parent()];
currLayer->parent = parentLayer;
}
}
if (layerProto.has_z_order_relative_of()) {
if (layerMap.count(layerProto.z_order_relative_of()) > 0) {
auto relativeLayer = layerMap[layerProto.z_order_relative_of()];
currLayer->zOrderRelativeOf = relativeLayer;
}
}
}
std::string LayerProtoParser::layersToString(
const std::vector<const LayerProtoParser::Layer*> layers) {
std::string result;
for (const LayerProtoParser::Layer* layer : layers) {
if (layer->zOrderRelativeOf != nullptr) {
continue;
}
result.append(layerToString(layer).c_str());
}
return result;
}
std::string LayerProtoParser::layerToString(const LayerProtoParser::Layer* layer) {
std::string result;
std::vector<const Layer*> traverse(layer->relatives);
for (const LayerProtoParser::Layer* child : layer->children) {
if (child->zOrderRelativeOf != nullptr) {
continue;
}
traverse.push_back(child);
}
std::sort(traverse.begin(), traverse.end(), sortLayers);
size_t i = 0;
for (; i < traverse.size(); i++) {
const auto& relative = traverse[i];
if (relative->z >= 0) {
break;
}
result.append(layerToString(relative).c_str());
}
result.append(layer->to_string().c_str());
result.append("\n");
for (; i < traverse.size(); i++) {
const auto& relative = traverse[i];
result.append(layerToString(relative).c_str());
}
return result;
}
} // namespace surfaceflinger
} // namespace android

View file

@ -0,0 +1,23 @@
/*
* Copyright (C) 2007 The Android Open Source Projectlayerproto/LayerProtoHeader.h
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// pragma is used here to disable the warnings emitted from the protobuf
// headers. By adding #pragma before including layer.pb.h, it supresses
// protobuf warnings, but allows the rest of the files to continuing using
// the current flags.
// This file should be included instead of directly including layer.b.h
#pragma GCC system_header
#include <layers.pb.h>

View file

@ -0,0 +1,174 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <layerproto/LayerProtoHeader.h>
#include <math/vec4.h>
#include <android-base/stringprintf.h>
#include <ui/DebugUtils.h>
#include <unordered_map>
#include <vector>
using android::base::StringAppendF;
using android::base::StringPrintf;
namespace android {
namespace surfaceflinger {
class LayerProtoParser {
public:
class ActiveBuffer {
public:
uint32_t width;
uint32_t height;
uint32_t stride;
int32_t format;
std::string to_string() const {
return StringPrintf("[%4ux%4u:%4u,%s]", width, height, stride,
decodePixelFormat(format).c_str());
}
};
class Transform {
public:
float dsdx;
float dtdx;
float dsdy;
float dtdy;
std::string to_string() const {
return StringPrintf("[%.2f, %.2f][%.2f, %.2f]", static_cast<double>(dsdx),
static_cast<double>(dtdx), static_cast<double>(dsdy),
static_cast<double>(dtdy));
}
};
class Rect {
public:
int32_t left;
int32_t top;
int32_t right;
int32_t bottom;
std::string to_string() const {
return StringPrintf("[%3d, %3d, %3d, %3d]", left, top, right, bottom);
}
};
class Region {
public:
uint64_t id;
std::vector<Rect> rects;
std::string to_string(const char* what) const {
std::string result =
StringPrintf(" Region %s (this=%lx count=%d)\n", what,
static_cast<unsigned long>(id), static_cast<int>(rects.size()));
for (auto& rect : rects) {
StringAppendF(&result, " %s\n", rect.to_string().c_str());
}
return result;
}
};
class Layer {
public:
int32_t id;
std::string name;
std::vector<const Layer*> children;
std::vector<const Layer*> relatives;
std::string type;
LayerProtoParser::Region transparentRegion;
LayerProtoParser::Region visibleRegion;
LayerProtoParser::Region damageRegion;
uint32_t layerStack;
int32_t z;
float2 position;
float2 requestedPosition;
int2 size;
LayerProtoParser::Rect crop;
LayerProtoParser::Rect finalCrop;
bool isOpaque;
bool invalidate;
std::string dataspace;
std::string pixelFormat;
half4 color;
half4 requestedColor;
uint32_t flags;
Transform transform;
Transform requestedTransform;
Layer* parent = 0;
Layer* zOrderRelativeOf = 0;
LayerProtoParser::ActiveBuffer activeBuffer;
int32_t queuedFrames;
bool refreshPending;
std::string to_string() const {
std::string result;
StringAppendF(&result, "+ %s (%s)\n", type.c_str(), name.c_str());
result.append(transparentRegion.to_string("TransparentRegion").c_str());
result.append(visibleRegion.to_string("VisibleRegion").c_str());
result.append(damageRegion.to_string("SurfaceDamageRegion").c_str());
StringAppendF(&result, " layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), ",
layerStack, z, static_cast<double>(position.x),
static_cast<double>(position.y), size.x, size.y);
StringAppendF(&result, "crop=%s, finalCrop=%s, ", crop.to_string().c_str(),
finalCrop.to_string().c_str());
StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate);
StringAppendF(&result, "dataspace=%s, ", dataspace.c_str());
StringAppendF(&result, "pixelformat=%s, ", pixelFormat.c_str());
StringAppendF(&result, "color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ",
static_cast<double>(color.r), static_cast<double>(color.g),
static_cast<double>(color.b), static_cast<double>(color.a), flags);
StringAppendF(&result, "tr=%s", transform.to_string().c_str());
result.append("\n");
StringAppendF(&result, " parent=%s\n",
parent == nullptr ? "none" : parent->name.c_str());
StringAppendF(&result, " zOrderRelativeOf=%s\n",
zOrderRelativeOf == nullptr ? "none" : zOrderRelativeOf->name.c_str());
StringAppendF(&result, " activeBuffer=%s,", activeBuffer.to_string().c_str());
StringAppendF(&result, " queued-frames=%d, mRefreshPending=%d", queuedFrames,
refreshPending);
return result;
}
};
static std::vector<const Layer*> generateLayerTree(const LayersProto& layersProto);
static std::string layersToString(const std::vector<const LayerProtoParser::Layer*> layers);
private:
static std::unordered_map<int32_t, Layer*> generateMap(const LayersProto& layersProto);
static LayerProtoParser::Layer* generateLayer(const LayerProto& layerProto);
static LayerProtoParser::Region generateRegion(const RegionProto& regionProto);
static LayerProtoParser::Rect generateRect(const RectProto& rectProto);
static LayerProtoParser::Transform generateTransform(const TransformProto& transformProto);
static LayerProtoParser::ActiveBuffer generateActiveBuffer(
const ActiveBufferProto& activeBufferProto);
static void updateChildrenAndRelative(const LayerProto& layerProto,
std::unordered_map<int32_t, Layer*>& layerMap);
static std::string layerToString(const LayerProtoParser::Layer* layer);
};
} // namespace surfaceflinger
} // namespace android

View file

@ -0,0 +1,110 @@
// Definitions for SurfaceFlinger layers.
syntax = "proto2";
option optimize_for = LITE_RUNTIME;
package android.surfaceflinger;
// Contains a list of all layers.
message LayersProto {
repeated LayerProto layers = 1;
}
// Information about each layer.
message LayerProto {
// unique id per layer.
optional int32 id = 1;
// unique name per layer.
optional string name = 2;
// list of children this layer may have. May be empty.
repeated int32 children = 3;
// list of layers that are z order relative to this layer.
repeated int32 relatives = 4;
// The type of layer, ex Color, Layer
optional string type = 5;
optional RegionProto transparent_region = 6;
optional RegionProto visible_region = 7;
optional RegionProto damage_region = 8;
optional uint32 layer_stack = 9;
// The layer's z order. Can be z order in layer stack, relative to parent,
// or relative to another layer specified in zOrderRelative.
optional int32 z = 10;
// The layer's position on the display.
optional PositionProto position = 11;
// The layer's requested position.
optional PositionProto requested_position = 12;
// The layer's size.
optional SizeProto size = 13;
// The layer's crop in it's own bounds.
optional RectProto crop = 14;
// The layer's crop in it's parent's bounds.
optional RectProto final_crop = 15;
optional bool is_opaque = 16;
optional bool invalidate = 17;
optional string dataspace = 18;
optional string pixel_format = 19;
// The layer's actual color.
optional ColorProto color = 20;
// The layer's requested color.
optional ColorProto requested_color = 21;
// Can be any combination of
// hidden = 0x01
// opaque = 0x02,
// secure = 0x80,
optional uint32 flags = 22;
// The layer's actual transform
optional TransformProto transform = 23;
// The layer's requested transform.
optional TransformProto requested_transform = 24;
// The parent layer. This value can be null if there is no parent.
optional int32 parent = 25 [default = -1];
// The layer that this layer has a z order relative to. This value can be null.
optional int32 z_order_relative_of = 26 [default = -1];
// This value can be null if there's nothing to draw.
optional ActiveBufferProto active_buffer = 27;
// The number of frames available.
optional int32 queued_frames = 28;
optional bool refresh_pending = 29;
}
message PositionProto {
optional float x = 1;
optional float y = 2;
}
message SizeProto {
optional int32 w = 1;
optional int32 h = 2;
}
message TransformProto {
optional float dsdx = 1;
optional float dtdx = 2;
optional float dsdy = 3;
optional float dtdy = 4;
}
message RegionProto {
optional uint64 id = 1;
repeated RectProto rect = 2;
}
message RectProto {
optional int32 left = 1;
optional int32 top = 2;
optional int32 right = 3;
optional int32 bottom = 4;
}
message ActiveBufferProto {
optional uint32 width = 1;
optional uint32 height = 2;
optional uint32 stride = 3;
optional int32 format = 4;
}
message ColorProto {
optional float r = 1;
optional float g = 2;
optional float b = 3;
optional float a = 4;
}

View file

@ -22,7 +22,8 @@ cc_test {
"libsync",
"libfmq",
"libbase",
"libhidltransport"
"libhidltransport",
"liblayers_proto"
],
static_libs: [
"libhwcomposer-client",