Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Unified Diff: ppapi/cpp/paint_manager.cc

Issue 7215030: Don't copy the Graphics2D when binding a new one. This brings the (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/cpp/paint_manager.h ('k') | ppapi/examples/2d/paint_manager_example.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/cpp/paint_manager.cc
===================================================================
--- ppapi/cpp/paint_manager.cc (revision 89742)
+++ ppapi/cpp/paint_manager.cc (working copy)
@@ -17,7 +17,8 @@
is_always_opaque_(false),
callback_factory_(NULL),
manual_callback_pending_(false),
- flush_pending_(false) {
+ flush_pending_(false),
+ has_pending_resize_(false) {
// Set the callback object outside of the initializer list to avoid a
// compiler warning about using "this" in an initializer list.
callback_factory_.Initialize(this);
@@ -31,7 +32,8 @@
is_always_opaque_(is_always_opaque),
callback_factory_(NULL),
manual_callback_pending_(false),
- flush_pending_(false) {
+ flush_pending_(false),
+ has_pending_resize_(false) {
// Set the callback object outside of the initializer list to avoid a
// compiler warning about using "this" in an initializer list.
callback_factory_.Initialize(this);
@@ -53,35 +55,29 @@
}
void PaintManager::SetSize(const Size& new_size) {
- if (new_size == graphics_.size())
+ if (GetEffectiveSize() == new_size)
return;
- graphics_ = Graphics2D(instance_, new_size, is_always_opaque_);
- if (graphics_.is_null())
- return;
- instance_->BindGraphics(graphics_);
+ has_pending_resize_ = true;
+ pending_size_ = new_size;
- manual_callback_pending_ = false;
- flush_pending_ = false;
- callback_factory_.CancelAll();
-
Invalidate();
}
void PaintManager::Invalidate() {
- // You must call SetDevice before using.
- PP_DCHECK(!graphics_.is_null());
+ // You must call SetSize before using.
+ PP_DCHECK(!graphics_.is_null() || has_pending_resize_);
EnsureCallbackPending();
- aggregator_.InvalidateRect(Rect(graphics_.size()));
+ aggregator_.InvalidateRect(Rect(GetEffectiveSize()));
}
void PaintManager::InvalidateRect(const Rect& rect) {
- // You must call SetDevice before using.
- PP_DCHECK(!graphics_.is_null());
+ // You must call SetSize before using.
+ PP_DCHECK(!graphics_.is_null() || has_pending_resize_);
// Clip the rect to the device area.
- Rect clipped_rect = rect.Intersect(Rect(graphics_.size()));
+ Rect clipped_rect = rect.Intersect(Rect(GetEffectiveSize()));
if (clipped_rect.IsEmpty())
return; // Nothing to do.
@@ -90,13 +86,17 @@
}
void PaintManager::ScrollRect(const Rect& clip_rect, const Point& amount) {
- // You must call SetDevice before using.
- PP_DCHECK(!graphics_.is_null());
+ // You must call SetSize before using.
+ PP_DCHECK(!graphics_.is_null() || has_pending_resize_);
EnsureCallbackPending();
aggregator_.ScrollRect(clip_rect, amount);
}
+Size PaintManager::GetEffectiveSize() const {
+ return has_pending_resize_ ? pending_size_ : graphics_.size();
+}
+
void PaintManager::EnsureCallbackPending() {
// The best way for us to do the next update is to get a notification that
// a previous one has completed. So if we're already waiting for one, we
@@ -125,32 +125,56 @@
PaintAggregator::PaintUpdate update = aggregator_.GetPendingUpdate();
aggregator_.ClearPendingUpdate();
+ // Apply any pending resize. Setting the graphics to this class must happen
+ // before asking the plugin to paint in case it requests the Graphics2D during
+ // painting. However, the bind must not happen until afterward since we don't
+ // want to have an unpainted device bound. The needs_binding flag tells us
+ // whether to do this later.
+ bool needs_binding = false;
+ if (has_pending_resize_) {
+ graphics_ = Graphics2D(instance_, pending_size_, is_always_opaque_);
+ needs_binding = true;
+
+ // Since we're binding a new one, all of the callbacks have been canceled.
+ manual_callback_pending_ = false;
+ flush_pending_ = false;
+ callback_factory_.CancelAll();
+
+ // This must be cleared before calling into the plugin since it may do
+ // additional invalidation or sizing operations.
+ has_pending_resize_ = false;
+ pending_size_ = Size();
+ }
+
// Apply any scroll before asking the client to paint.
if (update.has_scroll)
graphics_.Scroll(update.scroll_rect, update.scroll_delta);
- if (!client_->OnPaint(graphics_, update.paint_rects, update.paint_bounds))
- return; // Nothing was painted, don't schedule a flush.
+ if (client_->OnPaint(graphics_, update.paint_rects, update.paint_bounds)) {
+ // Something was painted, schedule a flush.
+ int32_t result = graphics_.Flush(
+ callback_factory_.NewCallback(&PaintManager::OnFlushComplete));
- int32_t result = graphics_.Flush(
- callback_factory_.NewCallback(&PaintManager::OnFlushComplete));
+ // If you trigger this assertion, then your plugin has called Flush()
+ // manually. When using the PaintManager, you should not call Flush, it
+ // will handle that for you because it needs to know when it can do the
+ // next paint by implementing the flush callback.
+ //
+ // Another possible cause of this assertion is re-using devices. If you
+ // use one device, swap it with another, then swap it back, we won't know
+ // that we've already scheduled a Flush on the first device. It's best to
+ // not re-use devices in this way.
+ PP_DCHECK(result != PP_ERROR_INPROGRESS);
- // If you trigger this assertion, then your plugin has called Flush()
- // manually. When using the PaintManager, you should not call Flush, it will
- // handle that for you because it needs to know when it can do the next paint
- // by implementing the flush callback.
- //
- // Another possible cause of this assertion is re-using devices. If you
- // use one device, swap it with another, then swap it back, we won't know
- // that we've already scheduled a Flush on the first device. It's best to not
- // re-use devices in this way.
- PP_DCHECK(result != PP_ERROR_INPROGRESS);
+ if (result == PP_OK_COMPLETIONPENDING) {
+ flush_pending_ = true;
+ } else {
+ PP_DCHECK(result == PP_OK); // Catch all other errors in debug mode.
+ }
+ }
- if (result == PP_OK_COMPLETIONPENDING) {
- flush_pending_ = true;
- } else {
- PP_DCHECK(result == PP_OK); // Catch all other errors in debug mode.
- }
+ if (needs_binding)
+ instance_->BindGraphics(graphics_);
}
void PaintManager::OnFlushComplete(int32_t) {
@@ -175,4 +199,5 @@
DoPaint();
}
+
} // namespace pp
« no previous file with comments | « ppapi/cpp/paint_manager.h ('k') | ppapi/examples/2d/paint_manager_example.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698