Skip to content

Commit 81bf158

Browse files
brencacodebytere
authored andcommitted
fix: port OSR code to new viz compositor codepath (electron#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
1 parent 1478bd3 commit 81bf158

22 files changed

+1300
-775
lines changed

BUILD.gn

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -632,11 +632,13 @@ static_library("electron_lib") {
632632

633633
if (enable_osr) {
634634
sources += [
635-
"atom/browser/osr/osr_output_device.cc",
636-
"atom/browser/osr/osr_output_device.h",
635+
"atom/browser/osr/osr_host_display_client.cc",
636+
"atom/browser/osr/osr_host_display_client.h",
637+
"atom/browser/osr/osr_host_display_client_mac.mm",
637638
"atom/browser/osr/osr_render_widget_host_view.cc",
638639
"atom/browser/osr/osr_render_widget_host_view.h",
639-
"atom/browser/osr/osr_render_widget_host_view_mac.mm",
640+
"atom/browser/osr/osr_video_consumer.cc",
641+
"atom/browser/osr/osr_video_consumer.h",
640642
"atom/browser/osr/osr_view_proxy.cc",
641643
"atom/browser/osr/osr_view_proxy.h",
642644
"atom/browser/osr/osr_web_contents_view.cc",
@@ -811,6 +813,11 @@ if (is_mac) {
811813
"ServiceManagement.framework",
812814
"StoreKit.framework",
813815
]
816+
817+
if (enable_osr) {
818+
libs += [ "IOSurface.framework" ]
819+
}
820+
814821
ldflags = [
815822
"-F",
816823
rebase_path("external_binaries", root_build_dir),

atom/browser/api/atom_api_web_contents.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@
9191
#include "ui/events/base_event_utils.h"
9292

9393
#if BUILDFLAG(ENABLE_OSR)
94-
#include "atom/browser/osr/osr_output_device.h"
9594
#include "atom/browser/osr/osr_render_widget_host_view.h"
9695
#include "atom/browser/osr/osr_web_contents_view.h"
9796
#endif

atom/browser/native_window_mac.mm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,10 @@ static bool FromV8(v8::Isolate* isolate,
233233
namespace {
234234

235235
bool IsFramelessWindow(NSView* view) {
236-
NativeWindow* window = [static_cast<AtomNSWindow*>([view window]) shell];
236+
NSWindow* nswindow = [view window];
237+
if (![nswindow respondsToSelector:@selector(shell)])
238+
return false;
239+
NativeWindow* window = [static_cast<AtomNSWindow*>(nswindow) shell];
237240
return window && !window->has_frame();
238241
}
239242

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Copyright (c) 2019 GitHub, Inc.
2+
// Use of this source code is governed by the MIT license that can be
3+
// found in the LICENSE file.
4+
5+
#include "atom/browser/osr/osr_host_display_client.h"
6+
7+
#include <utility>
8+
9+
#include "components/viz/common/resources/resource_format.h"
10+
#include "components/viz/common/resources/resource_sizes.h"
11+
#include "mojo/public/cpp/system/platform_handle.h"
12+
#include "skia/ext/platform_canvas.h"
13+
#include "third_party/skia/include/core/SkColor.h"
14+
#include "third_party/skia/include/core/SkRect.h"
15+
#include "third_party/skia/src/core/SkDevice.h"
16+
#include "ui/gfx/skia_util.h"
17+
18+
#if defined(OS_WIN)
19+
#include "skia/ext/skia_utils_win.h"
20+
#endif
21+
22+
namespace atom {
23+
24+
LayeredWindowUpdater::LayeredWindowUpdater(
25+
viz::mojom::LayeredWindowUpdaterRequest request,
26+
OnPaintCallback callback)
27+
: callback_(callback), binding_(this, std::move(request)) {}
28+
29+
LayeredWindowUpdater::~LayeredWindowUpdater() = default;
30+
31+
void LayeredWindowUpdater::SetActive(bool active) {
32+
active_ = active;
33+
}
34+
35+
void LayeredWindowUpdater::OnAllocatedSharedMemory(
36+
const gfx::Size& pixel_size,
37+
mojo::ScopedSharedBufferHandle scoped_buffer_handle) {
38+
canvas_.reset();
39+
40+
// Make sure |pixel_size| is sane.
41+
size_t expected_bytes;
42+
bool size_result = viz::ResourceSizes::MaybeSizeInBytes(
43+
pixel_size, viz::ResourceFormat::RGBA_8888, &expected_bytes);
44+
if (!size_result)
45+
return;
46+
47+
#if defined(WIN32)
48+
base::SharedMemoryHandle shm_handle;
49+
size_t required_bytes;
50+
MojoResult unwrap_result = mojo::UnwrapSharedMemoryHandle(
51+
std::move(scoped_buffer_handle), &shm_handle, &required_bytes, nullptr);
52+
if (unwrap_result != MOJO_RESULT_OK)
53+
return;
54+
55+
base::SharedMemory shm(shm_handle, false);
56+
if (!shm.Map(required_bytes)) {
57+
DLOG(ERROR) << "Failed to map " << required_bytes << " bytes";
58+
return;
59+
}
60+
61+
canvas_ = skia::CreatePlatformCanvasWithSharedSection(
62+
pixel_size.width(), pixel_size.height(), false, shm.handle().GetHandle(),
63+
skia::CRASH_ON_FAILURE);
64+
#else
65+
auto shm =
66+
mojo::UnwrapWritableSharedMemoryRegion(std::move(scoped_buffer_handle));
67+
if (!shm.IsValid()) {
68+
DLOG(ERROR) << "Failed to unwrap shared memory region";
69+
return;
70+
}
71+
72+
shm_mapping_ = shm.Map();
73+
if (!shm_mapping_.IsValid()) {
74+
DLOG(ERROR) << "Failed to map shared memory region";
75+
return;
76+
}
77+
78+
canvas_ = skia::CreatePlatformCanvasWithPixels(
79+
pixel_size.width(), pixel_size.height(), false,
80+
static_cast<uint8_t*>(shm_mapping_.memory()), skia::CRASH_ON_FAILURE);
81+
#endif
82+
}
83+
84+
void LayeredWindowUpdater::Draw(const gfx::Rect& damage_rect,
85+
DrawCallback draw_callback) {
86+
SkPixmap pixmap;
87+
SkBitmap bitmap;
88+
89+
if (active_ && canvas_->peekPixels(&pixmap)) {
90+
bitmap.installPixels(pixmap);
91+
callback_.Run(damage_rect, bitmap);
92+
}
93+
94+
std::move(draw_callback).Run();
95+
}
96+
97+
OffScreenHostDisplayClient::OffScreenHostDisplayClient(
98+
gfx::AcceleratedWidget widget,
99+
OnPaintCallback callback)
100+
: viz::HostDisplayClient(widget), callback_(callback) {}
101+
OffScreenHostDisplayClient::~OffScreenHostDisplayClient() {}
102+
103+
void OffScreenHostDisplayClient::SetActive(bool active) {
104+
active_ = active;
105+
if (layered_window_updater_) {
106+
layered_window_updater_->SetActive(active_);
107+
}
108+
}
109+
110+
void OffScreenHostDisplayClient::IsOffscreen(IsOffscreenCallback callback) {
111+
std::move(callback).Run(true);
112+
}
113+
114+
void OffScreenHostDisplayClient::CreateLayeredWindowUpdater(
115+
viz::mojom::LayeredWindowUpdaterRequest request) {
116+
layered_window_updater_ =
117+
std::make_unique<LayeredWindowUpdater>(std::move(request), callback_);
118+
layered_window_updater_->SetActive(active_);
119+
}
120+
121+
} // namespace atom
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) 2019 GitHub, Inc.
2+
// Use of this source code is governed by the MIT license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef ATOM_BROWSER_OSR_OSR_HOST_DISPLAY_CLIENT_H_
6+
#define ATOM_BROWSER_OSR_OSR_HOST_DISPLAY_CLIENT_H_
7+
8+
#include <memory>
9+
10+
#include "base/callback.h"
11+
#include "base/memory/shared_memory.h"
12+
#include "components/viz/host/host_display_client.h"
13+
#include "services/viz/privileged/interfaces/compositing/layered_window_updater.mojom.h"
14+
#include "third_party/skia/include/core/SkBitmap.h"
15+
#include "third_party/skia/include/core/SkCanvas.h"
16+
#include "ui/gfx/native_widget_types.h"
17+
18+
namespace atom {
19+
20+
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
21+
22+
class LayeredWindowUpdater : public viz::mojom::LayeredWindowUpdater {
23+
public:
24+
explicit LayeredWindowUpdater(viz::mojom::LayeredWindowUpdaterRequest request,
25+
OnPaintCallback callback);
26+
~LayeredWindowUpdater() override;
27+
28+
void SetActive(bool active);
29+
30+
// viz::mojom::LayeredWindowUpdater implementation.
31+
void OnAllocatedSharedMemory(
32+
const gfx::Size& pixel_size,
33+
mojo::ScopedSharedBufferHandle scoped_buffer_handle) override;
34+
void Draw(const gfx::Rect& damage_rect, DrawCallback draw_callback) override;
35+
36+
private:
37+
OnPaintCallback callback_;
38+
mojo::Binding<viz::mojom::LayeredWindowUpdater> binding_;
39+
std::unique_ptr<SkCanvas> canvas_;
40+
bool active_ = false;
41+
42+
#if !defined(WIN32)
43+
base::WritableSharedMemoryMapping shm_mapping_;
44+
#endif
45+
46+
DISALLOW_COPY_AND_ASSIGN(LayeredWindowUpdater);
47+
};
48+
49+
class OffScreenHostDisplayClient : public viz::HostDisplayClient {
50+
public:
51+
explicit OffScreenHostDisplayClient(gfx::AcceleratedWidget widget,
52+
OnPaintCallback callback);
53+
~OffScreenHostDisplayClient() override;
54+
55+
void SetActive(bool active);
56+
57+
private:
58+
void IsOffscreen(IsOffscreenCallback callback) override;
59+
60+
#if defined(OS_MACOSX)
61+
void OnDisplayReceivedCALayerParams(
62+
const gfx::CALayerParams& ca_layer_params) override;
63+
#endif
64+
65+
void CreateLayeredWindowUpdater(
66+
viz::mojom::LayeredWindowUpdaterRequest request) override;
67+
68+
std::unique_ptr<LayeredWindowUpdater> layered_window_updater_;
69+
OnPaintCallback callback_;
70+
bool active_ = false;
71+
72+
DISALLOW_COPY_AND_ASSIGN(OffScreenHostDisplayClient);
73+
};
74+
75+
} // namespace atom
76+
77+
#endif // ATOM_BROWSER_OSR_OSR_HOST_DISPLAY_CLIENT_H_
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) 2019 GitHub, Inc.
2+
// Use of this source code is governed by the MIT license that can be
3+
// found in the LICENSE file.
4+
5+
#include "atom/browser/osr/osr_host_display_client.h"
6+
7+
#include <IOSurface/IOSurface.h>
8+
9+
namespace atom {
10+
11+
void OffScreenHostDisplayClient::OnDisplayReceivedCALayerParams(
12+
const gfx::CALayerParams& ca_layer_params) {
13+
if (!ca_layer_params.is_empty) {
14+
base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
15+
IOSurfaceLookupFromMachPort(ca_layer_params.io_surface_mach_port));
16+
17+
gfx::Size pixel_size_ = ca_layer_params.pixel_size;
18+
void* pixels = static_cast<void*>(IOSurfaceGetBaseAddress(io_surface));
19+
size_t stride = IOSurfaceGetBytesPerRow(io_surface);
20+
21+
struct IOSurfacePinner {
22+
base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
23+
};
24+
25+
SkBitmap bitmap;
26+
bitmap.installPixels(
27+
SkImageInfo::MakeN32(pixel_size_.width(), pixel_size_.height(),
28+
kPremul_SkAlphaType),
29+
pixels, stride);
30+
bitmap.setImmutable();
31+
callback_.Run(ca_layer_params.damage, bitmap);
32+
}
33+
}
34+
35+
} // namespace atom

atom/browser/osr/osr_output_device.cc

Lines changed: 0 additions & 101 deletions
This file was deleted.

0 commit comments

Comments
 (0)