Bug 959118 - Dump layer tree with layer scope on the viewer. r=dglastonbury

We also want to dump layer tree on the viewer, so we
can check the layer tree and layerscope together
in the viewer. This can help us resolve more gfx bugs.

In this patch, I only add a part of the layer data to
the protocol buffer packet, and you can check the
.proto file for more information if you want to add
more layer data.

By the way, as Jeff's suggestion, use auto & MakeUnique<>()
to make the UniquePtr initialization more concise.
This commit is contained in:
Boris Chiou 2014-07-27 22:32:00 +02:00
Родитель 1f53d14f7d
Коммит 1188a41eb3
11 изменённых файлов: 4298 добавлений и 17 удалений

Просмотреть файл

@ -19,6 +19,10 @@ namespace layers {
class ImageContainer;
namespace layerscope {
class LayersPacket;
}
/**
* A Layer which renders an Image.
*/
@ -83,7 +87,7 @@ protected:
ImageLayer(LayerManager* aManager, void* aImplData);
~ImageLayer();
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent);
nsRefPtr<ImageContainer> mContainer;
GraphicsFilter mFilter;

Просмотреть файл

@ -381,7 +381,7 @@ public:
return true;
uint32_t size = aPacket.ByteSize();
UniquePtr<uint8_t[]> data(new uint8_t[size]);
auto data = MakeUnique<uint8_t[]>(size);
aPacket.SerializeToArray(data.get(), size);
return WebSocketHelper::GetSocketManager()->WriteAll(data.get(), size);
}
@ -410,8 +410,8 @@ public:
Packet packet;
packet.set_type(mDataType);
FramePacket *fp = packet.mutable_frame();
fp->set_value(mFrameStamp);
FramePacket* fp = packet.mutable_frame();
fp->set_value(static_cast<uint64_t>(mFrameStamp));
if (!WriteToStream(packet))
return false;
@ -459,7 +459,7 @@ private:
void pack(DataSourceSurface* aImage) {
mPacket.set_type(mDataType);
TexturePacket *tp = mPacket.mutable_texture();
TexturePacket* tp = mPacket.mutable_texture();
tp->set_layerref(reinterpret_cast<uint64_t>(mLayerRef));
tp->set_name(mName);
tp->set_target(mTarget);
@ -473,8 +473,7 @@ private:
mDatasize = aImage->GetSize().height * aImage->Stride();
UniquePtr<char[]> compresseddata(
new char[LZ4::maxCompressedSize(mDatasize)]);
auto compresseddata = MakeUnique<char[]>(LZ4::maxCompressedSize(mDatasize));
if (compresseddata) {
int ndatasize = LZ4::compress((char*)aImage->GetData(),
mDatasize,
@ -529,7 +528,7 @@ public:
Packet packet;
packet.set_type(mDataType);
ColorPacket *cp = packet.mutable_color();
ColorPacket* cp = packet.mutable_color();
cp->set_layerref(reinterpret_cast<uint64_t>(mLayerRef));
cp->set_color(mColor);
cp->set_width(mSize.width);
@ -541,11 +540,30 @@ public:
}
protected:
void *mLayerRef;
void* mLayerRef;
uint32_t mColor;
nsIntSize mSize;
};
class DebugGLLayersData : public DebugGLData {
public:
DebugGLLayersData(UniquePtr<Packet> aPacket)
: DebugGLData(Packet::LAYERS),
mPacket(Move(aPacket))
{ }
virtual bool Write() MOZ_OVERRIDE {
mPacket->set_type(mDataType);
if (!WriteToStream(*mPacket))
return false;
return true;
}
protected:
UniquePtr<Packet> mPacket;
};
class DebugListener : public nsIServerSocketListener
{
virtual ~DebugListener() { }
@ -933,6 +951,17 @@ LayerScope::SendLayer(LayerComposite* aLayer,
SenderHelper::SendLayer(aLayer, aWidth, aHeight);
}
void
LayerScope::SendLayerDump(UniquePtr<Packet> aPacket)
{
// Protect this public function
if (!CheckSendable()) {
return;
}
WebSocketHelper::GetSocketManager()->AppendDebugData(
new DebugGLLayersData(Move(aPacket)));
}
bool
LayerScope::CheckSendable()
{

Просмотреть файл

@ -7,6 +7,7 @@
#define GFX_LAYERSCOPE_H
#include <stdint.h>
#include <mozilla/UniquePtr.h>
struct nsIntSize;
@ -16,6 +17,8 @@ namespace gl { class GLContext; }
namespace layers {
namespace layerscope { class Packet; }
struct EffectChain;
class LayerComposite;
@ -30,6 +33,7 @@ public:
static void SendLayer(LayerComposite* aLayer,
int aWidth,
int aHeight);
static void SendLayerDump(UniquePtr<layerscope::Packet> aPacket);
static bool CheckSendable();
static void CleanLayer();
};

Просмотреть файл

@ -15,6 +15,7 @@
#include "LayersLogging.h" // for AppendToString
#include "ReadbackLayer.h" // for ReadbackLayer
#include "gfxPlatform.h" // for gfxPlatform
#include "gfxPrefs.h"
#include "gfxUtils.h" // for gfxUtils, etc
#include "gfx2DGlue.h"
#include "mozilla/DebugOnly.h" // for DebugOnly
@ -31,7 +32,7 @@
#include "nsCSSValue.h" // for nsCSSValue::Array, etc
#include "nsPrintfCString.h" // for nsPrintfCString
#include "nsStyleStruct.h" // for nsTimingFunction, etc
#include "gfxPrefs.h"
#include "protobuf/LayerScopePacket.pb.h"
uint8_t gLayerManagerLayerBuilder;
@ -1331,6 +1332,20 @@ Layer::DumpSelf(std::stringstream& aStream, const char* aPrefix)
aStream << "\n";
}
void
Layer::Dump(layerscope::LayersPacket* aPacket, const void* aParent)
{
DumpPacket(aPacket, aParent);
if (Layer* kid = GetFirstChild()) {
kid->Dump(aPacket, this);
}
if (Layer* next = GetNextSibling()) {
next->Dump(aPacket, aParent);
}
}
void
Layer::Log(const char* aPrefix)
{
@ -1426,6 +1441,105 @@ Layer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
}
}
// The static helper function sets the transform matrix into the packet
static void
DumpTransform(layerscope::LayersPacket::Layer::Matrix* aLayerMatrix, const Matrix4x4& aMatrix)
{
aLayerMatrix->set_is2d(aMatrix.Is2D());
if (aMatrix.Is2D()) {
Matrix m = aMatrix.As2D();
aLayerMatrix->set_isid(m.IsIdentity());
if (!m.IsIdentity()) {
aLayerMatrix->add_m(m._11), aLayerMatrix->add_m(m._12);
aLayerMatrix->add_m(m._21), aLayerMatrix->add_m(m._22);
aLayerMatrix->add_m(m._31), aLayerMatrix->add_m(m._32);
}
} else {
aLayerMatrix->add_m(aMatrix._11), aLayerMatrix->add_m(aMatrix._12);
aLayerMatrix->add_m(aMatrix._13), aLayerMatrix->add_m(aMatrix._14);
aLayerMatrix->add_m(aMatrix._21), aLayerMatrix->add_m(aMatrix._22);
aLayerMatrix->add_m(aMatrix._23), aLayerMatrix->add_m(aMatrix._24);
aLayerMatrix->add_m(aMatrix._31), aLayerMatrix->add_m(aMatrix._32);
aLayerMatrix->add_m(aMatrix._33), aLayerMatrix->add_m(aMatrix._34);
aLayerMatrix->add_m(aMatrix._41), aLayerMatrix->add_m(aMatrix._42);
aLayerMatrix->add_m(aMatrix._43), aLayerMatrix->add_m(aMatrix._44);
}
}
// The static helper function sets the nsIntRect into the packet
static void
DumpRect(layerscope::LayersPacket::Layer::Rect* aLayerRect, const nsIntRect& aRect)
{
aLayerRect->set_x(aRect.x);
aLayerRect->set_y(aRect.y);
aLayerRect->set_w(aRect.width);
aLayerRect->set_h(aRect.height);
}
// The static helper function sets the nsIntRegion into the packet
static void
DumpRegion(layerscope::LayersPacket::Layer::Region* aLayerRegion, const nsIntRegion& aRegion)
{
nsIntRegionRectIterator it(aRegion);
while (const nsIntRect* sr = it.Next()) {
DumpRect(aLayerRegion->add_r(), *sr);
}
}
void
Layer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
{
// Add a new layer (UnknownLayer)
using namespace layerscope;
LayersPacket::Layer* layer = aPacket->add_layer();
// Basic information
layer->set_type(LayersPacket::Layer::UnknownLayer);
layer->set_ptr(reinterpret_cast<uint64_t>(this));
layer->set_parentptr(reinterpret_cast<uint64_t>(aParent));
// Shadow
if (LayerComposite* lc = AsLayerComposite()) {
LayersPacket::Layer::Shadow* s = layer->mutable_shadow();
if (const nsIntRect* clipRect = lc->GetShadowClipRect()) {
DumpRect(s->mutable_clip(), *clipRect);
}
if (!lc->GetShadowTransform().IsIdentity()) {
DumpTransform(s->mutable_transform(), lc->GetShadowTransform());
}
if (!lc->GetShadowVisibleRegion().IsEmpty()) {
DumpRegion(s->mutable_vregion(), lc->GetShadowVisibleRegion());
}
}
// Clip
if (mUseClipRect) {
DumpRect(layer->mutable_clip(), mClipRect);
}
// Transform
if (!mTransform.IsIdentity()) {
DumpTransform(layer->mutable_transform(), mTransform);
}
// Visible region
if (!mVisibleRegion.IsEmpty()) {
DumpRegion(layer->mutable_vregion(), mVisibleRegion);
}
// Opacity
layer->set_opacity(mOpacity);
// Content opaque
layer->set_copaque(static_cast<bool>(GetContentFlags() & CONTENT_OPAQUE));
// Component alpha
layer->set_calpha(static_cast<bool>(GetContentFlags() & CONTENT_COMPONENT_ALPHA));
// Vertical or horizontal bar
if (GetScrollbarDirection() != NONE) {
layer->set_direct(GetScrollbarDirection() == VERTICAL ?
LayersPacket::Layer::VERTICAL :
LayersPacket::Layer::HORIZONTAL);
layer->set_barid(GetScrollbarTargetContainerId());
}
// Mask layer
if (mMaskLayer) {
layer->set_mask(reinterpret_cast<uint64_t>(mMaskLayer.get()));
}
}
void
ThebesLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{
@ -1435,6 +1549,19 @@ ThebesLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
}
}
void
ThebesLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
{
Layer::DumpPacket(aPacket, aParent);
// get this layer data
using namespace layerscope;
LayersPacket::Layer* layer = aPacket->mutable_layer(aPacket->layer_size()-1);
layer->set_type(LayersPacket::Layer::ThebesLayer);
if (!mValidRegion.IsEmpty()) {
DumpRegion(layer->mutable_valid(), mValidRegion);
}
}
void
ContainerLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{
@ -1453,6 +1580,16 @@ ContainerLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
}
}
void
ContainerLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
{
Layer::DumpPacket(aPacket, aParent);
// Get this layer data
using namespace layerscope;
LayersPacket::Layer* layer = aPacket->mutable_layer(aPacket->layer_size()-1);
layer->set_type(LayersPacket::Layer::ContainerLayer);
}
void
ColorLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{
@ -1460,6 +1597,17 @@ ColorLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
AppendToString(aStream, mColor, " [color=", "]");
}
void
ColorLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
{
Layer::DumpPacket(aPacket, aParent);
// Get this layer data
using namespace layerscope;
LayersPacket::Layer* layer = aPacket->mutable_layer(aPacket->layer_size()-1);
layer->set_type(LayersPacket::Layer::ColorLayer);
layer->set_color(mColor.Packed());
}
void
CanvasLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{
@ -1469,6 +1617,48 @@ CanvasLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
}
}
// This help function is used to assign the correct enum value
// to the packet
static void
DumpFilter(layerscope::LayersPacket::Layer* aLayer, const GraphicsFilter& aFilter)
{
using namespace layerscope;
switch (aFilter) {
case GraphicsFilter::FILTER_FAST:
aLayer->set_filter(LayersPacket::Layer::FILTER_FAST);
break;
case GraphicsFilter::FILTER_GOOD:
aLayer->set_filter(LayersPacket::Layer::FILTER_GOOD);
break;
case GraphicsFilter::FILTER_BEST:
aLayer->set_filter(LayersPacket::Layer::FILTER_BEST);
break;
case GraphicsFilter::FILTER_NEAREST:
aLayer->set_filter(LayersPacket::Layer::FILTER_NEAREST);
break;
case GraphicsFilter::FILTER_BILINEAR:
aLayer->set_filter(LayersPacket::Layer::FILTER_BILINEAR);
break;
case GraphicsFilter::FILTER_GAUSSIAN:
aLayer->set_filter(LayersPacket::Layer::FILTER_GAUSSIAN);
break;
default:
// ignore it
break;
}
}
void
CanvasLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
{
Layer::DumpPacket(aPacket, aParent);
// Get this layer data
using namespace layerscope;
LayersPacket::Layer* layer = aPacket->mutable_layer(aPacket->layer_size()-1);
layer->set_type(LayersPacket::Layer::CanvasLayer);
DumpFilter(layer, mFilter);
}
void
ImageLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{
@ -1478,6 +1668,17 @@ ImageLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
}
}
void
ImageLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
{
Layer::DumpPacket(aPacket, aParent);
// Get this layer data
using namespace layerscope;
LayersPacket::Layer* layer = aPacket->mutable_layer(aPacket->layer_size()-1);
layer->set_type(LayersPacket::Layer::ImageLayer);
DumpFilter(layer, mFilter);
}
void
RefLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{
@ -1487,6 +1688,17 @@ RefLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
}
}
void
RefLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
{
Layer::DumpPacket(aPacket, aParent);
// Get this layer data
using namespace layerscope;
LayersPacket::Layer* layer = aPacket->mutable_layer(aPacket->layer_size()-1);
layer->set_type(LayersPacket::Layer::RefLayer);
layer->set_refid(mId);
}
void
ReadbackLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{
@ -1502,6 +1714,19 @@ ReadbackLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
}
}
void
ReadbackLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
{
Layer::DumpPacket(aPacket, aParent);
// Get this layer data
using namespace layerscope;
LayersPacket::Layer* layer = aPacket->mutable_layer(aPacket->layer_size()-1);
layer->set_type(LayersPacket::Layer::ReadbackLayer);
LayersPacket::Layer::Size* size = layer->mutable_size();
size->set_w(mSize.width);
size->set_h(mSize.height);
}
//--------------------------------------------------
// LayerManager
@ -1549,6 +1774,16 @@ LayerManager::DumpSelf(std::stringstream& aStream, const char* aPrefix)
aStream << "\n";
}
void
LayerManager::Dump(layerscope::LayersPacket* aPacket)
{
DumpPacket(aPacket);
if (GetRoot()) {
GetRoot()->Dump(aPacket, this);
}
}
void
LayerManager::Log(const char* aPrefix)
{
@ -1582,6 +1817,18 @@ LayerManager::PrintInfo(std::stringstream& aStream, const char* aPrefix)
aStream << aPrefix << nsPrintfCString("%sLayerManager (0x%p)", Name(), this).get();
}
void
LayerManager::DumpPacket(layerscope::LayersPacket* aPacket)
{
using namespace layerscope;
// Add a new layer data (LayerManager)
LayersPacket::Layer* layer = aPacket->add_layer();
layer->set_type(LayersPacket::Layer::LayerManager);
layer->set_ptr(reinterpret_cast<uint64_t>(this));
// Layer Tree Root
layer->set_parentptr(0);
}
/*static*/ void
LayerManager::InitLog()
{

Просмотреть файл

@ -100,6 +100,10 @@ class Compositor;
struct TextureFactoryIdentifier;
struct EffectMask;
namespace layerscope {
class LayersPacket;
}
#define MOZ_LAYER_DECL_NAME(n, e) \
virtual const char* Name() const { return n; } \
virtual LayerType GetType() const { return e; }
@ -590,6 +594,12 @@ public:
}
}
/**
* Dump information about this layer manager and its managed tree to
* layerscope packet.
*/
void Dump(layerscope::LayersPacket* aPacket);
/**
* Log information about this layer manager and its managed tree to
* the NSPR log (if enabled for "Layers").
@ -678,6 +688,10 @@ protected:
// used to implement Dump*() and Log*().
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
// Print interesting information about this into layerscope packet.
// Internally used to implement Dump().
virtual void DumpPacket(layerscope::LayersPacket* aPacket);
static void InitLog();
static PRLogModuleInfo* sLog;
uint64_t mId;
@ -1365,6 +1379,12 @@ public:
*/
void DumpSelf(std::stringstream& aStream, const char* aPrefix="");
/**
* Dump information about this layer and its child & sibling layers to
* layerscope packet.
*/
void Dump(layerscope::LayersPacket* aPacket, const void* aParent);
/**
* Log information about this layer manager and its managed tree to
* the NSPR log (if enabled for "Layers").
@ -1383,6 +1403,10 @@ public:
// appends additional info to aTo.
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
// Just like PrintInfo, but this function dump information into layerscope packet,
// instead of a StringStream. It is also internally used to implement Dump();
virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent);
static bool IsLogEnabled() { return LayerManager::IsLogEnabled(); }
/**
@ -1619,6 +1643,8 @@ protected:
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent);
/**
* ComputeEffectiveTransforms snaps the ideal transform to get mEffectiveTransform.
* mResidualTranslation is the translation that should be applied *before*
@ -1838,6 +1864,8 @@ protected:
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent);
Layer* mFirstChild;
Layer* mLastChild;
FrameMetrics mFrameMetrics;
@ -1913,6 +1941,8 @@ protected:
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent);
nsIntRect mBounds;
gfxRGBA mColor;
};
@ -2072,6 +2102,8 @@ protected:
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent);
void FireDidTransactionCallback()
{
if (mPostTransCallback) {
@ -2189,6 +2221,8 @@ protected:
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent);
Layer* mTempReferent;
// 0 is a special value that means "no ID".
uint64_t mId;

Просмотреть файл

@ -26,6 +26,10 @@ namespace layers {
class ReadbackProcessor;
namespace layerscope {
class LayersPacket;
}
/**
* A ReadbackSink receives a stream of updates to a rectangle of pixels.
* These update callbacks are always called on the main thread, either during
@ -172,6 +176,8 @@ protected:
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent);
uint64_t mSequenceCounter;
nsAutoPtr<ReadbackSink> mSink;
nsIntSize mSize;

Просмотреть файл

@ -17,6 +17,7 @@
#include "ImageLayerComposite.h" // for ImageLayerComposite
#include "Layers.h" // for Layer, ContainerLayer, etc
#include "LayerScope.h" // for LayerScope Tool
#include "protobuf/LayerScopePacket.pb.h" // for protobuf (LayerScope)
#include "ThebesLayerComposite.h" // for ThebesLayerComposite
#include "TiledLayerBuffer.h" // for TiledLayerComposer
#include "Units.h" // for ScreenIntRect
@ -421,16 +422,27 @@ LayerManagerComposite::Render()
return;
}
if (gfxPrefs::LayersDump()) {
this->Dump();
}
/** Our more efficient but less powerful alter ego, if one is available. */
nsRefPtr<Composer2D> composer2D = mCompositor->GetWidget()->GetComposer2D();
// Set LayerScope begin/end frame
LayerScopeAutoFrame frame(PR_Now());
// Dump to console
if (gfxPrefs::LayersDump()) {
this->Dump();
}
// Dump to LayerScope Viewer
if (LayerScope::CheckSendable()) {
// Create a LayersPacket, dump Layers into it and transfer the
// packet('s ownership) to LayerScope.
auto packet = MakeUnique<layerscope::Packet>();
layerscope::LayersPacket* layersPacket = packet->mutable_layers();
this->Dump(layersPacket);
LayerScope::SendLayerDump(Move(packet));
}
if (!mTarget && composer2D && composer2D->TryRender(mRoot, mWorldMatrix, mGeometryChanged)) {
if (mFPS) {
double fps = mFPS->mCompositionFps.AddFrameAndGetFps(TimeStamp::Now());

Просмотреть файл

@ -36,6 +36,7 @@ EXPORTS += [
'opengl/Composer2D.h',
'opengl/OGLShaderProgram.h',
'opengl/TexturePoolOGL.h',
'protobuf/LayerScopePacket.pb.h',
'ReadbackLayer.h',
'SharedTextureImage.h',
'TiledLayerBuffer.h',

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -25,16 +25,103 @@ message TexturePacket {
optional bytes data = 9;
}
message LayersPacket {
message Layer {
enum LayerType {
UnknownLayer = 0;
LayerManager = 1;
ContainerLayer = 2;
ThebesLayer = 3;
CanvasLayer = 4;
ImageLayer = 5;
ColorLayer = 6;
RefLayer = 7;
ReadbackLayer = 8;
}
enum ScrollingDirect {
VERTICAL = 1;
HORIZONTAL = 2;
}
enum Filter {
FILTER_FAST = 0;
FILTER_GOOD = 1;
FILTER_BEST = 2;
FILTER_NEAREST = 3;
FILTER_BILINEAR = 4;
FILTER_GAUSSIAN = 5;
FILTER_SENTINEL = 6;
}
message Size {
optional int32 w = 1;
optional int32 h = 2;
}
message Rect {
optional int32 x = 1;
optional int32 y = 2;
optional int32 w = 3;
optional int32 h = 4;
}
message Region {
repeated Rect r = 1;
}
message Matrix {
optional bool is2D = 1;
optional bool isId = 2;
repeated float m = 3;
}
message Shadow {
optional Rect clip = 1;
optional Matrix transform = 2;
optional Region vRegion = 3;
}
// Basic info
// Note: Parent's pointer is used to recontruct the layer tree
required LayerType type = 1;
required uint64 ptr = 2;
required uint64 parentPtr = 3;
// Common info (10 to 99)
optional Rect clip = 10;
optional Matrix transform = 11;
optional Region vRegion = 12; // visible region
optional Shadow shadow = 13; // shadow info
optional float opacity = 14;
optional bool cOpaque = 15; // content opaque
optional bool cAlpha = 16; // component alpha
optional ScrollingDirect direct = 17;
optional uint64 barID = 18;
optional uint64 mask = 19; // mask layer
// Specific info (100 to max)
// Thebes Layer
optional Region valid = 100;
// Color Layer
optional uint32 color = 101;
// Canvas & Image Layer
optional Filter filter = 102;
// Ref Layer
optional uint64 refID = 103;
// Readback Layer
optional Size size = 104;
}
repeated Layer layer = 1;
}
// We only need to use this Packet.
// Other packet definitions are just type defines
message Packet {
enum DataType {
FRAMESTART = 1;
FRAMEEND = 2;
COLOR = 3;
TEXTURE = 4;
LAYERS = 5;
}
required DataType type = 1;
optional FramePacket frame = 2;
optional ColorPacket color = 3;
optional TexturePacket texture = 4;
optional LayersPacket layers = 5;
}