Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1061)

Unified Diff: content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc

Issue 2465093002: cc: Add OutputSurface state snapshots.
Patch Set: rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
diff --git a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
index 98fb73f9b0806fc70ab5f93c965a41e7daae2a19..0380c9789e785ce71af8d0979c3590c9019730d2 100644
--- a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
+++ b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
@@ -6,6 +6,11 @@
#include <utility>
+#include "base/barrier_closure.h"
+#include "base/base64.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/trace_event/trace_event.h"
#include "cc/output/output_surface_client.h"
#include "cc/output/output_surface_frame.h"
#include "components/display_compositor/buffer_queue.h"
@@ -15,8 +20,88 @@
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/skia_util.h"
namespace content {
+namespace {
+
+// How frequently to do a readback of the framebuffer and overlay textures
+// when tracing is turned on.
+const size_t kSnapshotInterval = 60;
+
+class Snapshot : public base::trace_event::ConvertableToTraceFormat {
+ public:
+ explicit Snapshot(base::TimeTicks vsync_time) : vsync_time_(vsync_time) {}
+
+ // base::trace_event::ConvertableToTraceFormat implementation.
+ void AppendAsTraceFormat(std::string* out) const override {
+ *out += "{";
+ // Add framebuffer or the first overlay texture as screenshot if available.
+ const SkBitmap& bitmap = overlay_texture_bitmaps_.empty()
+ ? framebuffer_bitmap_
+ : overlay_texture_bitmaps_.front();
+ if (!bitmap.isNull()) {
+ std::vector<unsigned char> png_data;
+ bool png_ok = gfx::PNGCodec::Encode(
+ static_cast<unsigned char*>(bitmap.getPixels()),
+ gfx::PNGCodec::FORMAT_RGBA, gfx::SkISizeToSize(bitmap.dimensions()),
+ bitmap.rowBytes(), false, std::vector<gfx::PNGCodec::Comment>(),
+ &png_data);
+ DCHECK(png_ok);
+
+ base::StringPiece base64_input(
+ reinterpret_cast<const char*>(&png_data[0]), png_data.size());
+ std::string base64_output;
+ Base64Encode(base64_input, &base64_output);
+
+ *out += "\"screenshot\":\"" + base64_output + "\",";
+ }
+ *out += "\"vsyncTime\":" +
+ base::Uint64ToString(vsync_time_.ToInternalValue()) + ",";
+ uint64_t elapsed_time =
+ (base::TimeTicks::Now() - vsync_time_).ToInternalValue();
+ *out += "\"vsyncJsTime\":" +
+ base::Uint64ToString(
+ static_cast<uint64_t>(base::Time::Now().ToJsTime() *
+ base::Time::kMicrosecondsPerMillisecond) -
+ elapsed_time) +
+ ",";
+ *out += "\"overlayTextures\":\"" +
+ base::SizeTToString(overlay_texture_bitmaps_.size()) + "\"";
+ *out += "}";
+ }
+
+ SkBitmap& framebuffer_bitmap() { return framebuffer_bitmap_; }
+ std::vector<SkBitmap>& overlay_texture_bitmaps() {
+ return overlay_texture_bitmaps_;
+ }
+
+ private:
+ const base::TimeTicks vsync_time_;
+ SkBitmap framebuffer_bitmap_;
+ std::vector<SkBitmap> overlay_texture_bitmaps_;
+
+ DISALLOW_COPY_AND_ASSIGN(Snapshot);
+};
+
+void CallbackForwader(const base::Closure& callback, bool result) {
+ callback.Run();
+}
+
+void SaveSnapshot(
+ void* id,
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat> snapshot,
+ base::TimeTicks page_flip_time) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.outputsurface"),
+ "SaveSnapshot");
+ TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID_AND_TIMESTAMP(
+ TRACE_DISABLED_BY_DEFAULT("cc.debug.outputsurface"), "cc::OutputSurface",
+ id, page_flip_time, std::move(snapshot));
+}
+
+} // namespace
GpuSurfacelessBrowserCompositorOutputSurface::
GpuSurfacelessBrowserCompositorOutputSurface(
@@ -51,10 +136,17 @@ GpuSurfacelessBrowserCompositorOutputSurface::
context_provider_->ContextGL(), target, internalformat, format,
gl_helper_.get(), gpu_memory_buffer_manager_, surface_handle));
buffer_queue_->Initialize();
+
+ TRACE_EVENT_OBJECT_CREATED_WITH_ID(
+ TRACE_DISABLED_BY_DEFAULT("cc.debug.outputsurface"), "cc::OutputSurface",
+ this);
}
GpuSurfacelessBrowserCompositorOutputSurface::
~GpuSurfacelessBrowserCompositorOutputSurface() {
+ TRACE_EVENT_OBJECT_DELETED_WITH_ID(
+ TRACE_DISABLED_BY_DEFAULT("cc.debug.outputsurface"), "cc::OutputSurface",
+ this);
}
bool GpuSurfacelessBrowserCompositorOutputSurface::IsDisplayedAsOverlayPlane()
@@ -113,6 +205,30 @@ void GpuSurfacelessBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(
buffer_queue_->RecreateBuffers();
force_swap = true;
}
+ bool is_tracing;
+ TRACE_EVENT_CATEGORY_GROUP_ENABLED(
+ TRACE_DISABLED_BY_DEFAULT("cc.debug.outputsurface"), &is_tracing);
+ // Create a snapshot of the previous frame now that we've received an ack
+ // for the new frame. |last_timebase_| is the page flip time for the
+ // previous frame.
+ if (is_tracing && !(++swap_count_ % kSnapshotInterval)) {
+ // |last_vsync_timebase_| should contain an accurate vsync time stamp for
+ // the previous frame at this time.
+ Snapshot* snapshot = new Snapshot(last_vsync_timebase_);
+ std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
+ scoped_snapshot(snapshot);
+ base::Closure save_snaphost_callback =
+ base::Bind(&SaveSnapshot, this, base::Passed(&scoped_snapshot),
+ last_vsync_timebase_);
+ base::Closure barrier_closure =
+ base::BarrierClosure(2, save_snaphost_callback);
+ buffer_queue_->ReadbackDisplayedFramebuffer(
+ &snapshot->framebuffer_bitmap(),
+ base::Bind(&CallbackForwader, barrier_closure));
+ client_->ReadbackSwappedOverlayTextures(
+ &snapshot->overlay_texture_bitmaps(),
+ base::Bind(&CallbackForwader, barrier_closure));
+ }
buffer_queue_->PageFlipComplete();
GpuBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(
latency_info, result, params_mac);
« no previous file with comments | « content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698