summaryrefslogtreecommitdiffstats
path: root/pdf/out_of_process_instance.cc
diff options
context:
space:
mode:
authorraymes@chromium.org <raymes@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-26 05:45:27 +0000
committerraymes@chromium.org <raymes@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-26 05:45:27 +0000
commit499e956b97a13c20ae6e820f78bb21a0b42ce243 (patch)
tree691ff62cddc190694978becb8509f651a5b6a881 /pdf/out_of_process_instance.cc
parentc0da00f011c226d181fbccef23db34dab607e4c2 (diff)
downloadchromium_src-499e956b97a13c20ae6e820f78bb21a0b42ce243.zip
chromium_src-499e956b97a13c20ae6e820f78bb21a0b42ce243.tar.gz
chromium_src-499e956b97a13c20ae6e820f78bb21a0b42ce243.tar.bz2
Improve scrolling performance in OOP PDF
This increases the performance of scrolling in OOP PDF by not sending viewport changes via postMessage every time a scroll event occurs on the page. Instead, scroll events are sent along with pepper DidChangeView messages, which is a much more responsive way of updating the scroll position. Unfortunately this introduces some issues coordinating zoom and scroll events on the page. When a zoom happens in the container page, a scroll message might be sent to the plugin via DidChangeView. Then we send a zoom change message via postMessage. The result is that the zooming and scrolling happen asynchronously and result in a flickering effect. To avoid this, we first notify the plugin that we are about to zoom which causes it to stop reacting to scroll messages. After we have finished zooming we notify the plugin again so that it can continue reacting to scroll messages. BUG=386920 Review URL: https://codereview.chromium.org/347763007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@279910 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'pdf/out_of_process_instance.cc')
-rw-r--r--pdf/out_of_process_instance.cc83
1 files changed, 51 insertions, 32 deletions
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc
index 9e77ec6..4d1bb8f 100644
--- a/pdf/out_of_process_instance.cc
+++ b/pdf/out_of_process_instance.cc
@@ -34,6 +34,7 @@
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/point.h"
#include "ppapi/cpp/private/pdf.h"
+#include "ppapi/cpp/private/var_private.h"
#include "ppapi/cpp/rect.h"
#include "ppapi/cpp/resource.h"
#include "ppapi/cpp/url_request_info.h"
@@ -70,6 +71,8 @@ const char* kJSViewportType = "viewport";
const char* kJSXOffset = "xOffset";
const char* kJSYOffset = "yOffset";
const char* kJSZoom = "zoom";
+// Stop scrolling message (Page -> Plugin)
+const char* kJSStopScrollingType = "stopScrolling";
// Document dimension arguments (Plugin -> Page).
const char* kJSDocumentDimensionsType = "documentDimensions";
const char* kJSDocumentWidth = "width";
@@ -244,7 +247,8 @@ OutOfProcessInstance::OutOfProcessInstance(PP_Instance instance)
last_progress_sent_(0),
recently_sent_find_update_(false),
received_viewport_message_(false),
- did_call_start_loading_(false) {
+ did_call_start_loading_(false),
+ stop_scrolling_(false) {
loader_factory_.Initialize(this);
timer_factory_.Initialize(this);
form_factory_.Initialize(this);
@@ -355,20 +359,17 @@ void OutOfProcessInstance::HandleMessage(const pp::Var& message) {
dict.Get(pp::Var(kJSYOffset)).is_int() &&
dict.Get(pp::Var(kJSZoom)).is_number()) {
received_viewport_message_ = true;
+ stop_scrolling_ = false;
double zoom = dict.Get(pp::Var(kJSZoom)).AsDouble();
- int x = dict.Get(pp::Var(kJSXOffset)).AsInt();
- int y = dict.Get(pp::Var(kJSYOffset)).AsInt();
+ pp::Point scroll_offset(dict.Get(pp::Var(kJSXOffset)).AsInt(),
+ dict.Get(pp::Var(kJSYOffset)).AsInt());
// Bound the input parameters.
zoom = std::max(kMinZoom, zoom);
- int max_x = document_size_.width() * zoom - plugin_dip_size_.width();
- x = std::max(std::min(x, max_x), 0);
- int max_y = document_size_.height() * zoom - plugin_dip_size_.height();
- y = std::max(std::min(y, max_y), 0);
-
SetZoom(zoom);
- engine_->ScrolledToXPosition(x * device_scale_);
- engine_->ScrolledToYPosition(y * device_scale_);
+ scroll_offset = BoundScrollOffsetToDocument(scroll_offset);
+ engine_->ScrolledToXPosition(scroll_offset.x() * device_scale_);
+ engine_->ScrolledToYPosition(scroll_offset.y() * device_scale_);
} else if (type == kJSGetPasswordCompleteType &&
dict.Get(pp::Var(kJSPassword)).is_string()) {
if (password_callback_) {
@@ -425,6 +426,8 @@ void OutOfProcessInstance::HandleMessage(const pp::Var& message) {
reply.Set(pp::Var(kJSAccessibilityJSON), pp::Var(json));
}
PostMessage(reply);
+ } else if (type == kJSStopScrollingType) {
+ stop_scrolling_ = true;
} else {
NOTREACHED();
}
@@ -507,32 +510,38 @@ void OutOfProcessInstance::DidChangeView(const pp::View& view) {
pp::Size view_device_size(view_rect.width() * device_scale,
view_rect.height() * device_scale);
- if (view_device_size == plugin_size_ && device_scale == device_scale_)
- return; // We don't care about the position, only the size.
-
- device_scale_ = device_scale;
- plugin_dip_size_ = view_rect.size();
- plugin_size_ = view_device_size;
+ if (view_device_size != plugin_size_ || device_scale != device_scale_) {
+ device_scale_ = device_scale;
+ plugin_dip_size_ = view_rect.size();
+ plugin_size_ = view_device_size;
+
+ paint_manager_.SetSize(view_device_size, device_scale_);
+
+ pp::Size new_image_data_size = PaintManager::GetNewContextSize(
+ image_data_.size(),
+ plugin_size_);
+ if (new_image_data_size != image_data_.size()) {
+ image_data_ = pp::ImageData(this,
+ PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ new_image_data_size,
+ false);
+ first_paint_ = true;
+ }
- paint_manager_.SetSize(view_device_size, device_scale_);
+ if (image_data_.is_null()) {
+ DCHECK(plugin_size_.IsEmpty());
+ return;
+ }
- pp::Size new_image_data_size = PaintManager::GetNewContextSize(
- image_data_.size(),
- plugin_size_);
- if (new_image_data_size != image_data_.size()) {
- image_data_ = pp::ImageData(this,
- PP_IMAGEDATAFORMAT_BGRA_PREMUL,
- new_image_data_size,
- false);
- first_paint_ = true;
+ OnGeometryChanged(zoom_, old_device_scale);
}
- if (image_data_.is_null()) {
- DCHECK(plugin_size_.IsEmpty());
- return;
+ if (!stop_scrolling_) {
+ pp::Point scroll_offset(
+ BoundScrollOffsetToDocument(view.GetScrollOffset()));
+ engine_->ScrolledToXPosition(scroll_offset.x() * device_scale_);
+ engine_->ScrolledToYPosition(scroll_offset.y() * device_scale_);
}
-
- OnGeometryChanged(zoom_, old_device_scale);
}
pp::Var OutOfProcessInstance::GetLinkAtPosition(
@@ -786,7 +795,8 @@ void OutOfProcessInstance::Invalidate(const pp::Rect& rect) {
}
void OutOfProcessInstance::Scroll(const pp::Point& point) {
- paint_manager_.ScrollRect(available_area_, point);
+ if (!image_data_.is_null())
+ paint_manager_.ScrollRect(available_area_, point);
}
void OutOfProcessInstance::ScrollToX(int x) {
@@ -1404,4 +1414,13 @@ void OutOfProcessInstance::UserMetricsRecordAction(
pp::PDF::UserMetricsRecordAction(this, pp::Var(action));
}
+pp::Point OutOfProcessInstance::BoundScrollOffsetToDocument(
+ const pp::Point& scroll_offset) {
+ int max_x = document_size_.width() * zoom_ - plugin_dip_size_.width();
+ int x = std::max(std::min(scroll_offset.x(), max_x), 0);
+ int max_y = document_size_.height() * zoom_ - plugin_dip_size_.height();
+ int y = std::max(std::min(scroll_offset.y(), max_y), 0);
+ return pp::Point(x, y);
+}
+
} // namespace chrome_pdf