Mac: use regions to improve painting performance (issue #360).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@377 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
69226efeb6
commit
0e4c6a648c
|
@ -2,21 +2,21 @@
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#import "browser_webview_mac.h"
|
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
#include "browser_impl.h"
|
#import "browser_webview_mac.h"
|
||||||
#include "cef_context.h"
|
#import "browser_impl.h"
|
||||||
|
#import "cef_context.h"
|
||||||
#import "web_drag_source_mac.h"
|
#import "web_drag_source_mac.h"
|
||||||
#import "web_drop_target_mac.h"
|
#import "web_drop_target_mac.h"
|
||||||
#include "webwidget_host.h"
|
#import "webwidget_host.h"
|
||||||
|
|
||||||
#include "base/memory/scoped_ptr.h"
|
#import "base/memory/scoped_ptr.h"
|
||||||
|
#import "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
|
||||||
|
#import "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
|
||||||
#import "third_party/mozilla/NSPasteboard+Utils.h"
|
#import "third_party/mozilla/NSPasteboard+Utils.h"
|
||||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
|
#import "third_party/skia/include/core/SkRegion.h"
|
||||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
|
#import "ui/gfx/rect.h"
|
||||||
#include "ui/gfx/rect.h"
|
|
||||||
|
|
||||||
@implementation BrowserWebView
|
@implementation BrowserWebView
|
||||||
|
|
||||||
|
@ -56,9 +56,21 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (browser_ && browser_->UIT_GetWebView()) {
|
if (browser_ && browser_->UIT_GetWebView()) {
|
||||||
gfx::Rect dirty_rect = gfx::Rect(NSRectToCGRect(rect));
|
NSInteger count;
|
||||||
dirty_rect.set_y(NSHeight([self bounds]) - dirty_rect.bottom());
|
const NSRect *rects;
|
||||||
browser_->UIT_GetWebViewHost()->Paint(dirty_rect);
|
[self getRectsBeingDrawn:&rects count:&count];
|
||||||
|
|
||||||
|
SkRegion update_rgn;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
const NSRect r = rects[i];
|
||||||
|
const float min_x = NSMinX(r);
|
||||||
|
const float max_x = NSMaxX(r);
|
||||||
|
const float min_y = NSHeight([self bounds]) - NSMaxY(r);
|
||||||
|
const float max_y = NSHeight([self bounds]) - NSMinY(r);
|
||||||
|
update_rgn.op(min_x, min_y, max_x, max_y, SkRegion::kUnion_Op);
|
||||||
|
}
|
||||||
|
|
||||||
|
browser_->UIT_GetWebViewHost()->Paint(update_rgn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ WebViewHost* WebViewHost::Create(NSView* parent_view,
|
||||||
|
|
||||||
NSRect content_rect = {{rect.x(), rect.y()}, {rect.width(), rect.height()}};
|
NSRect content_rect = {{rect.x(), rect.y()}, {rect.width(), rect.height()}};
|
||||||
host->view_ = [[BrowserWebView alloc] initWithFrame:content_rect];
|
host->view_ = [[BrowserWebView alloc] initWithFrame:content_rect];
|
||||||
// make the height and width track the window size.
|
|
||||||
[host->view_ setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
|
[host->view_ setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
|
||||||
[parent_view addSubview:host->view_];
|
[parent_view addSubview:host->view_];
|
||||||
[host->view_ release];
|
[host->view_ release];
|
||||||
|
|
|
@ -21,7 +21,7 @@ void WebWidgetHost::ScheduleAnimation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) {
|
void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) {
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
paint_rgn_.op(rect.x(), rect.y(), rect.right(), rect.bottom(),
|
paint_rgn_.op(rect.x(), rect.y(), rect.right(), rect.bottom(),
|
||||||
SkRegion::kUnion_Op);
|
SkRegion::kUnion_Op);
|
||||||
#else
|
#else
|
||||||
|
@ -96,8 +96,8 @@ void WebWidgetHost::DoPaint() {
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
if (MessageLoop::current()->IsIdle()) {
|
if (MessageLoop::current()->IsIdle()) {
|
||||||
has_update_task_ = false;
|
has_update_task_ = false;
|
||||||
// Paint to the delegate. The rect argument is unused.
|
// Paint to the delegate.
|
||||||
Paint(gfx::Rect());
|
Paint();
|
||||||
} else {
|
} else {
|
||||||
// Try again later.
|
// Try again later.
|
||||||
CefThread::PostTask(CefThread::UI, FROM_HERE,
|
CefThread::PostTask(CefThread::UI, FROM_HERE,
|
||||||
|
|
|
@ -87,7 +87,11 @@ class WebWidgetHost {
|
||||||
// is called. This is only used when window rendering is disabled.
|
// is called. This is only used when window rendering is disabled.
|
||||||
void UpdateRedrawRect(const gfx::Rect& rect);
|
void UpdateRedrawRect(const gfx::Rect& rect);
|
||||||
|
|
||||||
void Paint(const gfx::Rect& dirty_rect);
|
#if defined(OS_MACOSX)
|
||||||
|
void Paint(SkRegion& update_rgn);
|
||||||
|
#else
|
||||||
|
void Paint();
|
||||||
|
#endif
|
||||||
void InvalidateRect(const gfx::Rect& rect);
|
void InvalidateRect(const gfx::Rect& rect);
|
||||||
|
|
||||||
bool GetImage(int width, int height, void* buffer);
|
bool GetImage(int width, int height, void* buffer);
|
||||||
|
@ -211,8 +215,8 @@ class WebWidgetHost {
|
||||||
bool popup_;
|
bool popup_;
|
||||||
|
|
||||||
// Specifies the portion of the webwidget that needs painting.
|
// Specifies the portion of the webwidget that needs painting.
|
||||||
// TODO: Update all ports to use regions instead of rectangles.
|
// TODO(cef): Update the Linux port to use regions instead of rectangles.
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||||
SkRegion paint_rgn_;
|
SkRegion paint_rgn_;
|
||||||
#else
|
#else
|
||||||
gfx::Rect paint_rect_;
|
gfx::Rect paint_rect_;
|
||||||
|
|
|
@ -149,7 +149,7 @@ class WebWidgetHostGtkWidget {
|
||||||
g_handling_expose = true;
|
g_handling_expose = true;
|
||||||
gfx::Rect rect(expose->area);
|
gfx::Rect rect(expose->area);
|
||||||
host->UpdatePaintRect(rect);
|
host->UpdatePaintRect(rect);
|
||||||
host->Paint(rect);
|
host->Paint();
|
||||||
g_handling_expose = false;
|
g_handling_expose = false;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -342,7 +342,7 @@ void WebWidgetHost::Resize(const gfx::Size &newsize) {
|
||||||
SetSize(newsize.width(), newsize.height());
|
SetSize(newsize.width(), newsize.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebWidgetHost::Paint(const gfx::Rect& dirty_rect) {
|
void WebWidgetHost::Paint() {
|
||||||
int width = logical_size_.width();
|
int width = logical_size_.width();
|
||||||
int height = logical_size_.height();
|
int height = logical_size_.height();
|
||||||
gfx::Rect client_rect(width, height);
|
gfx::Rect client_rect(width, height);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#import "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h"
|
#import "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h"
|
||||||
#import "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
|
#import "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
|
||||||
#import "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
|
#import "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
|
||||||
|
#import "third_party/skia/include/core/SkRegion.h"
|
||||||
#import "ui/gfx/rect.h"
|
#import "ui/gfx/rect.h"
|
||||||
#import "ui/gfx/size.h"
|
#import "ui/gfx/size.h"
|
||||||
#import "webkit/glue/webkit_glue.h"
|
#import "webkit/glue/webkit_glue.h"
|
||||||
|
@ -27,6 +28,20 @@ using WebKit::WebScreenInfoFactory;
|
||||||
using WebKit::WebSize;
|
using WebKit::WebSize;
|
||||||
using WebKit::WebWidgetClient;
|
using WebKit::WebWidgetClient;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
inline SkIRect convertToSkiaRect(const gfx::Rect& r)
|
||||||
|
{
|
||||||
|
return SkIRect::MakeLTRB(r.x(), r.y(), r.right(), r.bottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline gfx::Rect convertFromSkiaRect(const SkIRect& r)
|
||||||
|
{
|
||||||
|
return gfx::Rect(r.x(), r.y(), r.width(), r.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
WebWidgetHost* WebWidgetHost::Create(NSView* parent_view,
|
WebWidgetHost* WebWidgetHost::Create(NSView* parent_view,
|
||||||
WebWidgetClient* client,
|
WebWidgetClient* client,
|
||||||
|
@ -44,15 +59,30 @@ WebWidgetHost* WebWidgetHost::Create(NSView* parent_view,
|
||||||
return host;
|
return host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebWidgetHost::WebWidgetHost()
|
||||||
|
: view_(NULL),
|
||||||
|
paint_delegate_(NULL),
|
||||||
|
webwidget_(NULL),
|
||||||
|
canvas_w_(0),
|
||||||
|
canvas_h_(0),
|
||||||
|
popup_(false),
|
||||||
|
has_update_task_(false),
|
||||||
|
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
|
||||||
|
set_painting(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebWidgetHost::~WebWidgetHost() {
|
||||||
|
}
|
||||||
|
|
||||||
void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) {
|
void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) {
|
||||||
const gfx::Rect client_rect(NSRectToCGRect([view_ bounds]));
|
const gfx::Rect client_rect(NSRectToCGRect([view_ bounds]));
|
||||||
const gfx::Rect damaged_rect_in_client = client_rect.Intersect(damaged_rect);
|
const gfx::Rect damaged_rect_in_client = client_rect.Intersect(damaged_rect);
|
||||||
|
|
||||||
if (!damaged_rect_in_client.IsEmpty()) {
|
if (!damaged_rect_in_client.IsEmpty()) {
|
||||||
paint_rect_ = paint_rect_.Union(damaged_rect_in_client);
|
UpdatePaintRect(damaged_rect_in_client);
|
||||||
NSRect r = NSRectFromCGRect(damaged_rect_in_client.ToCGRect());
|
NSRect cocoa_rect = NSRectFromCGRect(damaged_rect_in_client.ToCGRect());
|
||||||
r.origin.y = NSHeight([view_ bounds]) - NSMaxY(r);
|
cocoa_rect.origin.y = client_rect.height() - NSMaxY(cocoa_rect);
|
||||||
[view_ setNeedsDisplayInRect:r];
|
[view_ setNeedsDisplayInRect:cocoa_rect];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,14 +115,7 @@ void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
|
||||||
// The scrolling rect must not scroll outside the clip rect because that will
|
// The scrolling rect must not scroll outside the clip rect because that will
|
||||||
// clobber the scrollbars. As a result we shorten the rectangle a bit from the
|
// clobber the scrollbars. As a result we shorten the rectangle a bit from the
|
||||||
// leading side of the scroll (could be either horizontally or vertically).
|
// leading side of the scroll (could be either horizontally or vertically).
|
||||||
if (dx > 0)
|
rect = gfx::Rect(dx>=0? x: x + Dx, dy>=0? y: y + Dy, w - Dx, h - Dy);
|
||||||
rect = gfx::Rect(x, y, w - dx, h);
|
|
||||||
else if (dx < 0)
|
|
||||||
rect = gfx::Rect(x - dx, y, w + dx, h);
|
|
||||||
else if (dy > 0)
|
|
||||||
rect = gfx::Rect(x, y, w, h - dy);
|
|
||||||
else if (dy < 0)
|
|
||||||
rect = gfx::Rect(x, y - dy, w, h + dy);
|
|
||||||
|
|
||||||
// Convert the scroll rectangle to the view's coordinate system and perform
|
// Convert the scroll rectangle to the view's coordinate system and perform
|
||||||
// the scroll directly without invalidating the view. In theory this could
|
// the scroll directly without invalidating the view. In theory this could
|
||||||
|
@ -101,73 +124,28 @@ void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
|
||||||
// since just copying the pixels within the window is much faster than
|
// since just copying the pixels within the window is much faster than
|
||||||
// redrawing them.
|
// redrawing them.
|
||||||
NSRect cocoa_rect = NSRectFromCGRect(rect.ToCGRect());
|
NSRect cocoa_rect = NSRectFromCGRect(rect.ToCGRect());
|
||||||
cocoa_rect.origin.y = NSHeight([view_ bounds]) - NSMaxY(cocoa_rect);
|
cocoa_rect.origin.y = client_rect.height() - NSMaxY(cocoa_rect);
|
||||||
[view_ scrollRect:cocoa_rect by:NSMakeSize(dx, -dy)];
|
[view_ scrollRect:cocoa_rect by:NSMakeSize(dx, -dy)];
|
||||||
|
|
||||||
const gfx::Rect saved_paint_rect = paint_rect_;
|
|
||||||
if (![view_ lockFocusIfCanDraw])
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Repaint the rectangle that was revealed when scrolling the given rectangle.
|
// Repaint the rectangle that was revealed when scrolling the given rectangle.
|
||||||
// We don't want to invalidate this rectangle because that would cause the
|
// The invalidated area will be painted before the view contents are flushed
|
||||||
// invalidated area to be L-shaped due to the combination of this narrow area
|
// to the screen buffer.
|
||||||
// and the scrollbar area that may also be invalidated. The union of these two
|
rect = gfx::Rect(dx>=0? x: r - Dx, dy>=0? y: b - Dy,
|
||||||
// rectangles is pretty much the entire view area and we would not save any
|
dx>0? Dx: w, dy>0? Dy: h);
|
||||||
// work by doing the scrollRect: call above.
|
DidInvalidateRect(rect);
|
||||||
if (dx > 0)
|
|
||||||
paint_rect_ = gfx::Rect(x, y, dx, h);
|
|
||||||
else if (dx < 0)
|
|
||||||
paint_rect_ = gfx::Rect(r + dx, y, -dx, h);
|
|
||||||
else if (dy > 0)
|
|
||||||
paint_rect_ = gfx::Rect(x, y, w, dy);
|
|
||||||
else if (dy < 0)
|
|
||||||
paint_rect_ = gfx::Rect(x, b + dy, w, -dy);
|
|
||||||
|
|
||||||
paint_rect_ = paint_rect_.Intersect(client_rect);
|
|
||||||
if (!paint_rect_.IsEmpty())
|
|
||||||
Paint(paint_rect_);
|
|
||||||
|
|
||||||
// If any part of the scrolled rect was marked as dirty make sure to redraw
|
// If any part of the scrolled rect was marked as dirty make sure to redraw
|
||||||
// it in the new scrolled-to location. Otherwise we can end up with artifacts
|
// it in the new scrolled-to location. Otherwise we can end up with artifacts
|
||||||
// for overlapping elements.
|
// for overlapping elements. If there are multiple dirty regions in the scroll
|
||||||
gfx::Rect moved_paint_rect = saved_paint_rect.Intersect(clip_rect);
|
// rect the rectangle union of those regions will be redrawn.
|
||||||
if (!moved_paint_rect.IsEmpty()) {
|
SkRegion moved_paint_rgn(paint_rgn_);
|
||||||
moved_paint_rect.Offset(dx, dy);
|
moved_paint_rgn.translate(dx, dy);
|
||||||
paint_rect_ = moved_paint_rect;
|
moved_paint_rgn.op(convertToSkiaRect(client_rect), SkRegion::kIntersect_Op);
|
||||||
paint_rect_ = paint_rect_.Intersect(client_rect);
|
DidInvalidateRect(convertFromSkiaRect(moved_paint_rgn.getBounds()));
|
||||||
if (!paint_rect_.IsEmpty())
|
|
||||||
Paint(paint_rect_);
|
|
||||||
}
|
|
||||||
|
|
||||||
[view_ unlockFocus];
|
|
||||||
paint_rect_ = saved_paint_rect;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebWidgetHost::ScheduleComposite() {
|
void WebWidgetHost::Paint(SkRegion& update_rgn) {
|
||||||
if (!webwidget_)
|
|
||||||
return;
|
|
||||||
const WebSize size = webwidget_->size();
|
|
||||||
[view_ setNeedsDisplayInRect:NSMakeRect(0, 0, size.width, size.height)];
|
|
||||||
}
|
|
||||||
|
|
||||||
WebWidgetHost::WebWidgetHost()
|
|
||||||
: view_(NULL),
|
|
||||||
paint_delegate_(NULL),
|
|
||||||
webwidget_(NULL),
|
|
||||||
canvas_w_(0),
|
|
||||||
canvas_h_(0),
|
|
||||||
popup_(false),
|
|
||||||
has_update_task_(false),
|
|
||||||
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
|
|
||||||
set_painting(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
WebWidgetHost::~WebWidgetHost() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebWidgetHost::Paint(const gfx::Rect& dirty_rect) {
|
|
||||||
gfx::Rect client_rect(NSRectToCGRect([view_ bounds]));
|
gfx::Rect client_rect(NSRectToCGRect([view_ bounds]));
|
||||||
gfx::Rect copy_rect = dirty_rect;
|
|
||||||
|
|
||||||
// Union the rectangle that WebKit think needs repainting with the rectangle
|
// Union the rectangle that WebKit think needs repainting with the rectangle
|
||||||
// of the view that must be painted now. In most situations this will not
|
// of the view that must be painted now. In most situations this will not
|
||||||
|
@ -176,7 +154,7 @@ void WebWidgetHost::Paint(const gfx::Rect& dirty_rect) {
|
||||||
// itself. However, if we don't do this we can get artifacts when scrolling
|
// itself. However, if we don't do this we can get artifacts when scrolling
|
||||||
// because contents of the canvas are no longer correct after scrolling only
|
// because contents of the canvas are no longer correct after scrolling only
|
||||||
// in the view.
|
// in the view.
|
||||||
paint_rect_ = paint_rect_.Union(dirty_rect);
|
paint_rgn_.op(update_rgn, SkRegion::kUnion_Op);
|
||||||
|
|
||||||
// When we are not using accelerated compositing the canvas area is allowed
|
// When we are not using accelerated compositing the canvas area is allowed
|
||||||
// to differ in size from the client by a certain number of pixels (128 in
|
// to differ in size from the client by a certain number of pixels (128 in
|
||||||
|
@ -196,6 +174,7 @@ void WebWidgetHost::Paint(const gfx::Rect& dirty_rect) {
|
||||||
canvas_w_ = client_rect.width() + extra_w;
|
canvas_w_ = client_rect.width() + extra_w;
|
||||||
canvas_h_ = client_rect.height() + extra_h;
|
canvas_h_ = client_rect.height() + extra_h;
|
||||||
canvas_.reset(new skia::PlatformCanvas(canvas_w_, canvas_h_, true));
|
canvas_.reset(new skia::PlatformCanvas(canvas_w_, canvas_h_, true));
|
||||||
|
paint_rgn_.setRect(convertToSkiaRect(client_rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animate the view and layout any views that have not been laid out yet. The
|
// Animate the view and layout any views that have not been laid out yet. The
|
||||||
|
@ -216,29 +195,40 @@ void WebWidgetHost::Paint(const gfx::Rect& dirty_rect) {
|
||||||
[NSGraphicsContext setCurrentContext:paint_context];
|
[NSGraphicsContext setCurrentContext:paint_context];
|
||||||
|
|
||||||
// Paint the canvas if necessary. The painting operation can cause additional
|
// Paint the canvas if necessary. The painting operation can cause additional
|
||||||
// rectangles to be invalidated because some elements are laid out only the
|
// regions to be invalidated because some elements are laid out the first time
|
||||||
// first time they are painted.
|
// they are painted.
|
||||||
paint_rect_ = client_rect.Intersect(paint_rect_);
|
while (!paint_rgn_.isEmpty()) {
|
||||||
const gfx::Rect paint_rect = paint_rect_;
|
SkRegion draw_rgn;
|
||||||
paint_rect_ = gfx::Rect();
|
draw_rgn.swap(paint_rgn_);
|
||||||
PaintRect(paint_rect);
|
|
||||||
|
|
||||||
if (!paint_rect_.IsEmpty()) {
|
SkRegion::Cliperator iterator(draw_rgn, convertToSkiaRect(client_rect));
|
||||||
copy_rect = copy_rect.Union(paint_rect_);
|
for (; !iterator.done(); iterator.next())
|
||||||
const gfx::Rect paint_rect = paint_rect_;
|
PaintRect(convertFromSkiaRect(iterator.rect()));
|
||||||
paint_rect_ = gfx::Rect();
|
|
||||||
PaintRect(paint_rect);
|
// If any more rectangles were made dirty during the paint operation, make
|
||||||
|
// sure they are copied to the window buffer, by including the paint region.
|
||||||
|
// If nothing needs additional painting, this is a no-op.
|
||||||
|
update_rgn.op(paint_rgn_, SkRegion::kUnion_Op);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the context back to our view and copy the bitmap that we just painted
|
// Set the context back to our view and copy the bitmap that we just painted
|
||||||
// into to the view. Only the region that was updated is copied.
|
// into to the view. Only the regions that were updated are copied.
|
||||||
[NSGraphicsContext restoreGraphicsState];
|
[NSGraphicsContext restoreGraphicsState];
|
||||||
NSGraphicsContext* view_context = [NSGraphicsContext currentContext];
|
NSGraphicsContext* view_context = [NSGraphicsContext currentContext];
|
||||||
CGContextRef context = static_cast<CGContextRef>([view_context graphicsPort]);
|
CGContextRef context = static_cast<CGContextRef>([view_context graphicsPort]);
|
||||||
CGRect bitmap_rect = { { copy_rect.x(), copy_rect.y() },
|
|
||||||
{ copy_rect.width(), copy_rect.height() } };
|
SkRegion::Cliperator iterator(update_rgn, convertToSkiaRect(client_rect));
|
||||||
skia::DrawToNativeContext(canvas_.get(), context, copy_rect.x(),
|
for (; !iterator.done(); iterator.next()) {
|
||||||
client_rect.height() - copy_rect.bottom(), &bitmap_rect);
|
const SkIRect& r = iterator.rect();
|
||||||
|
CGRect copy_rect = { { r.x(), r.y() }, { r.width(), r.height() } };
|
||||||
|
const float x = r.x();
|
||||||
|
const float y = client_rect.height() - r.bottom();
|
||||||
|
skia::DrawToNativeContext(canvas_.get(), context, x, y, ©_rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebWidgetHost::ScheduleComposite() {
|
||||||
|
[view_ setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebWidgetHost::SetTooltipText(const CefString& tooltip_text)
|
void WebWidgetHost::SetTooltipText(const CefString& tooltip_text)
|
||||||
|
|
|
@ -123,8 +123,8 @@ LRESULT CALLBACK WebWidgetHost::WndProc(HWND hwnd, UINT message, WPARAM wparam,
|
||||||
if (host && !host->WndProc(message, wparam, lparam)) {
|
if (host && !host->WndProc(message, wparam, lparam)) {
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case WM_PAINT: {
|
case WM_PAINT: {
|
||||||
// Paint to the window. The rect argument is unused.
|
// Paint to the window.
|
||||||
host->Paint(gfx::Rect());
|
host->Paint();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ bool WebWidgetHost::WndProc(UINT message, WPARAM wparam, LPARAM lparam) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebWidgetHost::Paint(const gfx::Rect& /*dirty_rect*/) {
|
void WebWidgetHost::Paint() {
|
||||||
int width, height;
|
int width, height;
|
||||||
GetSize(width, height);
|
GetSize(width, height);
|
||||||
gfx::Rect client_rect(width, height);
|
gfx::Rect client_rect(width, height);
|
||||||
|
|
Loading…
Reference in New Issue