fixes software output device rendering

This commit is contained in:
gellert 2016-07-27 19:44:41 +02:00
parent 221714e141
commit 6e1db86a77
5 changed files with 85 additions and 71 deletions

View file

@ -281,8 +281,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
private: private:
AtomBrowserContext* GetBrowserContext() const; AtomBrowserContext* GetBrowserContext() const;
atom::OnPaintCallback paint_callback_;
uint32_t GetNextRequestId() { uint32_t GetNextRequestId() {
return ++request_id_; return ++request_id_;
} }

View file

@ -5,11 +5,15 @@
#include "atom/browser/osr_output_device.h" #include "atom/browser/osr_output_device.h"
#include <iostream> #include <iostream>
#include "third_party/skia/include/core/SkDevice.h"
#include "ui/gfx/skia_util.h"
namespace atom { namespace atom {
OffScreenOutputDevice::OffScreenOutputDevice() : callback_(nullptr) { OffScreenOutputDevice::OffScreenOutputDevice(const OnPaintCallback& callback)
std::cout << "OffScreenOutputDevice" << std::endl; : callback_(callback),
active_(false) {
DCHECK(!callback_.is_null());
} }
OffScreenOutputDevice::~OffScreenOutputDevice() { OffScreenOutputDevice::~OffScreenOutputDevice() {
@ -66,18 +70,19 @@ void OffScreenOutputDevice::EndPaint() {
cc::SoftwareOutputDevice::EndPaint(); cc::SoftwareOutputDevice::EndPaint();
OnPaint(damage_rect_); if (active_)
OnPaint(damage_rect_);
// SkAutoLockPixels bitmap_pixels_lock(*bitmap_.get());
// saveSkBitmapToBMPFile(*(bitmap_.get()), "test.bmp");
// uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap_->getPixels());
// for (int i = 0; i<16; i++) {
// int x = static_cast<int>(pixels[i]);
// std::cout << std::hex << x << std::dec << std::endl;
// }
} }
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) { void OffScreenOutputDevice::OnPaint(const gfx::Rect& damage_rect) {
gfx::Rect rect = damage_rect; gfx::Rect rect = damage_rect;
@ -91,10 +96,9 @@ void OffScreenOutputDevice::OnPaint(const gfx::Rect& damage_rect) {
return; return;
SkAutoLockPixels bitmap_pixels_lock(*bitmap_.get()); SkAutoLockPixels bitmap_pixels_lock(*bitmap_.get());
// std::cout << "Paint" << std::endl;
if (callback_.get()) callback_.Run(rect, bitmap_->width(), bitmap_->height(),
callback_->Run(rect, bitmap_->width(), bitmap_->height(), bitmap_->getPixels());
bitmap_->getPixels());
} }
} // namespace atom } // namespace atom

View file

@ -5,20 +5,22 @@
#ifndef ATOM_BROWSER_OSR_OUTPUT_DEVICE_H_ #ifndef ATOM_BROWSER_OSR_OUTPUT_DEVICE_H_
#define 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 "cc/output/software_output_device.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkCanvas.h"
#include "base/callback.h" #include "base/callback.h"
#include "content/browser/web_contents/web_contents_view.h"
namespace atom { namespace atom {
typedef base::Callback<void(const gfx::Rect&,int,int,void*)> OnPaintCallback; typedef base::Callback<void(const gfx::Rect&,int,int,void*)> OnPaintCallback;
class OffScreenOutputDevice : public cc::SoftwareOutputDevice { class OffScreenOutputDevice : public cc::SoftwareOutputDevice {
public: public:
OffScreenOutputDevice(); typedef base::Callback<void(const gfx::Rect&,int,int,void*)>
OnPaintCallback;
OffScreenOutputDevice(const OnPaintCallback& callback);
~OffScreenOutputDevice(); ~OffScreenOutputDevice();
void SetPaintCallback(const OnPaintCallback*); void SetPaintCallback(const OnPaintCallback*);
@ -32,7 +34,15 @@ public:
void OnPaint(const gfx::Rect& damage_rect); void OnPaint(const gfx::Rect& damage_rect);
void SetActive(bool active);
void OnPaint(const gfx::Rect& damage_rect);
private: private:
const OnPaintCallback callback_;
bool active_;
std::unique_ptr<SkCanvas> canvas_; std::unique_ptr<SkCanvas> canvas_;
std::unique_ptr<SkBitmap> bitmap_; std::unique_ptr<SkBitmap> bitmap_;
gfx::Rect pending_damage_rect_; gfx::Rect pending_damage_rect_;

View file

@ -309,20 +309,8 @@ class CefCopyFrameGenerator {
uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap.getPixels()); uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap.getPixels());
base::Time now = base::Time::Now(); std::cout << "ASDADASDA" << std::endl;
// std::cout << "delta: " << (now - last_time_).InMilliseconds() << " ms" << std::endl; view_->OnPaint(damage_rect, bitmap.width(), bitmap.height(), pixels);
last_time_ = now;
// for (int i = 0; i<4; i++) {
// int x = static_cast<int>(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();
// Reset the frame retry count on successful frame generation. // Reset the frame retry count on successful frame generation.
if (frame_retry_count_ > 0) if (frame_retry_count_ > 0)
@ -414,7 +402,6 @@ OffScreenWindow::OffScreenWindow(
compositor_widget_(gfx::kNullAcceleratedWidget), compositor_widget_(gfx::kNullAcceleratedWidget),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
DCHECK(render_widget_host_); DCHECK(render_widget_host_);
// std::cout << "OffScreenWindow" << std::endl;
render_widget_host_->SetView(this); render_widget_host_->SetView(this);
last_time_ = base::Time::Now(); last_time_ = base::Time::Now();
@ -653,40 +640,33 @@ void OffScreenWindow::OnSwapCompositorFrame(
last_scroll_offset_ = frame->metadata.root_scroll_offset; last_scroll_offset_ = frame->metadata.root_scroll_offset;
} }
if (!frame->delegated_frame_data) if (frame->delegated_frame_data) {
return; if (software_output_device_) {
if (!begin_frame_timer_.get()) {
software_output_device_->SetActive(true);
}
if (software_output_device_) { delegated_frame_host_->SwapDelegatedFrame(output_surface_id,
// if (!begin_frame_timer_.get()) { std::move(frame));
// software_output_device_->SetActive(true); } else {
// } if (!copy_frame_generator_.get()) {
copy_frame_generator_.reset(
new CefCopyFrameGenerator(frame_rate_threshold_ms_, this));
}
delegated_frame_host_->SwapDelegatedFrame(output_surface_id, cc::RenderPass* root_pass =
std::move(frame)); frame->delegated_frame_data->render_pass_list.back().get();
return; 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() { void OffScreenWindow::ClearCompositorFrame() {
@ -895,13 +875,15 @@ void OffScreenWindow::DelegatedFrameHostUpdateVSyncParameters(
render_widget_host_->UpdateVSyncParameters(timebase, interval); render_widget_host_->UpdateVSyncParameters(timebase, interval);
} }
std::unique_ptr<cc::SoftwareOutputDevice> std::unique_ptr<cc::SoftwareOutputDevice>
OffScreenWindow::CreateSoftwareOutputDevice(ui::Compositor* compositor) { OffScreenWindow::CreateSoftwareOutputDevice(ui::Compositor* compositor) {
DCHECK_EQ(compositor_.get(), compositor); DCHECK_EQ(compositor_.get(), compositor);
DCHECK(!copy_frame_generator_); DCHECK(!copy_frame_generator_);
DCHECK(!software_output_device_); DCHECK(!software_output_device_);
std::cout << "CREATED" << std::endl; std::cout << "CREATEEEEE" << std::endl;
software_output_device_ = new OffScreenOutputDevice(); software_output_device_ = new OffScreenOutputDevice(
base::Bind(&OffScreenWindow::OnPaint,
weak_ptr_factory_.GetWeakPtr()));
return base::WrapUnique(software_output_device_); return base::WrapUnique(software_output_device_);
} }
@ -910,6 +892,9 @@ void OffScreenWindow::OnSetNeedsBeginFrames(bool enabled) {
begin_frame_timer_->SetActive(enabled); begin_frame_timer_->SetActive(enabled);
if (software_output_device_) {
software_output_device_->SetActive(enabled);
}
// std::cout << "OnSetNeedsBeginFrames" << enabled << std::endl; // std::cout << "OnSetNeedsBeginFrames" << enabled << std::endl;
} }
@ -948,4 +933,16 @@ bool OffScreenWindow::IsAutoResizeEnabled() const {
return false; 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 } // namespace atom

View file

@ -93,7 +93,7 @@ public:
void UnlockMouse(void) override; void UnlockMouse(void) override;
bool GetScreenColorProfile(std::vector<char>*) override; bool GetScreenColorProfile(std::vector<char>*) override;
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
ui::AcceleratedWidgetMac* GetAcceleratedWidgetMac() const override; ui::AcceleratedWidgetMac* GetAcceleratedWidgetMac() const override;
void SetActive(bool active) override; void SetActive(bool active) override;
void ShowDefinitionForSelection() override; void ShowDefinitionForSelection() override;
@ -190,6 +190,11 @@ public:
std::unique_ptr<const atom::OnPaintCallback> paintCallback; std::unique_ptr<const atom::OnPaintCallback> paintCallback;
void SetPaintCallback(const atom::OnPaintCallback*); void SetPaintCallback(const atom::OnPaintCallback*);
void OnPaint(const gfx::Rect& damage_rect,
int bitmap_width,
int bitmap_height,
void* bitmap_pixels);
private: private:
void SetFrameRate(); void SetFrameRate();
void ResizeRootLayer(); void ResizeRootLayer();