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:
AtomBrowserContext* GetBrowserContext() const;
atom::OnPaintCallback paint_callback_;
uint32_t GetNextRequestId() {
return ++request_id_;
}

View file

@ -5,11 +5,15 @@
#include "atom/browser/osr_output_device.h"
#include <iostream>
#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();
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) {
gfx::Rect rect = damage_rect;
@ -91,9 +96,8 @@ 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(),
callback_.Run(rect, bitmap_->width(), bitmap_->height(),
bitmap_->getPixels());
}

View file

@ -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<void(const gfx::Rect&,int,int,void*)> OnPaintCallback;
class OffScreenOutputDevice : public cc::SoftwareOutputDevice {
public:
OffScreenOutputDevice();
typedef base::Callback<void(const gfx::Rect&,int,int,void*)>
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<SkCanvas> canvas_;
std::unique_ptr<SkBitmap> bitmap_;
gfx::Rect pending_damage_rect_;

View file

@ -309,20 +309,8 @@ class CefCopyFrameGenerator {
uint8_t* pixels = reinterpret_cast<uint8_t*>(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<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();
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,26 +640,20 @@ 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 (!begin_frame_timer_.get()) {
software_output_device_->SetActive(true);
}
delegated_frame_host_->SwapDelegatedFrame(output_surface_id,
std::move(frame));
return;
}
} else {
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();
@ -683,10 +664,9 @@ void OffScreenWindow::OnSwapCompositorFrame(
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() {
@ -900,8 +880,10 @@ std::unique_ptr<cc::SoftwareOutputDevice>
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

View file

@ -190,6 +190,11 @@ public:
std::unique_ptr<const atom::OnPaintCallback> 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();