Bug 728352 - Implement a render trace utility for GFX perf & debugging. r=mattwoodroow

This commit is contained in:
Benoit Girard 2012-03-05 15:17:13 -05:00
Родитель 44b468dead
Коммит 5908dc7ff3
6 изменённых файлов: 233 добавлений и 0 удалений

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

@ -73,6 +73,7 @@ CPPSRCS = \
BasicImages.cpp \
BasicLayers.cpp \
Layers.cpp \
RenderTrace.cpp \
ReadbackProcessor.cpp \
ThebesLayerBuffer.cpp \
CanvasLayerOGL.cpp \

107
gfx/layers/RenderTrace.cpp Normal file
Просмотреть файл

@ -0,0 +1,107 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Benoit Girard <bgirard@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "Layers.h"
#include "RenderTrace.h"
// If rendertrace is off let's no compile this code
#ifdef MOZ_RENDERTRACE
namespace mozilla {
namespace layers {
static int colorId = 0;
// This should be done in the printf but android's printf is buggy
const char* colors[] = {
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19"
};
static gfx3DMatrix GetRootTransform(Layer *aLayer) {
gfx3DMatrix layerTrans = aLayer->GetTransform().ProjectTo2D();
if (aLayer->GetParent() != NULL) {
return GetRootTransform(aLayer->GetParent()) * layerTrans;
}
return layerTrans;
}
void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx3DMatrix aRootTransform, bool aReset) {
if (!aLayer)
return;
gfx3DMatrix trans = aRootTransform * aLayer->GetTransform().ProjectTo2D();
nsIntRect clipRect = aLayer->GetEffectiveVisibleRegion().GetBounds();
gfxRect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
trans.TransformBounds(rect);
printf_stderr("%s RENDERTRACE %u rect #%02X%s %i %i %i %i\n",
aLayer->Name(), (int)PR_IntervalNow(),
colorId, aColor,
(int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
colorId++;
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
RenderTraceLayers(child, aColor, aRootTransform, false);
}
if (aReset) colorId = 0;
}
void RenderTraceInvalidateStart(Layer *aLayer, const char *aColor, const nsIntRect aRect) {
gfx3DMatrix trans = GetRootTransform(aLayer);
gfxRect rect(aRect.x, aRect.y, aRect.width, aRect.height);
trans.TransformBounds(rect);
printf_stderr("%s RENDERTRACE %u fillrect #%s %i %i %i %i\n",
aLayer->Name(), (int)PR_IntervalNow(),
aColor,
(int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
}
void RenderTraceInvalidateEnd(Layer *aLayer, const char *aColor) {
// Clear with an empty rect
RenderTraceInvalidateStart(aLayer, aColor, nsIntRect());
}
}
}
#endif

69
gfx/layers/RenderTrace.h Normal file
Просмотреть файл

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Benoit Girard <bgirard@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// This is a general tool that will let you visualize platform operation.
// Currently used for the layer system, the general syntax allows this
// tools to be adapted to trace other operations.
//
// For the front end see: https://github.com/staktrace/rendertrace
// Uncomment this line to enable RENDERTRACE
//#define MOZ_RENDERTRACE
#ifdef MOZ_RENDERTRACE
#include "gfx3DMatrix.h"
#include "nsRect.h"
#ifndef GFX_RENDERTRACE_H
#define GFX_RENDERTRACE_H
namespace mozilla {
namespace layers {
class Layer;
void RenderTraceLayers(Layer *aLayer, const char *aColor, gfx3DMatrix aRootTransform = gfx3DMatrix(), bool aReset = true);
void RenderTraceInvalidateStart(Layer *aLayer, const char *aColor, const nsIntRect aRect);
void RenderTraceInvalidateEnd(Layer *aLayer, const char *aColor);
}
}
#endif //GFX_RENDERTRACE_H
#endif // MOZ_RENDERTRACE

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

@ -49,6 +49,7 @@
#include "BasicLayers.h"
#include "ImageLayers.h"
#include "RenderTrace.h"
#include "prprf.h"
#include "nsTArray.h"
@ -688,6 +689,11 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
mBuffer.Clear();
nsIntRegion toDraw = IntersectWithClip(GetEffectiveVisibleRegion(), aContext);
#ifdef MOZ_RENDERTRACE
RenderTraceInvalidateStart(this, "FFFF00", toDraw.GetBounds());
#endif
if (!toDraw.IsEmpty() && !IsHidden()) {
if (!aCallback) {
BasicManager()->SetTransactionIncomplete();
@ -723,6 +729,10 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
aContext->Restore();
}
#ifdef MOZ_RENDERTRACE
RenderTraceInvalidateEnd(this, "FFFF00");
#endif
return;
}
@ -748,11 +758,20 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
GetEffectiveVisibleRegion());
nsIntRegion extendedDrawRegion = state.mRegionToDraw;
SetAntialiasingFlags(this, state.mContext);
#ifdef MOZ_RENDERTRACE
RenderTraceInvalidateStart(this, "FFFF00", state.mRegionToDraw.GetBounds());
#endif
PaintBuffer(state.mContext,
state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
state.mDidSelfCopy,
aCallback, aCallbackData);
Mutated();
#ifdef MOZ_RENDERTRACE
RenderTraceInvalidateEnd(this, "FFFF00");
#endif
} else {
// It's possible that state.mRegionToInvalidate is nonempty here,
// if we are shrinking the valid region to nothing.
@ -1600,6 +1619,11 @@ BasicLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
mPhase = PHASE_DRAWING;
#endif
#ifdef MOZ_RENDERTRACE
Layer* aLayer = GetRoot();
RenderTraceLayers(aLayer, "FF00");
#endif
mTransactionIncomplete = false;
if (mTarget && mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) {
@ -1820,6 +1844,8 @@ Transform3D(gfxASurface* aSource, gfxContext* aDest,
return destImage.forget();
}
void
BasicLayerManager::PaintLayer(gfxContext* aTarget,
Layer* aLayer,

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

@ -39,6 +39,7 @@
* ***** END LICENSE BLOCK ***** */
#include "CompositorParent.h"
#include "RenderTrace.h"
#include "ShadowLayersParent.h"
#include "LayerManagerOGL.h"
#include "nsIWidget.h"
@ -80,6 +81,12 @@ CompositorParent::ScheduleComposition()
{
CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
MessageLoop::current()->PostTask(FROM_HERE, composeTask);
#ifdef MOZ_RENDERTRACE
Layer* aLayer = mLayerManager->GetRoot();
mozilla::layers::RenderTraceLayers(aLayer, "0000");
#endif
}
void

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

@ -43,6 +43,7 @@
#include "ShadowLayersParent.h"
#include "ShadowLayerParent.h"
#include "ShadowLayers.h"
#include "RenderTrace.h"
#include "mozilla/unused.h"
@ -318,6 +319,10 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
static_cast<ShadowThebesLayer*>(shadow->AsLayer());
const ThebesBuffer& newFront = op.newFrontBuffer();
#ifdef MOZ_RENDERTRACE
RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds());
#endif
OptionalThebesBuffer newBack;
nsIntRegion newValidRegion;
OptionalThebesBuffer readonlyFront;
@ -330,6 +335,10 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
shadow, NULL,
newBack, newValidRegion,
readonlyFront, frontUpdatedRegion));
#ifdef MOZ_RENDERTRACE
RenderTraceInvalidateEnd(thebes, "FF00FF");
#endif
break;
}
case Edit::TOpPaintCanvas: {
@ -340,6 +349,10 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
ShadowCanvasLayer* canvas =
static_cast<ShadowCanvasLayer*>(shadow->AsLayer());
#ifdef MOZ_RENDERTRACE
RenderTraceInvalidateStart(canvas, "FF00FF", canvas->GetVisibleRegion().GetBounds());
#endif
canvas->SetAllocator(this);
CanvasSurface newBack;
canvas->Swap(op.newFrontBuffer(), op.needYFlip(), &newBack);
@ -347,6 +360,9 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
replyv.push_back(OpBufferSwap(shadow, NULL,
newBack));
#ifdef MOZ_RENDERTRACE
RenderTraceInvalidateEnd(canvas, "FF00FF");
#endif
break;
}
case Edit::TOpPaintImage: {
@ -357,12 +373,19 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
ShadowImageLayer* image =
static_cast<ShadowImageLayer*>(shadow->AsLayer());
#ifdef MOZ_RENDERTRACE
RenderTraceInvalidateStart(image, "FF00FF", image->GetVisibleRegion().GetBounds());
#endif
image->SetAllocator(this);
SharedImage newBack;
image->Swap(op.newFrontBuffer(), &newBack);
replyv.push_back(OpImageSwap(shadow, NULL,
newBack));
#ifdef MOZ_RENDERTRACE
RenderTraceInvalidateEnd(image, "FF00FF");
#endif
break;
}