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

Side by Side Diff: content/common/gpu/client/gl_surface_capturer_host.cc

Issue 22935009: Add content::SurfaceCapturer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@screencast_stride
Patch Set: af8f3e73 Separated from BrowserCompositorOutputSurface* components. Created 7 years, 3 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
OLDNEW
(Empty)
1 // Copyright (c) 2013 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.
4
5 #include "content/common/gpu/client/gl_surface_capturer_host.h"
6
7 #include "content/common/gpu/client/gpu_channel_host.h"
8 #include "content/common/gpu/gpu_messages.h"
9 #include "ipc/ipc_message_macros.h"
10
11 namespace content {
12
13 namespace {
14
15 enum {
16 kNumCaptureBuffers = 2,
17 kMaxCaptureSize = 4096,
18 };
19
20 } // anonymous namespace
21
22 GLSurfaceCapturerHost::GLSurfaceCapturerHost(int32 capturer_route_id,
23 SurfaceCapturer::Client* client,
24 CommandBufferProxyImpl* impl)
25 : thread_checker_(),
26 capturer_route_id_(capturer_route_id),
27 weak_this_factory_(this),
28 client_ptr_factory_(client),
29 client_(client),
30 impl_(impl),
31 channel_(impl_->channel()),
32 next_frame_id_(0) {
33 DCHECK(thread_checker_.CalledOnValidThread());
34 channel_->AddRoute(capturer_route_id_, weak_this_factory_.GetWeakPtr());
35 impl_->AddDeletionObserver(this);
36 }
37
38 void GLSurfaceCapturerHost::OnChannelError() {
39 DLOG(ERROR) << "OnChannelError()";
40 DCHECK(thread_checker_.CalledOnValidThread());
41 OnNotifyError(kPlatformFailureError);
42 if (channel_) {
43 weak_this_factory_.InvalidateWeakPtrs();
44 channel_->RemoveRoute(capturer_route_id_);
45 channel_ = NULL;
46 }
47 }
48
49 bool GLSurfaceCapturerHost::OnMessageReceived(const IPC::Message& message) {
50 bool handled = true;
51 IPC_BEGIN_MESSAGE_MAP(GLSurfaceCapturerHost, message)
52 IPC_MESSAGE_HANDLER(SurfaceCapturerHostMsg_NotifyCaptureParameters,
53 OnNotifyCaptureParameters)
54 IPC_MESSAGE_HANDLER(SurfaceCapturerHostMsg_NotifyCopyCaptureDone,
55 OnNotifyCopyCaptureDone)
56 IPC_MESSAGE_HANDLER(SurfaceCapturerHostMsg_NotifyError, OnNotifyError)
57 IPC_MESSAGE_UNHANDLED(handled = false)
58 IPC_END_MESSAGE_MAP()
59 return handled;
60 }
61
62 void GLSurfaceCapturerHost::Initialize(media::VideoFrame::Format format) {
63 DCHECK(thread_checker_.CalledOnValidThread());
64 Send(new SurfaceCapturerMsg_Initialize(capturer_route_id_, format));
65 }
66
67 void GLSurfaceCapturerHost::TryCapture() {
68 DCHECK(thread_checker_.CalledOnValidThread());
69 Send(new SurfaceCapturerMsg_TryCapture(capturer_route_id_));
70 }
71
72 void GLSurfaceCapturerHost::CopyCaptureToVideoFrame(
73 const scoped_refptr<media::VideoFrame>& frame) {
74 DCHECK(thread_checker_.CalledOnValidThread());
75 if (!channel_)
76 return;
77 if (!base::SharedMemory::IsHandleValid(frame->shared_memory_handle())) {
78 DLOG(ERROR) << "CopyCaptureToVideoFrame(): cannot capture to frame not "
79 "backed by shared memory";
80 OnNotifyError(kPlatformFailureError);
81 return;
82 }
83 base::SharedMemoryHandle handle =
84 channel_->ShareToGpuProcess(frame->shared_memory_handle());
85 if (!base::SharedMemory::IsHandleValid(frame->shared_memory_handle())) {
86 DLOG(ERROR) << "CopyCaptureToVideoFrame(): failed to duplicate buffer "
87 "handle for GPU process";
88 OnNotifyError(kPlatformFailureError);
89 return;
90 }
91
92 const size_t plane_count = media::VideoFrame::NumPlanes(frame->format());
93 size_t frame_size = 0;
94 for (size_t i = 0; i < plane_count; ++i) {
95 DCHECK_EQ(reinterpret_cast<void*>(frame->data(i)),
96 reinterpret_cast<void*>((frame->data(0) + frame_size)))
97 << "plane=" << i;
98 frame_size += frame->stride(i) * frame->rows(i);
99 }
100
101 Send(new SurfaceCapturerMsg_CopyCaptureToVideoFrame(
102 capturer_route_id_, next_frame_id_, handle, frame_size));
103 frame_map_[next_frame_id_] = frame;
104 next_frame_id_ = (next_frame_id_ + 1) & 0x3FFFFFFF;
105 }
106
107 void GLSurfaceCapturerHost::Destroy() {
108 DCHECK(thread_checker_.CalledOnValidThread());
109 client_ = NULL;
piman 2013/08/28 21:59:44 client_ptr_factory_.InvalidateWeakPtrs() (but see
sheu 2013/08/28 22:20:18 Done.
110 Send(new SurfaceCapturerMsg_Destroy(capturer_route_id_));
111 }
112
113 void GLSurfaceCapturerHost::OnWillDeleteImpl() {
114 DCHECK(thread_checker_.CalledOnValidThread());
115 impl_ = NULL;
116 OnChannelError();
117 }
118
119 GLSurfaceCapturerHost::~GLSurfaceCapturerHost() {
120 DCHECK(thread_checker_.CalledOnValidThread());
121 weak_this_factory_.InvalidateWeakPtrs();
122 if (channel_)
123 channel_->RemoveRoute(capturer_route_id_);
124 if (impl_)
125 impl_->RemoveDeletionObserver(this);
126 }
127
128 void GLSurfaceCapturerHost::NotifyError(Error error) {
129 DCHECK(thread_checker_.CalledOnValidThread());
130 base::MessageLoopProxy::current()->PostTask(
131 FROM_HERE,
132 base::Bind(&SurfaceCapturer::Client::NotifyError,
piman 2013/08/28 21:59:44 Why not PostTask(&GLSurfaceCapturerHost::OnNotifyE
sheu 2013/08/28 22:20:18 Done.
133 client_ptr_factory_.GetWeakPtr(),
134 error));
135 }
136
137 void GLSurfaceCapturerHost::OnNotifyCaptureParameters(
138 const gfx::Size& buffer_size,
139 const gfx::Rect& visible_rect) {
140 DVLOG(2) << "OnNotifyCaptureParameters(): "
141 "buffer_size=" << buffer_size.ToString()
142 << ", visible_rect=" << visible_rect.ToString();
143 DCHECK(thread_checker_.CalledOnValidThread());
144 if (buffer_size.width() < 1 || buffer_size.width() > kMaxCaptureSize ||
145 buffer_size.height() < 1 || buffer_size.height() > kMaxCaptureSize ||
146 visible_rect.x() < 0 || visible_rect.x() > kMaxCaptureSize - 1 ||
147 visible_rect.y() < 0 || visible_rect.y() > kMaxCaptureSize - 1 ||
148 visible_rect.width() < 1 || visible_rect.width() > kMaxCaptureSize ||
149 visible_rect.height() < 1 || visible_rect.height() > kMaxCaptureSize) {
150 DLOG(ERROR) << "OnNotifyCaptureParameters(): parameters out of bounds: "
151 "buffer_size=" << buffer_size.ToString()
152 << ", visible_rect=" << visible_rect.ToString();
153 OnNotifyError(kPlatformFailureError);
154 return;
155 }
156 if (client_)
157 client_->NotifyCaptureParameters(buffer_size, visible_rect);
158 }
159
160 void GLSurfaceCapturerHost::OnNotifyCopyCaptureDone(int32 frame_id) {
161 DVLOG(3) << "OnNotifyCopyCaptureDone(): frame_id=" << frame_id;
162 DCHECK(thread_checker_.CalledOnValidThread());
163 FrameMap::iterator iter = frame_map_.find(frame_id);
164 if (iter == frame_map_.end()) {
165 DLOG(ERROR) << "OnNotifyCopyCaptureDone(): invalid frame_id=" << frame_id;
166 OnNotifyError(kPlatformFailureError);
167 return;
168 }
169 if (client_)
170 client_->NotifyCopyCaptureDone(iter->second);
171 frame_map_.erase(iter);
172 }
173
174 void GLSurfaceCapturerHost::OnNotifyError(Error error) {
175 DVLOG(2) << "OnNotifyError(): error=" << error;
176 DCHECK(thread_checker_.CalledOnValidThread());
177 if (client_) {
178 client_->NotifyError(error);
179 client_ = NULL;
180 client_ptr_factory_.InvalidateWeakPtrs();
181 }
182 }
183
184 void GLSurfaceCapturerHost::Send(IPC::Message* message) {
185 DCHECK(thread_checker_.CalledOnValidThread());
186 uint32 type = message->type();
187 if (!channel_) {
188 DLOG(ERROR) << "Send(): no channel";
189 delete message;
190 NotifyError(kPlatformFailureError);
191 } else if (!channel_->Send(message)) {
192 DLOG(ERROR) << "Send(): failed: message->type()=" << type;
193 NotifyError(kPlatformFailureError);
194 }
195 }
196
197 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698