summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-24 00:42:04 +0000
committerwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-24 00:42:04 +0000
commit94bc2ccf947f2e97d4428c32da019ec6be1e6ed5 (patch)
tree09f2b0f3e50e48dc7b93b650bd936f6f46a76b1e
parentca5dfb21da662266e48f3b1802d86f5842e10f30 (diff)
downloadchromium_src-94bc2ccf947f2e97d4428c32da019ec6be1e6ed5.zip
chromium_src-94bc2ccf947f2e97d4428c32da019ec6be1e6ed5.tar.gz
chromium_src-94bc2ccf947f2e97d4428c32da019ec6be1e6ed5.tar.bz2
Make Chromoting client plugin always render at device DPI.
This addresses image quality issues when to a high-resolution device from a high-DPI but lower resolution client. In this case Chromoting would down-scale to the plugin's DIP dimensions, only for Chrome to up-scale to device dimensions. Follow-up CLs will add DPI information to the FrameConsumer interface, and try to optimize the plugin's up-scaling mode. BUG=133349,135089 Review URL: https://chromiumcodereview.appspot.com/10785041 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148012 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--remoting/client/plugin/chromoting_instance.cc13
-rw-r--r--remoting/client/plugin/chromoting_instance.h3
-rw-r--r--remoting/client/plugin/pepper_view.cc34
-rw-r--r--remoting/client/plugin/pepper_view.h26
4 files changed, 51 insertions, 25 deletions
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index 71ccd2a..fc7b46f 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -341,18 +341,13 @@ void ChromotingInstance::HandleMessage(const pp::Var& message) {
}
}
-void ChromotingInstance::DidChangeView(const pp::Rect& position,
- const pp::Rect& clip) {
+void ChromotingInstance::DidChangeView(const pp::View& view) {
DCHECK(plugin_message_loop_->BelongsToCurrentThread());
- SkISize new_size = SkISize::Make(position.width(), position.height());
- SkIRect new_clip =
- SkIRect::MakeXYWH(clip.x(), clip.y(), clip.width(), clip.height());
-
- view_->SetView(new_size, new_clip);
+ view_->SetView(view);
if (mouse_input_filter_.get()) {
- mouse_input_filter_->set_input_size(view_->get_view_size());
+ mouse_input_filter_->set_input_size(view_->get_view_size_dips());
}
}
@@ -484,7 +479,7 @@ void ChromotingInstance::Connect(const ClientConfig& config) {
// Construct the input pipeline
mouse_input_filter_.reset(
new protocol::MouseInputFilter(host_connection_->input_stub()));
- mouse_input_filter_->set_input_size(view_->get_view_size());
+ mouse_input_filter_->set_input_size(view_->get_view_size_dips());
input_tracker_.reset(
new protocol::InputEventTracker(mouse_input_filter_.get()));
diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h
index 7d0e5a2..04a5449 100644
--- a/remoting/client/plugin/chromoting_instance.h
+++ b/remoting/client/plugin/chromoting_instance.h
@@ -98,8 +98,7 @@ class ChromotingInstance :
virtual ~ChromotingInstance();
// pp::Instance interface.
- virtual void DidChangeView(const pp::Rect& position,
- const pp::Rect& clip) OVERRIDE;
+ virtual void DidChangeView(const pp::View& view) OVERRIDE;
virtual bool Init(uint32_t argc, const char* argn[],
const char* argv[]) OVERRIDE;
virtual void HandleMessage(const pp::Var& message) OVERRIDE;
diff --git a/remoting/client/plugin/pepper_view.cc b/remoting/client/plugin/pepper_view.cc
index b86af03..aabcba0 100644
--- a/remoting/client/plugin/pepper_view.cc
+++ b/remoting/client/plugin/pepper_view.cc
@@ -11,7 +11,8 @@
#include "base/time.h"
#include "base/synchronization/waitable_event.h"
#include "ppapi/cpp/completion_callback.h"
-#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/dev/graphics_2d_dev.h"
+#include "ppapi/cpp/dev/view_dev.h"
#include "ppapi/cpp/image_data.h"
#include "ppapi/cpp/point.h"
#include "ppapi/cpp/rect.h"
@@ -46,6 +47,8 @@ PepperView::PepperView(ChromotingInstance* instance,
clip_area_(SkIRect::MakeEmpty()),
source_size_(SkISize::Make(0, 0)),
source_dpi_(SkIPoint::Make(0, 0)),
+ view_size_dips_(SkISize::Make(0, 0)),
+ view_scale_(1.0f),
flush_pending_(false),
frame_received_(false) {
InitiateDrawing();
@@ -66,27 +69,46 @@ PepperView::~PepperView() {
}
}
-void PepperView::SetView(const SkISize& view_size, const SkIRect& clip_area) {
+void PepperView::SetView(const pp::View& view) {
bool view_changed = false;
- if (view_size_ != view_size) {
+ pp::Rect pp_size = view.GetRect();
+ SkISize new_size_dips = SkISize::Make(pp_size.width(), pp_size.height());
+ pp::ViewDev view_dev(view);
+ float new_scale = view_dev.GetDeviceScale();
+
+ if (view_size_dips_ != new_size_dips || view_scale_ != new_scale) {
view_changed = true;
- view_size_ = view_size;
+ view_scale_ = new_scale;
+ view_size_dips_ = new_size_dips;
+ view_size_ = SkISize::Make(ceilf(view_size_dips_.width() * view_scale_),
+ ceilf(view_size_dips_.height() * view_scale_));
pp::Size pp_size = pp::Size(view_size_.width(), view_size_.height());
graphics2d_ = pp::Graphics2D(instance_, pp_size, true);
+
+ // Ideally we would always let Graphics2D scale us, but the output quality
+ // is lousy, so we don't.
+ pp::Graphics2DDev graphics2d_dev(graphics2d_);
+ graphics2d_dev.SetScale(1.0f / view_scale_);
+
bool result = instance_->BindGraphics(graphics2d_);
// There is no good way to handle this error currently.
DCHECK(result) << "Couldn't bind the device context.";
}
- if (clip_area_ != clip_area) {
+ pp::Rect pp_clip = view.GetClipRect();
+ SkIRect new_clip = SkIRect::MakeLTRB(floorf(pp_clip.x() * view_scale_),
+ floorf(pp_clip.y() * view_scale_),
+ ceilf(pp_clip.right() * view_scale_),
+ ceilf(pp_clip.bottom() * view_scale_));
+ if (clip_area_ != new_clip) {
view_changed = true;
// YUV to RGB conversion may require even X and Y coordinates for
// the top left corner of the clipping area.
- clip_area_ = AlignRect(clip_area);
+ clip_area_ = AlignRect(new_clip);
clip_area_.intersect(SkIRect::MakeSize(view_size_));
}
diff --git a/remoting/client/plugin/pepper_view.h b/remoting/client/plugin/pepper_view.h
index 68446e4..cd015f0 100644
--- a/remoting/client/plugin/pepper_view.h
+++ b/remoting/client/plugin/pepper_view.h
@@ -12,6 +12,7 @@
#include "base/memory/weak_ptr.h"
#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/view.h"
#include "ppapi/cpp/point.h"
#include "remoting/client/frame_consumer.h"
@@ -44,10 +45,10 @@ class PepperView : public FrameConsumer,
virtual void SetSourceSize(const SkISize& source_size,
const SkIPoint& dpi) OVERRIDE;
- // Sets the display size and clipping area of this view.
- void SetView(const SkISize& view_size, const SkIRect& clip_area);
+ // Updates the PepperView's size, clipping area and scale factor.
+ void SetView(const pp::View& view);
- // Return the client view and original host dimensions.
+ // Return the dimensions of the view and source in device pixels.
const SkISize& get_view_size() const {
return view_size_;
}
@@ -55,6 +56,12 @@ class PepperView : public FrameConsumer,
return source_size_;
}
+ // Return the dimensions of the view in Density Independent Pixels (DIPs).
+ // On high-DPI devices this will be smaller than the size in device pixels.
+ const SkISize& get_view_size_dips() const {
+ return view_size_dips_;
+ }
+
private:
// This routine allocates an image buffer.
pp::ImageData* AllocateBuffer();
@@ -91,22 +98,25 @@ class PepperView : public FrameConsumer,
// List of allocated image buffers.
std::list<pp::ImageData*> buffers_;
+ // Queued buffer to paint, with clip area and dirty region in device pixels.
pp::ImageData* merge_buffer_;
SkIRect merge_clip_area_;
SkRegion merge_region_;
- // The size of the plugin element.
+ // View size, clip area and host dimensions, in device pixels.
SkISize view_size_;
-
- // The current clip area rectangle.
SkIRect clip_area_;
-
- // The size of the host screen.
SkISize source_size_;
// The DPI of the host screen.
SkIPoint source_dpi_;
+ // View size in Density-Independent pixels.
+ SkISize view_size_dips_;
+
+ // DIP-to-device pixel scale factor.
+ float view_scale_;
+
// True if there is already a Flush() pending on the Graphics2D context.
bool flush_pending_;