fix: port OSR code to new viz compositor codepath (#17538)
* fix: make OSR work with viz compositor * fix: update OSR patch * fix: update patch again * fix: update viz_osr.patch for macOS * fix: gn check warnings * chore: no need to change SoftwareOutputDeviceWinProxy * chore: add check in case we missed something * fix: consider scale factor when compare size * fix: make GPU OSR work * fix: autofill popups with OSR * chore: use UNIX line ending for osr_video_consumer * chore: code is already in defined(OS_MACOSX) * fix: share same OSR implementation on macOS This should also fix the crash when there is navigation on macOS. * test: osr window should not crash after navigation * fix: make osr work on Mac properly * fix: software osr on windows * fix: software osr on Linux * fix: compilation error introduced with rebase * fix: split local surface id allocation into two * Update osr_host_display_client_mac.mm * chore: update copyright year * fix: update patch
This commit is contained in:
parent
1478bd36fd
commit
81bf15877f
22 changed files with 1302 additions and 777 deletions
13
BUILD.gn
13
BUILD.gn
|
@ -632,11 +632,13 @@ static_library("electron_lib") {
|
||||||
|
|
||||||
if (enable_osr) {
|
if (enable_osr) {
|
||||||
sources += [
|
sources += [
|
||||||
"atom/browser/osr/osr_output_device.cc",
|
"atom/browser/osr/osr_host_display_client.cc",
|
||||||
"atom/browser/osr/osr_output_device.h",
|
"atom/browser/osr/osr_host_display_client.h",
|
||||||
|
"atom/browser/osr/osr_host_display_client_mac.mm",
|
||||||
"atom/browser/osr/osr_render_widget_host_view.cc",
|
"atom/browser/osr/osr_render_widget_host_view.cc",
|
||||||
"atom/browser/osr/osr_render_widget_host_view.h",
|
"atom/browser/osr/osr_render_widget_host_view.h",
|
||||||
"atom/browser/osr/osr_render_widget_host_view_mac.mm",
|
"atom/browser/osr/osr_video_consumer.cc",
|
||||||
|
"atom/browser/osr/osr_video_consumer.h",
|
||||||
"atom/browser/osr/osr_view_proxy.cc",
|
"atom/browser/osr/osr_view_proxy.cc",
|
||||||
"atom/browser/osr/osr_view_proxy.h",
|
"atom/browser/osr/osr_view_proxy.h",
|
||||||
"atom/browser/osr/osr_web_contents_view.cc",
|
"atom/browser/osr/osr_web_contents_view.cc",
|
||||||
|
@ -811,6 +813,11 @@ if (is_mac) {
|
||||||
"ServiceManagement.framework",
|
"ServiceManagement.framework",
|
||||||
"StoreKit.framework",
|
"StoreKit.framework",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (enable_osr) {
|
||||||
|
libs += [ "IOSurface.framework" ]
|
||||||
|
}
|
||||||
|
|
||||||
ldflags = [
|
ldflags = [
|
||||||
"-F",
|
"-F",
|
||||||
rebase_path("external_binaries", root_build_dir),
|
rebase_path("external_binaries", root_build_dir),
|
||||||
|
|
|
@ -91,7 +91,6 @@
|
||||||
#include "ui/events/base_event_utils.h"
|
#include "ui/events/base_event_utils.h"
|
||||||
|
|
||||||
#if BUILDFLAG(ENABLE_OSR)
|
#if BUILDFLAG(ENABLE_OSR)
|
||||||
#include "atom/browser/osr/osr_output_device.h"
|
|
||||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||||
#include "atom/browser/osr/osr_web_contents_view.h"
|
#include "atom/browser/osr/osr_web_contents_view.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -233,7 +233,10 @@ namespace atom {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool IsFramelessWindow(NSView* view) {
|
bool IsFramelessWindow(NSView* view) {
|
||||||
NativeWindow* window = [static_cast<AtomNSWindow*>([view window]) shell];
|
NSWindow* nswindow = [view window];
|
||||||
|
if (![nswindow respondsToSelector:@selector(shell)])
|
||||||
|
return false;
|
||||||
|
NativeWindow* window = [static_cast<AtomNSWindow*>(nswindow) shell];
|
||||||
return window && !window->has_frame();
|
return window && !window->has_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
121
atom/browser/osr/osr_host_display_client.cc
Normal file
121
atom/browser/osr/osr_host_display_client.cc
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
// Copyright (c) 2019 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "atom/browser/osr/osr_host_display_client.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "components/viz/common/resources/resource_format.h"
|
||||||
|
#include "components/viz/common/resources/resource_sizes.h"
|
||||||
|
#include "mojo/public/cpp/system/platform_handle.h"
|
||||||
|
#include "skia/ext/platform_canvas.h"
|
||||||
|
#include "third_party/skia/include/core/SkColor.h"
|
||||||
|
#include "third_party/skia/include/core/SkRect.h"
|
||||||
|
#include "third_party/skia/src/core/SkDevice.h"
|
||||||
|
#include "ui/gfx/skia_util.h"
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#include "skia/ext/skia_utils_win.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
LayeredWindowUpdater::LayeredWindowUpdater(
|
||||||
|
viz::mojom::LayeredWindowUpdaterRequest request,
|
||||||
|
OnPaintCallback callback)
|
||||||
|
: callback_(callback), binding_(this, std::move(request)) {}
|
||||||
|
|
||||||
|
LayeredWindowUpdater::~LayeredWindowUpdater() = default;
|
||||||
|
|
||||||
|
void LayeredWindowUpdater::SetActive(bool active) {
|
||||||
|
active_ = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayeredWindowUpdater::OnAllocatedSharedMemory(
|
||||||
|
const gfx::Size& pixel_size,
|
||||||
|
mojo::ScopedSharedBufferHandle scoped_buffer_handle) {
|
||||||
|
canvas_.reset();
|
||||||
|
|
||||||
|
// Make sure |pixel_size| is sane.
|
||||||
|
size_t expected_bytes;
|
||||||
|
bool size_result = viz::ResourceSizes::MaybeSizeInBytes(
|
||||||
|
pixel_size, viz::ResourceFormat::RGBA_8888, &expected_bytes);
|
||||||
|
if (!size_result)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
base::SharedMemoryHandle shm_handle;
|
||||||
|
size_t required_bytes;
|
||||||
|
MojoResult unwrap_result = mojo::UnwrapSharedMemoryHandle(
|
||||||
|
std::move(scoped_buffer_handle), &shm_handle, &required_bytes, nullptr);
|
||||||
|
if (unwrap_result != MOJO_RESULT_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
base::SharedMemory shm(shm_handle, false);
|
||||||
|
if (!shm.Map(required_bytes)) {
|
||||||
|
DLOG(ERROR) << "Failed to map " << required_bytes << " bytes";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas_ = skia::CreatePlatformCanvasWithSharedSection(
|
||||||
|
pixel_size.width(), pixel_size.height(), false, shm.handle().GetHandle(),
|
||||||
|
skia::CRASH_ON_FAILURE);
|
||||||
|
#else
|
||||||
|
auto shm =
|
||||||
|
mojo::UnwrapWritableSharedMemoryRegion(std::move(scoped_buffer_handle));
|
||||||
|
if (!shm.IsValid()) {
|
||||||
|
DLOG(ERROR) << "Failed to unwrap shared memory region";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shm_mapping_ = shm.Map();
|
||||||
|
if (!shm_mapping_.IsValid()) {
|
||||||
|
DLOG(ERROR) << "Failed to map shared memory region";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas_ = skia::CreatePlatformCanvasWithPixels(
|
||||||
|
pixel_size.width(), pixel_size.height(), false,
|
||||||
|
static_cast<uint8_t*>(shm_mapping_.memory()), skia::CRASH_ON_FAILURE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayeredWindowUpdater::Draw(const gfx::Rect& damage_rect,
|
||||||
|
DrawCallback draw_callback) {
|
||||||
|
SkPixmap pixmap;
|
||||||
|
SkBitmap bitmap;
|
||||||
|
|
||||||
|
if (active_ && canvas_->peekPixels(&pixmap)) {
|
||||||
|
bitmap.installPixels(pixmap);
|
||||||
|
callback_.Run(damage_rect, bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::move(draw_callback).Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
OffScreenHostDisplayClient::OffScreenHostDisplayClient(
|
||||||
|
gfx::AcceleratedWidget widget,
|
||||||
|
OnPaintCallback callback)
|
||||||
|
: viz::HostDisplayClient(widget), callback_(callback) {}
|
||||||
|
OffScreenHostDisplayClient::~OffScreenHostDisplayClient() {}
|
||||||
|
|
||||||
|
void OffScreenHostDisplayClient::SetActive(bool active) {
|
||||||
|
active_ = active;
|
||||||
|
if (layered_window_updater_) {
|
||||||
|
layered_window_updater_->SetActive(active_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffScreenHostDisplayClient::IsOffscreen(IsOffscreenCallback callback) {
|
||||||
|
std::move(callback).Run(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffScreenHostDisplayClient::CreateLayeredWindowUpdater(
|
||||||
|
viz::mojom::LayeredWindowUpdaterRequest request) {
|
||||||
|
layered_window_updater_ =
|
||||||
|
std::make_unique<LayeredWindowUpdater>(std::move(request), callback_);
|
||||||
|
layered_window_updater_->SetActive(active_);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace atom
|
77
atom/browser/osr/osr_host_display_client.h
Normal file
77
atom/browser/osr/osr_host_display_client.h
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// Copyright (c) 2019 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ATOM_BROWSER_OSR_OSR_HOST_DISPLAY_CLIENT_H_
|
||||||
|
#define ATOM_BROWSER_OSR_OSR_HOST_DISPLAY_CLIENT_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "base/callback.h"
|
||||||
|
#include "base/memory/shared_memory.h"
|
||||||
|
#include "components/viz/host/host_display_client.h"
|
||||||
|
#include "services/viz/privileged/interfaces/compositing/layered_window_updater.mojom.h"
|
||||||
|
#include "third_party/skia/include/core/SkBitmap.h"
|
||||||
|
#include "third_party/skia/include/core/SkCanvas.h"
|
||||||
|
#include "ui/gfx/native_widget_types.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
|
||||||
|
|
||||||
|
class LayeredWindowUpdater : public viz::mojom::LayeredWindowUpdater {
|
||||||
|
public:
|
||||||
|
explicit LayeredWindowUpdater(viz::mojom::LayeredWindowUpdaterRequest request,
|
||||||
|
OnPaintCallback callback);
|
||||||
|
~LayeredWindowUpdater() override;
|
||||||
|
|
||||||
|
void SetActive(bool active);
|
||||||
|
|
||||||
|
// viz::mojom::LayeredWindowUpdater implementation.
|
||||||
|
void OnAllocatedSharedMemory(
|
||||||
|
const gfx::Size& pixel_size,
|
||||||
|
mojo::ScopedSharedBufferHandle scoped_buffer_handle) override;
|
||||||
|
void Draw(const gfx::Rect& damage_rect, DrawCallback draw_callback) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OnPaintCallback callback_;
|
||||||
|
mojo::Binding<viz::mojom::LayeredWindowUpdater> binding_;
|
||||||
|
std::unique_ptr<SkCanvas> canvas_;
|
||||||
|
bool active_ = false;
|
||||||
|
|
||||||
|
#if !defined(WIN32)
|
||||||
|
base::WritableSharedMemoryMapping shm_mapping_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(LayeredWindowUpdater);
|
||||||
|
};
|
||||||
|
|
||||||
|
class OffScreenHostDisplayClient : public viz::HostDisplayClient {
|
||||||
|
public:
|
||||||
|
explicit OffScreenHostDisplayClient(gfx::AcceleratedWidget widget,
|
||||||
|
OnPaintCallback callback);
|
||||||
|
~OffScreenHostDisplayClient() override;
|
||||||
|
|
||||||
|
void SetActive(bool active);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void IsOffscreen(IsOffscreenCallback callback) override;
|
||||||
|
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
void OnDisplayReceivedCALayerParams(
|
||||||
|
const gfx::CALayerParams& ca_layer_params) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void CreateLayeredWindowUpdater(
|
||||||
|
viz::mojom::LayeredWindowUpdaterRequest request) override;
|
||||||
|
|
||||||
|
std::unique_ptr<LayeredWindowUpdater> layered_window_updater_;
|
||||||
|
OnPaintCallback callback_;
|
||||||
|
bool active_ = false;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(OffScreenHostDisplayClient);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
#endif // ATOM_BROWSER_OSR_OSR_HOST_DISPLAY_CLIENT_H_
|
35
atom/browser/osr/osr_host_display_client_mac.mm
Normal file
35
atom/browser/osr/osr_host_display_client_mac.mm
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (c) 2019 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "atom/browser/osr/osr_host_display_client.h"
|
||||||
|
|
||||||
|
#include <IOSurface/IOSurface.h>
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
void OffScreenHostDisplayClient::OnDisplayReceivedCALayerParams(
|
||||||
|
const gfx::CALayerParams& ca_layer_params) {
|
||||||
|
if (!ca_layer_params.is_empty) {
|
||||||
|
base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
|
||||||
|
IOSurfaceLookupFromMachPort(ca_layer_params.io_surface_mach_port));
|
||||||
|
|
||||||
|
gfx::Size pixel_size_ = ca_layer_params.pixel_size;
|
||||||
|
void* pixels = static_cast<void*>(IOSurfaceGetBaseAddress(io_surface));
|
||||||
|
size_t stride = IOSurfaceGetBytesPerRow(io_surface);
|
||||||
|
|
||||||
|
struct IOSurfacePinner {
|
||||||
|
base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
|
||||||
|
};
|
||||||
|
|
||||||
|
SkBitmap bitmap;
|
||||||
|
bitmap.installPixels(
|
||||||
|
SkImageInfo::MakeN32(pixel_size_.width(), pixel_size_.height(),
|
||||||
|
kPremul_SkAlphaType),
|
||||||
|
pixels, stride);
|
||||||
|
bitmap.setImmutable();
|
||||||
|
callback_.Run(ca_layer_params.damage, bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace atom
|
|
@ -1,101 +0,0 @@
|
||||||
// Copyright (c) 2016 GitHub, Inc.
|
|
||||||
// Use of this source code is governed by the MIT license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "atom/browser/osr/osr_output_device.h"
|
|
||||||
|
|
||||||
#include "third_party/skia/include/core/SkColor.h"
|
|
||||||
#include "third_party/skia/include/core/SkRect.h"
|
|
||||||
#include "third_party/skia/src/core/SkDevice.h"
|
|
||||||
#include "ui/gfx/skia_util.h"
|
|
||||||
|
|
||||||
namespace atom {
|
|
||||||
|
|
||||||
OffScreenOutputDevice::OffScreenOutputDevice(bool transparent,
|
|
||||||
const OnPaintCallback& callback)
|
|
||||||
: transparent_(transparent), callback_(callback) {
|
|
||||||
DCHECK(!callback_.is_null());
|
|
||||||
}
|
|
||||||
|
|
||||||
OffScreenOutputDevice::~OffScreenOutputDevice() {}
|
|
||||||
|
|
||||||
void OffScreenOutputDevice::Resize(const gfx::Size& pixel_size,
|
|
||||||
float scale_factor) {
|
|
||||||
if (viewport_pixel_size_ == pixel_size)
|
|
||||||
return;
|
|
||||||
viewport_pixel_size_ = pixel_size;
|
|
||||||
|
|
||||||
canvas_.reset();
|
|
||||||
bitmap_.reset(new SkBitmap);
|
|
||||||
bitmap_->allocN32Pixels(viewport_pixel_size_.width(),
|
|
||||||
viewport_pixel_size_.height(), !transparent_);
|
|
||||||
if (bitmap_->drawsNothing()) {
|
|
||||||
NOTREACHED();
|
|
||||||
bitmap_.reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transparent_) {
|
|
||||||
bitmap_->eraseColor(SK_ColorTRANSPARENT);
|
|
||||||
} else {
|
|
||||||
bitmap_->eraseColor(SK_ColorWHITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas_.reset(new SkCanvas(*bitmap_));
|
|
||||||
}
|
|
||||||
|
|
||||||
SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) {
|
|
||||||
DCHECK(canvas_.get());
|
|
||||||
DCHECK(bitmap_.get());
|
|
||||||
|
|
||||||
damage_rect_ = damage_rect;
|
|
||||||
SkIRect damage =
|
|
||||||
SkIRect::MakeXYWH(damage_rect_.x(), damage_rect_.y(),
|
|
||||||
damage_rect_.width(), damage_rect_.height());
|
|
||||||
|
|
||||||
if (transparent_) {
|
|
||||||
bitmap_->erase(SK_ColorTRANSPARENT, damage);
|
|
||||||
} else {
|
|
||||||
bitmap_->erase(SK_ColorWHITE, damage);
|
|
||||||
}
|
|
||||||
|
|
||||||
return canvas_.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OffScreenOutputDevice::EndPaint() {
|
|
||||||
DCHECK(canvas_.get());
|
|
||||||
DCHECK(bitmap_.get());
|
|
||||||
|
|
||||||
if (!bitmap_.get())
|
|
||||||
return;
|
|
||||||
|
|
||||||
viz::SoftwareOutputDevice::EndPaint();
|
|
||||||
|
|
||||||
if (active_)
|
|
||||||
OnPaint(damage_rect_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OffScreenOutputDevice::SetActive(bool active, bool paint) {
|
|
||||||
if (active == active_)
|
|
||||||
return;
|
|
||||||
active_ = active;
|
|
||||||
|
|
||||||
if (!active_ && !pending_damage_rect_.IsEmpty() && paint)
|
|
||||||
OnPaint(gfx::Rect(viewport_pixel_size_));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OffScreenOutputDevice::OnPaint(const gfx::Rect& damage_rect) {
|
|
||||||
gfx::Rect rect = damage_rect;
|
|
||||||
if (!pending_damage_rect_.IsEmpty()) {
|
|
||||||
rect.Union(pending_damage_rect_);
|
|
||||||
pending_damage_rect_.SetRect(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
rect.Intersect(gfx::Rect(viewport_pixel_size_));
|
|
||||||
if (rect.IsEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
callback_.Run(rect, *bitmap_);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace atom
|
|
|
@ -1,47 +0,0 @@
|
||||||
// Copyright (c) 2016 GitHub, Inc.
|
|
||||||
// Use of this source code is governed by the MIT license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef ATOM_BROWSER_OSR_OSR_OUTPUT_DEVICE_H_
|
|
||||||
#define ATOM_BROWSER_OSR_OSR_OUTPUT_DEVICE_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "base/callback.h"
|
|
||||||
#include "components/viz/service/display/software_output_device.h"
|
|
||||||
#include "third_party/skia/include/core/SkBitmap.h"
|
|
||||||
#include "third_party/skia/include/core/SkCanvas.h"
|
|
||||||
|
|
||||||
namespace atom {
|
|
||||||
|
|
||||||
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
|
|
||||||
|
|
||||||
class OffScreenOutputDevice : public viz::SoftwareOutputDevice {
|
|
||||||
public:
|
|
||||||
OffScreenOutputDevice(bool transparent, const OnPaintCallback& callback);
|
|
||||||
~OffScreenOutputDevice() override;
|
|
||||||
|
|
||||||
// viz::SoftwareOutputDevice:
|
|
||||||
void Resize(const gfx::Size& pixel_size, float scale_factor) override;
|
|
||||||
SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override;
|
|
||||||
void EndPaint() override;
|
|
||||||
|
|
||||||
void SetActive(bool active, bool paint);
|
|
||||||
void OnPaint(const gfx::Rect& damage_rect);
|
|
||||||
|
|
||||||
private:
|
|
||||||
const bool transparent_;
|
|
||||||
OnPaintCallback callback_;
|
|
||||||
|
|
||||||
bool active_ = false;
|
|
||||||
|
|
||||||
std::unique_ptr<SkCanvas> canvas_;
|
|
||||||
std::unique_ptr<SkBitmap> bitmap_;
|
|
||||||
gfx::Rect pending_damage_rect_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(OffScreenOutputDevice);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace atom
|
|
||||||
|
|
||||||
#endif // ATOM_BROWSER_OSR_OSR_OUTPUT_DEVICE_H_
|
|
|
@ -20,14 +20,15 @@
|
||||||
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
|
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
|
||||||
#include "components/viz/common/gl_helper.h"
|
#include "components/viz/common/gl_helper.h"
|
||||||
#include "components/viz/common/quads/render_pass.h"
|
#include "components/viz/common/quads/render_pass.h"
|
||||||
#include "content/browser/renderer_host/cursor_manager.h"
|
#include "content/browser/renderer_host/cursor_manager.h" // nogncheck
|
||||||
#include "content/browser/renderer_host/render_widget_host_delegate.h"
|
#include "content/browser/renderer_host/input/synthetic_gesture_target.h" // nogncheck
|
||||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
#include "content/browser/renderer_host/render_widget_host_delegate.h" // nogncheck
|
||||||
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h"
|
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h" // nogncheck
|
||||||
#include "content/common/view_messages.h"
|
#include "content/common/view_messages.h"
|
||||||
#include "content/public/browser/browser_task_traits.h"
|
#include "content/public/browser/browser_task_traits.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "content/public/browser/context_factory.h"
|
#include "content/public/browser/context_factory.h"
|
||||||
|
#include "content/public/browser/gpu_data_manager.h"
|
||||||
#include "content/public/browser/render_process_host.h"
|
#include "content/public/browser/render_process_host.h"
|
||||||
#include "media/base/video_frame.h"
|
#include "media/base/video_frame.h"
|
||||||
#include "third_party/blink/public/platform/web_input_event.h"
|
#include "third_party/blink/public/platform/web_input_event.h"
|
||||||
|
@ -50,7 +51,6 @@ namespace atom {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const float kDefaultScaleFactor = 1.0;
|
const float kDefaultScaleFactor = 1.0;
|
||||||
const int kFrameRetryLimit = 2;
|
|
||||||
|
|
||||||
ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
||||||
ui::EventType type = ui::EventType::ET_UNKNOWN;
|
ui::EventType type = ui::EventType::ET_UNKNOWN;
|
||||||
|
@ -120,105 +120,6 @@ ui::MouseWheelEvent UiMouseWheelEventFromWebMouseEvent(
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class AtomCopyFrameGenerator {
|
|
||||||
public:
|
|
||||||
AtomCopyFrameGenerator(OffScreenRenderWidgetHostView* view,
|
|
||||||
int frame_rate_threshold_us)
|
|
||||||
: view_(view),
|
|
||||||
frame_duration_(
|
|
||||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us)),
|
|
||||||
weak_ptr_factory_(this) {
|
|
||||||
last_time_ = base::Time::Now();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenerateCopyFrame(const gfx::Rect& damage_rect) {
|
|
||||||
if (!view_->render_widget_host() || !view_->IsPainting())
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto request = std::make_unique<viz::CopyOutputRequest>(
|
|
||||||
viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
|
|
||||||
base::BindOnce(
|
|
||||||
&AtomCopyFrameGenerator::CopyFromCompositingSurfaceHasResult,
|
|
||||||
weak_ptr_factory_.GetWeakPtr(), damage_rect));
|
|
||||||
|
|
||||||
request->set_area(gfx::Rect(view_->GetCompositorViewportPixelSize()));
|
|
||||||
view_->GetRootLayer()->RequestCopyOfOutput(std::move(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_frame_rate_threshold_us(int frame_rate_threshold_us) {
|
|
||||||
frame_duration_ =
|
|
||||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void CopyFromCompositingSurfaceHasResult(
|
|
||||||
const gfx::Rect& damage_rect,
|
|
||||||
std::unique_ptr<viz::CopyOutputResult> result) {
|
|
||||||
if (result->IsEmpty() || result->size().IsEmpty() ||
|
|
||||||
!view_->render_widget_host()) {
|
|
||||||
OnCopyFrameCaptureFailure(damage_rect);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DCHECK(!result->IsEmpty());
|
|
||||||
auto source = std::make_unique<SkBitmap>(result->AsSkBitmap());
|
|
||||||
DCHECK(source->readyToDraw());
|
|
||||||
if (source) {
|
|
||||||
base::AutoLock autolock(lock_);
|
|
||||||
std::shared_ptr<SkBitmap> bitmap(source.release());
|
|
||||||
|
|
||||||
base::TimeTicks now = base::TimeTicks::Now();
|
|
||||||
base::TimeDelta next_frame_in = next_frame_time_ - now;
|
|
||||||
if (next_frame_in > frame_duration_ / 4) {
|
|
||||||
next_frame_time_ += frame_duration_;
|
|
||||||
base::PostDelayedTaskWithTraits(
|
|
||||||
FROM_HERE, {content::BrowserThread::UI},
|
|
||||||
base::BindOnce(&AtomCopyFrameGenerator::OnCopyFrameCaptureSuccess,
|
|
||||||
weak_ptr_factory_.GetWeakPtr(), damage_rect, bitmap),
|
|
||||||
next_frame_in);
|
|
||||||
} else {
|
|
||||||
next_frame_time_ = now + frame_duration_;
|
|
||||||
OnCopyFrameCaptureSuccess(damage_rect, bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame_retry_count_ = 0;
|
|
||||||
} else {
|
|
||||||
OnCopyFrameCaptureFailure(damage_rect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnCopyFrameCaptureFailure(const gfx::Rect& damage_rect) {
|
|
||||||
const bool force_frame = (++frame_retry_count_ <= kFrameRetryLimit);
|
|
||||||
if (force_frame) {
|
|
||||||
// Retry with the same |damage_rect|.
|
|
||||||
base::PostTaskWithTraits(
|
|
||||||
FROM_HERE, {content::BrowserThread::UI},
|
|
||||||
base::BindOnce(&AtomCopyFrameGenerator::GenerateCopyFrame,
|
|
||||||
weak_ptr_factory_.GetWeakPtr(), damage_rect));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnCopyFrameCaptureSuccess(const gfx::Rect& damage_rect,
|
|
||||||
const std::shared_ptr<SkBitmap>& bitmap) {
|
|
||||||
base::AutoLock lock(onPaintLock_);
|
|
||||||
view_->OnPaint(damage_rect, *bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
base::Lock lock_;
|
|
||||||
base::Lock onPaintLock_;
|
|
||||||
OffScreenRenderWidgetHostView* view_;
|
|
||||||
|
|
||||||
base::Time last_time_;
|
|
||||||
|
|
||||||
int frame_retry_count_ = 0;
|
|
||||||
base::TimeTicks next_frame_time_ = base::TimeTicks::Now();
|
|
||||||
base::TimeDelta frame_duration_;
|
|
||||||
|
|
||||||
base::WeakPtrFactory<AtomCopyFrameGenerator> weak_ptr_factory_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomCopyFrameGenerator);
|
|
||||||
};
|
|
||||||
|
|
||||||
class AtomBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
|
class AtomBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
|
||||||
public:
|
public:
|
||||||
AtomBeginFrameTimer(int frame_rate_threshold_us,
|
AtomBeginFrameTimer(int frame_rate_threshold_us,
|
||||||
|
@ -253,7 +154,6 @@ class AtomBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomBeginFrameTimer);
|
DISALLOW_COPY_AND_ASSIGN(AtomBeginFrameTimer);
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !defined(OS_MACOSX)
|
|
||||||
class AtomDelegatedFrameHostClient : public content::DelegatedFrameHostClient {
|
class AtomDelegatedFrameHostClient : public content::DelegatedFrameHostClient {
|
||||||
public:
|
public:
|
||||||
explicit AtomDelegatedFrameHostClient(OffScreenRenderWidgetHostView* view)
|
explicit AtomDelegatedFrameHostClient(OffScreenRenderWidgetHostView* view)
|
||||||
|
@ -297,7 +197,6 @@ class AtomDelegatedFrameHostClient : public content::DelegatedFrameHostClient {
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomDelegatedFrameHostClient);
|
DISALLOW_COPY_AND_ASSIGN(AtomDelegatedFrameHostClient);
|
||||||
};
|
};
|
||||||
#endif // !defined(OS_MACOSX)
|
|
||||||
|
|
||||||
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||||
bool transparent,
|
bool transparent,
|
||||||
|
@ -315,19 +214,23 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||||
frame_rate_(frame_rate),
|
frame_rate_(frame_rate),
|
||||||
size_(initial_size),
|
size_(initial_size),
|
||||||
painting_(painting),
|
painting_(painting),
|
||||||
is_showing_(!render_widget_host_->is_hidden()),
|
is_showing_(false),
|
||||||
cursor_manager_(new content::CursorManager(this)),
|
cursor_manager_(new content::CursorManager(this)),
|
||||||
mouse_wheel_phase_handler_(this),
|
mouse_wheel_phase_handler_(this),
|
||||||
|
backing_(new SkBitmap),
|
||||||
weak_ptr_factory_(this) {
|
weak_ptr_factory_(this) {
|
||||||
DCHECK(render_widget_host_);
|
DCHECK(render_widget_host_);
|
||||||
bool is_guest_view_hack = parent_host_view_ != nullptr;
|
bool is_guest_view_hack = parent_host_view_ != nullptr;
|
||||||
|
|
||||||
current_device_scale_factor_ = kDefaultScaleFactor;
|
current_device_scale_factor_ = kDefaultScaleFactor;
|
||||||
|
|
||||||
#if !defined(OS_MACOSX)
|
delegated_frame_host_allocator_.GenerateId();
|
||||||
local_surface_id_allocator_.GenerateId();
|
delegated_frame_host_allocation_ =
|
||||||
local_surface_id_allocation_ =
|
delegated_frame_host_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
||||||
local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
compositor_allocator_.GenerateId();
|
||||||
|
compositor_allocation_ =
|
||||||
|
compositor_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
||||||
|
|
||||||
delegated_frame_host_client_.reset(new AtomDelegatedFrameHostClient(this));
|
delegated_frame_host_client_.reset(new AtomDelegatedFrameHostClient(this));
|
||||||
delegated_frame_host_ = std::make_unique<content::DelegatedFrameHost>(
|
delegated_frame_host_ = std::make_unique<content::DelegatedFrameHost>(
|
||||||
AllocateFrameSinkId(is_guest_view_hack),
|
AllocateFrameSinkId(is_guest_view_hack),
|
||||||
|
@ -335,59 +238,49 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||||
true /* should_register_frame_sink_id */);
|
true /* should_register_frame_sink_id */);
|
||||||
|
|
||||||
root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
|
root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
last_frame_root_background_color_ = SK_ColorTRANSPARENT;
|
|
||||||
CreatePlatformWidget(is_guest_view_hack);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool opaque = SkColorGetA(background_color_) == SK_AlphaOPAQUE;
|
bool opaque = SkColorGetA(background_color_) == SK_AlphaOPAQUE;
|
||||||
GetRootLayer()->SetFillsBoundsOpaquely(opaque);
|
GetRootLayer()->SetFillsBoundsOpaquely(opaque);
|
||||||
GetRootLayer()->SetColor(background_color_);
|
GetRootLayer()->SetColor(background_color_);
|
||||||
|
|
||||||
#if !defined(OS_MACOSX)
|
|
||||||
// On macOS the ui::Compositor is created/owned by the platform view.
|
|
||||||
content::ImageTransportFactory* factory =
|
content::ImageTransportFactory* factory =
|
||||||
content::ImageTransportFactory::GetInstance();
|
content::ImageTransportFactory::GetInstance();
|
||||||
|
|
||||||
ui::ContextFactoryPrivate* context_factory_private =
|
ui::ContextFactoryPrivate* context_factory_private =
|
||||||
factory->GetContextFactoryPrivate();
|
factory->GetContextFactoryPrivate();
|
||||||
compositor_.reset(new ui::Compositor(
|
compositor_.reset(
|
||||||
context_factory_private->AllocateFrameSinkId(),
|
new ui::Compositor(context_factory_private->AllocateFrameSinkId(),
|
||||||
content::GetContextFactory(), context_factory_private,
|
content::GetContextFactory(), context_factory_private,
|
||||||
base::ThreadTaskRunnerHandle::Get(), false /* enable_pixel_canvas */));
|
base::ThreadTaskRunnerHandle::Get(),
|
||||||
|
false /* enable_pixel_canvas */, this));
|
||||||
compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
|
compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
|
||||||
compositor_->SetRootLayer(root_layer_.get());
|
compositor_->SetRootLayer(root_layer_.get());
|
||||||
#endif
|
|
||||||
GetCompositor()->SetDelegate(this);
|
GetCompositor()->SetDelegate(this);
|
||||||
|
|
||||||
ResizeRootLayer(false);
|
ResizeRootLayer(false);
|
||||||
render_widget_host_->SetView(this);
|
render_widget_host_->SetView(this);
|
||||||
InstallTransparency();
|
InstallTransparency();
|
||||||
|
|
||||||
|
if (content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled()) {
|
||||||
|
video_consumer_.reset(new OffScreenVideoConsumer(
|
||||||
|
this, base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
|
||||||
|
weak_ptr_factory_.GetWeakPtr())));
|
||||||
|
video_consumer_->SetActive(IsPainting());
|
||||||
|
video_consumer_->SetFrameRate(GetFrameRate());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() {
|
OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() {
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
if (is_showing_)
|
|
||||||
browser_compositor_->SetRenderWidgetHostIsHidden(true);
|
|
||||||
#else
|
|
||||||
// Marking the DelegatedFrameHost as removed from the window hierarchy is
|
// Marking the DelegatedFrameHost as removed from the window hierarchy is
|
||||||
// necessary to remove all connections to its old ui::Compositor.
|
// necessary to remove all connections to its old ui::Compositor.
|
||||||
if (is_showing_)
|
if (is_showing_)
|
||||||
delegated_frame_host_->WasHidden();
|
delegated_frame_host_->WasHidden();
|
||||||
delegated_frame_host_->DetachFromCompositor();
|
delegated_frame_host_->DetachFromCompositor();
|
||||||
#endif
|
|
||||||
|
|
||||||
if (copy_frame_generator_.get())
|
|
||||||
copy_frame_generator_.reset(NULL);
|
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
DestroyPlatformWidget();
|
|
||||||
#else
|
|
||||||
delegated_frame_host_.reset(NULL);
|
delegated_frame_host_.reset(NULL);
|
||||||
compositor_.reset(NULL);
|
compositor_.reset(NULL);
|
||||||
root_layer_.reset(NULL);
|
root_layer_.reset(NULL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
content::BrowserAccessibilityManager*
|
content::BrowserAccessibilityManager*
|
||||||
|
@ -422,8 +315,17 @@ void OffScreenRenderWidgetHostView::SendBeginFrame(
|
||||||
DCHECK(begin_frame_args.IsValid());
|
DCHECK(begin_frame_args.IsValid());
|
||||||
begin_frame_number_++;
|
begin_frame_number_++;
|
||||||
|
|
||||||
if (renderer_compositor_frame_sink_)
|
compositor_->context_factory_private()->IssueExternalBeginFrame(
|
||||||
renderer_compositor_frame_sink_->OnBeginFrame(begin_frame_args, {});
|
compositor_.get(), begin_frame_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffScreenRenderWidgetHostView::OnDisplayDidFinishFrame(
|
||||||
|
const viz::BeginFrameAck& ack) {}
|
||||||
|
|
||||||
|
void OffScreenRenderWidgetHostView::OnNeedsExternalBeginFrames(
|
||||||
|
bool needs_begin_frames) {
|
||||||
|
SetupFrameRate(true);
|
||||||
|
begin_frame_timer_->SetActive(needs_begin_frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
|
void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
|
||||||
|
@ -437,7 +339,7 @@ void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
|
||||||
parent_host_view_->Hide();
|
parent_host_view_->Hide();
|
||||||
|
|
||||||
ResizeRootLayer(false);
|
ResizeRootLayer(false);
|
||||||
Show();
|
SetPainting(parent_host_view_->IsPainting());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::SetSize(const gfx::Size& size) {
|
void OffScreenRenderWidgetHostView::SetSize(const gfx::Size& size) {
|
||||||
|
@ -478,14 +380,10 @@ void OffScreenRenderWidgetHostView::Show() {
|
||||||
|
|
||||||
is_showing_ = true;
|
is_showing_ = true;
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
browser_compositor_->SetRenderWidgetHostIsHidden(false);
|
|
||||||
#else
|
|
||||||
delegated_frame_host_->AttachToCompositor(compositor_.get());
|
delegated_frame_host_->AttachToCompositor(compositor_.get());
|
||||||
delegated_frame_host_->WasShown(
|
delegated_frame_host_->WasShown(
|
||||||
GetLocalSurfaceIdAllocation().local_surface_id(),
|
GetLocalSurfaceIdAllocation().local_surface_id(),
|
||||||
GetRootLayer()->bounds().size(), false);
|
GetRootLayer()->bounds().size(), false);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (render_widget_host_)
|
if (render_widget_host_)
|
||||||
render_widget_host_->WasShown(false);
|
render_widget_host_->WasShown(false);
|
||||||
|
@ -498,12 +396,8 @@ void OffScreenRenderWidgetHostView::Hide() {
|
||||||
if (render_widget_host_)
|
if (render_widget_host_)
|
||||||
render_widget_host_->WasHidden();
|
render_widget_host_->WasHidden();
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
browser_compositor_->SetRenderWidgetHostIsHidden(true);
|
|
||||||
#else
|
|
||||||
GetDelegatedFrameHost()->WasHidden();
|
GetDelegatedFrameHost()->WasHidden();
|
||||||
GetDelegatedFrameHost()->DetachFromCompositor();
|
GetDelegatedFrameHost()->DetachFromCompositor();
|
||||||
#endif
|
|
||||||
|
|
||||||
is_showing_ = false;
|
is_showing_ = false;
|
||||||
}
|
}
|
||||||
|
@ -576,67 +470,17 @@ void OffScreenRenderWidgetHostView::DidCreateNewRendererCompositorFrameSink(
|
||||||
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
|
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
|
||||||
renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
|
renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
browser_compositor_->DidCreateNewRendererCompositorFrameSink(
|
|
||||||
renderer_compositor_frame_sink_);
|
|
||||||
#else
|
|
||||||
if (GetDelegatedFrameHost()) {
|
if (GetDelegatedFrameHost()) {
|
||||||
GetDelegatedFrameHost()->DidCreateNewRendererCompositorFrameSink(
|
GetDelegatedFrameHost()->DidCreateNewRendererCompositorFrameSink(
|
||||||
renderer_compositor_frame_sink_);
|
renderer_compositor_frame_sink_);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
|
void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
|
||||||
const viz::LocalSurfaceId& local_surface_id,
|
const viz::LocalSurfaceId& local_surface_id,
|
||||||
viz::CompositorFrame frame,
|
viz::CompositorFrame frame,
|
||||||
base::Optional<viz::HitTestRegionList> hit_test_region_list) {
|
base::Optional<viz::HitTestRegionList> hit_test_region_list) {
|
||||||
#if defined(OS_MACOSX)
|
NOTREACHED();
|
||||||
last_frame_root_background_color_ = frame.metadata.root_background_color;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (frame.metadata.root_scroll_offset != last_scroll_offset_) {
|
|
||||||
last_scroll_offset_ = frame.metadata.root_scroll_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!frame.render_pass_list.empty()) {
|
|
||||||
if (software_output_device_) {
|
|
||||||
if (!begin_frame_timer_.get() || IsPopupWidget()) {
|
|
||||||
software_output_device_->SetActive(painting_, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The compositor will draw directly to the SoftwareOutputDevice which
|
|
||||||
// then calls OnPaint.
|
|
||||||
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
|
|
||||||
// macOS, however it contains compositor resize logic that we don't want.
|
|
||||||
// Consequently we instead call the SubmitCompositorFrame method directly.
|
|
||||||
GetDelegatedFrameHost()->SubmitCompositorFrame(
|
|
||||||
local_surface_id, std::move(frame), std::move(hit_test_region_list));
|
|
||||||
} else {
|
|
||||||
if (!copy_frame_generator_.get()) {
|
|
||||||
copy_frame_generator_.reset(
|
|
||||||
new AtomCopyFrameGenerator(this, frame_rate_threshold_us_));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the damage rectangle for the current frame. This is the same
|
|
||||||
// calculation that SwapDelegatedFrame uses.
|
|
||||||
viz::RenderPass* root_pass = frame.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));
|
|
||||||
|
|
||||||
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
|
|
||||||
// macOS, however it contains compositor resize logic that we don't want.
|
|
||||||
// Consequently we instead call the SubmitCompositorFrame method directly.
|
|
||||||
GetDelegatedFrameHost()->SubmitCompositorFrame(
|
|
||||||
local_surface_id, std::move(frame), std::move(hit_test_region_list));
|
|
||||||
|
|
||||||
// Request a copy of the last compositor frame which will eventually call
|
|
||||||
// OnPaint asynchronously.
|
|
||||||
copy_frame_generator_->GenerateCopyFrame(damage_rect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::ClearCompositorFrame() {
|
void OffScreenRenderWidgetHostView::ClearCompositorFrame() {
|
||||||
|
@ -651,13 +495,13 @@ void OffScreenRenderWidgetHostView::InitAsPopup(
|
||||||
content::RenderWidgetHostView* parent_host_view,
|
content::RenderWidgetHostView* parent_host_view,
|
||||||
const gfx::Rect& pos) {
|
const gfx::Rect& pos) {
|
||||||
DCHECK_EQ(parent_host_view_, parent_host_view);
|
DCHECK_EQ(parent_host_view_, parent_host_view);
|
||||||
|
DCHECK_EQ(widget_type_, content::WidgetType::kPopup);
|
||||||
|
|
||||||
if (parent_host_view_->popup_host_view_) {
|
if (parent_host_view_->popup_host_view_) {
|
||||||
parent_host_view_->popup_host_view_->CancelWidget();
|
parent_host_view_->popup_host_view_->CancelWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
parent_host_view_->set_popup_host_view(this);
|
parent_host_view_->set_popup_host_view(this);
|
||||||
parent_host_view_->popup_bitmap_.reset(new SkBitmap);
|
|
||||||
parent_callback_ =
|
parent_callback_ =
|
||||||
base::Bind(&OffScreenRenderWidgetHostView::OnPopupPaint,
|
base::Bind(&OffScreenRenderWidgetHostView::OnPopupPaint,
|
||||||
parent_host_view_->weak_ptr_factory_.GetWeakPtr());
|
parent_host_view_->weak_ptr_factory_.GetWeakPtr());
|
||||||
|
@ -665,6 +509,10 @@ void OffScreenRenderWidgetHostView::InitAsPopup(
|
||||||
popup_position_ = pos;
|
popup_position_ = pos;
|
||||||
|
|
||||||
ResizeRootLayer(false);
|
ResizeRootLayer(false);
|
||||||
|
SetPainting(parent_host_view_->IsPainting());
|
||||||
|
if (video_consumer_) {
|
||||||
|
video_consumer_->SizeChanged();
|
||||||
|
}
|
||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,7 +546,6 @@ void OffScreenRenderWidgetHostView::Destroy() {
|
||||||
} else {
|
} else {
|
||||||
if (popup_host_view_)
|
if (popup_host_view_)
|
||||||
popup_host_view_->CancelWidget();
|
popup_host_view_->CancelWidget();
|
||||||
popup_bitmap_.reset();
|
|
||||||
if (child_host_view_)
|
if (child_host_view_)
|
||||||
child_host_view_->CancelWidget();
|
child_host_view_->CancelWidget();
|
||||||
if (!guest_host_views_.empty()) {
|
if (!guest_host_views_.empty()) {
|
||||||
|
@ -748,6 +595,7 @@ void OffScreenRenderWidgetHostView::InitAsGuest(
|
||||||
content::RenderWidgetHostView* parent_host_view,
|
content::RenderWidgetHostView* parent_host_view,
|
||||||
content::RenderWidgetHostViewGuest* guest_view) {
|
content::RenderWidgetHostViewGuest* guest_view) {
|
||||||
parent_host_view_->AddGuestHostView(this);
|
parent_host_view_->AddGuestHostView(this);
|
||||||
|
SetPainting(parent_host_view_->IsPainting());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::TransformPointToRootSurface(
|
void OffScreenRenderWidgetHostView::TransformPointToRootSurface(
|
||||||
|
@ -763,6 +611,12 @@ viz::SurfaceId OffScreenRenderWidgetHostView::GetCurrentSurfaceId() const {
|
||||||
: viz::SurfaceId();
|
: viz::SurfaceId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<content::SyntheticGestureTarget>
|
||||||
|
OffScreenRenderWidgetHostView::CreateSyntheticGestureTarget() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::ImeCompositionRangeChanged(
|
void OffScreenRenderWidgetHostView::ImeCompositionRangeChanged(
|
||||||
const gfx::Range&,
|
const gfx::Range&,
|
||||||
const std::vector<gfx::Rect>&) {}
|
const std::vector<gfx::Rect>&) {}
|
||||||
|
@ -800,12 +654,8 @@ const viz::FrameSinkId& OffScreenRenderWidgetHostView::GetFrameSinkId() const {
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::DidNavigate() {
|
void OffScreenRenderWidgetHostView::DidNavigate() {
|
||||||
ResizeRootLayer(true);
|
ResizeRootLayer(true);
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
browser_compositor_->DidNavigate();
|
|
||||||
#else
|
|
||||||
if (delegated_frame_host_)
|
if (delegated_frame_host_)
|
||||||
delegated_frame_host_->DidNavigate();
|
delegated_frame_host_->DidNavigate();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OffScreenRenderWidgetHostView::TransformPointToLocalCoordSpaceLegacy(
|
bool OffScreenRenderWidgetHostView::TransformPointToLocalCoordSpaceLegacy(
|
||||||
|
@ -829,8 +679,7 @@ bool OffScreenRenderWidgetHostView::TransformPointToLocalCoordSpaceLegacy(
|
||||||
bool OffScreenRenderWidgetHostView::TransformPointToCoordSpaceForView(
|
bool OffScreenRenderWidgetHostView::TransformPointToCoordSpaceForView(
|
||||||
const gfx::PointF& point,
|
const gfx::PointF& point,
|
||||||
RenderWidgetHostViewBase* target_view,
|
RenderWidgetHostViewBase* target_view,
|
||||||
gfx::PointF* transformed_point,
|
gfx::PointF* transformed_point) {
|
||||||
viz::EventSource source) {
|
|
||||||
if (target_view == this) {
|
if (target_view == this) {
|
||||||
*transformed_point = point;
|
*transformed_point = point;
|
||||||
return true;
|
return true;
|
||||||
|
@ -847,7 +696,6 @@ void OffScreenRenderWidgetHostView::CancelWidget() {
|
||||||
if (parent_host_view_) {
|
if (parent_host_view_) {
|
||||||
if (parent_host_view_->popup_host_view_ == this) {
|
if (parent_host_view_->popup_host_view_ == this) {
|
||||||
parent_host_view_->set_popup_host_view(NULL);
|
parent_host_view_->set_popup_host_view(NULL);
|
||||||
parent_host_view_->popup_bitmap_.reset();
|
|
||||||
} else if (parent_host_view_->child_host_view_ == this) {
|
} else if (parent_host_view_->child_host_view_ == this) {
|
||||||
parent_host_view_->set_child_host_view(NULL);
|
parent_host_view_->set_child_host_view(NULL);
|
||||||
parent_host_view_->Show();
|
parent_host_view_->Show();
|
||||||
|
@ -890,29 +738,21 @@ void OffScreenRenderWidgetHostView::ProxyViewDestroyed(
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<viz::SoftwareOutputDevice>
|
std::unique_ptr<viz::HostDisplayClient>
|
||||||
OffScreenRenderWidgetHostView::CreateSoftwareOutputDevice(
|
OffScreenRenderWidgetHostView::CreateHostDisplayClient(
|
||||||
ui::Compositor* compositor) {
|
ui::Compositor* compositor) {
|
||||||
DCHECK_EQ(GetCompositor(), compositor);
|
host_display_client_ = new OffScreenHostDisplayClient(
|
||||||
DCHECK(!copy_frame_generator_);
|
gfx::kNullAcceleratedWidget,
|
||||||
DCHECK(!software_output_device_);
|
base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
|
||||||
|
weak_ptr_factory_.GetWeakPtr()));
|
||||||
ResizeRootLayer(false);
|
host_display_client_->SetActive(IsPainting());
|
||||||
|
return base::WrapUnique(host_display_client_);
|
||||||
software_output_device_ = new OffScreenOutputDevice(
|
|
||||||
transparent_, base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
|
|
||||||
weak_ptr_factory_.GetWeakPtr()));
|
|
||||||
return base::WrapUnique(software_output_device_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OffScreenRenderWidgetHostView::InstallTransparency() {
|
bool OffScreenRenderWidgetHostView::InstallTransparency() {
|
||||||
if (transparent_) {
|
if (transparent_) {
|
||||||
SetBackgroundColor(SkColor());
|
SetBackgroundColor(SkColor());
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
browser_compositor_->SetBackgroundColor(SK_ColorTRANSPARENT);
|
|
||||||
#else
|
|
||||||
compositor_->SetBackgroundColor(SK_ColorTRANSPARENT);
|
compositor_->SetBackgroundColor(SK_ColorTRANSPARENT);
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -921,76 +761,99 @@ bool OffScreenRenderWidgetHostView::InstallTransparency() {
|
||||||
void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
|
void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
|
||||||
bool needs_begin_frames) {
|
bool needs_begin_frames) {
|
||||||
SetupFrameRate(true);
|
SetupFrameRate(true);
|
||||||
|
|
||||||
begin_frame_timer_->SetActive(needs_begin_frames);
|
begin_frame_timer_->SetActive(needs_begin_frames);
|
||||||
|
|
||||||
if (software_output_device_) {
|
|
||||||
software_output_device_->SetActive(painting_, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::SetWantsAnimateOnlyBeginFrames() {
|
void OffScreenRenderWidgetHostView::SetWantsAnimateOnlyBeginFrames() {}
|
||||||
if (GetDelegatedFrameHost()) {
|
|
||||||
GetDelegatedFrameHost()->SetWantsAnimateOnlyBeginFrames();
|
#if defined(OS_MACOSX)
|
||||||
}
|
void OffScreenRenderWidgetHostView::SetActive(bool active) {}
|
||||||
|
|
||||||
|
void OffScreenRenderWidgetHostView::ShowDefinitionForSelection() {}
|
||||||
|
|
||||||
|
void OffScreenRenderWidgetHostView::SpeakSelection() {}
|
||||||
|
|
||||||
|
bool OffScreenRenderWidgetHostView::UpdateNSViewAndDisplay() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::OnPaint(const gfx::Rect& damage_rect,
|
void OffScreenRenderWidgetHostView::OnPaint(const gfx::Rect& damage_rect,
|
||||||
const SkBitmap& bitmap) {
|
const SkBitmap& bitmap) {
|
||||||
|
backing_.reset(new SkBitmap());
|
||||||
|
backing_->allocN32Pixels(bitmap.width(), bitmap.height(), !transparent_);
|
||||||
|
bitmap.readPixels(backing_->pixmap());
|
||||||
|
|
||||||
|
if (IsPopupWidget() && parent_callback_) {
|
||||||
|
parent_callback_.Run(this->popup_position_);
|
||||||
|
} else {
|
||||||
|
CompositeFrame(damage_rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::Size OffScreenRenderWidgetHostView::SizeInPixels() {
|
||||||
|
if (IsPopupWidget()) {
|
||||||
|
return gfx::ConvertSizeToPixel(current_device_scale_factor_,
|
||||||
|
popup_position_.size());
|
||||||
|
} else {
|
||||||
|
return gfx::ConvertSizeToPixel(current_device_scale_factor_,
|
||||||
|
GetViewBounds().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffScreenRenderWidgetHostView::CompositeFrame(
|
||||||
|
const gfx::Rect& damage_rect) {
|
||||||
HoldResize();
|
HoldResize();
|
||||||
|
|
||||||
if (parent_callback_) {
|
gfx::Size size_in_pixels = SizeInPixels();
|
||||||
parent_callback_.Run(damage_rect, bitmap);
|
|
||||||
|
SkBitmap frame;
|
||||||
|
|
||||||
|
// Optimize for the case when there is no popup
|
||||||
|
if (proxy_views_.size() == 0 && !popup_host_view_) {
|
||||||
|
frame = GetBacking();
|
||||||
} else {
|
} else {
|
||||||
gfx::Rect damage(damage_rect);
|
frame.allocN32Pixels(size_in_pixels.width(), size_in_pixels.height(),
|
||||||
|
false);
|
||||||
|
if (!GetBacking().drawsNothing()) {
|
||||||
|
SkCanvas canvas(frame);
|
||||||
|
canvas.writePixels(GetBacking(), 0, 0);
|
||||||
|
|
||||||
gfx::Size size_in_pixels = gfx::ConvertSizeToPixel(
|
if (popup_host_view_ && !popup_host_view_->GetBacking().drawsNothing()) {
|
||||||
current_device_scale_factor_, GetViewBounds().size());
|
gfx::Rect rect = popup_host_view_->popup_position_;
|
||||||
|
gfx::Point origin_in_pixels = gfx::ConvertPointToPixel(
|
||||||
|
current_device_scale_factor_, rect.origin());
|
||||||
|
canvas.writePixels(popup_host_view_->GetBacking(), origin_in_pixels.x(),
|
||||||
|
origin_in_pixels.y());
|
||||||
|
}
|
||||||
|
|
||||||
SkBitmap backing;
|
for (auto* proxy_view : proxy_views_) {
|
||||||
backing.allocN32Pixels(size_in_pixels.width(), size_in_pixels.height(),
|
gfx::Rect rect = proxy_view->GetBounds();
|
||||||
false);
|
gfx::Point origin_in_pixels = gfx::ConvertPointToPixel(
|
||||||
SkCanvas canvas(backing);
|
current_device_scale_factor_, rect.origin());
|
||||||
|
canvas.writePixels(*proxy_view->GetBitmap(), origin_in_pixels.x(),
|
||||||
canvas.writePixels(bitmap, 0, 0);
|
origin_in_pixels.y());
|
||||||
|
}
|
||||||
if (popup_host_view_ && popup_bitmap_.get()) {
|
|
||||||
gfx::Rect rect = popup_host_view_->popup_position_;
|
|
||||||
gfx::Point origin_in_pixels =
|
|
||||||
gfx::ConvertPointToPixel(current_device_scale_factor_, rect.origin());
|
|
||||||
damage.Union(rect);
|
|
||||||
canvas.writePixels(*popup_bitmap_.get(), origin_in_pixels.x(),
|
|
||||||
origin_in_pixels.y());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto* proxy_view : proxy_views_) {
|
|
||||||
gfx::Rect rect = proxy_view->GetBounds();
|
|
||||||
gfx::Point origin_in_pixels =
|
|
||||||
gfx::ConvertPointToPixel(current_device_scale_factor_, rect.origin());
|
|
||||||
damage.Union(rect);
|
|
||||||
canvas.writePixels(*proxy_view->GetBitmap(), origin_in_pixels.x(),
|
|
||||||
origin_in_pixels.y());
|
|
||||||
}
|
|
||||||
|
|
||||||
damage.Intersect(GetViewBounds());
|
|
||||||
paint_callback_running_ = true;
|
|
||||||
callback_.Run(damage, backing);
|
|
||||||
paint_callback_running_ = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
paint_callback_running_ = true;
|
||||||
|
callback_.Run(gfx::IntersectRects(gfx::Rect(size_in_pixels), damage_rect),
|
||||||
|
frame);
|
||||||
|
paint_callback_running_ = false;
|
||||||
|
|
||||||
ReleaseResize();
|
ReleaseResize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::OnPopupPaint(const gfx::Rect& damage_rect,
|
void OffScreenRenderWidgetHostView::OnPopupPaint(const gfx::Rect& damage_rect) {
|
||||||
const SkBitmap& bitmap) {
|
InvalidateBounds(
|
||||||
if (popup_host_view_ && popup_bitmap_.get())
|
gfx::ConvertRectToPixel(current_device_scale_factor_, damage_rect));
|
||||||
popup_bitmap_.reset(new SkBitmap(bitmap));
|
|
||||||
InvalidateBounds(popup_host_view_->popup_position_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::OnProxyViewPaint(
|
void OffScreenRenderWidgetHostView::OnProxyViewPaint(
|
||||||
const gfx::Rect& damage_rect) {
|
const gfx::Rect& damage_rect) {
|
||||||
InvalidateBounds(damage_rect);
|
InvalidateBounds(
|
||||||
|
gfx::ConvertRectToPixel(current_device_scale_factor_, damage_rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::HoldResize() {
|
void OffScreenRenderWidgetHostView::HoldResize() {
|
||||||
|
@ -1020,7 +883,7 @@ void OffScreenRenderWidgetHostView::SynchronizeVisualProperties() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResizeRootLayer(false);
|
ResizeRootLayer(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::SendMouseEvent(
|
void OffScreenRenderWidgetHostView::SendMouseEvent(
|
||||||
|
@ -1147,8 +1010,17 @@ void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
|
||||||
void OffScreenRenderWidgetHostView::SetPainting(bool painting) {
|
void OffScreenRenderWidgetHostView::SetPainting(bool painting) {
|
||||||
painting_ = painting;
|
painting_ = painting;
|
||||||
|
|
||||||
if (software_output_device_) {
|
if (popup_host_view_) {
|
||||||
software_output_device_->SetActive(painting_, !paint_callback_running_);
|
popup_host_view_->SetPainting(painting);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto* guest_host_view : guest_host_views_)
|
||||||
|
guest_host_view->SetPainting(painting);
|
||||||
|
|
||||||
|
if (video_consumer_) {
|
||||||
|
video_consumer_->SetActive(IsPainting());
|
||||||
|
} else if (host_display_client_) {
|
||||||
|
host_display_client_->SetActive(IsPainting());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1173,6 +1045,10 @@ void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) {
|
||||||
|
|
||||||
SetupFrameRate(true);
|
SetupFrameRate(true);
|
||||||
|
|
||||||
|
if (video_consumer_) {
|
||||||
|
video_consumer_->SetFrameRate(GetFrameRate());
|
||||||
|
}
|
||||||
|
|
||||||
for (auto* guest_host_view : guest_host_views_)
|
for (auto* guest_host_view : guest_host_views_)
|
||||||
guest_host_view->SetFrameRate(frame_rate);
|
guest_host_view->SetFrameRate(frame_rate);
|
||||||
}
|
}
|
||||||
|
@ -1181,7 +1057,6 @@ int OffScreenRenderWidgetHostView::GetFrameRate() const {
|
||||||
return frame_rate_;
|
return frame_rate_;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(OS_MACOSX)
|
|
||||||
ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() const {
|
ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() const {
|
||||||
return compositor_.get();
|
return compositor_.get();
|
||||||
}
|
}
|
||||||
|
@ -1190,18 +1065,15 @@ ui::Layer* OffScreenRenderWidgetHostView::GetRootLayer() const {
|
||||||
return root_layer_.get();
|
return root_layer_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(OS_MACOSX)
|
|
||||||
const viz::LocalSurfaceIdAllocation&
|
const viz::LocalSurfaceIdAllocation&
|
||||||
OffScreenRenderWidgetHostView::GetLocalSurfaceIdAllocation() const {
|
OffScreenRenderWidgetHostView::GetLocalSurfaceIdAllocation() const {
|
||||||
return local_surface_id_allocation_;
|
return delegated_frame_host_allocation_;
|
||||||
}
|
}
|
||||||
#endif // defined(OS_MACOSX)
|
|
||||||
|
|
||||||
content::DelegatedFrameHost*
|
content::DelegatedFrameHost*
|
||||||
OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
|
OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
|
||||||
return delegated_frame_host_.get();
|
return delegated_frame_host_.get();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
||||||
if (!force && frame_rate_threshold_us_ != 0)
|
if (!force && frame_rate_threshold_us_ != 0)
|
||||||
|
@ -1209,11 +1081,6 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
||||||
|
|
||||||
frame_rate_threshold_us_ = 1000000 / frame_rate_;
|
frame_rate_threshold_us_ = 1000000 / frame_rate_;
|
||||||
|
|
||||||
if (copy_frame_generator_.get()) {
|
|
||||||
copy_frame_generator_->set_frame_rate_threshold_us(
|
|
||||||
frame_rate_threshold_us_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (begin_frame_timer_.get()) {
|
if (begin_frame_timer_.get()) {
|
||||||
begin_frame_timer_->SetFrameRateThresholdUs(frame_rate_threshold_us_);
|
begin_frame_timer_->SetFrameRateThresholdUs(frame_rate_threshold_us_);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1225,15 +1092,11 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::Invalidate() {
|
void OffScreenRenderWidgetHostView::Invalidate() {
|
||||||
InvalidateBounds(GetViewBounds());
|
InvalidateBounds(gfx::Rect(GetRequestedRendererSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::InvalidateBounds(const gfx::Rect& bounds) {
|
void OffScreenRenderWidgetHostView::InvalidateBounds(const gfx::Rect& bounds) {
|
||||||
if (software_output_device_) {
|
CompositeFrame(bounds);
|
||||||
software_output_device_->OnPaint(bounds);
|
|
||||||
} else if (copy_frame_generator_) {
|
|
||||||
copy_frame_generator_->GenerateCopyFrame(bounds);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
|
void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
|
||||||
|
@ -1259,23 +1122,24 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
|
||||||
|
|
||||||
GetRootLayer()->SetBounds(gfx::Rect(size));
|
GetRootLayer()->SetBounds(gfx::Rect(size));
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
bool resized = UpdateNSViewAndDisplay();
|
|
||||||
#else
|
|
||||||
const gfx::Size& size_in_pixels =
|
const gfx::Size& size_in_pixels =
|
||||||
gfx::ConvertSizeToPixel(current_device_scale_factor_, size);
|
gfx::ConvertSizeToPixel(current_device_scale_factor_, size);
|
||||||
|
|
||||||
local_surface_id_allocator_.GenerateId();
|
compositor_allocator_.GenerateId();
|
||||||
local_surface_id_allocation_ =
|
compositor_allocation_ =
|
||||||
local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
compositor_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
||||||
|
|
||||||
GetCompositor()->SetScaleAndSize(current_device_scale_factor_, size_in_pixels,
|
GetCompositor()->SetScaleAndSize(current_device_scale_factor_, size_in_pixels,
|
||||||
local_surface_id_allocation_);
|
compositor_allocation_);
|
||||||
|
|
||||||
|
delegated_frame_host_allocator_.GenerateId();
|
||||||
|
delegated_frame_host_allocation_ =
|
||||||
|
delegated_frame_host_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
||||||
|
|
||||||
bool resized = true;
|
bool resized = true;
|
||||||
GetDelegatedFrameHost()->EmbedSurface(
|
GetDelegatedFrameHost()->EmbedSurface(
|
||||||
local_surface_id_allocation_.local_surface_id(), size,
|
delegated_frame_host_allocation_.local_surface_id(), size,
|
||||||
cc::DeadlinePolicy::UseDefaultDeadline());
|
cc::DeadlinePolicy::UseDefaultDeadline());
|
||||||
#endif
|
|
||||||
|
|
||||||
// Note that |render_widget_host_| will retrieve resize parameters from the
|
// Note that |render_widget_host_| will retrieve resize parameters from the
|
||||||
// DelegatedFrameHost, so it must have SynchronizeVisualProperties called
|
// DelegatedFrameHost, so it must have SynchronizeVisualProperties called
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "atom/browser/osr/osr_output_device.h"
|
#include "atom/browser/osr/osr_host_display_client.h"
|
||||||
|
#include "atom/browser/osr/osr_video_consumer.h"
|
||||||
#include "atom/browser/osr/osr_view_proxy.h"
|
#include "atom/browser/osr/osr_view_proxy.h"
|
||||||
#include "base/process/kill.h"
|
#include "base/process/kill.h"
|
||||||
#include "base/threading/thread.h"
|
#include "base/threading/thread.h"
|
||||||
|
@ -23,12 +24,12 @@
|
||||||
#include "components/viz/common/frame_sinks/begin_frame_source.h"
|
#include "components/viz/common/frame_sinks/begin_frame_source.h"
|
||||||
#include "components/viz/common/quads/compositor_frame.h"
|
#include "components/viz/common/quads/compositor_frame.h"
|
||||||
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
|
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
|
||||||
#include "content/browser/frame_host/render_widget_host_view_guest.h"
|
#include "content/browser/frame_host/render_widget_host_view_guest.h" // nogncheck
|
||||||
#include "content/browser/renderer_host/delegated_frame_host.h"
|
#include "content/browser/renderer_host/delegated_frame_host.h" // nogncheck
|
||||||
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
|
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h" // nogncheck
|
||||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
#include "content/browser/renderer_host/render_widget_host_impl.h" // nogncheck
|
||||||
#include "content/browser/renderer_host/render_widget_host_view_base.h"
|
#include "content/browser/renderer_host/render_widget_host_view_base.h" // nogncheck
|
||||||
#include "content/browser/web_contents/web_contents_view.h"
|
#include "content/browser/web_contents/web_contents_view.h" // nogncheck
|
||||||
#include "third_party/blink/public/platform/web_vector.h"
|
#include "third_party/blink/public/platform/web_vector.h"
|
||||||
#include "third_party/skia/include/core/SkBitmap.h"
|
#include "third_party/skia/include/core/SkBitmap.h"
|
||||||
#include "ui/base/ime/text_input_client.h"
|
#include "ui/base/ime/text_input_client.h"
|
||||||
|
@ -37,24 +38,13 @@
|
||||||
#include "ui/compositor/layer_owner.h"
|
#include "ui/compositor/layer_owner.h"
|
||||||
#include "ui/gfx/geometry/point.h"
|
#include "ui/gfx/geometry/point.h"
|
||||||
|
|
||||||
|
#include "components/viz/host/host_display_client.h"
|
||||||
|
#include "ui/compositor/external_begin_frame_client.h"
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
#include "ui/gfx/win/window_impl.h"
|
#include "ui/gfx/win/window_impl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
#include "content/browser/renderer_host/browser_compositor_view_mac.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
#ifdef __OBJC__
|
|
||||||
@class CALayer;
|
|
||||||
@class NSWindow;
|
|
||||||
#else
|
|
||||||
class CALayer;
|
|
||||||
class NSWindow;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace content {
|
namespace content {
|
||||||
class CursorManager;
|
class CursorManager;
|
||||||
} // namespace content
|
} // namespace content
|
||||||
|
@ -64,13 +54,13 @@ namespace atom {
|
||||||
class AtomCopyFrameGenerator;
|
class AtomCopyFrameGenerator;
|
||||||
class AtomBeginFrameTimer;
|
class AtomBeginFrameTimer;
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
class MacHelper;
|
|
||||||
#else
|
|
||||||
class AtomDelegatedFrameHostClient;
|
class AtomDelegatedFrameHostClient;
|
||||||
#endif
|
|
||||||
|
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
|
||||||
|
typedef base::Callback<void(const gfx::Rect&)> OnPopupPaintCallback;
|
||||||
|
|
||||||
class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||||
|
public ui::ExternalBeginFrameClient,
|
||||||
public ui::CompositorDelegate,
|
public ui::CompositorDelegate,
|
||||||
public OffscreenViewProxyObserver {
|
public OffscreenViewProxyObserver {
|
||||||
public:
|
public:
|
||||||
|
@ -87,6 +77,9 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||||
content::BrowserAccessibilityDelegate*,
|
content::BrowserAccessibilityDelegate*,
|
||||||
bool) override;
|
bool) override;
|
||||||
|
|
||||||
|
void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) override;
|
||||||
|
void OnNeedsExternalBeginFrames(bool needs_begin_frames) override;
|
||||||
|
|
||||||
// content::RenderWidgetHostView:
|
// content::RenderWidgetHostView:
|
||||||
void InitAsChild(gfx::NativeView) override;
|
void InitAsChild(gfx::NativeView) override;
|
||||||
void SetSize(const gfx::Size&) override;
|
void SetSize(const gfx::Size&) override;
|
||||||
|
@ -152,15 +145,12 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||||
void TransformPointToRootSurface(gfx::PointF* point) override;
|
void TransformPointToRootSurface(gfx::PointF* point) override;
|
||||||
gfx::Rect GetBoundsInRootWindow(void) override;
|
gfx::Rect GetBoundsInRootWindow(void) override;
|
||||||
viz::SurfaceId GetCurrentSurfaceId() const override;
|
viz::SurfaceId GetCurrentSurfaceId() const override;
|
||||||
|
std::unique_ptr<content::SyntheticGestureTarget>
|
||||||
|
CreateSyntheticGestureTarget() override;
|
||||||
void ImeCompositionRangeChanged(const gfx::Range&,
|
void ImeCompositionRangeChanged(const gfx::Range&,
|
||||||
const std::vector<gfx::Rect>&) override;
|
const std::vector<gfx::Rect>&) override;
|
||||||
gfx::Size GetCompositorViewportPixelSize() const override;
|
gfx::Size GetCompositorViewportPixelSize() const override;
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(
|
|
||||||
const cc::RenderFrameMetadata& metadata) override;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
content::RenderWidgetHostViewBase* CreateViewForWidget(
|
content::RenderWidgetHostViewBase* CreateViewForWidget(
|
||||||
content::RenderWidgetHost*,
|
content::RenderWidgetHost*,
|
||||||
content::RenderWidgetHost*,
|
content::RenderWidgetHost*,
|
||||||
|
@ -179,11 +169,10 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||||
bool TransformPointToCoordSpaceForView(
|
bool TransformPointToCoordSpaceForView(
|
||||||
const gfx::PointF& point,
|
const gfx::PointF& point,
|
||||||
RenderWidgetHostViewBase* target_view,
|
RenderWidgetHostViewBase* target_view,
|
||||||
gfx::PointF* transformed_point,
|
gfx::PointF* transformed_point) override;
|
||||||
viz::EventSource source = viz::EventSource::ANY) override;
|
|
||||||
|
|
||||||
// ui::CompositorDelegate:
|
// ui::CompositorDelegate:
|
||||||
std::unique_ptr<viz::SoftwareOutputDevice> CreateSoftwareOutputDevice(
|
std::unique_ptr<viz::HostDisplayClient> CreateHostDisplayClient(
|
||||||
ui::Compositor* compositor) override;
|
ui::Compositor* compositor) override;
|
||||||
|
|
||||||
bool InstallTransparency();
|
bool InstallTransparency();
|
||||||
|
@ -191,14 +180,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||||
void OnBeginFrameTimerTick();
|
void OnBeginFrameTimerTick();
|
||||||
void SendBeginFrame(base::TimeTicks frame_time, base::TimeDelta vsync_period);
|
void SendBeginFrame(base::TimeTicks frame_time, base::TimeDelta vsync_period);
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
void CreatePlatformWidget(bool is_guest_view_hack);
|
|
||||||
void DestroyPlatformWidget();
|
|
||||||
SkColor last_frame_root_background_color() const {
|
|
||||||
return last_frame_root_background_color_;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void CancelWidget();
|
void CancelWidget();
|
||||||
void AddGuestHostView(OffScreenRenderWidgetHostView* guest_host);
|
void AddGuestHostView(OffScreenRenderWidgetHostView* guest_host);
|
||||||
void RemoveGuestHostView(OffScreenRenderWidgetHostView* guest_host);
|
void RemoveGuestHostView(OffScreenRenderWidgetHostView* guest_host);
|
||||||
|
@ -207,13 +188,19 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||||
void ProxyViewDestroyed(OffscreenViewProxy* proxy) override;
|
void ProxyViewDestroyed(OffscreenViewProxy* proxy) override;
|
||||||
|
|
||||||
void OnPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
|
void OnPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
|
||||||
void OnPopupPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
|
void OnPopupPaint(const gfx::Rect& damage_rect);
|
||||||
void OnProxyViewPaint(const gfx::Rect& damage_rect) override;
|
void OnProxyViewPaint(const gfx::Rect& damage_rect) override;
|
||||||
|
|
||||||
|
gfx::Size SizeInPixels();
|
||||||
|
|
||||||
|
void CompositeFrame(const gfx::Rect& damage_rect);
|
||||||
|
|
||||||
bool IsPopupWidget() const {
|
bool IsPopupWidget() const {
|
||||||
return widget_type_ == content::WidgetType::kPopup;
|
return widget_type_ == content::WidgetType::kPopup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SkBitmap& GetBacking() { return *backing_.get(); }
|
||||||
|
|
||||||
void HoldResize();
|
void HoldResize();
|
||||||
void ReleaseResize();
|
void ReleaseResize();
|
||||||
void SynchronizeVisualProperties();
|
void SynchronizeVisualProperties();
|
||||||
|
@ -230,12 +217,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||||
ui::Compositor* GetCompositor() const;
|
ui::Compositor* GetCompositor() const;
|
||||||
ui::Layer* GetRootLayer() const;
|
ui::Layer* GetRootLayer() const;
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
content::BrowserCompositorMac* browser_compositor() const {
|
|
||||||
return browser_compositor_.get();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
content::DelegatedFrameHost* GetDelegatedFrameHost() const;
|
content::DelegatedFrameHost* GetDelegatedFrameHost() const;
|
||||||
|
|
||||||
void Invalidate();
|
void Invalidate();
|
||||||
|
@ -256,12 +237,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
display::Display GetDisplay();
|
|
||||||
void OnDidUpdateVisualPropertiesComplete(
|
|
||||||
const cc::RenderFrameMetadata& metadata);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void SetupFrameRate(bool force);
|
void SetupFrameRate(bool force);
|
||||||
void ResizeRootLayer(bool force);
|
void ResizeRootLayer(bool force);
|
||||||
|
|
||||||
|
@ -276,16 +251,13 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||||
|
|
||||||
OffScreenRenderWidgetHostView* parent_host_view_ = nullptr;
|
OffScreenRenderWidgetHostView* parent_host_view_ = nullptr;
|
||||||
OffScreenRenderWidgetHostView* popup_host_view_ = nullptr;
|
OffScreenRenderWidgetHostView* popup_host_view_ = nullptr;
|
||||||
std::unique_ptr<SkBitmap> popup_bitmap_;
|
|
||||||
OffScreenRenderWidgetHostView* child_host_view_ = nullptr;
|
OffScreenRenderWidgetHostView* child_host_view_ = nullptr;
|
||||||
std::set<OffScreenRenderWidgetHostView*> guest_host_views_;
|
std::set<OffScreenRenderWidgetHostView*> guest_host_views_;
|
||||||
std::set<OffscreenViewProxy*> proxy_views_;
|
std::set<OffscreenViewProxy*> proxy_views_;
|
||||||
|
|
||||||
OffScreenOutputDevice* software_output_device_ = nullptr;
|
|
||||||
|
|
||||||
const bool transparent_;
|
const bool transparent_;
|
||||||
OnPaintCallback callback_;
|
OnPaintCallback callback_;
|
||||||
OnPaintCallback parent_callback_;
|
OnPopupPaintCallback parent_callback_;
|
||||||
|
|
||||||
int frame_rate_ = 0;
|
int frame_rate_ = 0;
|
||||||
int frame_rate_threshold_us_ = 0;
|
int frame_rate_threshold_us_ = 0;
|
||||||
|
@ -305,8 +277,11 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||||
|
|
||||||
bool paint_callback_running_ = false;
|
bool paint_callback_running_ = false;
|
||||||
|
|
||||||
viz::LocalSurfaceIdAllocation local_surface_id_allocation_;
|
viz::LocalSurfaceIdAllocation delegated_frame_host_allocation_;
|
||||||
viz::ParentLocalSurfaceIdAllocator local_surface_id_allocator_;
|
viz::ParentLocalSurfaceIdAllocator delegated_frame_host_allocator_;
|
||||||
|
|
||||||
|
viz::LocalSurfaceIdAllocation compositor_allocation_;
|
||||||
|
viz::ParentLocalSurfaceIdAllocator compositor_allocator_;
|
||||||
|
|
||||||
std::unique_ptr<ui::Layer> root_layer_;
|
std::unique_ptr<ui::Layer> root_layer_;
|
||||||
std::unique_ptr<ui::Compositor> compositor_;
|
std::unique_ptr<ui::Compositor> compositor_;
|
||||||
|
@ -314,27 +289,15 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||||
|
|
||||||
std::unique_ptr<content::CursorManager> cursor_manager_;
|
std::unique_ptr<content::CursorManager> cursor_manager_;
|
||||||
|
|
||||||
std::unique_ptr<AtomCopyFrameGenerator> copy_frame_generator_;
|
|
||||||
std::unique_ptr<AtomBeginFrameTimer> begin_frame_timer_;
|
std::unique_ptr<AtomBeginFrameTimer> begin_frame_timer_;
|
||||||
|
OffScreenHostDisplayClient* host_display_client_;
|
||||||
|
std::unique_ptr<OffScreenVideoConsumer> video_consumer_;
|
||||||
|
|
||||||
// Provides |source_id| for BeginFrameArgs that we create.
|
// Provides |source_id| for BeginFrameArgs that we create.
|
||||||
viz::StubBeginFrameSource begin_frame_source_;
|
viz::StubBeginFrameSource begin_frame_source_;
|
||||||
uint64_t begin_frame_number_ = viz::BeginFrameArgs::kStartingFrameNumber;
|
uint64_t begin_frame_number_ = viz::BeginFrameArgs::kStartingFrameNumber;
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
|
||||||
std::unique_ptr<content::BrowserCompositorMac> browser_compositor_;
|
|
||||||
|
|
||||||
SkColor last_frame_root_background_color_;
|
|
||||||
|
|
||||||
// Can not be managed by smart pointer because its header can not be included
|
|
||||||
// in the file that has the destructor.
|
|
||||||
MacHelper* mac_helper_;
|
|
||||||
|
|
||||||
// Selected text on the renderer.
|
|
||||||
std::string selected_text_;
|
|
||||||
#else
|
|
||||||
std::unique_ptr<AtomDelegatedFrameHostClient> delegated_frame_host_client_;
|
std::unique_ptr<AtomDelegatedFrameHostClient> delegated_frame_host_client_;
|
||||||
#endif
|
|
||||||
|
|
||||||
content::MouseWheelPhaseHandler mouse_wheel_phase_handler_;
|
content::MouseWheelPhaseHandler mouse_wheel_phase_handler_;
|
||||||
|
|
||||||
|
@ -348,6 +311,8 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||||
|
|
||||||
SkColor background_color_ = SkColor();
|
SkColor background_color_ = SkColor();
|
||||||
|
|
||||||
|
std::unique_ptr<SkBitmap> backing_;
|
||||||
|
|
||||||
base::WeakPtrFactory<OffScreenRenderWidgetHostView> weak_ptr_factory_;
|
base::WeakPtrFactory<OffScreenRenderWidgetHostView> weak_ptr_factory_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(OffScreenRenderWidgetHostView);
|
DISALLOW_COPY_AND_ASSIGN(OffScreenRenderWidgetHostView);
|
||||||
|
|
|
@ -1,150 +0,0 @@
|
||||||
// Copyright (c) 2016 GitHub, Inc.
|
|
||||||
// Use of this source code is governed by the MIT license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
|
|
||||||
#include "base/strings/utf_string_conversions.h"
|
|
||||||
#include "content/common/view_messages.h"
|
|
||||||
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
|
|
||||||
#include "ui/display/screen.h"
|
|
||||||
|
|
||||||
#include "components/viz/common/features.h"
|
|
||||||
|
|
||||||
namespace atom {
|
|
||||||
|
|
||||||
class MacHelper : public content::BrowserCompositorMacClient,
|
|
||||||
public ui::AcceleratedWidgetMacNSView {
|
|
||||||
public:
|
|
||||||
explicit MacHelper(OffScreenRenderWidgetHostView* view) : view_(view) {
|
|
||||||
[view_->GetNativeView().GetNativeNSView() setWantsLayer:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~MacHelper() {}
|
|
||||||
|
|
||||||
// content::BrowserCompositorMacClient:
|
|
||||||
SkColor BrowserCompositorMacGetGutterColor() const override {
|
|
||||||
// When making an element on the page fullscreen the element's background
|
|
||||||
// may not match the page's, so use black as the gutter color to avoid
|
|
||||||
// flashes of brighter colors during the transition.
|
|
||||||
if (view_->render_widget_host()->delegate() &&
|
|
||||||
view_->render_widget_host()->delegate()->IsFullscreenForCurrentTab()) {
|
|
||||||
return SK_ColorBLACK;
|
|
||||||
}
|
|
||||||
return view_->last_frame_root_background_color();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BrowserCompositorMacOnBeginFrame(base::TimeTicks frame_time) override {}
|
|
||||||
|
|
||||||
void OnFrameTokenChanged(uint32_t frame_token) override {
|
|
||||||
view_->render_widget_host()->DidProcessFrame(frame_token);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AcceleratedWidgetCALayerParamsUpdated() override {}
|
|
||||||
|
|
||||||
void DestroyCompositorForShutdown() override {}
|
|
||||||
|
|
||||||
bool OnBrowserCompositorSurfaceIdChanged() override {
|
|
||||||
return view_->render_widget_host()->SynchronizeVisualProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction() override {
|
|
||||||
return view_->render_widget_host()->CollectSurfaceIdsForEviction();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
OffScreenRenderWidgetHostView* view_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(MacHelper);
|
|
||||||
};
|
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::SetActive(bool active) {}
|
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::ShowDefinitionForSelection() {}
|
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::SpeakSelection() {}
|
|
||||||
|
|
||||||
bool OffScreenRenderWidgetHostView::UpdateNSViewAndDisplay() {
|
|
||||||
return browser_compositor_->UpdateSurfaceFromNSView(
|
|
||||||
GetRootLayer()->bounds().size(), GetDisplay());
|
|
||||||
}
|
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::CreatePlatformWidget(
|
|
||||||
bool is_guest_view_hack) {
|
|
||||||
mac_helper_ = new MacHelper(this);
|
|
||||||
browser_compositor_.reset(new content::BrowserCompositorMac(
|
|
||||||
mac_helper_, mac_helper_, render_widget_host_->is_hidden(), GetDisplay(),
|
|
||||||
AllocateFrameSinkId(is_guest_view_hack)));
|
|
||||||
|
|
||||||
if (!base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
|
|
||||||
SetNeedsBeginFrames(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::DestroyPlatformWidget() {
|
|
||||||
browser_compositor_.reset();
|
|
||||||
delete mac_helper_;
|
|
||||||
}
|
|
||||||
|
|
||||||
viz::ScopedSurfaceIdAllocator
|
|
||||||
OffScreenRenderWidgetHostView::DidUpdateVisualProperties(
|
|
||||||
const cc::RenderFrameMetadata& metadata) {
|
|
||||||
base::OnceCallback<void()> allocation_task = base::BindOnce(
|
|
||||||
base::IgnoreResult(
|
|
||||||
&OffScreenRenderWidgetHostView::OnDidUpdateVisualPropertiesComplete),
|
|
||||||
weak_ptr_factory_.GetWeakPtr(), metadata);
|
|
||||||
return browser_compositor_->GetScopedRendererSurfaceIdAllocator(
|
|
||||||
std::move(allocation_task));
|
|
||||||
}
|
|
||||||
|
|
||||||
display::Display OffScreenRenderWidgetHostView::GetDisplay() {
|
|
||||||
content::ScreenInfo screen_info;
|
|
||||||
GetScreenInfo(&screen_info);
|
|
||||||
|
|
||||||
// Start with a reasonable display representation.
|
|
||||||
display::Display display =
|
|
||||||
display::Screen::GetScreen()->GetDisplayNearestView(nullptr);
|
|
||||||
|
|
||||||
// Populate attributes based on |screen_info|.
|
|
||||||
display.set_bounds(screen_info.rect);
|
|
||||||
display.set_work_area(screen_info.available_rect);
|
|
||||||
display.set_device_scale_factor(screen_info.device_scale_factor);
|
|
||||||
display.set_color_space(screen_info.color_space);
|
|
||||||
display.set_color_depth(screen_info.depth);
|
|
||||||
display.set_depth_per_component(screen_info.depth_per_component);
|
|
||||||
display.set_is_monochrome(screen_info.is_monochrome);
|
|
||||||
display.SetRotationAsDegree(screen_info.orientation_angle);
|
|
||||||
|
|
||||||
return display;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OffScreenRenderWidgetHostView::OnDidUpdateVisualPropertiesComplete(
|
|
||||||
const cc::RenderFrameMetadata& metadata) {
|
|
||||||
DCHECK_EQ(current_device_scale_factor_, metadata.device_scale_factor);
|
|
||||||
browser_compositor_->UpdateSurfaceFromChild(
|
|
||||||
metadata.device_scale_factor, metadata.viewport_size_in_pixels,
|
|
||||||
metadata.local_surface_id_allocation.value_or(
|
|
||||||
viz::LocalSurfaceIdAllocation()));
|
|
||||||
}
|
|
||||||
|
|
||||||
const viz::LocalSurfaceIdAllocation&
|
|
||||||
OffScreenRenderWidgetHostView::GetLocalSurfaceIdAllocation() const {
|
|
||||||
return browser_compositor_->GetRendererLocalSurfaceIdAllocation();
|
|
||||||
}
|
|
||||||
|
|
||||||
ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() const {
|
|
||||||
return browser_compositor_->GetCompositor();
|
|
||||||
}
|
|
||||||
|
|
||||||
ui::Layer* OffScreenRenderWidgetHostView::GetRootLayer() const {
|
|
||||||
return browser_compositor_->GetRootLayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
content::DelegatedFrameHost*
|
|
||||||
OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
|
|
||||||
return browser_compositor_->GetDelegatedFrameHost();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace atom
|
|
137
atom/browser/osr/osr_video_consumer.cc
Normal file
137
atom/browser/osr/osr_video_consumer.cc
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
// Copyright (c) 2019 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "atom/browser/osr/osr_video_consumer.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||||
|
#include "media/base/video_frame_metadata.h"
|
||||||
|
#include "media/capture/mojom/video_capture_types.mojom.h"
|
||||||
|
#include "ui/gfx/skbitmap_operations.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
OffScreenVideoConsumer::OffScreenVideoConsumer(
|
||||||
|
OffScreenRenderWidgetHostView* view,
|
||||||
|
OnPaintCallback callback)
|
||||||
|
: callback_(callback),
|
||||||
|
view_(view),
|
||||||
|
video_capturer_(view->CreateVideoCapturer()),
|
||||||
|
weak_ptr_factory_(this) {
|
||||||
|
video_capturer_->SetResolutionConstraints(view_->SizeInPixels(),
|
||||||
|
view_->SizeInPixels(), true);
|
||||||
|
video_capturer_->SetAutoThrottlingEnabled(false);
|
||||||
|
video_capturer_->SetMinSizeChangePeriod(base::TimeDelta());
|
||||||
|
video_capturer_->SetFormat(media::PIXEL_FORMAT_ARGB,
|
||||||
|
gfx::ColorSpace::CreateREC709());
|
||||||
|
SetFrameRate(view_->GetFrameRate());
|
||||||
|
}
|
||||||
|
|
||||||
|
OffScreenVideoConsumer::~OffScreenVideoConsumer() = default;
|
||||||
|
|
||||||
|
void OffScreenVideoConsumer::SetActive(bool active) {
|
||||||
|
if (active) {
|
||||||
|
video_capturer_->Start(this);
|
||||||
|
} else {
|
||||||
|
video_capturer_->Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffScreenVideoConsumer::SetFrameRate(int frame_rate) {
|
||||||
|
video_capturer_->SetMinCapturePeriod(base::TimeDelta::FromSeconds(1) /
|
||||||
|
frame_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffScreenVideoConsumer::SizeChanged() {
|
||||||
|
video_capturer_->SetResolutionConstraints(view_->SizeInPixels(),
|
||||||
|
view_->SizeInPixels(), true);
|
||||||
|
video_capturer_->RequestRefreshFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffScreenVideoConsumer::OnFrameCaptured(
|
||||||
|
base::ReadOnlySharedMemoryRegion data,
|
||||||
|
::media::mojom::VideoFrameInfoPtr info,
|
||||||
|
const gfx::Rect& content_rect,
|
||||||
|
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) {
|
||||||
|
if (!CheckContentRect(content_rect)) {
|
||||||
|
gfx::Size view_size = view_->SizeInPixels();
|
||||||
|
video_capturer_->SetResolutionConstraints(view_size, view_size, true);
|
||||||
|
video_capturer_->RequestRefreshFrame();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.IsValid()) {
|
||||||
|
callbacks->Done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
base::ReadOnlySharedMemoryMapping mapping = data.Map();
|
||||||
|
if (!mapping.IsValid()) {
|
||||||
|
DLOG(ERROR) << "Shared memory mapping failed.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mapping.size() <
|
||||||
|
media::VideoFrame::AllocationSize(info->pixel_format, info->coded_size)) {
|
||||||
|
DLOG(ERROR) << "Shared memory size was less than expected.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The SkBitmap's pixels will be marked as immutable, but the installPixels()
|
||||||
|
// API requires a non-const pointer. So, cast away the const.
|
||||||
|
void* const pixels = const_cast<void*>(mapping.memory());
|
||||||
|
|
||||||
|
// Call installPixels() with a |releaseProc| that: 1) notifies the capturer
|
||||||
|
// that this consumer has finished with the frame, and 2) releases the shared
|
||||||
|
// memory mapping.
|
||||||
|
struct FramePinner {
|
||||||
|
// Keeps the shared memory that backs |frame_| mapped.
|
||||||
|
base::ReadOnlySharedMemoryMapping mapping;
|
||||||
|
// Prevents FrameSinkVideoCapturer from recycling the shared memory that
|
||||||
|
// backs |frame_|.
|
||||||
|
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr releaser;
|
||||||
|
};
|
||||||
|
|
||||||
|
SkBitmap bitmap;
|
||||||
|
bitmap.installPixels(
|
||||||
|
SkImageInfo::MakeN32(content_rect.width(), content_rect.height(),
|
||||||
|
kPremul_SkAlphaType),
|
||||||
|
pixels,
|
||||||
|
media::VideoFrame::RowBytes(media::VideoFrame::kARGBPlane,
|
||||||
|
info->pixel_format, info->coded_size.width()),
|
||||||
|
[](void* addr, void* context) {
|
||||||
|
delete static_cast<FramePinner*>(context);
|
||||||
|
},
|
||||||
|
new FramePinner{std::move(mapping), std::move(callbacks)});
|
||||||
|
bitmap.setImmutable();
|
||||||
|
|
||||||
|
media::VideoFrameMetadata metadata;
|
||||||
|
metadata.MergeInternalValuesFrom(info->metadata);
|
||||||
|
gfx::Rect damage_rect;
|
||||||
|
|
||||||
|
auto UPDATE_RECT = media::VideoFrameMetadata::CAPTURE_UPDATE_RECT;
|
||||||
|
if (!metadata.GetRect(UPDATE_RECT, &damage_rect)) {
|
||||||
|
damage_rect = content_rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback_.Run(damage_rect, bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffScreenVideoConsumer::OnStopped() {}
|
||||||
|
|
||||||
|
bool OffScreenVideoConsumer::CheckContentRect(const gfx::Rect& content_rect) {
|
||||||
|
gfx::Size view_size = view_->SizeInPixels();
|
||||||
|
gfx::Size content_size = content_rect.size();
|
||||||
|
|
||||||
|
if (std::abs(view_size.width() - content_size.width()) > 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::abs(view_size.height() - content_size.height()) > 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace atom
|
53
atom/browser/osr/osr_video_consumer.h
Normal file
53
atom/browser/osr/osr_video_consumer.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// Copyright (c) 2019 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ATOM_BROWSER_OSR_OSR_VIDEO_CONSUMER_H_
|
||||||
|
#define ATOM_BROWSER_OSR_OSR_VIDEO_CONSUMER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "base/callback.h"
|
||||||
|
#include "base/memory/weak_ptr.h"
|
||||||
|
#include "components/viz/host/client_frame_sink_video_capturer.h"
|
||||||
|
|
||||||
|
namespace atom {
|
||||||
|
|
||||||
|
class OffScreenRenderWidgetHostView;
|
||||||
|
|
||||||
|
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
|
||||||
|
|
||||||
|
class OffScreenVideoConsumer : public viz::mojom::FrameSinkVideoConsumer {
|
||||||
|
public:
|
||||||
|
OffScreenVideoConsumer(OffScreenRenderWidgetHostView* view,
|
||||||
|
OnPaintCallback callback);
|
||||||
|
~OffScreenVideoConsumer() override;
|
||||||
|
|
||||||
|
void SetActive(bool active);
|
||||||
|
void SetFrameRate(int frame_rate);
|
||||||
|
void SizeChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// viz::mojom::FrameSinkVideoConsumer implementation.
|
||||||
|
void OnFrameCaptured(
|
||||||
|
base::ReadOnlySharedMemoryRegion data,
|
||||||
|
::media::mojom::VideoFrameInfoPtr info,
|
||||||
|
const gfx::Rect& content_rect,
|
||||||
|
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) override;
|
||||||
|
void OnStopped() override;
|
||||||
|
|
||||||
|
bool CheckContentRect(const gfx::Rect& content_rect);
|
||||||
|
|
||||||
|
OnPaintCallback callback_;
|
||||||
|
|
||||||
|
OffScreenRenderWidgetHostView* view_;
|
||||||
|
std::unique_ptr<viz::ClientFrameSinkVideoCapturer> video_capturer_;
|
||||||
|
|
||||||
|
base::WeakPtrFactory<OffScreenVideoConsumer> weak_ptr_factory_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(OffScreenVideoConsumer);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace atom
|
||||||
|
|
||||||
|
#endif // ATOM_BROWSER_OSR_OSR_VIDEO_CONSUMER_H_
|
|
@ -5,7 +5,7 @@
|
||||||
#include "atom/browser/osr/osr_web_contents_view.h"
|
#include "atom/browser/osr/osr_web_contents_view.h"
|
||||||
|
|
||||||
#include "atom/common/api/api_messages.h"
|
#include "atom/common/api/api_messages.h"
|
||||||
#include "content/browser/web_contents/web_contents_impl.h"
|
#include "content/browser/web_contents/web_contents_impl.h" // nogncheck
|
||||||
#include "content/public/browser/render_view_host.h"
|
#include "content/public/browser/render_view_host.h"
|
||||||
#include "third_party/blink/public/platform/web_screen_info.h"
|
#include "third_party/blink/public/platform/web_screen_info.h"
|
||||||
#include "ui/display/screen.h"
|
#include "ui/display/screen.h"
|
||||||
|
@ -140,7 +140,7 @@ OffScreenWebContentsView::CreateViewForChildWidget(
|
||||||
->GetRenderWidgetHostView()
|
->GetRenderWidgetHostView()
|
||||||
: web_contents_impl->GetRenderWidgetHostView());
|
: web_contents_impl->GetRenderWidgetHostView());
|
||||||
|
|
||||||
return new OffScreenRenderWidgetHostView(transparent_, true,
|
return new OffScreenRenderWidgetHostView(transparent_, painting_,
|
||||||
view->GetFrameRate(), callback_,
|
view->GetFrameRate(), callback_,
|
||||||
render_widget_host, view, GetSize());
|
render_widget_host, view, GetSize());
|
||||||
}
|
}
|
||||||
|
@ -166,11 +166,9 @@ void OffScreenWebContentsView::RenderViewHostChanged(
|
||||||
void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled) {}
|
void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled) {}
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
bool OffScreenWebContentsView::IsEventTracking() const {
|
bool OffScreenWebContentsView::CloseTabAfterEventTrackingIfNeeded() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffScreenWebContentsView::CloseTabAfterEventTracking() {}
|
|
||||||
#endif // defined(OS_MACOSX)
|
#endif // defined(OS_MACOSX)
|
||||||
|
|
||||||
void OffScreenWebContentsView::StartDragging(
|
void OffScreenWebContentsView::StartDragging(
|
||||||
|
@ -189,10 +187,9 @@ void OffScreenWebContentsView::UpdateDragCursor(
|
||||||
|
|
||||||
void OffScreenWebContentsView::SetPainting(bool painting) {
|
void OffScreenWebContentsView::SetPainting(bool painting) {
|
||||||
auto* view = GetView();
|
auto* view = GetView();
|
||||||
|
painting_ = painting;
|
||||||
if (view != nullptr) {
|
if (view != nullptr) {
|
||||||
view->SetPainting(painting);
|
view->SetPainting(painting);
|
||||||
} else {
|
|
||||||
painting_ = painting;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,10 +204,9 @@ bool OffScreenWebContentsView::IsPainting() const {
|
||||||
|
|
||||||
void OffScreenWebContentsView::SetFrameRate(int frame_rate) {
|
void OffScreenWebContentsView::SetFrameRate(int frame_rate) {
|
||||||
auto* view = GetView();
|
auto* view = GetView();
|
||||||
|
frame_rate_ = frame_rate;
|
||||||
if (view != nullptr) {
|
if (view != nullptr) {
|
||||||
view->SetFrameRate(frame_rate);
|
view->SetFrameRate(frame_rate);
|
||||||
} else {
|
|
||||||
frame_rate_ = frame_rate;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
#include "atom/browser/native_window_observer.h"
|
#include "atom/browser/native_window_observer.h"
|
||||||
|
|
||||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||||
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
|
#include "content/browser/renderer_host/render_view_host_delegate_view.h" // nogncheck
|
||||||
#include "content/browser/web_contents/web_contents_view.h"
|
#include "content/browser/web_contents/web_contents_view.h" // nogncheck
|
||||||
#include "content/public/browser/web_contents.h"
|
#include "content/public/browser/web_contents.h"
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
|
@ -67,8 +67,7 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
||||||
void SetOverscrollControllerEnabled(bool enabled) override;
|
void SetOverscrollControllerEnabled(bool enabled) override;
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
bool IsEventTracking() const override;
|
bool CloseTabAfterEventTrackingIfNeeded() override;
|
||||||
void CloseTabAfterEventTracking() override;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// content::RenderViewHostDelegateView
|
// content::RenderViewHostDelegateView
|
||||||
|
|
|
@ -69,7 +69,6 @@ void AutofillPopup::CreateView(content::RenderFrameHost* frame_host,
|
||||||
parent_->AddObserver(this);
|
parent_->AddObserver(this);
|
||||||
|
|
||||||
view_ = new AutofillPopupView(this, parent->GetWidget());
|
view_ = new AutofillPopupView(this, parent->GetWidget());
|
||||||
view_->Show();
|
|
||||||
|
|
||||||
#if BUILDFLAG(ENABLE_OSR)
|
#if BUILDFLAG(ENABLE_OSR)
|
||||||
if (offscreen) {
|
if (offscreen) {
|
||||||
|
@ -83,6 +82,9 @@ void AutofillPopup::CreateView(content::RenderFrameHost* frame_host,
|
||||||
osr_rwhv->AddViewProxy(view_->view_proxy_.get());
|
osr_rwhv->AddViewProxy(view_->view_proxy_.get());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Do this after OSR setup, we check for view_proxy_ when showing
|
||||||
|
view_->Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutofillPopup::Hide() {
|
void AutofillPopup::Hide() {
|
||||||
|
|
|
@ -56,7 +56,11 @@ AutofillPopupView::~AutofillPopupView() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutofillPopupView::Show() {
|
void AutofillPopupView::Show() {
|
||||||
if (!popup_ || !parent_widget_->IsVisible() || parent_widget_->IsClosed())
|
bool visible = parent_widget_->IsVisible();
|
||||||
|
#if BUILDFLAG(ENABLE_OSR)
|
||||||
|
visible = visible || view_proxy_;
|
||||||
|
#endif
|
||||||
|
if (!popup_ || !visible || parent_widget_->IsClosed())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const bool initialize_widget = !GetWidget();
|
const bool initialize_widget = !GetWidget();
|
||||||
|
|
|
@ -8,7 +8,7 @@ declare_args() {
|
||||||
# Allow running Electron as a node binary.
|
# Allow running Electron as a node binary.
|
||||||
enable_run_as_node = true
|
enable_run_as_node = true
|
||||||
|
|
||||||
enable_osr = false
|
enable_osr = true
|
||||||
|
|
||||||
enable_view_api = false
|
enable_view_api = false
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ blink_local_frame.patch
|
||||||
blink_world_context.patch
|
blink_world_context.patch
|
||||||
browser_compositor_mac.patch
|
browser_compositor_mac.patch
|
||||||
can_create_window.patch
|
can_create_window.patch
|
||||||
compositor_delegate.patch
|
|
||||||
disable_hidden.patch
|
disable_hidden.patch
|
||||||
dom_storage_limits.patch
|
dom_storage_limits.patch
|
||||||
frame_host_manager.patch
|
frame_host_manager.patch
|
||||||
|
@ -74,3 +73,4 @@ disable_custom_libcxx_on_windows.patch
|
||||||
fix_retain_compatibility_with_msvc.patch
|
fix_retain_compatibility_with_msvc.patch
|
||||||
disable_network_services_by_default.patch
|
disable_network_services_by_default.patch
|
||||||
unsandboxed_ppapi_processes_skip_zygote.patch
|
unsandboxed_ppapi_processes_skip_zygote.patch
|
||||||
|
viz_osr.patch
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Anonymous <anonymous@electronjs.org>
|
|
||||||
Date: Thu, 20 Sep 2018 17:45:36 -0700
|
|
||||||
Subject: compositor_delegate.patch
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
|
|
||||||
index ff4e3109b11fea4e0a732ebf9ac9c17e4b5d5e8e..09eee0aae0306545af49258a8f11813c06655023 100644
|
|
||||||
--- a/content/browser/compositor/gpu_process_transport_factory.cc
|
|
||||||
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
|
|
||||||
@@ -451,11 +451,20 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
|
|
||||||
// surfaces as they are not following the correct mode.
|
|
||||||
DisableGpuCompositing(compositor.get());
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ std::unique_ptr<viz::SoftwareOutputDevice> output_device;
|
|
||||||
+ if (compositor->delegate()) {
|
|
||||||
+ output_device =
|
|
||||||
+ compositor->delegate()->CreateSoftwareOutputDevice(compositor.get());
|
|
||||||
+ }
|
|
||||||
+ if (!output_device) {
|
|
||||||
+ output_device = CreateSoftwareOutputDevice(compositor->widget(),
|
|
||||||
+ compositor->task_runner());
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
display_output_surface =
|
|
||||||
std::make_unique<SoftwareBrowserCompositorOutputSurface>(
|
|
||||||
- CreateSoftwareOutputDevice(compositor->widget(),
|
|
||||||
- compositor->task_runner()),
|
|
||||||
- std::move(vsync_callback));
|
|
||||||
+ std::move(output_device), std::move(vsync_callback));
|
|
||||||
} else {
|
|
||||||
DCHECK(context_provider);
|
|
||||||
const auto& capabilities = context_provider->ContextCapabilities();
|
|
||||||
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
|
|
||||||
index 29784c677f4be6e4fd7cfb298ab3554d22e1beaa..07b61abe7ce666b5eb6448ef795f838ddb805947 100644
|
|
||||||
--- a/ui/compositor/compositor.h
|
|
||||||
+++ b/ui/compositor/compositor.h
|
|
||||||
@@ -25,6 +25,7 @@
|
|
||||||
#include "components/viz/common/surfaces/frame_sink_id.h"
|
|
||||||
#include "components/viz/common/surfaces/local_surface_id_allocation.h"
|
|
||||||
#include "components/viz/host/host_frame_sink_client.h"
|
|
||||||
+#include "components/viz/service/display/software_output_device.h"
|
|
||||||
#include "third_party/skia/include/core/SkColor.h"
|
|
||||||
#include "third_party/skia/include/core/SkMatrix44.h"
|
|
||||||
#include "ui/compositor/compositor_animation_observer.h"
|
|
||||||
@@ -193,6 +194,15 @@ class COMPOSITOR_EXPORT ContextFactory {
|
|
||||||
virtual bool SyncTokensRequiredForDisplayCompositor() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
+class COMPOSITOR_EXPORT CompositorDelegate {
|
|
||||||
+ public:
|
|
||||||
+ virtual std::unique_ptr<viz::SoftwareOutputDevice> CreateSoftwareOutputDevice(
|
|
||||||
+ ui::Compositor* compositor) = 0;
|
|
||||||
+
|
|
||||||
+ protected:
|
|
||||||
+ virtual ~CompositorDelegate() {}
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
// Compositor object to take care of GPU painting.
|
|
||||||
// A Browser compositor object is responsible for generating the final
|
|
||||||
// displayable form of pixels comprising a single widget's contents. It draws an
|
|
||||||
@@ -235,6 +245,9 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
|
|
||||||
// Schedules a redraw of the layer tree associated with this compositor.
|
|
||||||
void ScheduleDraw();
|
|
||||||
|
|
||||||
+ CompositorDelegate* delegate() const { return delegate_; }
|
|
||||||
+ void SetDelegate(CompositorDelegate* delegate) { delegate_ = delegate; }
|
|
||||||
+
|
|
||||||
// Sets the root of the layer tree drawn by this Compositor. The root layer
|
|
||||||
// must have no parent. The compositor's root layer is reset if the root layer
|
|
||||||
// is destroyed. NULL can be passed to reset the root layer, in which case the
|
|
||||||
@@ -458,6 +471,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
|
|
||||||
ui::ContextFactory* context_factory_;
|
|
||||||
ui::ContextFactoryPrivate* context_factory_private_;
|
|
||||||
|
|
||||||
+ CompositorDelegate* delegate_ = nullptr;
|
|
||||||
+
|
|
||||||
// The root of the Layer tree drawn by this compositor.
|
|
||||||
Layer* root_layer_ = nullptr;
|
|
||||||
|
|
638
patches/common/chromium/viz_osr.patch
Normal file
638
patches/common/chromium/viz_osr.patch
Normal file
|
@ -0,0 +1,638 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Heilig Benedek <benecene@gmail.com>
|
||||||
|
Date: Wed, 20 Mar 2019 20:30:44 +0100
|
||||||
|
Subject: feat: offscreen rendering with viz compositor
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/components/viz/host/host_display_client.cc b/components/viz/host/host_display_client.cc
|
||||||
|
index bdd1e8bde77ac458639d2b6064c58a133becc5ee..b21917e760c9bf183a75d1ed4e4104eeeb8948ad 100644
|
||||||
|
--- a/components/viz/host/host_display_client.cc
|
||||||
|
+++ b/components/viz/host/host_display_client.cc
|
||||||
|
@@ -18,6 +18,10 @@
|
||||||
|
|
||||||
|
namespace viz {
|
||||||
|
|
||||||
|
+void HostDisplayClient::IsOffscreen(IsOffscreenCallback callback) {
|
||||||
|
+ std::move(callback).Run(false);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
HostDisplayClient::HostDisplayClient(gfx::AcceleratedWidget widget)
|
||||||
|
: binding_(this) {
|
||||||
|
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||||
|
@@ -49,9 +53,9 @@ void HostDisplayClient::OnDisplayReceivedCALayerParams(
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#if defined(OS_WIN)
|
||||||
|
void HostDisplayClient::CreateLayeredWindowUpdater(
|
||||||
|
mojom::LayeredWindowUpdaterRequest request) {
|
||||||
|
+#if defined(OS_WIN)
|
||||||
|
if (!NeedsToUseLayerWindow(widget_)) {
|
||||||
|
DLOG(ERROR) << "HWND shouldn't be using a layered window";
|
||||||
|
return;
|
||||||
|
@@ -59,7 +63,11 @@ void HostDisplayClient::CreateLayeredWindowUpdater(
|
||||||
|
|
||||||
|
layered_window_updater_ =
|
||||||
|
std::make_unique<LayeredWindowUpdaterImpl>(widget_, std::move(request));
|
||||||
|
-}
|
||||||
|
+#else
|
||||||
|
+ CHECK(false) << "Chromium is calling CreateLayeredWindowUpdater for non-OSR "
|
||||||
|
+ "windows on POSIX platforms, something is wrong with "
|
||||||
|
+ "Electron's OSR implementation.";
|
||||||
|
#endif
|
||||||
|
+}
|
||||||
|
|
||||||
|
} // namespace viz
|
||||||
|
diff --git a/components/viz/host/host_display_client.h b/components/viz/host/host_display_client.h
|
||||||
|
index af64385aa93f7abc7a85e1f6eec3c99134e0d2b5..011007ba451e71d46d02cb2d28f6489fe2a805ec 100644
|
||||||
|
--- a/components/viz/host/host_display_client.h
|
||||||
|
+++ b/components/viz/host/host_display_client.h
|
||||||
|
@@ -30,17 +30,17 @@ class VIZ_HOST_EXPORT HostDisplayClient : public mojom::DisplayClient {
|
||||||
|
mojom::DisplayClientPtr GetBoundPtr(
|
||||||
|
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
|
||||||
|
|
||||||
|
- private:
|
||||||
|
+ protected:
|
||||||
|
// mojom::DisplayClient implementation:
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
void OnDisplayReceivedCALayerParams(
|
||||||
|
const gfx::CALayerParams& ca_layer_params) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#if defined(OS_WIN)
|
||||||
|
+ void IsOffscreen(IsOffscreenCallback callback) override;
|
||||||
|
+
|
||||||
|
void CreateLayeredWindowUpdater(
|
||||||
|
mojom::LayeredWindowUpdaterRequest request) override;
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
mojo::Binding<mojom::DisplayClient> binding_;
|
||||||
|
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||||
|
diff --git a/components/viz/host/layered_window_updater_impl.cc b/components/viz/host/layered_window_updater_impl.cc
|
||||||
|
index d3a49ed8be8dc11b86af67cdd600b05ddc0fc486..88bf86f3938b8267d731b52c8c3baa35d3128c7a 100644
|
||||||
|
--- a/components/viz/host/layered_window_updater_impl.cc
|
||||||
|
+++ b/components/viz/host/layered_window_updater_impl.cc
|
||||||
|
@@ -47,7 +47,9 @@ void LayeredWindowUpdaterImpl::OnAllocatedSharedMemory(
|
||||||
|
shm_handle.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
-void LayeredWindowUpdaterImpl::Draw(DrawCallback draw_callback) {
|
||||||
|
+void LayeredWindowUpdaterImpl::Draw(
|
||||||
|
+ const gfx::Rect& damage_rect,
|
||||||
|
+ DrawCallback draw_callback) {
|
||||||
|
TRACE_EVENT0("viz", "LayeredWindowUpdaterImpl::Draw");
|
||||||
|
|
||||||
|
if (!canvas_) {
|
||||||
|
diff --git a/components/viz/host/layered_window_updater_impl.h b/components/viz/host/layered_window_updater_impl.h
|
||||||
|
index 93c52d2b928cba6e98723e19b005fb7bd7089a58..4dc645e770a2a039ed8e4ff4de555767fee34a3a 100644
|
||||||
|
--- a/components/viz/host/layered_window_updater_impl.h
|
||||||
|
+++ b/components/viz/host/layered_window_updater_impl.h
|
||||||
|
@@ -33,7 +33,7 @@ class VIZ_HOST_EXPORT LayeredWindowUpdaterImpl
|
||||||
|
void OnAllocatedSharedMemory(
|
||||||
|
const gfx::Size& pixel_size,
|
||||||
|
mojo::ScopedSharedBufferHandle scoped_buffer_handle) override;
|
||||||
|
- void Draw(DrawCallback draw_callback) override;
|
||||||
|
+ void Draw(const gfx::Rect& damage_rect, DrawCallback draw_callback) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const HWND hwnd_;
|
||||||
|
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
|
||||||
|
index 1ac721a2781faecd0c7ee5709e8ed20b227bf298..dd7ae27ececbe2a81d9dc62f7e49dc520916d58c 100644
|
||||||
|
--- a/components/viz/service/BUILD.gn
|
||||||
|
+++ b/components/viz/service/BUILD.gn
|
||||||
|
@@ -113,6 +113,8 @@ viz_component("service") {
|
||||||
|
"display_embedder/in_process_gpu_memory_buffer_manager.h",
|
||||||
|
"display_embedder/server_shared_bitmap_manager.cc",
|
||||||
|
"display_embedder/server_shared_bitmap_manager.h",
|
||||||
|
+ "display_embedder/software_output_device_proxy.cc",
|
||||||
|
+ "display_embedder/software_output_device_proxy.h",
|
||||||
|
"display_embedder/software_output_surface.cc",
|
||||||
|
"display_embedder/software_output_surface.h",
|
||||||
|
"display_embedder/viz_process_context_provider.cc",
|
||||||
|
diff --git a/components/viz/service/display_embedder/gpu_display_provider.cc b/components/viz/service/display_embedder/gpu_display_provider.cc
|
||||||
|
index 72e6374ccb67b625fa5936a08cc948c653d71e0e..71b1c7e16ea7a48fee3a9c17c66d5d6927c2783a 100644
|
||||||
|
--- a/components/viz/service/display_embedder/gpu_display_provider.cc
|
||||||
|
+++ b/components/viz/service/display_embedder/gpu_display_provider.cc
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
|
||||||
|
#include "components/viz/service/display_embedder/skia_output_surface_impl.h"
|
||||||
|
#include "components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.h"
|
||||||
|
+#include "components/viz/service/display_embedder/software_output_device_proxy.h"
|
||||||
|
#include "components/viz/service/display_embedder/software_output_surface.h"
|
||||||
|
#include "components/viz/service/display_embedder/viz_process_context_provider.h"
|
||||||
|
#include "components/viz/service/gl/gpu_service_impl.h"
|
||||||
|
@@ -279,6 +280,19 @@ GpuDisplayProvider::CreateSoftwareOutputDeviceForPlatform(
|
||||||
|
if (headless_)
|
||||||
|
return std::make_unique<SoftwareOutputDevice>();
|
||||||
|
|
||||||
|
+#if !defined(OS_MACOSX)
|
||||||
|
+ DCHECK(display_client);
|
||||||
|
+ bool offscreen = false;
|
||||||
|
+ if (display_client->IsOffscreen(&offscreen) && offscreen) {
|
||||||
|
+ mojom::LayeredWindowUpdaterPtr layered_window_updater;
|
||||||
|
+ display_client->CreateLayeredWindowUpdater(
|
||||||
|
+ mojo::MakeRequest(&layered_window_updater));
|
||||||
|
+
|
||||||
|
+ return std::make_unique<SoftwareOutputDeviceProxy>(
|
||||||
|
+ std::move(layered_window_updater));
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
return CreateSoftwareOutputDeviceWinGpu(
|
||||||
|
surface_handle, &output_device_backing_, display_client);
|
||||||
|
diff --git a/components/viz/service/display_embedder/software_output_device_mac.cc b/components/viz/service/display_embedder/software_output_device_mac.cc
|
||||||
|
index b9357082293cc55650144ccbc8bada8fe6d1cac4..b4cb07e26d1504719f80e5835c1cb5f138b9f1ab 100644
|
||||||
|
--- a/components/viz/service/display_embedder/software_output_device_mac.cc
|
||||||
|
+++ b/components/viz/service/display_embedder/software_output_device_mac.cc
|
||||||
|
@@ -102,6 +102,8 @@ void SoftwareOutputDeviceMac::UpdateAndCopyBufferDamage(
|
||||||
|
|
||||||
|
SkCanvas* SoftwareOutputDeviceMac::BeginPaint(
|
||||||
|
const gfx::Rect& new_damage_rect) {
|
||||||
|
+ last_damage = new_damage_rect;
|
||||||
|
+
|
||||||
|
// Record the previous paint buffer.
|
||||||
|
Buffer* previous_paint_buffer =
|
||||||
|
buffer_queue_.empty() ? nullptr : buffer_queue_.back().get();
|
||||||
|
@@ -184,6 +186,7 @@ void SoftwareOutputDeviceMac::EndPaint() {
|
||||||
|
ca_layer_params.is_empty = false;
|
||||||
|
ca_layer_params.scale_factor = scale_factor_;
|
||||||
|
ca_layer_params.pixel_size = pixel_size_;
|
||||||
|
+ ca_layer_params.damage = last_damage;
|
||||||
|
ca_layer_params.io_surface_mach_port.reset(
|
||||||
|
IOSurfaceCreateMachPort(current_paint_buffer_->io_surface));
|
||||||
|
client_->SoftwareDeviceUpdatedCALayerParams(ca_layer_params);
|
||||||
|
diff --git a/components/viz/service/display_embedder/software_output_device_mac.h b/components/viz/service/display_embedder/software_output_device_mac.h
|
||||||
|
index f3867356e3d641416e00e6d115ae9ae2a0be90ab..b1d192d2b20ccb63fba07093101d745e5ffe86dd 100644
|
||||||
|
--- a/components/viz/service/display_embedder/software_output_device_mac.h
|
||||||
|
+++ b/components/viz/service/display_embedder/software_output_device_mac.h
|
||||||
|
@@ -56,6 +56,7 @@ class VIZ_SERVICE_EXPORT SoftwareOutputDeviceMac : public SoftwareOutputDevice {
|
||||||
|
void UpdateAndCopyBufferDamage(Buffer* previous_paint_buffer,
|
||||||
|
const SkRegion& new_damage_rect);
|
||||||
|
|
||||||
|
+ gfx::Rect last_damage;
|
||||||
|
gfx::Size pixel_size_;
|
||||||
|
float scale_factor_ = 1;
|
||||||
|
|
||||||
|
diff --git a/components/viz/service/display_embedder/software_output_device_proxy.cc b/components/viz/service/display_embedder/software_output_device_proxy.cc
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..c784a841f74e7a6215595fd8b1166655857f3e31
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/components/viz/service/display_embedder/software_output_device_proxy.cc
|
||||||
|
@@ -0,0 +1,167 @@
|
||||||
|
+// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||||
|
+// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
+// found in the LICENSE file.
|
||||||
|
+
|
||||||
|
+#include "components/viz/service/display_embedder/software_output_device_proxy.h"
|
||||||
|
+
|
||||||
|
+#include "base/memory/shared_memory.h"
|
||||||
|
+#include "base/threading/thread_checker.h"
|
||||||
|
+#include "components/viz/common/resources/resource_sizes.h"
|
||||||
|
+#include "components/viz/service/display_embedder/output_device_backing.h"
|
||||||
|
+#include "mojo/public/cpp/system/platform_handle.h"
|
||||||
|
+#include "services/viz/privileged/interfaces/compositing/layered_window_updater.mojom.h"
|
||||||
|
+#include "skia/ext/platform_canvas.h"
|
||||||
|
+#include "third_party/skia/include/core/SkCanvas.h"
|
||||||
|
+#include "ui/gfx/skia_util.h"
|
||||||
|
+
|
||||||
|
+#if defined(OS_WIN)
|
||||||
|
+#include "skia/ext/skia_utils_win.h"
|
||||||
|
+#include "ui/gfx/gdi_util.h"
|
||||||
|
+#include "ui/gfx/win/hwnd_util.h"
|
||||||
|
+#else
|
||||||
|
+#include "mojo/public/cpp/base/shared_memory_utils.h"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+namespace viz {
|
||||||
|
+
|
||||||
|
+SoftwareOutputDeviceBase::~SoftwareOutputDeviceBase() {
|
||||||
|
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||||
|
+ DCHECK(!in_paint_);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void SoftwareOutputDeviceBase::Resize(const gfx::Size& viewport_pixel_size,
|
||||||
|
+ float scale_factor) {
|
||||||
|
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||||
|
+ DCHECK(!in_paint_);
|
||||||
|
+
|
||||||
|
+ if (viewport_pixel_size_ == viewport_pixel_size)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ viewport_pixel_size_ = viewport_pixel_size;
|
||||||
|
+ ResizeDelegated();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+SkCanvas* SoftwareOutputDeviceBase::BeginPaint(
|
||||||
|
+ const gfx::Rect& damage_rect) {
|
||||||
|
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||||
|
+ DCHECK(!in_paint_);
|
||||||
|
+
|
||||||
|
+ damage_rect_ = damage_rect;
|
||||||
|
+ in_paint_ = true;
|
||||||
|
+ return BeginPaintDelegated();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void SoftwareOutputDeviceBase::EndPaint() {
|
||||||
|
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||||
|
+ DCHECK(in_paint_);
|
||||||
|
+
|
||||||
|
+ in_paint_ = false;
|
||||||
|
+
|
||||||
|
+ gfx::Rect intersected_damage_rect = damage_rect_;
|
||||||
|
+ intersected_damage_rect.Intersect(gfx::Rect(viewport_pixel_size_));
|
||||||
|
+ if (intersected_damage_rect.IsEmpty())
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ EndPaintDelegated(intersected_damage_rect);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+SoftwareOutputDeviceProxy::~SoftwareOutputDeviceProxy() = default;
|
||||||
|
+
|
||||||
|
+SoftwareOutputDeviceProxy::SoftwareOutputDeviceProxy(
|
||||||
|
+ mojom::LayeredWindowUpdaterPtr layered_window_updater)
|
||||||
|
+ : layered_window_updater_(std::move(layered_window_updater)) {
|
||||||
|
+ DCHECK(layered_window_updater_.is_bound());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void SoftwareOutputDeviceProxy::OnSwapBuffers(
|
||||||
|
+ base::OnceClosure swap_ack_callback) {
|
||||||
|
+ DCHECK(swap_ack_callback_.is_null());
|
||||||
|
+
|
||||||
|
+ // We aren't waiting on DrawAck() and can immediately run the callback.
|
||||||
|
+ if (!waiting_on_draw_ack_) {
|
||||||
|
+ task_runner_->PostTask(FROM_HERE, std::move(swap_ack_callback));
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ swap_ack_callback_ = std::move(swap_ack_callback);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void SoftwareOutputDeviceProxy::ResizeDelegated() {
|
||||||
|
+ canvas_.reset();
|
||||||
|
+
|
||||||
|
+ size_t required_bytes;
|
||||||
|
+ if (!ResourceSizes::MaybeSizeInBytes(
|
||||||
|
+ viewport_pixel_size_, ResourceFormat::RGBA_8888, &required_bytes)) {
|
||||||
|
+ DLOG(ERROR) << "Invalid viewport size " << viewport_pixel_size_.ToString();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ #if defined(WIN32)
|
||||||
|
+ base::SharedMemory shm;
|
||||||
|
+ if (!shm.CreateAnonymous(required_bytes)) {
|
||||||
|
+ DLOG(ERROR) << "Failed to allocate " << required_bytes << " bytes";
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ canvas_ = skia::CreatePlatformCanvasWithSharedSection(
|
||||||
|
+ viewport_pixel_size_.width(), viewport_pixel_size_.height(), false,
|
||||||
|
+ shm.handle().GetHandle(), skia::CRASH_ON_FAILURE);
|
||||||
|
+
|
||||||
|
+ // Transfer handle ownership to the browser process.
|
||||||
|
+ mojo::ScopedSharedBufferHandle scoped_handle = mojo::WrapSharedMemoryHandle(
|
||||||
|
+ shm.TakeHandle(), required_bytes,
|
||||||
|
+ mojo::UnwrappedSharedMemoryHandleProtection::kReadWrite);
|
||||||
|
+ #else
|
||||||
|
+ auto shm = mojo::CreateWritableSharedMemoryRegion(required_bytes);
|
||||||
|
+ if (!shm.IsValid()) {
|
||||||
|
+ DLOG(ERROR) << "Failed to allocate " << required_bytes << " bytes";
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ shm_mapping_ = shm.Map();
|
||||||
|
+ if (!shm_mapping_.IsValid()) {
|
||||||
|
+ DLOG(ERROR) << "Failed to map " << required_bytes << " bytes";
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ canvas_ = skia::CreatePlatformCanvasWithPixels(
|
||||||
|
+ viewport_pixel_size_.width(), viewport_pixel_size_.height(), false,
|
||||||
|
+ static_cast<uint8_t*>(shm_mapping_.memory()), skia::CRASH_ON_FAILURE);
|
||||||
|
+
|
||||||
|
+ mojo::ScopedSharedBufferHandle scoped_handle =
|
||||||
|
+ mojo::WrapWritableSharedMemoryRegion(std::move(shm));
|
||||||
|
+ #endif
|
||||||
|
+
|
||||||
|
+ layered_window_updater_->OnAllocatedSharedMemory(viewport_pixel_size_,
|
||||||
|
+ std::move(scoped_handle));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+SkCanvas* SoftwareOutputDeviceProxy::BeginPaintDelegated() {
|
||||||
|
+ return canvas_.get();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void SoftwareOutputDeviceProxy::EndPaintDelegated(
|
||||||
|
+ const gfx::Rect& damage_rect) {
|
||||||
|
+ DCHECK(!waiting_on_draw_ack_);
|
||||||
|
+
|
||||||
|
+ if (!canvas_)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ layered_window_updater_->Draw(damage_rect, base::BindOnce(
|
||||||
|
+ &SoftwareOutputDeviceProxy::DrawAck, base::Unretained(this)));
|
||||||
|
+ waiting_on_draw_ack_ = true;
|
||||||
|
+
|
||||||
|
+ TRACE_EVENT_ASYNC_BEGIN0("viz", "SoftwareOutputDeviceProxy::Draw", this);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void SoftwareOutputDeviceProxy::DrawAck() {
|
||||||
|
+ DCHECK(waiting_on_draw_ack_);
|
||||||
|
+ DCHECK(!swap_ack_callback_.is_null());
|
||||||
|
+
|
||||||
|
+ TRACE_EVENT_ASYNC_END0("viz", "SoftwareOutputDeviceProxy::Draw", this);
|
||||||
|
+
|
||||||
|
+ waiting_on_draw_ack_ = false;
|
||||||
|
+ std::move(swap_ack_callback_).Run();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+} // namespace viz
|
||||||
|
diff --git a/components/viz/service/display_embedder/software_output_device_proxy.h b/components/viz/service/display_embedder/software_output_device_proxy.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..01e1e2f0860faa1afe42c342c8905a7f838bd363
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/components/viz/service/display_embedder/software_output_device_proxy.h
|
||||||
|
@@ -0,0 +1,88 @@
|
||||||
|
+// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||||
|
+// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
+// found in the LICENSE file.
|
||||||
|
+
|
||||||
|
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_DEVICE_PROXY_H_
|
||||||
|
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_DEVICE_PROXY_H_
|
||||||
|
+
|
||||||
|
+#if defined(OS_WIN)
|
||||||
|
+#include <windows.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#include <memory>
|
||||||
|
+
|
||||||
|
+#include "components/viz/host/host_display_client.h"
|
||||||
|
+#include "components/viz/service/display/software_output_device.h"
|
||||||
|
+#include "components/viz/service/viz_service_export.h"
|
||||||
|
+#include "services/viz/privileged/interfaces/compositing/display_private.mojom.h"
|
||||||
|
+#include "services/viz/privileged/interfaces/compositing/layered_window_updater.mojom.h"
|
||||||
|
+
|
||||||
|
+namespace viz {
|
||||||
|
+
|
||||||
|
+// Shared base class for SoftwareOutputDevice implementations.
|
||||||
|
+class SoftwareOutputDeviceBase : public SoftwareOutputDevice {
|
||||||
|
+ public:
|
||||||
|
+ SoftwareOutputDeviceBase() = default;
|
||||||
|
+ ~SoftwareOutputDeviceBase() override;
|
||||||
|
+
|
||||||
|
+ // SoftwareOutputDevice implementation.
|
||||||
|
+ void Resize(const gfx::Size& viewport_pixel_size,
|
||||||
|
+ float scale_factor) override;
|
||||||
|
+ SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override;
|
||||||
|
+ void EndPaint() override;
|
||||||
|
+
|
||||||
|
+ // Called from Resize() if |viewport_pixel_size_| has changed.
|
||||||
|
+ virtual void ResizeDelegated() = 0;
|
||||||
|
+
|
||||||
|
+ // Called from BeginPaint() and should return an SkCanvas.
|
||||||
|
+ virtual SkCanvas* BeginPaintDelegated() = 0;
|
||||||
|
+
|
||||||
|
+ // Called from EndPaint() if there is damage.
|
||||||
|
+ virtual void EndPaintDelegated(const gfx::Rect& damage_rect) = 0;
|
||||||
|
+
|
||||||
|
+ private:
|
||||||
|
+ bool in_paint_ = false;
|
||||||
|
+
|
||||||
|
+ THREAD_CHECKER(thread_checker_);
|
||||||
|
+
|
||||||
|
+ DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceBase);
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+// SoftwareOutputDevice implementation that draws indirectly. An implementation
|
||||||
|
+// of mojom::LayeredWindowUpdater in the browser process handles the actual
|
||||||
|
+// drawing. Pixel backing is in SharedMemory so no copying between processes
|
||||||
|
+// is required.
|
||||||
|
+class SoftwareOutputDeviceProxy : public SoftwareOutputDeviceBase {
|
||||||
|
+ public:
|
||||||
|
+ explicit SoftwareOutputDeviceProxy(
|
||||||
|
+ mojom::LayeredWindowUpdaterPtr layered_window_updater);
|
||||||
|
+ ~SoftwareOutputDeviceProxy() override;
|
||||||
|
+
|
||||||
|
+ // SoftwareOutputDevice implementation.
|
||||||
|
+ void OnSwapBuffers(base::OnceClosure swap_ack_callback) override;
|
||||||
|
+
|
||||||
|
+ // SoftwareOutputDeviceBase implementation.
|
||||||
|
+ void ResizeDelegated() override;
|
||||||
|
+ SkCanvas* BeginPaintDelegated() override;
|
||||||
|
+ void EndPaintDelegated(const gfx::Rect& rect) override;
|
||||||
|
+
|
||||||
|
+ private:
|
||||||
|
+ // Runs |swap_ack_callback_| after draw has happened.
|
||||||
|
+ void DrawAck();
|
||||||
|
+
|
||||||
|
+ mojom::LayeredWindowUpdaterPtr layered_window_updater_;
|
||||||
|
+
|
||||||
|
+ std::unique_ptr<SkCanvas> canvas_;
|
||||||
|
+ bool waiting_on_draw_ack_ = false;
|
||||||
|
+ base::OnceClosure swap_ack_callback_;
|
||||||
|
+
|
||||||
|
+#if !defined(WIN32)
|
||||||
|
+ base::WritableSharedMemoryMapping shm_mapping_;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceProxy);
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+} // namespace viz
|
||||||
|
+
|
||||||
|
+#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_DEVICE_PROXY_H_
|
||||||
|
diff --git a/components/viz/service/display_embedder/software_output_device_win.cc b/components/viz/service/display_embedder/software_output_device_win.cc
|
||||||
|
index a339eaa4dc9ccec292b3df9f31adf1ad45119a77..33146bbe7bb01fbe24cea10d79cad2748dd04a24 100644
|
||||||
|
--- a/components/viz/service/display_embedder/software_output_device_win.cc
|
||||||
|
+++ b/components/viz/service/display_embedder/software_output_device_win.cc
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
#include "components/viz/common/display/use_layered_window.h"
|
||||||
|
#include "components/viz/common/resources/resource_sizes.h"
|
||||||
|
#include "components/viz/service/display_embedder/output_device_backing.h"
|
||||||
|
+#include "components/viz/service/display_embedder/software_output_device_proxy.h"
|
||||||
|
#include "mojo/public/cpp/system/platform_handle.h"
|
||||||
|
#include "services/viz/privileged/interfaces/compositing/layered_window_updater.mojom.h"
|
||||||
|
#include "skia/ext/platform_canvas.h"
|
||||||
|
@@ -321,7 +322,7 @@ void SoftwareOutputDeviceWinProxy::EndPaintDelegated(
|
||||||
|
if (!canvas_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- layered_window_updater_->Draw(base::BindOnce(
|
||||||
|
+ layered_window_updater_->Draw(damage_rect, base::BindOnce(
|
||||||
|
&SoftwareOutputDeviceWinProxy::DrawAck, base::Unretained(this)));
|
||||||
|
waiting_on_draw_ack_ = true;
|
||||||
|
|
||||||
|
@@ -362,8 +363,13 @@ std::unique_ptr<SoftwareOutputDevice> CreateSoftwareOutputDeviceWinGpu(
|
||||||
|
display_client->CreateLayeredWindowUpdater(
|
||||||
|
mojo::MakeRequest(&layered_window_updater));
|
||||||
|
|
||||||
|
- return std::make_unique<SoftwareOutputDeviceWinProxy>(
|
||||||
|
- hwnd, std::move(layered_window_updater));
|
||||||
|
+ bool offscreen = false;
|
||||||
|
+ if (display_client->IsOffscreen(&offscreen) && offscreen)
|
||||||
|
+ return std::make_unique<SoftwareOutputDeviceProxy>(
|
||||||
|
+ std::move(layered_window_updater));
|
||||||
|
+ else
|
||||||
|
+ return std::make_unique<SoftwareOutputDeviceWinProxy>(
|
||||||
|
+ hwnd, std::move(layered_window_updater));
|
||||||
|
} else {
|
||||||
|
return std::make_unique<SoftwareOutputDeviceWinDirect>(hwnd, backing);
|
||||||
|
}
|
||||||
|
diff --git a/services/viz/privileged/interfaces/compositing/display_private.mojom b/services/viz/privileged/interfaces/compositing/display_private.mojom
|
||||||
|
index 4c29f4ec2cde99749d4642928ff52ad3d4842f4a..5db220422bbc0ec6384c98681c245502a6442d6d 100644
|
||||||
|
--- a/services/viz/privileged/interfaces/compositing/display_private.mojom
|
||||||
|
+++ b/services/viz/privileged/interfaces/compositing/display_private.mojom
|
||||||
|
@@ -58,12 +58,14 @@ interface DisplayPrivate {
|
||||||
|
};
|
||||||
|
|
||||||
|
interface DisplayClient {
|
||||||
|
+ [Sync]
|
||||||
|
+ IsOffscreen() => (bool success);
|
||||||
|
+
|
||||||
|
[EnableIf=is_mac]
|
||||||
|
OnDisplayReceivedCALayerParams(gfx.mojom.CALayerParams ca_layer_params);
|
||||||
|
|
||||||
|
// Creates a LayeredWindowUpdater implementation to draw into a layered
|
||||||
|
// window.
|
||||||
|
- [EnableIf=is_win]
|
||||||
|
CreateLayeredWindowUpdater(LayeredWindowUpdater& layered_window_updater);
|
||||||
|
|
||||||
|
// Notifies that a swap has occurred and provides information about the pixel
|
||||||
|
diff --git a/services/viz/privileged/interfaces/compositing/layered_window_updater.mojom b/services/viz/privileged/interfaces/compositing/layered_window_updater.mojom
|
||||||
|
index 360cab3eee4c5189a55269d76daa1d78a98ed3d3..6834242f23d27fd6d428c2cd6040206a79d5097b 100644
|
||||||
|
--- a/services/viz/privileged/interfaces/compositing/layered_window_updater.mojom
|
||||||
|
+++ b/services/viz/privileged/interfaces/compositing/layered_window_updater.mojom
|
||||||
|
@@ -22,5 +22,5 @@ interface LayeredWindowUpdater {
|
||||||
|
// Draws to the HWND by copying pixels from shared memory. Callback must be
|
||||||
|
// called after draw operation is complete to signal shared memory can be
|
||||||
|
// modified.
|
||||||
|
- Draw() => ();
|
||||||
|
+ Draw(gfx.mojom.Rect damage_rect) => ();
|
||||||
|
};
|
||||||
|
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
|
||||||
|
index 29784c677f4be6e4fd7cfb298ab3554d22e1beaa..5d7da6481ebedb706c1dd31de1f7dfe4735433e8 100644
|
||||||
|
--- a/ui/compositor/compositor.h
|
||||||
|
+++ b/ui/compositor/compositor.h
|
||||||
|
@@ -24,6 +24,7 @@
|
||||||
|
#include "components/viz/common/frame_sinks/begin_frame_args.h"
|
||||||
|
#include "components/viz/common/surfaces/frame_sink_id.h"
|
||||||
|
#include "components/viz/common/surfaces/local_surface_id_allocation.h"
|
||||||
|
+#include "components/viz/host/host_display_client.h"
|
||||||
|
#include "components/viz/host/host_frame_sink_client.h"
|
||||||
|
#include "third_party/skia/include/core/SkColor.h"
|
||||||
|
#include "third_party/skia/include/core/SkMatrix44.h"
|
||||||
|
@@ -193,6 +194,15 @@ class COMPOSITOR_EXPORT ContextFactory {
|
||||||
|
virtual bool SyncTokensRequiredForDisplayCompositor() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
+class COMPOSITOR_EXPORT CompositorDelegate {
|
||||||
|
+ public:
|
||||||
|
+ virtual std::unique_ptr<viz::HostDisplayClient> CreateHostDisplayClient(
|
||||||
|
+ ui::Compositor* compositor) = 0;
|
||||||
|
+
|
||||||
|
+ protected:
|
||||||
|
+ virtual ~CompositorDelegate() {}
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
// Compositor object to take care of GPU painting.
|
||||||
|
// A Browser compositor object is responsible for generating the final
|
||||||
|
// displayable form of pixels comprising a single widget's contents. It draws an
|
||||||
|
@@ -235,6 +245,9 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
|
||||||
|
// Schedules a redraw of the layer tree associated with this compositor.
|
||||||
|
void ScheduleDraw();
|
||||||
|
|
||||||
|
+ CompositorDelegate* delegate() const { return delegate_; }
|
||||||
|
+ void SetDelegate(CompositorDelegate* delegate) { delegate_ = delegate; }
|
||||||
|
+
|
||||||
|
// Sets the root of the layer tree drawn by this Compositor. The root layer
|
||||||
|
// must have no parent. The compositor's root layer is reset if the root layer
|
||||||
|
// is destroyed. NULL can be passed to reset the root layer, in which case the
|
||||||
|
@@ -458,6 +471,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
|
||||||
|
ui::ContextFactory* context_factory_;
|
||||||
|
ui::ContextFactoryPrivate* context_factory_private_;
|
||||||
|
|
||||||
|
+ CompositorDelegate* delegate_ = nullptr;
|
||||||
|
+
|
||||||
|
// The root of the Layer tree drawn by this compositor.
|
||||||
|
Layer* root_layer_ = nullptr;
|
||||||
|
|
||||||
|
diff --git a/ui/compositor/host/host_context_factory_private.cc b/ui/compositor/host/host_context_factory_private.cc
|
||||||
|
index 8297e1aabe3b29698a965407e24d1e987be679d3..a78d455e99eb27730b6ac42cd5fd9469caa4a7de 100644
|
||||||
|
--- a/ui/compositor/host/host_context_factory_private.cc
|
||||||
|
+++ b/ui/compositor/host/host_context_factory_private.cc
|
||||||
|
@@ -70,8 +70,12 @@ void HostContextFactoryPrivate::ConfigureCompositor(
|
||||||
|
mojo::MakeRequest(&root_params->compositor_frame_sink_client);
|
||||||
|
root_params->display_private =
|
||||||
|
mojo::MakeRequest(&compositor_data.display_private);
|
||||||
|
- compositor_data.display_client =
|
||||||
|
- std::make_unique<viz::HostDisplayClient>(compositor->widget());
|
||||||
|
+ if (compositor->delegate())
|
||||||
|
+ compositor_data.display_client = compositor->delegate()->CreateHostDisplayClient(
|
||||||
|
+ compositor);
|
||||||
|
+ else
|
||||||
|
+ compositor_data.display_client =
|
||||||
|
+ std::make_unique<viz::HostDisplayClient>(compositor->widget());
|
||||||
|
root_params->display_client =
|
||||||
|
compositor_data.display_client->GetBoundPtr(resize_task_runner_)
|
||||||
|
.PassInterface();
|
||||||
|
diff --git a/ui/gfx/ca_layer_params.h b/ui/gfx/ca_layer_params.h
|
||||||
|
index 4014e64a75da88cf66c02e8adb71171c2666cab7..25e57784e1a1ffc546b003daa4cd0059c468432f 100644
|
||||||
|
--- a/ui/gfx/ca_layer_params.h
|
||||||
|
+++ b/ui/gfx/ca_layer_params.h
|
||||||
|
@@ -6,6 +6,7 @@
|
||||||
|
#define UI_GFX_CA_LAYER_PARAMS_H_
|
||||||
|
|
||||||
|
#include "build/build_config.h"
|
||||||
|
+#include "ui/gfx/geometry/rect.h"
|
||||||
|
#include "ui/gfx/geometry/size.h"
|
||||||
|
#include "ui/gfx/gfx_export.h"
|
||||||
|
|
||||||
|
@@ -41,6 +42,8 @@ struct GFX_EXPORT CALayerParams {
|
||||||
|
gfx::ScopedRefCountedIOSurfaceMachPort io_surface_mach_port;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ gfx::Rect damage;
|
||||||
|
+
|
||||||
|
// The geometry of the frame.
|
||||||
|
gfx::Size pixel_size;
|
||||||
|
float scale_factor = 1.f;
|
||||||
|
diff --git a/ui/gfx/mojo/ca_layer_params.mojom b/ui/gfx/mojo/ca_layer_params.mojom
|
||||||
|
index 7bf735643541b18bafffe645d3ff37e96caa4dea..f7eaf10ffd665789f10a587142fac0c0c79b9798 100644
|
||||||
|
--- a/ui/gfx/mojo/ca_layer_params.mojom
|
||||||
|
+++ b/ui/gfx/mojo/ca_layer_params.mojom
|
||||||
|
@@ -18,5 +18,6 @@ struct CALayerParams {
|
||||||
|
bool is_empty;
|
||||||
|
CALayerContent content;
|
||||||
|
gfx.mojom.Size pixel_size;
|
||||||
|
+ gfx.mojom.Rect damage;
|
||||||
|
float scale_factor;
|
||||||
|
};
|
||||||
|
diff --git a/ui/gfx/mojo/ca_layer_params_struct_traits.cc b/ui/gfx/mojo/ca_layer_params_struct_traits.cc
|
||||||
|
index dd553996b5c6ff5ec0c210a020a18a6a843b8aae..26d1e0bda2640052d42ea4e691c3df73074dea08 100644
|
||||||
|
--- a/ui/gfx/mojo/ca_layer_params_struct_traits.cc
|
||||||
|
+++ b/ui/gfx/mojo/ca_layer_params_struct_traits.cc
|
||||||
|
@@ -52,6 +52,9 @@ bool StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams>::Read(
|
||||||
|
if (!data.ReadPixelSize(&out->pixel_size))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
+ if (!data.ReadDamage(&out->damage))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
out->scale_factor = data.scale_factor();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
diff --git a/ui/gfx/mojo/ca_layer_params_struct_traits.h b/ui/gfx/mojo/ca_layer_params_struct_traits.h
|
||||||
|
index 94127a0d5b50b052318e9e5a360755fe771f87e9..348fa26c5c95a13d1ddd0ff2545aca3a35841a77 100644
|
||||||
|
--- a/ui/gfx/mojo/ca_layer_params_struct_traits.h
|
||||||
|
+++ b/ui/gfx/mojo/ca_layer_params_struct_traits.h
|
||||||
|
@@ -20,6 +20,10 @@ struct StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams> {
|
||||||
|
return ca_layer_params.pixel_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ static gfx::Rect damage(const gfx::CALayerParams& ca_layer_params) {
|
||||||
|
+ return ca_layer_params.damage;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
static float scale_factor(const gfx::CALayerParams& ca_layer_params) {
|
||||||
|
return ca_layer_params.scale_factor;
|
||||||
|
}
|
|
@ -3702,14 +3702,18 @@ describe('BrowserWindow module', () => {
|
||||||
w.webContents.once('paint', function (event, rect, data) {
|
w.webContents.once('paint', function (event, rect, data) {
|
||||||
assert.notStrictEqual(data.length, 0)
|
assert.notStrictEqual(data.length, 0)
|
||||||
const size = data.getSize()
|
const size = data.getSize()
|
||||||
const scale = process.platform === 'darwin' ? devicePixelRatio : 1
|
assertWithinDelta(size.width, 100 * devicePixelRatio, 2, 'width')
|
||||||
assertWithinDelta(size.width, 100 * scale, 2, 'width')
|
assertWithinDelta(size.height, 100 * devicePixelRatio, 2, 'height')
|
||||||
assertWithinDelta(size.height, 100 * scale, 2, 'height')
|
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
w.loadFile(path.join(fixtures, 'api', 'offscreen-rendering.html'))
|
w.loadFile(path.join(fixtures, 'api', 'offscreen-rendering.html'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('does not crash after navigation', () => {
|
||||||
|
w.webContents.loadURL('about:blank')
|
||||||
|
w.loadFile(path.join(fixtures, 'api', 'offscreen-rendering.html'))
|
||||||
|
})
|
||||||
|
|
||||||
describe('window.webContents.isOffscreen()', () => {
|
describe('window.webContents.isOffscreen()', () => {
|
||||||
it('is true for offscreen type', () => {
|
it('is true for offscreen type', () => {
|
||||||
w.loadFile(path.join(fixtures, 'api', 'offscreen-rendering.html'))
|
w.loadFile(path.join(fixtures, 'api', 'offscreen-rendering.html'))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue