| 
									
										
										
										
											2015-09-18 15:57:43 +08:00
										 |  |  | // Copyright (c) 2015 GitHub, Inc.
 | 
					
						
							|  |  |  | // Use of this source code is governed by the MIT license that can be
 | 
					
						
							|  |  |  | // found in the LICENSE file.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "atom/browser/api/frame_subscriber.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 02:15:39 +02:00
										 |  |  | #include "atom/common/native_mate_converters/gfx_converter.h"
 | 
					
						
							| 
									
										
										
										
											2016-08-26 15:30:02 -07:00
										 |  |  | #include "base/bind.h"
 | 
					
						
							| 
									
										
										
										
											2016-02-25 23:48:58 +01:00
										 |  |  | #include "content/public/browser/render_widget_host.h"
 | 
					
						
							| 
									
										
										
										
											2016-09-09 23:17:17 +02:00
										 |  |  | #include "ui/display/display.h"
 | 
					
						
							| 
									
										
										
										
											2016-09-09 23:50:01 +02:00
										 |  |  | #include "ui/display/screen.h"
 | 
					
						
							| 
									
										
										
										
											2016-02-25 23:48:58 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-06 17:24:37 +09:00
										 |  |  | #include "atom/common/node_includes.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 15:57:43 +08:00
										 |  |  | namespace atom { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace api { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | FrameSubscriber::FrameSubscriber(v8::Isolate* isolate, | 
					
						
							| 
									
										
										
										
											2016-02-18 01:15:00 +01:00
										 |  |  |                                  content::RenderWidgetHostView* view, | 
					
						
							| 
									
										
										
										
											2016-06-21 02:15:39 +02:00
										 |  |  |                                  const FrameCaptureCallback& callback, | 
					
						
							| 
									
										
										
										
											2016-06-25 18:23:40 +02:00
										 |  |  |                                  bool only_dirty) | 
					
						
							| 
									
										
										
										
											2016-06-26 11:46:40 +09:00
										 |  |  |     : isolate_(isolate), | 
					
						
							|  |  |  |       view_(view), | 
					
						
							|  |  |  |       callback_(callback), | 
					
						
							|  |  |  |       only_dirty_(only_dirty), | 
					
						
							|  |  |  |       weak_factory_(this) { | 
					
						
							| 
									
										
										
										
											2015-09-18 15:57:43 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-16 10:44:10 +08:00
										 |  |  | bool FrameSubscriber::ShouldCaptureFrame( | 
					
						
							| 
									
										
										
										
											2016-06-25 18:23:40 +02:00
										 |  |  |     const gfx::Rect& dirty_rect, | 
					
						
							| 
									
										
										
										
											2015-09-18 15:57:43 +08:00
										 |  |  |     base::TimeTicks present_time, | 
					
						
							|  |  |  |     scoped_refptr<media::VideoFrame>* storage, | 
					
						
							|  |  |  |     DeliverFrameCallback* callback) { | 
					
						
							| 
									
										
										
										
											2016-02-26 02:05:57 +01:00
										 |  |  |   const auto host = view_ ? view_->GetRenderWidgetHost() : nullptr; | 
					
						
							|  |  |  |   if (!view_ || !host) | 
					
						
							| 
									
										
										
										
											2016-02-18 01:15:00 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-25 18:23:40 +02:00
										 |  |  |   if (dirty_rect.IsEmpty()) | 
					
						
							| 
									
										
										
										
											2016-06-21 02:15:39 +02:00
										 |  |  |     return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gfx::Rect rect = gfx::Rect(view_->GetVisibleViewportSize()); | 
					
						
							| 
									
										
										
										
											2016-06-25 18:23:40 +02:00
										 |  |  |   if (only_dirty_) | 
					
						
							|  |  |  |     rect = dirty_rect; | 
					
						
							| 
									
										
										
										
											2016-02-18 01:15:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-09 23:17:17 +02:00
										 |  |  |   gfx::Size view_size = rect.size(); | 
					
						
							|  |  |  |   gfx::Size bitmap_size = view_size; | 
					
						
							|  |  |  |   const gfx::NativeView native_view = view_->GetNativeView(); | 
					
						
							|  |  |  |   const float scale = | 
					
						
							|  |  |  |       display::Screen::GetScreen()->GetDisplayNearestWindow(native_view) | 
					
						
							|  |  |  |       .device_scale_factor(); | 
					
						
							|  |  |  |   if (scale > 1.0f) | 
					
						
							|  |  |  |     bitmap_size = gfx::ScaleToCeiledSize(view_size, scale); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   rect = gfx::Rect(rect.origin(), bitmap_size); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-18 01:15:00 +01:00
										 |  |  |   host->CopyFromBackingStore( | 
					
						
							| 
									
										
										
										
											2016-06-21 02:15:39 +02:00
										 |  |  |       rect, | 
					
						
							|  |  |  |       rect.size(), | 
					
						
							| 
									
										
										
										
											2016-02-18 01:15:00 +01:00
										 |  |  |       base::Bind(&FrameSubscriber::OnFrameDelivered, | 
					
						
							| 
									
										
										
										
											2016-06-21 02:15:39 +02:00
										 |  |  |                  weak_factory_.GetWeakPtr(), callback_, rect), | 
					
						
							| 
									
										
										
										
											2016-02-18 01:15:00 +01:00
										 |  |  |       kBGRA_8888_SkColorType); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return false; | 
					
						
							| 
									
										
										
										
											2015-09-18 15:57:43 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-18 01:15:00 +01:00
										 |  |  | void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback, | 
					
						
							| 
									
										
										
										
											2016-06-26 11:46:40 +09:00
										 |  |  |                                        const gfx::Rect& damage_rect, | 
					
						
							|  |  |  |                                        const SkBitmap& bitmap, | 
					
						
							|  |  |  |                                        content::ReadbackResponse response) { | 
					
						
							| 
									
										
										
										
											2016-06-21 02:15:39 +02:00
										 |  |  |   if (response != content::ReadbackResponse::READBACK_SUCCESS) | 
					
						
							| 
									
										
										
										
											2015-09-18 15:57:43 +08:00
										 |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-14 23:59:38 +01:00
										 |  |  |   v8::Locker locker(isolate_); | 
					
						
							|  |  |  |   v8::HandleScope handle_scope(isolate_); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-18 01:15:00 +01:00
										 |  |  |   size_t rgb_arr_size = bitmap.width() * bitmap.height() * | 
					
						
							|  |  |  |     bitmap.bytesPerPixel(); | 
					
						
							| 
									
										
										
										
											2015-09-18 15:57:43 +08:00
										 |  |  |   v8::MaybeLocal<v8::Object> buffer = node::Buffer::New(isolate_, rgb_arr_size); | 
					
						
							|  |  |  |   if (buffer.IsEmpty()) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-18 01:15:00 +01:00
										 |  |  |   bitmap.copyPixelsTo( | 
					
						
							| 
									
										
										
										
											2016-03-08 23:28:53 +09:00
										 |  |  |     reinterpret_cast<uint8_t*>(node::Buffer::Data(buffer.ToLocalChecked())), | 
					
						
							| 
									
										
										
										
											2016-02-18 01:15:00 +01:00
										 |  |  |     rgb_arr_size); | 
					
						
							| 
									
										
										
										
											2015-09-18 15:57:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 02:15:39 +02:00
										 |  |  |   v8::Local<v8::Value> damage = | 
					
						
							| 
									
										
										
										
											2016-06-26 11:46:40 +09:00
										 |  |  |       mate::Converter<gfx::Rect>::ToV8(isolate_, damage_rect); | 
					
						
							| 
									
										
										
										
											2016-06-21 02:15:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   callback_.Run(buffer.ToLocalChecked(), damage); | 
					
						
							| 
									
										
										
										
											2015-09-18 15:57:43 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace api
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace atom
 |