diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 203dd9d42617..762e8bb7289f 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -281,8 +281,6 @@ class WebContents : public mate::TrackableObject, private: AtomBrowserContext* GetBrowserContext() const; - atom::OnPaintCallback paint_callback_; - uint32_t GetNextRequestId() { return ++request_id_; } diff --git a/atom/browser/osr_output_device.cc b/atom/browser/osr_output_device.cc index 4c2447594d0c..d2b338414cec 100644 --- a/atom/browser/osr_output_device.cc +++ b/atom/browser/osr_output_device.cc @@ -5,11 +5,15 @@ #include "atom/browser/osr_output_device.h" #include +#include "third_party/skia/include/core/SkDevice.h" +#include "ui/gfx/skia_util.h" namespace atom { -OffScreenOutputDevice::OffScreenOutputDevice() : callback_(nullptr) { - std::cout << "OffScreenOutputDevice" << std::endl; +OffScreenOutputDevice::OffScreenOutputDevice(const OnPaintCallback& callback) + : callback_(callback), + active_(false) { + DCHECK(!callback_.is_null()); } OffScreenOutputDevice::~OffScreenOutputDevice() { @@ -66,18 +70,19 @@ void OffScreenOutputDevice::EndPaint() { cc::SoftwareOutputDevice::EndPaint(); - OnPaint(damage_rect_); - - // SkAutoLockPixels bitmap_pixels_lock(*bitmap_.get()); - // saveSkBitmapToBMPFile(*(bitmap_.get()), "test.bmp"); - - // uint8_t* pixels = reinterpret_cast(bitmap_->getPixels()); - // for (int i = 0; i<16; i++) { - // int x = static_cast(pixels[i]); - // std::cout << std::hex << x << std::dec << std::endl; - // } + if (active_) + OnPaint(damage_rect_); } +void OffScreenOutputDevice::SetActive(bool active) { + if (active == active_) + return; + active_ = active; + + // Call OnPaint immediately if deactivated while a damage rect is pending. + if (!active_ && !pending_damage_rect_.IsEmpty()) + OnPaint(pending_damage_rect_); +} void OffScreenOutputDevice::OnPaint(const gfx::Rect& damage_rect) { gfx::Rect rect = damage_rect; @@ -91,10 +96,9 @@ void OffScreenOutputDevice::OnPaint(const gfx::Rect& damage_rect) { return; SkAutoLockPixels bitmap_pixels_lock(*bitmap_.get()); - // std::cout << "Paint" << std::endl; - if (callback_.get()) - callback_->Run(rect, bitmap_->width(), bitmap_->height(), - bitmap_->getPixels()); + + callback_.Run(rect, bitmap_->width(), bitmap_->height(), + bitmap_->getPixels()); } } // namespace atom diff --git a/atom/browser/osr_output_device.h b/atom/browser/osr_output_device.h index a093b773637b..f0e44aff7265 100644 --- a/atom/browser/osr_output_device.h +++ b/atom/browser/osr_output_device.h @@ -5,20 +5,22 @@ #ifndef ATOM_BROWSER_OSR_OUTPUT_DEVICE_H_ #define ATOM_BROWSER_OSR_OUTPUT_DEVICE_H_ +#include "base/callback.h" #include "cc/output/software_output_device.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" #include "base/callback.h" -#include "content/browser/web_contents/web_contents_view.h" - namespace atom { typedef base::Callback OnPaintCallback; class OffScreenOutputDevice : public cc::SoftwareOutputDevice { public: - OffScreenOutputDevice(); + typedef base::Callback + OnPaintCallback; + + OffScreenOutputDevice(const OnPaintCallback& callback); ~OffScreenOutputDevice(); void SetPaintCallback(const OnPaintCallback*); @@ -32,7 +34,15 @@ public: void OnPaint(const gfx::Rect& damage_rect); + void SetActive(bool active); + + void OnPaint(const gfx::Rect& damage_rect); + private: + const OnPaintCallback callback_; + + bool active_; + std::unique_ptr canvas_; std::unique_ptr bitmap_; gfx::Rect pending_damage_rect_; diff --git a/atom/browser/osr_window.cc b/atom/browser/osr_window.cc index b10886061fb0..0f41db584f58 100644 --- a/atom/browser/osr_window.cc +++ b/atom/browser/osr_window.cc @@ -309,20 +309,8 @@ class CefCopyFrameGenerator { uint8_t* pixels = reinterpret_cast(bitmap.getPixels()); - base::Time now = base::Time::Now(); - // std::cout << "delta: " << (now - last_time_).InMilliseconds() << " ms" << std::endl; - last_time_ = now; - // for (int i = 0; i<4; i++) { - // int x = static_cast(pixels[i]); - // std::cout << std::hex << x << std::dec << std::endl; - // } - TRACE_EVENT0("electron", "OffScreenWindow::OnPaint"); - if (view_->paintCallback) { - view_->paintCallback->Run(damage_rect, bitmap.width(), bitmap.height(), - pixels); - } - - bitmap_pixels_lock.reset(); + std::cout << "ASDADASDA" << std::endl; + view_->OnPaint(damage_rect, bitmap.width(), bitmap.height(), pixels); // Reset the frame retry count on successful frame generation. if (frame_retry_count_ > 0) @@ -414,7 +402,6 @@ OffScreenWindow::OffScreenWindow( compositor_widget_(gfx::kNullAcceleratedWidget), weak_ptr_factory_(this) { DCHECK(render_widget_host_); - // std::cout << "OffScreenWindow" << std::endl; render_widget_host_->SetView(this); last_time_ = base::Time::Now(); @@ -653,40 +640,33 @@ void OffScreenWindow::OnSwapCompositorFrame( last_scroll_offset_ = frame->metadata.root_scroll_offset; } - if (!frame->delegated_frame_data) - return; + if (frame->delegated_frame_data) { + if (software_output_device_) { + if (!begin_frame_timer_.get()) { + software_output_device_->SetActive(true); + } - if (software_output_device_) { - // if (!begin_frame_timer_.get()) { - // software_output_device_->SetActive(true); - // } + delegated_frame_host_->SwapDelegatedFrame(output_surface_id, + std::move(frame)); + } else { + if (!copy_frame_generator_.get()) { + copy_frame_generator_.reset( + new CefCopyFrameGenerator(frame_rate_threshold_ms_, this)); + } - delegated_frame_host_->SwapDelegatedFrame(output_surface_id, - std::move(frame)); - return; + cc::RenderPass* root_pass = + frame->delegated_frame_data->render_pass_list.back().get(); + gfx::Size frame_size = root_pass->output_rect.size(); + gfx::Rect damage_rect = + gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect)); + damage_rect.Intersect(gfx::Rect(frame_size)); + + delegated_frame_host_->SwapDelegatedFrame(output_surface_id, + std::move(frame)); + + copy_frame_generator_->GenerateCopyFrame(true, damage_rect); + } } - - if (!copy_frame_generator_.get()) { - copy_frame_generator_.reset( - new CefCopyFrameGenerator(frame_rate_threshold_ms_, this)); - } - - // Determine the damage rectangle for the current frame. This is the same - // calculation that SwapDelegatedFrame uses. - cc::RenderPass* root_pass = - frame->delegated_frame_data->render_pass_list.back().get(); - gfx::Size frame_size = root_pass->output_rect.size(); - gfx::Rect damage_rect = - gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect)); - damage_rect.Intersect(gfx::Rect(frame_size)); - - delegated_frame_host_->SwapDelegatedFrame(output_surface_id, - std::move(frame)); - - // Request a copy of the last compositor frame which will eventually call - // OnPaint asynchronously. - // std::cout << "FRAME COPY REQUESTED" << std::endl; - copy_frame_generator_->GenerateCopyFrame(true, damage_rect); } void OffScreenWindow::ClearCompositorFrame() { @@ -895,13 +875,15 @@ void OffScreenWindow::DelegatedFrameHostUpdateVSyncParameters( render_widget_host_->UpdateVSyncParameters(timebase, interval); } -std::unique_ptr +std::unique_ptr OffScreenWindow::CreateSoftwareOutputDevice(ui::Compositor* compositor) { DCHECK_EQ(compositor_.get(), compositor); DCHECK(!copy_frame_generator_); DCHECK(!software_output_device_); - std::cout << "CREATED" << std::endl; - software_output_device_ = new OffScreenOutputDevice(); + std::cout << "CREATEEEEE" << std::endl; + software_output_device_ = new OffScreenOutputDevice( + base::Bind(&OffScreenWindow::OnPaint, + weak_ptr_factory_.GetWeakPtr())); return base::WrapUnique(software_output_device_); } @@ -910,6 +892,9 @@ void OffScreenWindow::OnSetNeedsBeginFrames(bool enabled) { begin_frame_timer_->SetActive(enabled); + if (software_output_device_) { + software_output_device_->SetActive(enabled); + } // std::cout << "OnSetNeedsBeginFrames" << enabled << std::endl; } @@ -948,4 +933,16 @@ bool OffScreenWindow::IsAutoResizeEnabled() const { return false; } +void OffScreenWindow::OnPaint( + const gfx::Rect& damage_rect, + int bitmap_width, + int bitmap_height, + void* bitmap_pixels) { + TRACE_EVENT0("electron", "OffScreenWindow::OnPaint"); + + if (paintCallback) { + paintCallback->Run(damage_rect, bitmap_width, bitmap_height, bitmap_pixels); + } +} + } // namespace atom diff --git a/atom/browser/osr_window.h b/atom/browser/osr_window.h index 44a4f607347d..87265d470a82 100644 --- a/atom/browser/osr_window.h +++ b/atom/browser/osr_window.h @@ -93,7 +93,7 @@ public: void UnlockMouse(void) override; bool GetScreenColorProfile(std::vector*) override; -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) ui::AcceleratedWidgetMac* GetAcceleratedWidgetMac() const override; void SetActive(bool active) override; void ShowDefinitionForSelection() override; @@ -190,6 +190,11 @@ public: std::unique_ptr paintCallback; void SetPaintCallback(const atom::OnPaintCallback*); + void OnPaint(const gfx::Rect& damage_rect, + int bitmap_width, + int bitmap_height, + void* bitmap_pixels); + private: void SetFrameRate(); void ResizeRootLayer();