summaryrefslogtreecommitdiff
path: root/xfa_test/pdf/paint_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'xfa_test/pdf/paint_manager.cc')
-rw-r--r--xfa_test/pdf/paint_manager.cc302
1 files changed, 0 insertions, 302 deletions
diff --git a/xfa_test/pdf/paint_manager.cc b/xfa_test/pdf/paint_manager.cc
deleted file mode 100644
index f452b37186..0000000000
--- a/xfa_test/pdf/paint_manager.cc
+++ /dev/null
@@ -1,302 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "pdf/paint_manager.h"
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/cpp/instance.h"
-#include "ppapi/cpp/module.h"
-
-PaintManager::PaintManager(pp::Instance* instance,
- Client* client,
- bool is_always_opaque)
- : instance_(instance),
- client_(client),
- is_always_opaque_(is_always_opaque),
- callback_factory_(NULL),
- manual_callback_pending_(false),
- flush_pending_(false),
- has_pending_resize_(false),
- graphics_need_to_be_bound_(false),
- pending_device_scale_(1.0),
- device_scale_(1.0),
- in_paint_(false),
- first_paint_(true),
- view_size_changed_waiting_for_paint_(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);
-
- // You can not use a NULL client pointer.
- DCHECK(client);
-}
-
-PaintManager::~PaintManager() {
-}
-
-// static
-pp::Size PaintManager::GetNewContextSize(const pp::Size& current_context_size,
- const pp::Size& plugin_size) {
- // The amount of additional space in pixels to allocate to the right/bottom of
- // the context.
- const int kBufferSize = 50;
-
- // Default to returning the same size.
- pp::Size result = current_context_size;
-
- // The minimum size of the plugin before resizing the context to ensure we
- // aren't wasting too much memory. We deduct twice the kBufferSize from the
- // current context size which gives a threshhold that is kBufferSize below
- // the plugin size when the context size was last computed.
- pp::Size min_size(
- std::max(current_context_size.width() - 2 * kBufferSize, 0),
- std::max(current_context_size.height() - 2 * kBufferSize, 0));
-
- // If the plugin size is bigger than the current context size, we need to
- // resize the context. If the plugin size is smaller than the current
- // context size by a given threshhold then resize the context so that we
- // aren't wasting too much memory.
- if (plugin_size.width() > current_context_size.width() ||
- plugin_size.height() > current_context_size.height() ||
- plugin_size.width() < min_size.width() ||
- plugin_size.height() < min_size.height()) {
- // Create a larger context than needed so that if we only resize by a
- // small margin, we don't need a new context.
- result = pp::Size(plugin_size.width() + kBufferSize,
- plugin_size.height() + kBufferSize);
- }
-
- return result;
-}
-
-void PaintManager::Initialize(pp::Instance* instance,
- Client* client,
- bool is_always_opaque) {
- DCHECK(!instance_ && !client_); // Can't initialize twice.
- instance_ = instance;
- client_ = client;
- is_always_opaque_ = is_always_opaque;
-}
-
-void PaintManager::SetSize(const pp::Size& new_size, float device_scale) {
- if (GetEffectiveSize() == new_size &&
- GetEffectiveDeviceScale() == device_scale)
- return;
-
- has_pending_resize_ = true;
- pending_size_ = new_size;
- pending_device_scale_ = device_scale;
-
- view_size_changed_waiting_for_paint_ = true;
-
- Invalidate();
-}
-
-void PaintManager::Invalidate() {
- // You must call SetSize before using.
- DCHECK(!graphics_.is_null() || has_pending_resize_);
-
- EnsureCallbackPending();
- aggregator_.InvalidateRect(pp::Rect(GetEffectiveSize()));
-}
-
-void PaintManager::InvalidateRect(const pp::Rect& rect) {
- DCHECK(!in_paint_);
-
- // You must call SetSize before using.
- DCHECK(!graphics_.is_null() || has_pending_resize_);
-
- // Clip the rect to the device area.
- pp::Rect clipped_rect = rect.Intersect(pp::Rect(GetEffectiveSize()));
- if (clipped_rect.IsEmpty())
- return; // Nothing to do.
-
- EnsureCallbackPending();
- aggregator_.InvalidateRect(clipped_rect);
-}
-
-void PaintManager::ScrollRect(const pp::Rect& clip_rect,
- const pp::Point& amount) {
- DCHECK(!in_paint_);
-
- // You must call SetSize before using.
- DCHECK(!graphics_.is_null() || has_pending_resize_);
-
- EnsureCallbackPending();
-
- aggregator_.ScrollRect(clip_rect, amount);
-}
-
-pp::Size PaintManager::GetEffectiveSize() const {
- return has_pending_resize_ ? pending_size_ : plugin_size_;
-}
-
-float PaintManager::GetEffectiveDeviceScale() const {
- return has_pending_resize_ ? pending_device_scale_ : device_scale_;
-}
-
-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
- // don't have to do anything differently now.
- if (flush_pending_)
- return;
-
- // If no flush is pending, we need to do a manual call to get back to the
- // main thread. We may have one already pending, or we may need to schedule.
- if (manual_callback_pending_)
- return;
-
- pp::Module::Get()->core()->CallOnMainThread(
- 0,
- callback_factory_.NewCallback(&PaintManager::OnManualCallbackComplete),
- 0);
- manual_callback_pending_ = true;
-}
-
-void PaintManager::DoPaint() {
- in_paint_ = true;
-
- std::vector<ReadyRect> ready;
- std::vector<pp::Rect> pending;
-
- DCHECK(aggregator_.HasPendingUpdate());
-
- // Apply any pending resize. Setting the graphics to this class must happen
- // before asking the plugin to paint in case it requests invalides or resizes.
- // 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.
- if (has_pending_resize_) {
- plugin_size_ = pending_size_;
- // Only create a new graphics context if the current context isn't big
- // enough or if it is far too big. This avoids creating a new context if
- // we only resize by a small amount.
- pp::Size new_size = GetNewContextSize(graphics_.size(), pending_size_);
- if (graphics_.size() != new_size) {
- graphics_ = pp::Graphics2D(instance_, new_size, is_always_opaque_);
- graphics_need_to_be_bound_ = 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();
- }
-
- if (pending_device_scale_ != 1.0)
- graphics_.SetScale(1.0 / pending_device_scale_);
- device_scale_ = pending_device_scale_;
-
- // This must be cleared before calling into the plugin since it may do
- // additional invalidation or sizing operations.
- has_pending_resize_ = false;
- pending_size_ = pp::Size();
- }
-
- PaintAggregator::PaintUpdate update = aggregator_.GetPendingUpdate();
- client_->OnPaint(update.paint_rects, &ready, &pending);
-
- if (ready.empty() && pending.empty()) {
- in_paint_ = false;
- return; // Nothing was painted, don't schedule a flush.
- }
-
- std::vector<PaintAggregator::ReadyRect> ready_now;
- if (pending.empty()) {
- std::vector<PaintAggregator::ReadyRect> temp_ready;
- for (size_t i = 0; i < ready.size(); ++i)
- temp_ready.push_back(ready[i]);
- aggregator_.SetIntermediateResults(temp_ready, pending);
- ready_now = aggregator_.GetReadyRects();
- aggregator_.ClearPendingUpdate();
-
- // Apply any scroll first.
- if (update.has_scroll)
- graphics_.Scroll(update.scroll_rect, update.scroll_delta);
-
- view_size_changed_waiting_for_paint_ = false;
- } else {
- std::vector<PaintAggregator::ReadyRect> ready_later;
- for (size_t i = 0; i < ready.size(); ++i) {
- // Don't flush any part (i.e. scrollbars) if we're resizing the browser,
- // as that'll lead to flashes. Until we flush, the browser will use the
- // previous image, but if we flush, it'll revert to using the blank image.
- // We make an exception for the first paint since we want to show the
- // default background color instead of the pepper default of black.
- if (ready[i].flush_now &&
- (!view_size_changed_waiting_for_paint_ || first_paint_)) {
- ready_now.push_back(ready[i]);
- } else {
- ready_later.push_back(ready[i]);
- }
- }
- // Take the rectangles, except the ones that need to be flushed right away,
- // and save them so that everything is flushed at once.
- aggregator_.SetIntermediateResults(ready_later, pending);
-
- if (ready_now.empty()) {
- in_paint_ = false;
- EnsureCallbackPending();
- return;
- }
- }
-
- for (size_t i = 0; i < ready_now.size(); ++i) {
- graphics_.PaintImageData(
- ready_now[i].image_data, ready_now[i].offset, ready_now[i].rect);
- }
-
- 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.
- DCHECK(result != PP_ERROR_INPROGRESS);
-
- if (result == PP_OK_COMPLETIONPENDING) {
- flush_pending_ = true;
- } else {
- DCHECK(result == PP_OK); // Catch all other errors in debug mode.
- }
-
- in_paint_ = false;
- first_paint_ = false;
-
- if (graphics_need_to_be_bound_) {
- instance_->BindGraphics(graphics_);
- graphics_need_to_be_bound_ = false;
- }
-}
-
-void PaintManager::OnFlushComplete(int32_t) {
- DCHECK(flush_pending_);
- flush_pending_ = false;
-
- // If more paints were enqueued while we were waiting for the flush to
- // complete, execute them now.
- if (aggregator_.HasPendingUpdate())
- DoPaint();
-}
-
-void PaintManager::OnManualCallbackComplete(int32_t) {
- DCHECK(manual_callback_pending_);
- manual_callback_pending_ = false;
-
- // Just because we have a manual callback doesn't mean there are actually any
- // invalid regions. Even though we only schedule this callback when something
- // is pending, a Flush callback could have come in before this callback was
- // executed and that could have cleared the queue.
- if (aggregator_.HasPendingUpdate())
- DoPaint();
-}