ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / content / browser / devtools / devtools_frame_trace_recorder.cc
blob0626bfa8fdbcec0f2eb4e48c11a24a260e82888f
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/devtools/devtools_frame_trace_recorder.h"
7 #include <string>
8 #include <vector>
10 #include "base/atomicops.h"
11 #include "base/base64.h"
12 #include "base/bind.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/trace_event/trace_event_impl.h"
15 #include "cc/output/compositor_frame_metadata.h"
16 #include "content/browser/frame_host/render_frame_host_impl.h"
17 #include "content/browser/renderer_host/render_widget_host_view_base.h"
18 #include "content/public/browser/readback_types.h"
19 #include "third_party/skia/include/core/SkBitmap.h"
20 #include "ui/gfx/codec/png_codec.h"
21 #include "ui/gfx/geometry/size.h"
22 #include "ui/gfx/geometry/size_conversions.h"
24 namespace content {
26 namespace {
28 static base::subtle::Atomic32 frame_data_count = 0;
29 static int kMaximumFrameDataCount = 150;
30 static size_t kFrameAreaLimit = 256000;
32 } // namespace
34 class DevToolsFrameTraceRecorderData
35 : public base::trace_event::ConvertableToTraceFormat {
36 public:
37 DevToolsFrameTraceRecorderData(const cc::CompositorFrameMetadata& metadata)
38 : metadata_(metadata),
39 weak_factory_(this) {
42 base::WeakPtr<DevToolsFrameTraceRecorderData> GetWeakPtr() {
43 return weak_factory_.GetWeakPtr();
46 void FrameCaptured(const SkBitmap& bitmap, ReadbackResponse response) {
47 if (response != READBACK_SUCCESS)
48 return;
49 int current_frame_count = base::subtle::NoBarrier_Load(&frame_data_count);
50 if (current_frame_count >= kMaximumFrameDataCount)
51 return;
52 frame_ = bitmap;
53 if (!frame_.drawsNothing())
54 base::subtle::NoBarrier_AtomicIncrement(&frame_data_count, 1);
57 void CaptureFrame(RenderFrameHostImpl* host) {
58 RenderWidgetHostViewBase* view =
59 static_cast<RenderWidgetHostViewBase*>(host->GetView());
60 if (!view)
61 return;
62 int current_frame_count = base::subtle::NoBarrier_Load(&frame_data_count);
63 if (current_frame_count >= kMaximumFrameDataCount)
64 return;
65 float scale = metadata_.page_scale_factor;
66 float area = metadata_.scrollable_viewport_size.GetArea();
67 if (area * scale * scale > kFrameAreaLimit)
68 scale = sqrt(kFrameAreaLimit / area);
69 gfx::Size snapshot_size(gfx::ToRoundedSize(gfx::ScaleSize(
70 metadata_.scrollable_viewport_size, scale)));
71 view->CopyFromCompositingSurface(gfx::Rect(), snapshot_size,
72 base::Bind(
73 &DevToolsFrameTraceRecorderData::FrameCaptured,
74 GetWeakPtr()),
75 kN32_SkColorType);
78 void AppendAsTraceFormat(std::string* out) const override {
79 out->append("\"");
80 std::vector<unsigned char> data;
81 SkAutoLockPixels lock_image(frame_);
82 bool encoded = gfx::PNGCodec::Encode(
83 reinterpret_cast<unsigned char*>(frame_.getAddr32(0, 0)),
84 gfx::PNGCodec::FORMAT_SkBitmap,
85 gfx::Size(frame_.width(), frame_.height()),
86 frame_.width() * frame_.bytesPerPixel(),
87 false, std::vector<gfx::PNGCodec::Comment>(), &data);
88 if (encoded) {
89 std::string encoded_data;
90 base::Base64Encode(
91 base::StringPiece(reinterpret_cast<char*>(&data[0]), data.size()),
92 &encoded_data);
93 out->append(encoded_data);
95 out->append("\"");
98 private:
99 ~DevToolsFrameTraceRecorderData() override {
100 if (!frame_.drawsNothing())
101 base::subtle::NoBarrier_AtomicIncrement(&frame_data_count, -1);
104 cc::CompositorFrameMetadata metadata_;
105 SkBitmap frame_;
106 base::WeakPtrFactory<DevToolsFrameTraceRecorderData> weak_factory_;
108 DISALLOW_COPY_AND_ASSIGN(DevToolsFrameTraceRecorderData);
111 DevToolsFrameTraceRecorder::DevToolsFrameTraceRecorder() { }
113 DevToolsFrameTraceRecorder::~DevToolsFrameTraceRecorder() { }
115 void DevToolsFrameTraceRecorder::OnSwapCompositorFrame(
116 RenderFrameHostImpl* host,
117 const cc::CompositorFrameMetadata& frame_metadata) {
118 if (!host)
119 return;
121 bool enabled;
122 TRACE_EVENT_CATEGORY_GROUP_ENABLED(
123 TRACE_DISABLED_BY_DEFAULT("devtools.screenshot"), &enabled);
124 if (!enabled)
125 return;
127 if (last_event_data_.get())
128 last_event_data_->CaptureFrame(host);
130 scoped_refptr<DevToolsFrameTraceRecorderData> data(
131 new DevToolsFrameTraceRecorderData(frame_metadata));
132 last_event_data_ = data->GetWeakPtr();
133 TRACE_EVENT_INSTANT1(
134 TRACE_DISABLED_BY_DEFAULT("devtools.screenshot"),
135 "CaptureFrame",
136 TRACE_EVENT_SCOPE_THREAD,
137 "data",
138 scoped_refptr<base::trace_event::ConvertableToTraceFormat>(data));
141 } // namespace content