feat: GPU shared texture offscreen rendering (#42953)

* feat: GPU shared texture offscreen rendering

* docs: clarify texture infos that passed by the paint event.

* feat: make gpu osr spec test optional

* fix: osr image compare

* fix: remove duplicate test

* fix: update patch file

* fix: code review

* feat: expose more metadata

* feat: use better switch design

* feat: add warning when user forget to release the texture.

* fix: typo

* chore: update patch

* fix: update patch

* fix: update patch description

* fix: update docs

* fix: apply suggestions from code review

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* fix: apply suggested fixes

---------

Co-authored-by: Charles Kerr <charles@charleskerr.com>
This commit is contained in:
reito 2024-08-23 08:23:13 +08:00 committed by GitHub
parent b481966f02
commit 1aeca6fd0e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 1009 additions and 102 deletions

View file

@ -121,6 +121,7 @@
#include "shell/common/gin_converters/image_converter.h"
#include "shell/common/gin_converters/net_converter.h"
#include "shell/common/gin_converters/optional_converter.h"
#include "shell/common/gin_converters/osr_converter.h"
#include "shell/common/gin_converters/value_converter.h"
#include "shell/common/gin_helper/dictionary.h"
#include "shell/common/gin_helper/error_thrower.h"
@ -760,9 +761,23 @@ WebContents::WebContents(v8::Isolate* isolate,
// Get transparent for guest view
options.Get("transparent", &guest_transparent_);
bool b = false;
if (options.Get(options::kOffscreen, &b) && b)
type_ = Type::kOffScreen;
// Offscreen rendering
v8::Local<v8::Value> use_offscreen;
if (options.Get(options::kOffscreen, &use_offscreen)) {
if (use_offscreen->IsBoolean()) {
bool b = false;
if (options.Get(options::kOffscreen, &b) && b) {
type_ = Type::kOffScreen;
}
} else if (use_offscreen->IsObject()) {
type_ = Type::kOffScreen;
auto use_offscreen_dict =
gin_helper::Dictionary::CreateEmpty(options.isolate());
options.Get(options::kOffscreen, &use_offscreen_dict);
use_offscreen_dict.Get(options::kUseSharedTexture,
&offscreen_use_shared_texture_);
}
}
// Init embedder earlier
options.Get("embedder", &embedder_);
@ -798,7 +813,7 @@ WebContents::WebContents(v8::Isolate* isolate,
if (embedder_ && embedder_->IsOffScreen()) {
auto* view = new OffScreenWebContentsView(
false,
false, offscreen_use_shared_texture_,
base::BindRepeating(&WebContents::OnPaint, base::Unretained(this)));
params.view = view;
params.delegate_view = view;
@ -818,7 +833,7 @@ WebContents::WebContents(v8::Isolate* isolate,
content::WebContents::CreateParams params(session->browser_context());
auto* view = new OffScreenWebContentsView(
transparent,
transparent, offscreen_use_shared_texture_,
base::BindRepeating(&WebContents::OnPaint, base::Unretained(this)));
params.view = view;
params.delegate_view = view;
@ -3535,8 +3550,23 @@ bool WebContents::IsOffScreen() const {
return type_ == Type::kOffScreen;
}
void WebContents::OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap) {
Emit("paint", dirty_rect, gfx::Image::CreateFrom1xBitmap(bitmap));
void WebContents::OnPaint(const gfx::Rect& dirty_rect,
const SkBitmap& bitmap,
const OffscreenSharedTexture& tex) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope handle_scope(isolate);
gin::Handle<gin_helper::internal::Event> event =
gin_helper::internal::Event::New(isolate);
v8::Local<v8::Object> event_object = event.ToV8().As<v8::Object>();
gin_helper::Dictionary dict(isolate, event_object);
if (offscreen_use_shared_texture_) {
dict.Set("texture", tex);
}
EmitWithoutEvent("paint", event, dirty_rect,
gfx::Image::CreateFrom1xBitmap(bitmap));
}
void WebContents::StartPainting() {