Merge pull request #8839 from brenca/offscreen-child-window
Offscreen rendering enhancements
This commit is contained in:
commit
1b1c663b32
16 changed files with 675 additions and 285 deletions
|
@ -49,6 +49,7 @@
|
|||
#include "chrome/browser/ssl/security_state_tab_helper.h"
|
||||
#include "content/browser/frame_host/navigation_entry_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_base.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/public/browser/favicon_status.h"
|
||||
|
@ -316,6 +317,9 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
|
|||
else if (options.Get("offscreen", &b) && b)
|
||||
type_ = OFF_SCREEN;
|
||||
|
||||
// Init embedder earlier
|
||||
options.Get("embedder", &embedder_);
|
||||
|
||||
// Whether to enable DevTools.
|
||||
options.Get("devTools", &enable_devtools_);
|
||||
|
||||
|
@ -340,7 +344,18 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
|
|||
session->browser_context(), site_instance);
|
||||
guest_delegate_.reset(new WebViewGuestDelegate);
|
||||
params.guest_delegate = guest_delegate_.get();
|
||||
web_contents = content::WebContents::Create(params);
|
||||
|
||||
if (embedder_ && embedder_->IsOffScreen()) {
|
||||
auto* view = new OffScreenWebContentsView(false,
|
||||
base::Bind(&WebContents::OnPaint, base::Unretained(this)));
|
||||
params.view = view;
|
||||
params.delegate_view = view;
|
||||
|
||||
web_contents = content::WebContents::Create(params);
|
||||
view->SetWebContents(web_contents);
|
||||
} else {
|
||||
web_contents = content::WebContents::Create(params);
|
||||
}
|
||||
} else if (IsOffScreen()) {
|
||||
bool transparent = false;
|
||||
options.Get("transparent", &transparent);
|
||||
|
@ -390,7 +405,7 @@ void WebContents::InitWithSessionAndOptions(v8::Isolate* isolate,
|
|||
guest_delegate_->Initialize(this);
|
||||
|
||||
NativeWindow* owner_window = nullptr;
|
||||
if (options.Get("embedder", &embedder_) && embedder_) {
|
||||
if (embedder_) {
|
||||
// New WebContents's owner_window is the embedder's owner_window.
|
||||
auto relay =
|
||||
NativeWindowRelay::FromWebContents(embedder_->web_contents());
|
||||
|
@ -1404,18 +1419,16 @@ bool WebContents::SendIPCMessage(bool all_frames,
|
|||
|
||||
void WebContents::SendInputEvent(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> input_event) {
|
||||
const auto view = web_contents()->GetRenderWidgetHostView();
|
||||
const auto view = static_cast<content::RenderWidgetHostViewBase*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
if (!view)
|
||||
return;
|
||||
const auto host = view->GetRenderWidgetHost();
|
||||
if (!host)
|
||||
return;
|
||||
|
||||
int type = mate::GetWebInputEventType(isolate, input_event);
|
||||
if (blink::WebInputEvent::isMouseEventType(type)) {
|
||||
blink::WebMouseEvent mouse_event;
|
||||
if (mate::ConvertFromV8(isolate, input_event, &mouse_event)) {
|
||||
host->ForwardMouseEvent(mouse_event);
|
||||
view->ProcessMouseEvent(mouse_event, ui::LatencyInfo());
|
||||
return;
|
||||
}
|
||||
} else if (blink::WebInputEvent::isKeyboardEventType(type)) {
|
||||
|
@ -1424,13 +1437,13 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
|
|||
blink::WebInputEvent::NoModifiers,
|
||||
ui::EventTimeForNow());
|
||||
if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) {
|
||||
host->ForwardKeyboardEvent(keyboard_event);
|
||||
view->ProcessKeyboardEvent(keyboard_event);
|
||||
return;
|
||||
}
|
||||
} else if (type == blink::WebInputEvent::MouseWheel) {
|
||||
blink::WebMouseWheelEvent mouse_wheel_event;
|
||||
if (mate::ConvertFromV8(isolate, input_event, &mouse_wheel_event)) {
|
||||
host->ForwardWheelEvent(mouse_wheel_event);
|
||||
view->ProcessMouseWheelEvent(mouse_wheel_event, ui::LatencyInfo());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1567,9 +1580,7 @@ bool WebContents::IsOffScreen() const {
|
|||
}
|
||||
|
||||
void WebContents::OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap) {
|
||||
mate::Handle<NativeImage> image =
|
||||
NativeImage::Create(isolate(), gfx::Image::CreateFrom1xBitmap(bitmap));
|
||||
Emit("paint", dirty_rect, image);
|
||||
Emit("paint", dirty_rect, gfx::Image::CreateFrom1xBitmap(bitmap));
|
||||
}
|
||||
|
||||
void WebContents::StartPainting() {
|
||||
|
|
|
@ -147,6 +147,7 @@ class NativeWindow : public base::SupportsUserData,
|
|||
virtual void SetMenu(AtomMenuModel* menu);
|
||||
virtual void SetParentWindow(NativeWindow* parent);
|
||||
virtual void SetBrowserView(NativeBrowserView* browser_view) = 0;
|
||||
virtual gfx::NativeView GetNativeView() = 0;
|
||||
virtual gfx::NativeWindow GetNativeWindow() = 0;
|
||||
virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ class NativeWindowMac : public NativeWindow,
|
|||
void SetContentProtection(bool enable) override;
|
||||
void SetBrowserView(NativeBrowserView* browser_view) override;
|
||||
void SetParentWindow(NativeWindow* parent) override;
|
||||
gfx::NativeView GetNativeView() override;
|
||||
gfx::NativeWindow GetNativeWindow() override;
|
||||
gfx::AcceleratedWidget GetAcceleratedWidget() override;
|
||||
void SetProgressBar(double progress, const ProgressState state) override;
|
||||
|
|
|
@ -1314,6 +1314,10 @@ void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
|
|||
[parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove];
|
||||
}
|
||||
|
||||
gfx::NativeView NativeWindowMac::GetNativeView() {
|
||||
return inspectable_web_contents()->GetView()->GetNativeView();
|
||||
}
|
||||
|
||||
gfx::NativeWindow NativeWindowMac::GetNativeWindow() {
|
||||
return window_;
|
||||
}
|
||||
|
|
|
@ -924,6 +924,10 @@ void NativeWindowViews::SetParentWindow(NativeWindow* parent) {
|
|||
#endif
|
||||
}
|
||||
|
||||
gfx::NativeView NativeWindowViews::GetNativeView() {
|
||||
return window_->GetNativeView();
|
||||
}
|
||||
|
||||
gfx::NativeWindow NativeWindowViews::GetNativeWindow() {
|
||||
return window_->GetNativeWindow();
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ class NativeWindowViews : public NativeWindow,
|
|||
void SetMenu(AtomMenuModel* menu_model) override;
|
||||
void SetBrowserView(NativeBrowserView* browser_view) override;
|
||||
void SetParentWindow(NativeWindow* parent) override;
|
||||
gfx::NativeView GetNativeView() override;
|
||||
gfx::NativeWindow GetNativeWindow() override;
|
||||
void SetOverlayIcon(const gfx::Image& overlay,
|
||||
const std::string& description) override;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#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"
|
||||
|
||||
|
@ -36,8 +38,11 @@ void OffScreenOutputDevice::Resize(
|
|||
return;
|
||||
}
|
||||
|
||||
if (transparent_)
|
||||
bitmap_->eraseARGB(0, 0, 0, 0);
|
||||
if (transparent_) {
|
||||
bitmap_->eraseColor(SK_ColorTRANSPARENT);
|
||||
} else {
|
||||
bitmap_->eraseColor(SK_ColorWHITE);
|
||||
}
|
||||
|
||||
canvas_.reset(new SkCanvas(*bitmap_));
|
||||
}
|
||||
|
@ -47,6 +52,17 @@ SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) {
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "content/browser/renderer_host/render_widget_host_delegate.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_frame_subscriber.h"
|
||||
#include "content/browser/renderer_host/resize_lock.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/context_factory.h"
|
||||
|
@ -27,6 +28,7 @@
|
|||
#include "ui/events/latency_info.h"
|
||||
#include "ui/gfx/geometry/dip_util.h"
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
#include "ui/gfx/skbitmap_operations.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
|
@ -35,72 +37,87 @@ namespace {
|
|||
const float kDefaultScaleFactor = 1.0;
|
||||
const int kFrameRetryLimit = 2;
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
|
||||
const int kResizeLockTimeoutMs = 67;
|
||||
|
||||
class AtomResizeLock : public content::ResizeLock {
|
||||
public:
|
||||
AtomResizeLock(OffScreenRenderWidgetHostView* host,
|
||||
const gfx::Size new_size,
|
||||
bool defer_compositor_lock)
|
||||
: ResizeLock(new_size, defer_compositor_lock),
|
||||
host_(host),
|
||||
cancelled_(false),
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(host_);
|
||||
host_->HoldResize();
|
||||
|
||||
content::BrowserThread::PostDelayedTask(content::BrowserThread::UI,
|
||||
FROM_HERE, base::Bind(&AtomResizeLock::CancelLock,
|
||||
weak_ptr_factory_.GetWeakPtr()),
|
||||
base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs));
|
||||
}
|
||||
|
||||
~AtomResizeLock() override {
|
||||
CancelLock();
|
||||
}
|
||||
|
||||
bool GrabDeferredLock() override {
|
||||
return ResizeLock::GrabDeferredLock();
|
||||
}
|
||||
|
||||
void UnlockCompositor() override {
|
||||
ResizeLock::UnlockCompositor();
|
||||
compositor_lock_ = NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
void LockCompositor() override {
|
||||
ResizeLock::LockCompositor();
|
||||
compositor_lock_ = host_->GetCompositor()->GetCompositorLock();
|
||||
}
|
||||
|
||||
void CancelLock() {
|
||||
if (cancelled_)
|
||||
return;
|
||||
cancelled_ = true;
|
||||
UnlockCompositor();
|
||||
host_->ReleaseResize();
|
||||
}
|
||||
|
||||
private:
|
||||
OffScreenRenderWidgetHostView* host_;
|
||||
scoped_refptr<ui::CompositorLock> compositor_lock_;
|
||||
bool cancelled_;
|
||||
base::WeakPtrFactory<AtomResizeLock> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomResizeLock);
|
||||
};
|
||||
|
||||
#endif // !defined(OS_MACOSX)
|
||||
|
||||
} // namespace
|
||||
|
||||
class AtomCopyFrameGenerator {
|
||||
public:
|
||||
AtomCopyFrameGenerator(int frame_rate_threshold_ms,
|
||||
OffScreenRenderWidgetHostView* view)
|
||||
: frame_rate_threshold_ms_(frame_rate_threshold_ms),
|
||||
view_(view),
|
||||
frame_pending_(false),
|
||||
frame_in_progress_(false),
|
||||
AtomCopyFrameGenerator(OffScreenRenderWidgetHostView* view,
|
||||
int frame_rate_threshold_us)
|
||||
: view_(view),
|
||||
frame_retry_count_(0),
|
||||
next_frame_time_(base::TimeTicks::Now()),
|
||||
frame_duration_(base::TimeDelta::FromMicroseconds(
|
||||
frame_rate_threshold_us)),
|
||||
weak_ptr_factory_(this) {
|
||||
last_time_ = base::Time::Now();
|
||||
}
|
||||
|
||||
void GenerateCopyFrame(
|
||||
bool force_frame,
|
||||
const gfx::Rect& damage_rect) {
|
||||
if (force_frame && !frame_pending_)
|
||||
frame_pending_ = true;
|
||||
|
||||
if (!frame_pending_)
|
||||
return;
|
||||
|
||||
if (!damage_rect.IsEmpty())
|
||||
pending_damage_rect_.Union(damage_rect);
|
||||
|
||||
if (frame_in_progress_)
|
||||
return;
|
||||
|
||||
frame_in_progress_ = true;
|
||||
|
||||
const int64_t frame_rate_delta =
|
||||
(base::TimeTicks::Now() - frame_start_time_).InMilliseconds();
|
||||
if (frame_rate_delta < frame_rate_threshold_ms_) {
|
||||
content::BrowserThread::PostDelayedTask(content::BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&AtomCopyFrameGenerator::InternalGenerateCopyFrame,
|
||||
weak_ptr_factory_.GetWeakPtr()),
|
||||
base::TimeDelta::FromMilliseconds(
|
||||
frame_rate_threshold_ms_ - frame_rate_delta));
|
||||
return;
|
||||
}
|
||||
|
||||
InternalGenerateCopyFrame();
|
||||
}
|
||||
|
||||
bool frame_pending() const { return frame_pending_; }
|
||||
|
||||
void set_frame_rate_threshold_ms(int frame_rate_threshold_ms) {
|
||||
frame_rate_threshold_ms_ = frame_rate_threshold_ms;
|
||||
}
|
||||
|
||||
private:
|
||||
void InternalGenerateCopyFrame() {
|
||||
frame_pending_ = false;
|
||||
frame_start_time_ = base::TimeTicks::Now();
|
||||
|
||||
void GenerateCopyFrame(const gfx::Rect& damage_rect) {
|
||||
if (!view_->render_widget_host())
|
||||
return;
|
||||
|
||||
const gfx::Rect damage_rect = pending_damage_rect_;
|
||||
pending_damage_rect_.SetRect(0, 0, 0, 0);
|
||||
|
||||
std::unique_ptr<cc::CopyOutputRequest> request =
|
||||
cc::CopyOutputRequest::CreateRequest(base::Bind(
|
||||
cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(
|
||||
&AtomCopyFrameGenerator::CopyFromCompositingSurfaceHasResult,
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
damage_rect));
|
||||
|
@ -109,6 +126,12 @@ class AtomCopyFrameGenerator {
|
|||
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<cc::CopyOutputResult> result) {
|
||||
|
@ -118,180 +141,62 @@ class AtomCopyFrameGenerator {
|
|||
return;
|
||||
}
|
||||
|
||||
if (result->HasTexture()) {
|
||||
PrepareTextureCopyOutputResult(damage_rect, std::move(result));
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(result->HasBitmap());
|
||||
PrepareBitmapCopyOutputResult(damage_rect, std::move(result));
|
||||
}
|
||||
|
||||
void PrepareTextureCopyOutputResult(
|
||||
const gfx::Rect& damage_rect,
|
||||
std::unique_ptr<cc::CopyOutputResult> result) {
|
||||
DCHECK(result->HasTexture());
|
||||
base::ScopedClosureRunner scoped_callback_runner(
|
||||
base::Bind(&AtomCopyFrameGenerator::OnCopyFrameCaptureFailure,
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
damage_rect));
|
||||
|
||||
const gfx::Size& result_size = result->size();
|
||||
SkIRect bitmap_size;
|
||||
if (bitmap_)
|
||||
bitmap_->getBounds(&bitmap_size);
|
||||
|
||||
if (!bitmap_ ||
|
||||
bitmap_size.width() != result_size.width() ||
|
||||
bitmap_size.height() != result_size.height()) {
|
||||
bitmap_.reset(new SkBitmap);
|
||||
bitmap_->allocN32Pixels(result_size.width(),
|
||||
result_size.height(),
|
||||
true);
|
||||
if (bitmap_->drawsNothing())
|
||||
return;
|
||||
}
|
||||
|
||||
content::ImageTransportFactory* factory =
|
||||
content::ImageTransportFactory::GetInstance();
|
||||
display_compositor::GLHelper* gl_helper = factory->GetGLHelper();
|
||||
if (!gl_helper)
|
||||
return;
|
||||
|
||||
std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock(
|
||||
new SkAutoLockPixels(*bitmap_));
|
||||
uint8_t* pixels = static_cast<uint8_t*>(bitmap_->getPixels());
|
||||
|
||||
cc::TextureMailbox texture_mailbox;
|
||||
std::unique_ptr<cc::SingleReleaseCallback> release_callback;
|
||||
result->TakeTexture(&texture_mailbox, &release_callback);
|
||||
DCHECK(texture_mailbox.IsTexture());
|
||||
if (!texture_mailbox.IsTexture())
|
||||
return;
|
||||
|
||||
ignore_result(scoped_callback_runner.Release());
|
||||
|
||||
gl_helper->CropScaleReadbackAndCleanMailbox(
|
||||
texture_mailbox.mailbox(),
|
||||
texture_mailbox.sync_token(),
|
||||
result_size,
|
||||
gfx::Rect(result_size),
|
||||
result_size,
|
||||
pixels,
|
||||
kN32_SkColorType,
|
||||
base::Bind(
|
||||
&AtomCopyFrameGenerator::CopyFromCompositingSurfaceFinishedProxy,
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
base::Passed(&release_callback),
|
||||
damage_rect,
|
||||
base::Passed(&bitmap_),
|
||||
base::Passed(&bitmap_pixels_lock)),
|
||||
display_compositor::GLHelper::SCALER_QUALITY_FAST);
|
||||
}
|
||||
|
||||
static void CopyFromCompositingSurfaceFinishedProxy(
|
||||
base::WeakPtr<AtomCopyFrameGenerator> generator,
|
||||
std::unique_ptr<cc::SingleReleaseCallback> release_callback,
|
||||
const gfx::Rect& damage_rect,
|
||||
std::unique_ptr<SkBitmap> bitmap,
|
||||
std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock,
|
||||
bool result) {
|
||||
gpu::SyncToken sync_token;
|
||||
if (result) {
|
||||
display_compositor::GLHelper* gl_helper =
|
||||
content::ImageTransportFactory::GetInstance()->GetGLHelper();
|
||||
if (gl_helper)
|
||||
gl_helper->GenerateSyncToken(&sync_token);
|
||||
}
|
||||
const bool lost_resource = !sync_token.HasData();
|
||||
release_callback->Run(sync_token, lost_resource);
|
||||
|
||||
if (generator) {
|
||||
generator->CopyFromCompositingSurfaceFinished(
|
||||
damage_rect, std::move(bitmap), std::move(bitmap_pixels_lock),
|
||||
result);
|
||||
} else {
|
||||
bitmap_pixels_lock.reset();
|
||||
bitmap.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void CopyFromCompositingSurfaceFinished(
|
||||
const gfx::Rect& damage_rect,
|
||||
std::unique_ptr<SkBitmap> bitmap,
|
||||
std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock,
|
||||
bool result) {
|
||||
DCHECK(!bitmap_);
|
||||
bitmap_ = std::move(bitmap);
|
||||
|
||||
if (result) {
|
||||
OnCopyFrameCaptureSuccess(damage_rect, *bitmap_,
|
||||
std::move(bitmap_pixels_lock));
|
||||
} else {
|
||||
bitmap_pixels_lock.reset();
|
||||
OnCopyFrameCaptureFailure(damage_rect);
|
||||
}
|
||||
}
|
||||
|
||||
void PrepareBitmapCopyOutputResult(
|
||||
const gfx::Rect& damage_rect,
|
||||
std::unique_ptr<cc::CopyOutputResult> result) {
|
||||
DCHECK(result->HasBitmap());
|
||||
std::unique_ptr<SkBitmap> source = result->TakeBitmap();
|
||||
DCHECK(source);
|
||||
if (source) {
|
||||
std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock(
|
||||
new SkAutoLockPixels(*source));
|
||||
OnCopyFrameCaptureSuccess(damage_rect, *source,
|
||||
std::move(bitmap_pixels_lock));
|
||||
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_;
|
||||
content::BrowserThread::PostDelayedTask(content::BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&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) {
|
||||
pending_damage_rect_.Union(damage_rect);
|
||||
|
||||
void OnCopyFrameCaptureFailure(const gfx::Rect& damage_rect) {
|
||||
const bool force_frame = (++frame_retry_count_ <= kFrameRetryLimit);
|
||||
OnCopyFrameCaptureCompletion(force_frame);
|
||||
if (force_frame) {
|
||||
// Retry with the same |damage_rect|.
|
||||
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&AtomCopyFrameGenerator::GenerateCopyFrame,
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
damage_rect));
|
||||
}
|
||||
}
|
||||
|
||||
void OnCopyFrameCaptureSuccess(
|
||||
const gfx::Rect& damage_rect,
|
||||
const SkBitmap& bitmap,
|
||||
std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock) {
|
||||
view_->OnPaint(damage_rect, bitmap);
|
||||
|
||||
if (frame_retry_count_ > 0)
|
||||
frame_retry_count_ = 0;
|
||||
|
||||
OnCopyFrameCaptureCompletion(false);
|
||||
std::shared_ptr<SkBitmap> bitmap) {
|
||||
base::AutoLock lock(onPaintLock_);
|
||||
view_->OnPaint(damage_rect, *bitmap);
|
||||
}
|
||||
|
||||
void OnCopyFrameCaptureCompletion(bool force_frame) {
|
||||
frame_in_progress_ = false;
|
||||
|
||||
if (frame_pending_) {
|
||||
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&AtomCopyFrameGenerator::GenerateCopyFrame,
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
force_frame,
|
||||
gfx::Rect()));
|
||||
}
|
||||
}
|
||||
|
||||
int frame_rate_threshold_ms_;
|
||||
base::Lock lock_;
|
||||
base::Lock onPaintLock_;
|
||||
OffScreenRenderWidgetHostView* view_;
|
||||
|
||||
base::Time last_time_;
|
||||
|
||||
base::TimeTicks frame_start_time_;
|
||||
bool frame_pending_;
|
||||
bool frame_in_progress_;
|
||||
int frame_retry_count_;
|
||||
std::unique_ptr<SkBitmap> bitmap_;
|
||||
gfx::Rect pending_damage_rect_;
|
||||
base::TimeTicks next_frame_time_;
|
||||
base::TimeDelta frame_duration_;
|
||||
|
||||
base::WeakPtrFactory<AtomCopyFrameGenerator> weak_ptr_factory_;
|
||||
|
||||
|
@ -300,12 +205,15 @@ class AtomCopyFrameGenerator {
|
|||
|
||||
class AtomBeginFrameTimer : public cc::DelayBasedTimeSourceClient {
|
||||
public:
|
||||
AtomBeginFrameTimer(int frame_rate_threshold_ms,
|
||||
AtomBeginFrameTimer(int frame_rate_threshold_us,
|
||||
const base::Closure& callback)
|
||||
: callback_(callback) {
|
||||
time_source_.reset(new cc::DelayBasedTimeSource(
|
||||
content::BrowserThread::GetTaskRunnerForThread(
|
||||
content::BrowserThread::UI).get()));
|
||||
time_source_->SetTimebaseAndInterval(
|
||||
base::TimeTicks(),
|
||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us));
|
||||
time_source_->SetClient(this);
|
||||
}
|
||||
|
||||
|
@ -317,10 +225,10 @@ class AtomBeginFrameTimer : public cc::DelayBasedTimeSourceClient {
|
|||
return time_source_->Active();
|
||||
}
|
||||
|
||||
void SetFrameRateThresholdMs(int frame_rate_threshold_ms) {
|
||||
void SetFrameRateThresholdUs(int frame_rate_threshold_us) {
|
||||
time_source_->SetTimebaseAndInterval(
|
||||
base::TimeTicks::Now(),
|
||||
base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms));
|
||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us));
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -338,24 +246,31 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
|||
bool transparent,
|
||||
const OnPaintCallback& callback,
|
||||
content::RenderWidgetHost* host,
|
||||
bool is_guest_view_hack,
|
||||
OffScreenRenderWidgetHostView* parent_host_view,
|
||||
NativeWindow* native_window)
|
||||
: render_widget_host_(content::RenderWidgetHostImpl::From(host)),
|
||||
parent_host_view_(parent_host_view),
|
||||
popup_host_view_(nullptr),
|
||||
child_host_view_(nullptr),
|
||||
native_window_(native_window),
|
||||
software_output_device_(nullptr),
|
||||
transparent_(transparent),
|
||||
callback_(callback),
|
||||
parent_callback_(nullptr),
|
||||
frame_rate_(60),
|
||||
frame_rate_threshold_ms_(0),
|
||||
frame_rate_threshold_us_(0),
|
||||
last_time_(base::Time::Now()),
|
||||
scale_factor_(kDefaultScaleFactor),
|
||||
is_showing_(!render_widget_host_->is_hidden()),
|
||||
size_(native_window->GetSize()),
|
||||
painting_(true),
|
||||
is_showing_(!render_widget_host_->is_hidden()),
|
||||
is_destroyed_(false),
|
||||
popup_position_(gfx::Rect()),
|
||||
hold_resize_(false),
|
||||
pending_resize_(false),
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(render_widget_host_);
|
||||
render_widget_host_->SetView(this);
|
||||
|
||||
bool is_guest_view_hack = parent_host_view_ != nullptr;
|
||||
#if !defined(OS_MACOSX)
|
||||
delegated_frame_host_ = base::MakeUnique<content::DelegatedFrameHost>(
|
||||
AllocateFrameSinkId(is_guest_view_hack), this);
|
||||
|
@ -383,6 +298,8 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
|||
native_window_->AddObserver(this);
|
||||
|
||||
ResizeRootLayer();
|
||||
render_widget_host_->SetView(this);
|
||||
InstallTransparency();
|
||||
}
|
||||
|
||||
OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() {
|
||||
|
@ -400,8 +317,15 @@ OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() {
|
|||
delegated_frame_host_->ResetCompositor();
|
||||
#endif
|
||||
|
||||
if (copy_frame_generator_.get())
|
||||
copy_frame_generator_.reset(NULL);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
DestroyPlatformWidget();
|
||||
#else
|
||||
delegated_frame_host_.reset(NULL);
|
||||
compositor_.reset(NULL);
|
||||
root_layer_.reset(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -419,7 +343,7 @@ void OffScreenRenderWidgetHostView::OnWindowClosed() {
|
|||
void OffScreenRenderWidgetHostView::OnBeginFrameTimerTick() {
|
||||
const base::TimeTicks frame_time = base::TimeTicks::Now();
|
||||
const base::TimeDelta vsync_period =
|
||||
base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms_);
|
||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_);
|
||||
SendBeginFrame(frame_time, vsync_period);
|
||||
}
|
||||
|
||||
|
@ -461,6 +385,17 @@ bool OffScreenRenderWidgetHostView::OnMessageReceived(
|
|||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
|
||||
DCHECK(parent_host_view_);
|
||||
|
||||
if (parent_host_view_->child_host_view_) {
|
||||
parent_host_view_->child_host_view_->CancelWidget();
|
||||
}
|
||||
|
||||
parent_host_view_->set_child_host_view(this);
|
||||
parent_host_view_->Hide();
|
||||
|
||||
ResizeRootLayer();
|
||||
Show();
|
||||
}
|
||||
|
||||
content::RenderWidgetHost* OffScreenRenderWidgetHostView::GetRenderWidgetHost()
|
||||
|
@ -470,14 +405,11 @@ content::RenderWidgetHost* OffScreenRenderWidgetHostView::GetRenderWidgetHost()
|
|||
|
||||
void OffScreenRenderWidgetHostView::SetSize(const gfx::Size& size) {
|
||||
size_ = size;
|
||||
|
||||
ResizeRootLayer();
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->WasResized();
|
||||
GetDelegatedFrameHost()->WasResized();
|
||||
WasResized();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetBounds(const gfx::Rect& new_bounds) {
|
||||
SetSize(new_bounds.size());
|
||||
}
|
||||
|
||||
gfx::Vector2dF OffScreenRenderWidgetHostView::GetLastScrollOffset() const {
|
||||
|
@ -547,6 +479,9 @@ bool OffScreenRenderWidgetHostView::IsShowing() {
|
|||
}
|
||||
|
||||
gfx::Rect OffScreenRenderWidgetHostView::GetViewBounds() const {
|
||||
if (IsPopupWidget())
|
||||
return popup_position_;
|
||||
|
||||
return gfx::Rect(size_);
|
||||
}
|
||||
|
||||
|
@ -587,7 +522,7 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame(
|
|||
|
||||
if (!frame.render_pass_list.empty()) {
|
||||
if (software_output_device_) {
|
||||
if (!begin_frame_timer_.get()) {
|
||||
if (!begin_frame_timer_.get() || IsPopupWidget()) {
|
||||
software_output_device_->SetActive(painting_);
|
||||
}
|
||||
|
||||
|
@ -601,7 +536,7 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame(
|
|||
} else {
|
||||
if (!copy_frame_generator_.get()) {
|
||||
copy_frame_generator_.reset(
|
||||
new AtomCopyFrameGenerator(frame_rate_threshold_ms_, this));
|
||||
new AtomCopyFrameGenerator(this, frame_rate_threshold_us_));
|
||||
}
|
||||
|
||||
// Determine the damage rectangle for the current frame. This is the same
|
||||
|
@ -620,7 +555,7 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame(
|
|||
|
||||
// Request a copy of the last compositor frame which will eventually call
|
||||
// OnPaint asynchronously.
|
||||
copy_frame_generator_->GenerateCopyFrame(true, damage_rect);
|
||||
copy_frame_generator_->GenerateCopyFrame(damage_rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -631,10 +566,25 @@ void OffScreenRenderWidgetHostView::ClearCompositorFrame() {
|
|||
|
||||
void OffScreenRenderWidgetHostView::InitAsPopup(
|
||||
content::RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
|
||||
DCHECK_EQ(parent_host_view_, parent_host_view);
|
||||
|
||||
if (parent_host_view_->popup_host_view_) {
|
||||
parent_host_view_->popup_host_view_->CancelWidget();
|
||||
}
|
||||
|
||||
parent_host_view_->set_popup_host_view(this);
|
||||
parent_host_view_->popup_bitmap_.reset(new SkBitmap);
|
||||
parent_callback_ = base::Bind(&OffScreenRenderWidgetHostView::OnPopupPaint,
|
||||
parent_host_view_->weak_ptr_factory_.GetWeakPtr());
|
||||
|
||||
popup_position_ = pos;
|
||||
|
||||
ResizeRootLayer();
|
||||
Show();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::InitAsFullscreen(
|
||||
content::RenderWidgetHostView *) {
|
||||
content::RenderWidgetHostView *) {
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::UpdateCursor(const content::WebCursor &) {
|
||||
|
@ -656,6 +606,23 @@ void OffScreenRenderWidgetHostView::RenderProcessGone(base::TerminationStatus,
|
|||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::Destroy() {
|
||||
if (!is_destroyed_) {
|
||||
is_destroyed_ = true;
|
||||
|
||||
if (parent_host_view_ != NULL) {
|
||||
CancelWidget();
|
||||
} else {
|
||||
if (popup_host_view_)
|
||||
popup_host_view_->CancelWidget();
|
||||
popup_bitmap_.reset();
|
||||
if (child_host_view_)
|
||||
child_host_view_->CancelWidget();
|
||||
for (auto guest_host_view : guest_host_views_)
|
||||
guest_host_view->CancelWidget();
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
@ -692,6 +659,13 @@ void OffScreenRenderWidgetHostView::EndFrameSubscription() {
|
|||
GetDelegatedFrameHost()->EndFrameSubscription();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::InitAsGuest(
|
||||
content::RenderWidgetHostView* parent_host_view,
|
||||
content::RenderWidgetHostViewGuest* guest_view) {
|
||||
parent_host_view_->AddGuestHostView(this);
|
||||
parent_host_view_->RegisterGuestViewFrameSwappedCallback(guest_view);
|
||||
}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::HasAcceleratedSurface(const gfx::Size &) {
|
||||
return false;
|
||||
}
|
||||
|
@ -705,11 +679,35 @@ void OffScreenRenderWidgetHostView::ImeCompositionRangeChanged(
|
|||
}
|
||||
|
||||
gfx::Size OffScreenRenderWidgetHostView::GetPhysicalBackingSize() const {
|
||||
return size_;
|
||||
return gfx::ConvertSizeToPixel(scale_factor_, GetRequestedRendererSize());
|
||||
}
|
||||
|
||||
gfx::Size OffScreenRenderWidgetHostView::GetRequestedRendererSize() const {
|
||||
return size_;
|
||||
return GetDelegatedFrameHost()->GetRequestedRendererSize();
|
||||
}
|
||||
|
||||
content::RenderWidgetHostViewBase*
|
||||
OffScreenRenderWidgetHostView::CreateViewForWidget(
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
content::RenderWidgetHost* embedder_render_widget_host,
|
||||
content::WebContentsView* web_contents_view) {
|
||||
if (render_widget_host->GetView()) {
|
||||
return static_cast<content::RenderWidgetHostViewBase*>(
|
||||
render_widget_host->GetView());
|
||||
}
|
||||
|
||||
OffScreenRenderWidgetHostView* embedder_host_view = nullptr;
|
||||
if (embedder_render_widget_host) {
|
||||
embedder_host_view = static_cast<OffScreenRenderWidgetHostView*>(
|
||||
embedder_render_widget_host->GetView());
|
||||
}
|
||||
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_,
|
||||
callback_,
|
||||
render_widget_host,
|
||||
embedder_host_view,
|
||||
native_window_);
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
|
@ -723,22 +721,29 @@ bool OffScreenRenderWidgetHostView::DelegatedFrameHostIsVisible() const {
|
|||
|
||||
SkColor OffScreenRenderWidgetHostView::DelegatedFrameHostGetGutterColor(
|
||||
SkColor color) const {
|
||||
if (render_widget_host_->delegate() &&
|
||||
render_widget_host_->delegate()->IsFullscreenForCurrentTab()) {
|
||||
return SK_ColorWHITE;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
gfx::Size OffScreenRenderWidgetHostView::DelegatedFrameHostDesiredSizeInDIP()
|
||||
const {
|
||||
return size_;
|
||||
return GetRootLayer()->bounds().size();
|
||||
}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::DelegatedFrameCanCreateResizeLock() const {
|
||||
return false;
|
||||
return !render_widget_host_->auto_resize_enabled();
|
||||
}
|
||||
|
||||
std::unique_ptr<content::ResizeLock>
|
||||
OffScreenRenderWidgetHostView::DelegatedFrameHostCreateResizeLock(
|
||||
bool defer_compositor_lock) {
|
||||
return nullptr;
|
||||
return std::unique_ptr<content::ResizeLock>(new AtomResizeLock(
|
||||
this,
|
||||
DelegatedFrameHostDesiredSizeInDIP(),
|
||||
defer_compositor_lock));
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::DelegatedFrameHostResizeLockWasReleased() {
|
||||
|
@ -795,6 +800,57 @@ bool OffScreenRenderWidgetHostView::TransformPointToCoordSpaceForView(
|
|||
point, target_view, transformed_point);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::CancelWidget() {
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->LostCapture();
|
||||
Hide();
|
||||
|
||||
if (parent_host_view_) {
|
||||
if (parent_host_view_->popup_host_view_ == this) {
|
||||
parent_host_view_->set_popup_host_view(NULL);
|
||||
parent_host_view_->popup_bitmap_.reset();
|
||||
} else if (parent_host_view_->child_host_view_ == this) {
|
||||
parent_host_view_->set_child_host_view(NULL);
|
||||
parent_host_view_->Show();
|
||||
} else {
|
||||
parent_host_view_->RemoveGuestHostView(this);
|
||||
}
|
||||
parent_host_view_ = NULL;
|
||||
}
|
||||
|
||||
if (render_widget_host_ && !is_destroyed_) {
|
||||
is_destroyed_ = true;
|
||||
// Results in a call to Destroy().
|
||||
render_widget_host_->ShutdownAndDestroyWidget(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::AddGuestHostView(
|
||||
OffScreenRenderWidgetHostView* guest_host) {
|
||||
guest_host_views_.insert(guest_host);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::RemoveGuestHostView(
|
||||
OffScreenRenderWidgetHostView* guest_host) {
|
||||
guest_host_views_.erase(guest_host);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::RegisterGuestViewFrameSwappedCallback(
|
||||
content::RenderWidgetHostViewGuest* guest_host_view) {
|
||||
guest_host_view->RegisterFrameSwappedCallback(base::MakeUnique<base::Closure>(
|
||||
base::Bind(&OffScreenRenderWidgetHostView::OnGuestViewFrameSwapped,
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
base::Unretained(guest_host_view))));
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnGuestViewFrameSwapped(
|
||||
content::RenderWidgetHostViewGuest* guest_host_view) {
|
||||
InvalidateBounds(
|
||||
gfx::ConvertRectToPixel(scale_factor_, guest_host_view->GetViewBounds()));
|
||||
|
||||
RegisterGuestViewFrameSwappedCallback(guest_host_view);
|
||||
}
|
||||
|
||||
std::unique_ptr<cc::SoftwareOutputDevice>
|
||||
OffScreenRenderWidgetHostView::CreateSoftwareOutputDevice(
|
||||
ui::Compositor* compositor) {
|
||||
|
@ -823,7 +879,7 @@ bool OffScreenRenderWidgetHostView::InstallTransparency() {
|
|||
}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::IsAutoResizeEnabled() const {
|
||||
return false;
|
||||
return render_widget_host_->auto_resize_enabled();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
|
||||
|
@ -837,10 +893,147 @@ void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
|
|||
}
|
||||
}
|
||||
|
||||
void CopyBitmapTo(
|
||||
const SkBitmap& destination,
|
||||
const SkBitmap& source,
|
||||
const gfx::Rect& pos) {
|
||||
SkAutoLockPixels source_pixels_lock(source);
|
||||
SkAutoLockPixels destination_pixels_lock(destination);
|
||||
|
||||
char* src = static_cast<char*>(source.getPixels());
|
||||
char* dest = static_cast<char*>(destination.getPixels());
|
||||
int pixelsize = source.bytesPerPixel();
|
||||
|
||||
if (pos.x() + pos.width() <= destination.width() &&
|
||||
pos.y() + pos.height() <= destination.height()) {
|
||||
for (int i = 0; i < pos.height(); i++) {
|
||||
memcpy(dest + ((pos.y() + i) * destination.width() + pos.x()) * pixelsize,
|
||||
src + (i * source.width()) * pixelsize,
|
||||
pos.width() * pixelsize);
|
||||
}
|
||||
}
|
||||
|
||||
destination.notifyPixelsChanged();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnPaint(
|
||||
const gfx::Rect& damage_rect, const SkBitmap& bitmap) {
|
||||
TRACE_EVENT0("electron", "OffScreenRenderWidgetHostView::OnPaint");
|
||||
callback_.Run(damage_rect, bitmap);
|
||||
|
||||
HoldResize();
|
||||
|
||||
if (parent_callback_) {
|
||||
parent_callback_.Run(damage_rect, bitmap);
|
||||
} else if (popup_host_view_ && popup_bitmap_.get()) {
|
||||
gfx::Rect pos = popup_host_view_->popup_position_;
|
||||
gfx::Rect damage(damage_rect);
|
||||
damage.Union(pos);
|
||||
|
||||
SkBitmap copy = SkBitmapOperations::CreateTiledBitmap(bitmap,
|
||||
pos.x(), pos.y(), pos.width(), pos.height());
|
||||
|
||||
CopyBitmapTo(bitmap, *popup_bitmap_, pos);
|
||||
callback_.Run(damage, bitmap);
|
||||
CopyBitmapTo(bitmap, copy, pos);
|
||||
} else {
|
||||
callback_.Run(damage_rect, bitmap);
|
||||
}
|
||||
|
||||
ReleaseResize();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnPopupPaint(
|
||||
const gfx::Rect& damage_rect, const SkBitmap& bitmap) {
|
||||
if (popup_host_view_ && popup_bitmap_.get())
|
||||
bitmap.deepCopyTo(popup_bitmap_.get());
|
||||
InvalidateBounds(popup_host_view_->popup_position_);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::HoldResize() {
|
||||
if (!hold_resize_)
|
||||
hold_resize_ = true;
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ReleaseResize() {
|
||||
if (!hold_resize_)
|
||||
return;
|
||||
|
||||
hold_resize_ = false;
|
||||
if (pending_resize_) {
|
||||
pending_resize_ = false;
|
||||
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&OffScreenRenderWidgetHostView::WasResized,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::WasResized() {
|
||||
if (hold_resize_) {
|
||||
if (!pending_resize_)
|
||||
pending_resize_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ResizeRootLayer();
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->WasResized();
|
||||
GetDelegatedFrameHost()->WasResized();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ProcessKeyboardEvent(
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
if (!render_widget_host_)
|
||||
return;
|
||||
render_widget_host_->ForwardKeyboardEvent(event);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ProcessMouseEvent(
|
||||
const blink::WebMouseEvent& event,
|
||||
const ui::LatencyInfo& latency) {
|
||||
if (!IsPopupWidget()) {
|
||||
if (popup_host_view_ &&
|
||||
popup_host_view_->popup_position_.Contains(event.x, event.y)) {
|
||||
blink::WebMouseEvent popup_event(event);
|
||||
popup_event.x -= popup_host_view_->popup_position_.x();
|
||||
popup_event.y -= popup_host_view_->popup_position_.y();
|
||||
popup_event.windowX = popup_event.x;
|
||||
popup_event.windowY = popup_event.y;
|
||||
|
||||
popup_host_view_->ProcessMouseEvent(popup_event, latency);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!render_widget_host_)
|
||||
return;
|
||||
render_widget_host_->ForwardMouseEvent(event);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ProcessMouseWheelEvent(
|
||||
const blink::WebMouseWheelEvent& event,
|
||||
const ui::LatencyInfo& latency) {
|
||||
if (!IsPopupWidget()) {
|
||||
if (popup_host_view_) {
|
||||
if (popup_host_view_->popup_position_.Contains(event.x, event.y)) {
|
||||
blink::WebMouseWheelEvent popup_event(event);
|
||||
popup_event.x -= popup_host_view_->popup_position_.x();
|
||||
popup_event.y -= popup_host_view_->popup_position_.y();
|
||||
popup_event.windowX = popup_event.x;
|
||||
popup_event.windowY = popup_event.y;
|
||||
popup_host_view_->ProcessMouseWheelEvent(popup_event, latency);
|
||||
return;
|
||||
} else {
|
||||
// Scrolling outside of the popup widget so destroy it.
|
||||
// Execute asynchronously to avoid deleting the widget from inside some
|
||||
// other callback.
|
||||
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&OffScreenRenderWidgetHostView::CancelWidget,
|
||||
popup_host_view_->weak_ptr_factory_.GetWeakPtr()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!render_widget_host_)
|
||||
return;
|
||||
render_widget_host_->ForwardWheelEvent(event);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetPainting(bool painting) {
|
||||
|
@ -856,12 +1049,22 @@ bool OffScreenRenderWidgetHostView::IsPainting() const {
|
|||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) {
|
||||
if (frame_rate <= 0)
|
||||
frame_rate = 1;
|
||||
if (frame_rate > 60)
|
||||
frame_rate = 60;
|
||||
if (parent_host_view_) {
|
||||
if (parent_host_view_->GetFrameRate() == GetFrameRate())
|
||||
return;
|
||||
|
||||
frame_rate_ = frame_rate;
|
||||
frame_rate_ = parent_host_view_->GetFrameRate();
|
||||
} else {
|
||||
if (frame_rate <= 0)
|
||||
frame_rate = 1;
|
||||
if (frame_rate > 60)
|
||||
frame_rate = 60;
|
||||
|
||||
frame_rate_ = frame_rate;
|
||||
}
|
||||
|
||||
for (auto guest_host_view : guest_host_views_)
|
||||
guest_host_view->SetFrameRate(frame_rate);
|
||||
|
||||
SetupFrameRate(true);
|
||||
}
|
||||
|
@ -886,36 +1089,38 @@ OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
|
|||
#endif
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
||||
if (!force && frame_rate_threshold_ms_ != 0)
|
||||
if (!force && frame_rate_threshold_us_ != 0)
|
||||
return;
|
||||
|
||||
frame_rate_threshold_ms_ = 1000 / frame_rate_;
|
||||
frame_rate_threshold_us_ = 1000000 / frame_rate_;
|
||||
|
||||
GetCompositor()->vsync_manager()->SetAuthoritativeVSyncInterval(
|
||||
base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms_));
|
||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_));
|
||||
|
||||
if (copy_frame_generator_) {
|
||||
copy_frame_generator_->set_frame_rate_threshold_ms(
|
||||
frame_rate_threshold_ms_);
|
||||
if (copy_frame_generator_.get()) {
|
||||
copy_frame_generator_->set_frame_rate_threshold_us(
|
||||
frame_rate_threshold_us_);
|
||||
}
|
||||
|
||||
if (begin_frame_timer_) {
|
||||
begin_frame_timer_->SetFrameRateThresholdMs(frame_rate_threshold_ms_);
|
||||
if (begin_frame_timer_.get()) {
|
||||
begin_frame_timer_->SetFrameRateThresholdUs(frame_rate_threshold_us_);
|
||||
} else {
|
||||
begin_frame_timer_.reset(new AtomBeginFrameTimer(
|
||||
frame_rate_threshold_ms_,
|
||||
frame_rate_threshold_us_,
|
||||
base::Bind(&OffScreenRenderWidgetHostView::OnBeginFrameTimerTick,
|
||||
weak_ptr_factory_.GetWeakPtr())));
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::Invalidate() {
|
||||
const gfx::Rect& bounds_in_pixels = GetViewBounds();
|
||||
InvalidateBounds(GetViewBounds());
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::InvalidateBounds(const gfx::Rect& bounds) {
|
||||
if (software_output_device_) {
|
||||
software_output_device_->OnPaint(bounds_in_pixels);
|
||||
software_output_device_->OnPaint(bounds);
|
||||
} else if (copy_frame_generator_) {
|
||||
copy_frame_generator_->GenerateCopyFrame(true, bounds_in_pixels);
|
||||
copy_frame_generator_->GenerateCopyFrame(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -925,7 +1130,11 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer() {
|
|||
const float orgScaleFactor = scale_factor_;
|
||||
const bool scaleFactorDidChange = (orgScaleFactor != scale_factor_);
|
||||
|
||||
gfx::Size size = GetViewBounds().size();
|
||||
gfx::Size size;
|
||||
if (!IsPopupWidget())
|
||||
size = GetViewBounds().size();
|
||||
else
|
||||
size = popup_position_.size();
|
||||
|
||||
if (!scaleFactorDidChange && size == GetRootLayer()->bounds().size())
|
||||
return;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#ifndef ATOM_BROWSER_OSR_OSR_RENDER_WIDGET_HOST_VIEW_H_
|
||||
#define ATOM_BROWSER_OSR_OSR_RENDER_WIDGET_HOST_VIEW_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -20,10 +21,13 @@
|
|||
#include "base/time/time.h"
|
||||
#include "cc/output/compositor_frame.h"
|
||||
#include "cc/scheduler/begin_frame_source.h"
|
||||
#include "content/browser/frame_host/render_widget_host_view_guest.h"
|
||||
#include "content/browser/renderer_host/delegated_frame_host.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_base.h"
|
||||
#include "content/browser/renderer_host/resize_lock.h"
|
||||
#include "content/browser/web_contents/web_contents_view.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "third_party/WebKit/public/platform/WebVector.h"
|
||||
#include "ui/base/ime/text_input_client.h"
|
||||
#include "ui/compositor/compositor.h"
|
||||
|
@ -69,7 +73,7 @@ class OffScreenRenderWidgetHostView
|
|||
OffScreenRenderWidgetHostView(bool transparent,
|
||||
const OnPaintCallback& callback,
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
bool is_guest_view_hack,
|
||||
OffScreenRenderWidgetHostView* parent_host_view,
|
||||
NativeWindow* native_window);
|
||||
~OffScreenRenderWidgetHostView() override;
|
||||
|
||||
|
@ -139,6 +143,9 @@ class OffScreenRenderWidgetHostView
|
|||
void BeginFrameSubscription(
|
||||
std::unique_ptr<content::RenderWidgetHostViewFrameSubscriber>) override;
|
||||
void EndFrameSubscription() override;
|
||||
void InitAsGuest(
|
||||
content::RenderWidgetHostView*,
|
||||
content::RenderWidgetHostViewGuest*) override;
|
||||
bool HasAcceleratedSurface(const gfx::Size &) override;
|
||||
gfx::Rect GetBoundsInRootWindow(void) override;
|
||||
void ImeCompositionRangeChanged(
|
||||
|
@ -146,6 +153,11 @@ class OffScreenRenderWidgetHostView
|
|||
gfx::Size GetPhysicalBackingSize() const override;
|
||||
gfx::Size GetRequestedRendererSize() const override;
|
||||
|
||||
content::RenderWidgetHostViewBase* CreateViewForWidget(
|
||||
content::RenderWidgetHost*,
|
||||
content::RenderWidgetHost*,
|
||||
content::WebContentsView*) override;
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
// content::DelegatedFrameHostClient:
|
||||
int DelegatedFrameHostGetGpuMemoryBufferClientId(void) const;
|
||||
|
@ -193,7 +205,32 @@ class OffScreenRenderWidgetHostView
|
|||
void DestroyPlatformWidget();
|
||||
#endif
|
||||
|
||||
void CancelWidget();
|
||||
void AddGuestHostView(OffScreenRenderWidgetHostView* guest_host);
|
||||
void RemoveGuestHostView(OffScreenRenderWidgetHostView* guest_host);
|
||||
|
||||
void RegisterGuestViewFrameSwappedCallback(
|
||||
content::RenderWidgetHostViewGuest* guest_host_view);
|
||||
void OnGuestViewFrameSwapped(
|
||||
content::RenderWidgetHostViewGuest* guest_host_view);
|
||||
|
||||
void OnPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
|
||||
void OnPopupPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
|
||||
|
||||
bool IsPopupWidget() const {
|
||||
return popup_type_ != blink::WebPopupTypeNone;
|
||||
}
|
||||
|
||||
void HoldResize();
|
||||
void ReleaseResize();
|
||||
void WasResized();
|
||||
|
||||
void ProcessKeyboardEvent(
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
void ProcessMouseEvent(const blink::WebMouseEvent& event,
|
||||
const ui::LatencyInfo& latency) override;
|
||||
void ProcessMouseWheelEvent(const blink::WebMouseWheelEvent& event,
|
||||
const ui::LatencyInfo& latency) override;
|
||||
|
||||
void SetPainting(bool painting);
|
||||
bool IsPainting() const;
|
||||
|
@ -206,6 +243,7 @@ class OffScreenRenderWidgetHostView
|
|||
content::DelegatedFrameHost* GetDelegatedFrameHost() const;
|
||||
|
||||
void Invalidate();
|
||||
void InvalidateBounds(const gfx::Rect&);
|
||||
|
||||
content::RenderWidgetHostImpl* render_widget_host() const
|
||||
{ return render_widget_host_; }
|
||||
|
@ -213,6 +251,14 @@ class OffScreenRenderWidgetHostView
|
|||
gfx::Size size() const { return size_; }
|
||||
float scale_factor() const { return scale_factor_; }
|
||||
|
||||
void set_popup_host_view(OffScreenRenderWidgetHostView* popup_view) {
|
||||
popup_host_view_ = popup_view;
|
||||
}
|
||||
|
||||
void set_child_host_view(OffScreenRenderWidgetHostView* child_view) {
|
||||
child_host_view_ = child_view;
|
||||
}
|
||||
|
||||
private:
|
||||
void SetupFrameRate(bool force);
|
||||
void ResizeRootLayer();
|
||||
|
@ -221,23 +267,37 @@ class OffScreenRenderWidgetHostView
|
|||
|
||||
// Weak ptrs.
|
||||
content::RenderWidgetHostImpl* render_widget_host_;
|
||||
|
||||
OffScreenRenderWidgetHostView* parent_host_view_;
|
||||
OffScreenRenderWidgetHostView* popup_host_view_;
|
||||
std::unique_ptr<SkBitmap> popup_bitmap_;
|
||||
OffScreenRenderWidgetHostView* child_host_view_;
|
||||
std::set<OffScreenRenderWidgetHostView*> guest_host_views_;
|
||||
|
||||
NativeWindow* native_window_;
|
||||
OffScreenOutputDevice* software_output_device_;
|
||||
|
||||
const bool transparent_;
|
||||
OnPaintCallback callback_;
|
||||
OnPaintCallback parent_callback_;
|
||||
|
||||
int frame_rate_;
|
||||
int frame_rate_threshold_ms_;
|
||||
int frame_rate_threshold_us_;
|
||||
|
||||
base::Time last_time_;
|
||||
|
||||
float scale_factor_;
|
||||
bool is_showing_;
|
||||
gfx::Vector2dF last_scroll_offset_;
|
||||
gfx::Size size_;
|
||||
bool painting_;
|
||||
|
||||
bool is_showing_;
|
||||
bool is_destroyed_;
|
||||
gfx::Rect popup_position_;
|
||||
|
||||
bool hold_resize_;
|
||||
bool pending_resize_;
|
||||
|
||||
std::unique_ptr<ui::Layer> root_layer_;
|
||||
std::unique_ptr<ui::Compositor> compositor_;
|
||||
std::unique_ptr<content::DelegatedFrameHost> delegated_frame_host_;
|
||||
|
|
|
@ -4,7 +4,11 @@
|
|||
|
||||
#include "atom/browser/osr/osr_web_contents_view.h"
|
||||
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "third_party/WebKit/public/platform/WebScreenInfo.h"
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
|
@ -27,19 +31,33 @@ OffScreenWebContentsView::~OffScreenWebContentsView() {
|
|||
void OffScreenWebContentsView::SetWebContents(
|
||||
content::WebContents* web_contents) {
|
||||
web_contents_ = web_contents;
|
||||
|
||||
RenderViewCreated(web_contents_->GetRenderViewHost());
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
gfx::NativeView OffScreenWebContentsView::GetNativeView() const {
|
||||
return gfx::NativeView();
|
||||
if (!web_contents_) return gfx::NativeView();
|
||||
|
||||
auto relay = NativeWindowRelay::FromWebContents(web_contents_);
|
||||
if (!relay) return gfx::NativeView();
|
||||
return relay->window->GetNativeView();
|
||||
}
|
||||
|
||||
gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const {
|
||||
return gfx::NativeView();
|
||||
if (!web_contents_) return gfx::NativeView();
|
||||
|
||||
auto relay = NativeWindowRelay::FromWebContents(web_contents_);
|
||||
if (!relay) return gfx::NativeView();
|
||||
return relay->window->GetNativeView();
|
||||
}
|
||||
|
||||
gfx::NativeWindow OffScreenWebContentsView::GetTopLevelNativeWindow() const {
|
||||
return gfx::NativeWindow();
|
||||
if (!web_contents_) return gfx::NativeWindow();
|
||||
|
||||
auto relay = NativeWindowRelay::FromWebContents(web_contents_);
|
||||
if (!relay) return gfx::NativeWindow();
|
||||
return relay->window->GetNativeWindow();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -67,7 +85,7 @@ content::DropData* OffScreenWebContentsView::GetDropData() const {
|
|||
}
|
||||
|
||||
gfx::Rect OffScreenWebContentsView::GetViewBounds() const {
|
||||
return view_ ? view_->GetViewBounds() : gfx::Rect();
|
||||
return GetView() ? GetView()->GetViewBounds() : gfx::Rect();
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::CreateView(const gfx::Size& initial_size,
|
||||
|
@ -77,20 +95,40 @@ void OffScreenWebContentsView::CreateView(const gfx::Size& initial_size,
|
|||
content::RenderWidgetHostViewBase*
|
||||
OffScreenWebContentsView::CreateViewForWidget(
|
||||
content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) {
|
||||
if (render_widget_host->GetView()) {
|
||||
return static_cast<content::RenderWidgetHostViewBase*>(
|
||||
render_widget_host->GetView());
|
||||
}
|
||||
|
||||
auto relay = NativeWindowRelay::FromWebContents(web_contents_);
|
||||
view_ = new OffScreenRenderWidgetHostView(
|
||||
transparent_, callback_, render_widget_host,
|
||||
is_guest_view_hack, relay->window.get());
|
||||
return view_;
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_,
|
||||
callback_,
|
||||
render_widget_host,
|
||||
nullptr,
|
||||
relay->window.get());
|
||||
}
|
||||
|
||||
content::RenderWidgetHostViewBase*
|
||||
OffScreenWebContentsView::CreateViewForPopupWidget(
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
auto relay = NativeWindowRelay::FromWebContents(web_contents_);
|
||||
view_ = new OffScreenRenderWidgetHostView(
|
||||
transparent_, callback_, render_widget_host, false, relay->window.get());
|
||||
return view_;
|
||||
|
||||
content::WebContentsImpl *web_contents_impl =
|
||||
static_cast<content::WebContentsImpl*>(web_contents_);
|
||||
|
||||
OffScreenRenderWidgetHostView *view =
|
||||
static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents_impl->GetOuterWebContents()
|
||||
? web_contents_impl->GetOuterWebContents()->GetRenderWidgetHostView()
|
||||
: web_contents_impl->GetRenderWidgetHostView());
|
||||
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_,
|
||||
callback_,
|
||||
render_widget_host,
|
||||
view,
|
||||
relay->window.get());
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::SetPageTitle(const base::string16& title) {
|
||||
|
@ -98,8 +136,12 @@ void OffScreenWebContentsView::SetPageTitle(const base::string16& title) {
|
|||
|
||||
void OffScreenWebContentsView::RenderViewCreated(
|
||||
content::RenderViewHost* host) {
|
||||
if (view_)
|
||||
view_->InstallTransparency();
|
||||
if (GetView())
|
||||
GetView()->InstallTransparency();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
host->Send(new AtomViewMsg_Offscreen(host->GetRoutingID()));
|
||||
#endif
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::RenderViewSwappedIn(
|
||||
|
@ -111,14 +153,22 @@ void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled) {
|
|||
|
||||
void OffScreenWebContentsView::GetScreenInfo(
|
||||
content::ScreenInfo* screen_info) const {
|
||||
screen_info->rect = gfx::Rect(view_->size());
|
||||
screen_info->available_rect = gfx::Rect(view_->size());
|
||||
screen_info->depth = 24;
|
||||
screen_info->depth_per_component = 8;
|
||||
screen_info->device_scale_factor = view_->scale_factor();
|
||||
screen_info->orientation_angle = 0;
|
||||
screen_info->device_scale_factor = 1.0;
|
||||
screen_info->orientation_type =
|
||||
content::SCREEN_ORIENTATION_VALUES_LANDSCAPE_PRIMARY;
|
||||
|
||||
if (GetView()) {
|
||||
screen_info->rect = gfx::Rect(GetView()->size());
|
||||
screen_info->available_rect = gfx::Rect(GetView()->size());
|
||||
} else {
|
||||
const display::Display display =
|
||||
display::Screen::GetScreen()->GetPrimaryDisplay();
|
||||
screen_info->rect = display.bounds();
|
||||
screen_info->available_rect = display.work_area();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
|
@ -152,4 +202,12 @@ void OffScreenWebContentsView::UpdateDragCursor(
|
|||
blink::WebDragOperation operation) {
|
||||
}
|
||||
|
||||
OffScreenRenderWidgetHostView* OffScreenWebContentsView::GetView() const {
|
||||
if (web_contents_) {
|
||||
return static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents_->GetRenderViewHost()->GetWidget()->GetView());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -75,11 +75,12 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
|||
void PlatformDestroy();
|
||||
#endif
|
||||
|
||||
OffScreenRenderWidgetHostView* GetView() const;
|
||||
|
||||
const bool transparent_;
|
||||
OnPaintCallback callback_;
|
||||
|
||||
// Weak refs.
|
||||
OffScreenRenderWidgetHostView* view_;
|
||||
content::WebContents* web_contents_;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
|
|
|
@ -35,6 +35,8 @@ IPC_MESSAGE_ROUTED3(AtomViewMsg_Message,
|
|||
base::string16 /* channel */,
|
||||
base::ListValue /* arguments */)
|
||||
|
||||
IPC_MESSAGE_ROUTED0(AtomViewMsg_Offscreen)
|
||||
|
||||
// Sent by the renderer when the draggable regions are updated.
|
||||
IPC_MESSAGE_ROUTED1(AtomViewHostMsg_UpdateDraggableRegions,
|
||||
std::vector<atom::DraggableRegion> /* regions */)
|
||||
|
|
|
@ -202,6 +202,11 @@ void Noop(char*, void*) {
|
|||
NativeImage::NativeImage(v8::Isolate* isolate, const gfx::Image& image)
|
||||
: image_(image) {
|
||||
Init(isolate);
|
||||
if (image_.HasRepresentation(gfx::Image::kImageRepSkia)) {
|
||||
isolate->AdjustAmountOfExternalAllocatedMemory(
|
||||
image_.ToImageSkia()->bitmap()->computeSize64());
|
||||
}
|
||||
MarkHighMemoryUsage();
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
@ -212,10 +217,20 @@ NativeImage::NativeImage(v8::Isolate* isolate, const base::FilePath& hicon_path)
|
|||
ReadImageSkiaFromICO(&image_skia, GetHICON(256));
|
||||
image_ = gfx::Image(image_skia);
|
||||
Init(isolate);
|
||||
if (image_.HasRepresentation(gfx::Image::kImageRepSkia)) {
|
||||
isolate->AdjustAmountOfExternalAllocatedMemory(
|
||||
image_.ToImageSkia()->bitmap()->computeSize64());
|
||||
}
|
||||
MarkHighMemoryUsage();
|
||||
}
|
||||
#endif
|
||||
|
||||
NativeImage::~NativeImage() {}
|
||||
NativeImage::~NativeImage() {
|
||||
if (image_.HasRepresentation(gfx::Image::kImageRepSkia)) {
|
||||
isolate()->AdjustAmountOfExternalAllocatedMemory(
|
||||
- image_.ToImageSkia()->bitmap()->computeSize64());
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
HICON NativeImage::GetHICON(int size) {
|
||||
|
|
|
@ -136,6 +136,7 @@ bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
|
|||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(AtomRenderViewObserver, message)
|
||||
IPC_MESSAGE_HANDLER(AtomViewMsg_Message, OnBrowserMessage)
|
||||
IPC_MESSAGE_HANDLER(AtomViewMsg_Offscreen, OnOffscreen)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
|
||||
|
@ -169,4 +170,8 @@ void AtomRenderViewObserver::OnBrowserMessage(bool send_to_all,
|
|||
}
|
||||
}
|
||||
|
||||
void AtomRenderViewObserver::OnOffscreen() {
|
||||
blink::WebView::setUseExternalPopupMenus(false);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -40,6 +40,8 @@ class AtomRenderViewObserver : public content::RenderViewObserver {
|
|||
const base::string16& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
void OnOffscreen();
|
||||
|
||||
AtomRendererClient* renderer_client_;
|
||||
|
||||
// Whether the document object has been created.
|
||||
|
|
2
vendor/native_mate
vendored
2
vendor/native_mate
vendored
|
@ -1 +1 @@
|
|||
Subproject commit fd0e7dc4ab778f0d1ccda6c9640464ea06ee771e
|
||||
Subproject commit 7d9c1a80f025f4c46f7da8ea73246fe0f1968579
|
Loading…
Add table
Reference in a new issue