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

Side by Side Diff: content/browser/devtools/devtools_frame_trace_recorder.cc

Issue 1188773005: DevTools: fix concurrency problems in DevToolsFrameTraceRecorder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review comments addressed Created 5 years, 6 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 unified diff | Download patch
« no previous file with comments | « content/browser/devtools/devtools_frame_trace_recorder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/devtools/devtools_frame_trace_recorder.h" 5 #include "content/browser/devtools/devtools_frame_trace_recorder.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/atomicops.h" 10 #include "base/atomicops.h"
(...skipping 11 matching lines...) Expand all
22 #include "ui/gfx/geometry/size_conversions.h" 22 #include "ui/gfx/geometry/size_conversions.h"
23 23
24 namespace content { 24 namespace content {
25 25
26 namespace { 26 namespace {
27 27
28 static base::subtle::Atomic32 frame_data_count = 0; 28 static base::subtle::Atomic32 frame_data_count = 0;
29 static int kMaximumFrameDataCount = 150; 29 static int kMaximumFrameDataCount = 150;
30 static size_t kFrameAreaLimit = 256000; 30 static size_t kFrameAreaLimit = 256000;
31 31
32 class TraceableDevToolsScreenshot
33 : public base::trace_event::ConvertableToTraceFormat {
34 public:
35 TraceableDevToolsScreenshot(const SkBitmap& bitmap) : frame_(bitmap) {}
36
37 void AppendAsTraceFormat(std::string* out) const override {
38 out->append("\"");
39 if (!frame_.drawsNothing()) {
40 std::vector<unsigned char> data;
41 SkAutoLockPixels lock_image(frame_);
42 bool encoded = gfx::PNGCodec::Encode(
43 reinterpret_cast<unsigned char*>(frame_.getAddr32(0, 0)),
44 gfx::PNGCodec::FORMAT_SkBitmap,
45 gfx::Size(frame_.width(), frame_.height()),
46 frame_.width() * frame_.bytesPerPixel(), false,
47 std::vector<gfx::PNGCodec::Comment>(), &data);
48 if (encoded) {
49 std::string encoded_data;
50 base::Base64Encode(
51 base::StringPiece(reinterpret_cast<char*>(&data[0]), data.size()),
52 &encoded_data);
53 out->append(encoded_data);
54 }
55 }
56 out->append("\"");
57 }
58
59 private:
60 ~TraceableDevToolsScreenshot() override {
61 base::subtle::NoBarrier_AtomicIncrement(&frame_data_count, -1);
62 }
63
64 SkBitmap frame_;
65 };
66
32 } // namespace 67 } // namespace
33 68
34 class DevToolsFrameTraceRecorderData 69 class DevToolsFrameTraceRecorderData
35 : public base::trace_event::ConvertableToTraceFormat { 70 : public base::RefCounted<DevToolsFrameTraceRecorderData> {
36 public: 71 public:
37 DevToolsFrameTraceRecorderData(const cc::CompositorFrameMetadata& metadata) 72 DevToolsFrameTraceRecorderData(const cc::CompositorFrameMetadata& metadata)
38 : metadata_(metadata), 73 : metadata_(metadata), timestamp_(base::TraceTicks::Now()) {}
39 weak_factory_(this) {
40 }
41
42 base::WeakPtr<DevToolsFrameTraceRecorderData> GetWeakPtr() {
43 return weak_factory_.GetWeakPtr();
44 }
45 74
46 void FrameCaptured(const SkBitmap& bitmap, ReadbackResponse response) { 75 void FrameCaptured(const SkBitmap& bitmap, ReadbackResponse response) {
47 if (response != READBACK_SUCCESS) 76 if (response != READBACK_SUCCESS)
48 return; 77 return;
49 int current_frame_count = base::subtle::NoBarrier_Load(&frame_data_count); 78 int current_frame_count = base::subtle::NoBarrier_Load(&frame_data_count);
50 if (current_frame_count >= kMaximumFrameDataCount) 79 if (current_frame_count >= kMaximumFrameDataCount)
51 return; 80 return;
52 frame_ = bitmap; 81 if (bitmap.drawsNothing())
53 if (!frame_.drawsNothing()) 82 return;
54 base::subtle::NoBarrier_AtomicIncrement(&frame_data_count, 1); 83 base::subtle::NoBarrier_AtomicIncrement(&frame_data_count, 1);
84 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID_AND_TIMESTAMP(
85 TRACE_DISABLED_BY_DEFAULT("devtools.screenshot"), "Screenshot", 1,
86 timestamp_.ToInternalValue(),
87 scoped_refptr<base::trace_event::ConvertableToTraceFormat>(
88 new TraceableDevToolsScreenshot(bitmap)));
55 } 89 }
56 90
57 void CaptureFrame(RenderFrameHostImpl* host) { 91 void CaptureFrame(RenderFrameHostImpl* host) {
58 RenderWidgetHostViewBase* view = 92 RenderWidgetHostViewBase* view =
59 static_cast<RenderWidgetHostViewBase*>(host->GetView()); 93 static_cast<RenderWidgetHostViewBase*>(host->GetView());
60 if (!view) 94 if (!view)
61 return; 95 return;
62 int current_frame_count = base::subtle::NoBarrier_Load(&frame_data_count); 96 int current_frame_count = base::subtle::NoBarrier_Load(&frame_data_count);
63 if (current_frame_count >= kMaximumFrameDataCount) 97 if (current_frame_count >= kMaximumFrameDataCount)
64 return; 98 return;
65 float scale = metadata_.page_scale_factor; 99 float scale = metadata_.page_scale_factor;
66 float area = metadata_.scrollable_viewport_size.GetArea(); 100 float area = metadata_.scrollable_viewport_size.GetArea();
67 if (area * scale * scale > kFrameAreaLimit) 101 if (area * scale * scale > kFrameAreaLimit)
68 scale = sqrt(kFrameAreaLimit / area); 102 scale = sqrt(kFrameAreaLimit / area);
69 gfx::Size snapshot_size(gfx::ToRoundedSize(gfx::ScaleSize( 103 gfx::Size snapshot_size(gfx::ToRoundedSize(gfx::ScaleSize(
70 metadata_.scrollable_viewport_size, scale))); 104 metadata_.scrollable_viewport_size, scale)));
71 view->CopyFromCompositingSurface(gfx::Rect(), snapshot_size, 105 view->CopyFromCompositingSurface(
72 base::Bind( 106 gfx::Rect(), snapshot_size,
73 &DevToolsFrameTraceRecorderData::FrameCaptured, 107 base::Bind(&DevToolsFrameTraceRecorderData::FrameCaptured, this),
74 GetWeakPtr()),
75 kN32_SkColorType); 108 kN32_SkColorType);
76 } 109 }
77 110
78 void AppendAsTraceFormat(std::string* out) const override {
79 out->append("\"");
80 if (!frame_.drawsNothing()) {
81 std::vector<unsigned char> data;
82 SkAutoLockPixels lock_image(frame_);
83 bool encoded = gfx::PNGCodec::Encode(
84 reinterpret_cast<unsigned char*>(frame_.getAddr32(0, 0)),
85 gfx::PNGCodec::FORMAT_SkBitmap,
86 gfx::Size(frame_.width(), frame_.height()),
87 frame_.width() * frame_.bytesPerPixel(),
88 false, std::vector<gfx::PNGCodec::Comment>(), &data);
89 if (encoded) {
90 std::string encoded_data;
91 base::Base64Encode(
92 base::StringPiece(reinterpret_cast<char*>(&data[0]), data.size()),
93 &encoded_data);
94 out->append(encoded_data);
95 }
96 }
97 out->append("\"");
98 }
99
100 private: 111 private:
101 ~DevToolsFrameTraceRecorderData() override { 112 friend class base::RefCounted<DevToolsFrameTraceRecorderData>;
102 if (!frame_.drawsNothing()) 113 ~DevToolsFrameTraceRecorderData() {}
103 base::subtle::NoBarrier_AtomicIncrement(&frame_data_count, -1);
104 }
105 114
106 cc::CompositorFrameMetadata metadata_; 115 cc::CompositorFrameMetadata metadata_;
107 SkBitmap frame_; 116 base::TraceTicks timestamp_;
108 base::WeakPtrFactory<DevToolsFrameTraceRecorderData> weak_factory_;
109 117
110 DISALLOW_COPY_AND_ASSIGN(DevToolsFrameTraceRecorderData); 118 DISALLOW_COPY_AND_ASSIGN(DevToolsFrameTraceRecorderData);
111 }; 119 };
112 120
113 DevToolsFrameTraceRecorder::DevToolsFrameTraceRecorder() { } 121 DevToolsFrameTraceRecorder::DevToolsFrameTraceRecorder() { }
114 122
115 DevToolsFrameTraceRecorder::~DevToolsFrameTraceRecorder() { } 123 DevToolsFrameTraceRecorder::~DevToolsFrameTraceRecorder() { }
116 124
117 void DevToolsFrameTraceRecorder::OnSwapCompositorFrame( 125 void DevToolsFrameTraceRecorder::OnSwapCompositorFrame(
118 RenderFrameHostImpl* host, 126 RenderFrameHostImpl* host,
119 const cc::CompositorFrameMetadata& frame_metadata) { 127 const cc::CompositorFrameMetadata& frame_metadata) {
120 if (!host) 128 if (!host)
121 return; 129 return;
122 130
123 bool enabled; 131 bool enabled;
124 TRACE_EVENT_CATEGORY_GROUP_ENABLED( 132 TRACE_EVENT_CATEGORY_GROUP_ENABLED(
125 TRACE_DISABLED_BY_DEFAULT("devtools.screenshot"), &enabled); 133 TRACE_DISABLED_BY_DEFAULT("devtools.screenshot"), &enabled);
126 if (!enabled) 134 if (!enabled) {
135 pending_frame_data_ = nullptr;
127 return; 136 return;
128 137 }
129 if (last_event_data_.get()) 138 if (pending_frame_data_.get())
130 last_event_data_->CaptureFrame(host); 139 pending_frame_data_->CaptureFrame(host);
131 140 pending_frame_data_ = new DevToolsFrameTraceRecorderData(frame_metadata);
132 scoped_refptr<DevToolsFrameTraceRecorderData> data(
133 new DevToolsFrameTraceRecorderData(frame_metadata));
134 last_event_data_ = data->GetWeakPtr();
135 TRACE_EVENT_INSTANT1(
136 TRACE_DISABLED_BY_DEFAULT("devtools.screenshot"),
137 "CaptureFrame",
138 TRACE_EVENT_SCOPE_THREAD,
139 "data",
140 scoped_refptr<base::trace_event::ConvertableToTraceFormat>(data));
141 } 141 }
142 142
143 } // namespace content 143 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/devtools/devtools_frame_trace_recorder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698