Skip to content
Permalink
Browse files

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
  • Loading branch information...
brenca authored and codebytere committed Apr 17, 2019
1 parent 1478bd3 commit 81bf15877f169dcd9680cfed088a751c5f5aff5a
@@ -632,11 +632,13 @@ static_library("electron_lib") {

if (enable_osr) {
sources += [
"atom/browser/osr/osr_output_device.cc",
"atom/browser/osr/osr_output_device.h",
"atom/browser/osr/osr_host_display_client.cc",
"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.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.h",
"atom/browser/osr/osr_web_contents_view.cc",
@@ -811,6 +813,11 @@ if (is_mac) {
"ServiceManagement.framework",
"StoreKit.framework",
]

if (enable_osr) {
libs += [ "IOSurface.framework" ]
}

ldflags = [
"-F",
rebase_path("external_binaries", root_build_dir),
@@ -91,7 +91,6 @@
#include "ui/events/base_event_utils.h"

#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_web_contents_view.h"
#endif
@@ -233,7 +233,10 @@ static bool FromV8(v8::Isolate* isolate,
namespace {

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();
}

@@ -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
@@ -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_
@@ -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

This file was deleted.

Oops, something went wrong.
Oops, something went wrong.

0 comments on commit 81bf158

Please sign in to comment.
You can’t perform that action at this time.