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:
parent
a039340cac
commit
1d04428c3c
16 changed files with 809 additions and 10 deletions
1
include/layerproto
Symbolic link
1
include/layerproto
Symbolic link
|
@ -0,0 +1 @@
|
|||
../services/surfaceflinger/layerproto/include/layerproto/
|
|
@ -5,4 +5,4 @@ cc_library_static {
|
|||
export_static_lib_headers = ["libserviceutils"],
|
||||
}
|
||||
|
||||
subdirs = ["tests/fakehwc"]
|
||||
subdirs = ["tests/fakehwc", "layerproto"]
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
63
services/surfaceflinger/LayerProtoHelper.cpp
Normal file
63
services/surfaceflinger/LayerProtoHelper.cpp
Normal 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>(®ion);
|
||||
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
|
39
services/surfaceflinger/LayerProtoHelper.h
Normal file
39
services/surfaceflinger/LayerProtoHelper.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
35
services/surfaceflinger/layerproto/Android.bp
Normal file
35
services/surfaceflinger/layerproto/Android.bp
Normal 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",
|
||||
],
|
||||
|
||||
}
|
223
services/surfaceflinger/layerproto/LayerProtoParser.cpp
Normal file
223
services/surfaceflinger/layerproto/LayerProtoParser.cpp
Normal 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
|
|
@ -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>
|
|
@ -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
|
110
services/surfaceflinger/layerproto/layers.proto
Normal file
110
services/surfaceflinger/layerproto/layers.proto
Normal 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;
|
||||
}
|
|
@ -22,7 +22,8 @@ cc_test {
|
|||
"libsync",
|
||||
"libfmq",
|
||||
"libbase",
|
||||
"libhidltransport"
|
||||
"libhidltransport",
|
||||
"liblayers_proto"
|
||||
],
|
||||
static_libs: [
|
||||
"libhwcomposer-client",
|
||||
|
|
Loading…
Reference in a new issue