fixes software output device rendering
This commit is contained in:
parent
221714e141
commit
6e1db86a77
5 changed files with 85 additions and 71 deletions
|
@ -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_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue