mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
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:
commit
b258a3367f
@ -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() {
|
||||
}
|
||||
|
||||
|
||||
@ -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_;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -27,8 +27,6 @@ class ShellView {
|
||||
void StartDartTracing();
|
||||
void StopDartTracing(mojo::ScopedDataPipeProducerHandle producer);
|
||||
|
||||
void SaveFrameToSkPicture(base::FilePath& destination);
|
||||
|
||||
private:
|
||||
void CreateEngine();
|
||||
void CreatePlatformView();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user