Merge pull request #1265 from chinmaygarde/master

SkPicture tracing to file follows same path as rendering into the OpenGL context
This commit is contained in:
Chinmay Garde 2015-09-21 16:01:48 -07:00
commit b258a3367f
10 changed files with 106 additions and 86 deletions

View File

@ -5,6 +5,7 @@
#include "sky/compositor/paint_context.h"
#include "base/logging.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "services/sky/compositor/picture_serializer.h"
namespace sky {
namespace compositor {
@ -55,6 +56,39 @@ PaintContext::ScopedFrame PaintContext::AcquireFrame(SkCanvas& canvas) {
return ScopedFrame(*this, canvas);
}
PaintContext::ScopedFrame PaintContext::AcquireFrame(
const std::string& trace_file_name) {
return ScopedFrame(*this, trace_file_name);
}
PaintContext::ScopedFrame::ScopedFrame(PaintContext& context, SkCanvas& canvas)
: context_(context), canvas_(&canvas) {
context_.beginFrame(*this);
};
PaintContext::ScopedFrame::ScopedFrame(ScopedFrame&& frame) = default;
PaintContext::ScopedFrame::ScopedFrame(PaintContext& context,
const std::string& trace_file_name)
: context_(context),
trace_file_name_(trace_file_name),
trace_recorder_(new SkPictureRecorder()) {
trace_recorder_->beginRecording(
SkRect::MakeWH(SK_ScalarInfinity, SK_ScalarInfinity));
canvas_ = trace_recorder_->getRecordingCanvas();
DCHECK(canvas_);
context_.beginFrame(*this);
};
PaintContext::ScopedFrame::~ScopedFrame() {
context_.endFrame(*this);
if (trace_file_name_.length() > 0) {
auto picture = trace_recorder_->endRecordingAsPicture();
SerializePicture(trace_file_name_.c_str(), picture);
}
}
PaintContext::~PaintContext() {
}

View File

@ -10,6 +10,7 @@
#include "sky/compositor/compositor_options.h"
#include "sky/compositor/instrumentation.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
namespace sky {
namespace compositor {
@ -18,23 +19,21 @@ class PaintContext {
public:
class ScopedFrame {
public:
SkCanvas& canvas() { return canvas_; }
SkCanvas& canvas() { return *canvas_; }
ScopedFrame(ScopedFrame&& frame) = default;
ScopedFrame(ScopedFrame&& frame);
~ScopedFrame() { context_.endFrame(*this); }
~ScopedFrame();
private:
PaintContext& context_;
SkCanvas& canvas_;
SkCanvas* canvas_;
std::string trace_file_name_;
std::unique_ptr<SkPictureRecorder> trace_recorder_;
ScopedFrame() = delete;
ScopedFrame(PaintContext& context, SkCanvas& canvas);
ScopedFrame(PaintContext& context, SkCanvas& canvas)
: context_(context), canvas_(canvas) {
DCHECK(&canvas) << "The frame requries a valid canvas";
context_.beginFrame(*this);
};
ScopedFrame(PaintContext& context, const std::string& trace_file_name);
friend class PaintContext;
@ -48,6 +47,8 @@ class PaintContext {
ScopedFrame AcquireFrame(SkCanvas& canvas);
ScopedFrame AcquireFrame(const std::string& trace_file_name);
private:
CompositorOptions options_;

View File

@ -12,40 +12,21 @@
#include "sky/shell/gpu/ganesh_context.h"
#include "sky/shell/gpu/ganesh_surface.h"
#include "sky/shell/gpu/picture_serializer.h"
#include "sky/shell/shell.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_share_group.h"
#include "ui/gl/gl_surface.h"
// Set this value to 1 to serialize the layer tree to disk.
#define SERIALIZE_LAYER_TREE 0
#include "mojo/public/cpp/system/data_pipe.h"
namespace sky {
namespace shell {
namespace {
#if SERIALIZE_LAYER_TREE
void SketchySerializeLayerTree(const char* path,
compositor::LayerTree* layer_tree) {
const auto& layers =
static_cast<compositor::ContainerLayer*>(layer_tree->root_layer())
->layers();
if (layers.empty())
return;
SerializePicture(
path, static_cast<compositor::PictureLayer*>(layers[0].get())->picture());
}
#endif
} // namespace
Rasterizer::Rasterizer()
: share_group_(new gfx::GLShareGroup()),
weak_factory_(this) {}
: share_group_(new gfx::GLShareGroup()), weak_factory_(this) {
}
Rasterizer::~Rasterizer() {
}
@ -55,8 +36,8 @@ base::WeakPtr<Rasterizer> Rasterizer::GetWeakPtr() {
}
void Rasterizer::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) {
surface_ = gfx::GLSurface::CreateViewGLSurface(widget,
gfx::SurfaceConfiguration());
surface_ =
gfx::GLSurface::CreateViewGLSurface(widget, gfx::SurfaceConfiguration());
CHECK(surface_) << "GLSurface required.";
}
@ -72,6 +53,8 @@ void Rasterizer::Draw(scoped_ptr<compositor::LayerTree> layer_tree) {
if (surface_->GetSize() != size)
surface_->Resize(size);
// Use the canvas from the Ganesh Surface to render the current frame into
EnsureGLContext();
CHECK(context_->MakeCurrent(surface_.get()));
EnsureGaneshSurface(surface_->GetBackingFrameBufferObject(), size);
@ -79,16 +62,22 @@ void Rasterizer::Draw(scoped_ptr<compositor::LayerTree> layer_tree) {
canvas->clear(SK_ColorBLACK);
{
auto frame = paint_context_.AcquireFrame(*canvas);
sky::compositor::PaintContext::ScopedFrame frame =
paint_context_.AcquireFrame(*canvas);
layer_tree->root_layer()->Paint(frame);
}
canvas->flush();
surface_->SwapBuffers();
#if SERIALIZE_LAYER_TREE
SketchySerializeLayerTree("/data/data/org.domokit.sky.shell/cache/layer0.skp",
layer_tree.get());
#endif
// Optionally, if the user has specified tracing the current scene to a file,
// acquire another frame and draw into it to obtain an SkPicture to serialize
auto options = Shell::Shared().tracing_controller().picture_tracing_options();
if (options.first) {
sky::compositor::PaintContext::ScopedFrame to_file_frame =
paint_context_.AcquireFrame(options.second);
layer_tree->root_layer()->Paint(to_file_frame);
}
}
void Rasterizer::OnOutputSurfaceDestroyed() {
@ -118,7 +107,7 @@ void Rasterizer::EnsureGaneshSurface(intptr_t window_fbo,
const gfx::Size& size) {
if (!ganesh_surface_ || ganesh_surface_->size() != size)
ganesh_surface_.reset(
new GaneshSurface(window_fbo, ganesh_context_.get(), size));
new GaneshSurface(window_fbo, ganesh_context_.get(), size));
}
} // namespace shell

View File

@ -55,9 +55,24 @@ static inline int64 InputEventTimestampFromNSTimeInterval(
#endif
}
static std::string SkPictureTracingPath() {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
char* temp = reinterpret_cast<char*>(calloc(256, sizeof(char)));
snprintf(temp, 256, "%s/layers.skp", [paths.firstObject UTF8String]);
std::string path(temp);
free(temp);
return path;
}
-(instancetype) initWithShellView:(sky::shell::ShellView *) shellView {
self = [super init];
if (self) {
sky::shell::Shell::Shared().tracing_controller().set_picture_tracing_path(
SkPictureTracingPath());
_shell_view.reset(shellView);
self.multipleTouchEnabled = YES;
}
@ -254,27 +269,3 @@ static inline int64 InputEventTimestampFromNSTimeInterval(
}
@end
void SaveFrameToSkPicture() {
@autoreleasepool {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString* basePath = paths.firstObject;
if (basePath.length == 0) {
return;
}
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"HH_mm_ss"];
NSString* dateString = [formatter stringFromDate:[NSDate date]];
[formatter release];
NSString* path =
[NSString stringWithFormat:@"%@/%@.trace.skp", basePath, dateString];
base::FilePath filePath(path.UTF8String);
sky::shell::Shell::Shared().tracing_controller().SaveFrameToSkPicture(
filePath);
}
}

View File

@ -63,11 +63,5 @@ void ShellView::StopDartTracing(
base::Passed(&producer)));
}
void ShellView::SaveFrameToSkPicture(base::FilePath& destination) {
shell_.ui_task_runner()->PostTask(
FROM_HERE, base::Bind(&Engine::SaveFrameToSkPicture,
engine_->GetWeakPtr(), destination));
}
} // namespace shell
} // namespace sky

View File

@ -27,8 +27,6 @@ class ShellView {
void StartDartTracing();
void StopDartTracing(mojo::ScopedDataPipeProducerHandle producer);
void SaveFrameToSkPicture(base::FilePath& destination);
private:
void CreateEngine();
void CreatePlatformView();

View File

@ -17,7 +17,8 @@ const char kBaseTraceStart[] = "{\"traceEvents\":[";
const char kBaseTraceEnd[] = "]}";
const char kSentinel[] = "\0";
TracingController::TracingController() : view_(nullptr) {}
TracingController::TracingController()
: view_(nullptr), picture_tracing_enabled_(false) {}
TracingController::~TracingController() {}
@ -108,12 +109,6 @@ void TracingController::OnBaseTraceChunk(
}
}
void TracingController::SaveFrameToSkPicture(base::FilePath& destination) {
if (view_ != nullptr) {
view_->SaveFrameToSkPicture(destination);
}
}
void TracingController::RegisterShellView(ShellView* view) {
view_ = view;
}
@ -122,5 +117,20 @@ void TracingController::UnregisterShellView(ShellView* view) {
view_ = nullptr;
}
TracingController::SkPictureTracingOptions
TracingController::picture_tracing_options() const {
return SkPictureTracingOptions(
picture_tracing_path_.length() == 0 ? false : picture_tracing_enabled_,
picture_tracing_path_);
}
void TracingController::set_picture_tracing_path(const std::string& path) {
picture_tracing_path_ = path;
}
void TracingController::set_picture_tracing_enabled(bool enabled) {
picture_tracing_enabled_ = enabled;
}
} // namespace shell
} // namespace sky

View File

@ -35,7 +35,13 @@ class TracingController : public mojo::common::DataPipeDrainer::Client {
// be merged before viewing in the trace viewer
void StopTracing(const base::FilePath& path);
void SaveFrameToSkPicture(base::FilePath& destination);
using SkPictureTracingOptions =
std::pair<bool /* enabled */, std::string /* path */>;
SkPictureTracingOptions picture_tracing_options() const;
void set_picture_tracing_path(const std::string& path);
void set_picture_tracing_enabled(bool enabled);
private:
std::unique_ptr<mojo::common::DataPipeDrainer> drainer_;
@ -44,6 +50,8 @@ class TracingController : public mojo::common::DataPipeDrainer::Client {
// the ability to host multiple shell views, references to each must be stored
// instead and trace data from each serialized to the output trace.
ShellView* view_;
std::string picture_tracing_path_;
bool picture_tracing_enabled_;
void StartDartTracing();
void StartBaseTracing();

View File

@ -264,8 +264,5 @@ void Engine::StopDartTracing(mojo::ScopedDataPipeProducerHandle producer) {
sky_view_->StopDartTracing(producer.Pass());
}
void Engine::SaveFrameToSkPicture(const base::FilePath& destination) {
}
} // namespace shell
} // namespace sky

View File

@ -60,8 +60,6 @@ class Engine : public UIDelegate,
void StartDartTracing();
void StopDartTracing(mojo::ScopedDataPipeProducerHandle producer);
void SaveFrameToSkPicture(const base::FilePath& destination);
private:
// UIDelegate implementation:
void ConnectToEngine(mojo::InterfaceRequest<SkyEngine> request) override;