diff options
author | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-24 00:42:04 +0000 |
---|---|---|
committer | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-24 00:42:04 +0000 |
commit | 94bc2ccf947f2e97d4428c32da019ec6be1e6ed5 (patch) | |
tree | 09f2b0f3e50e48dc7b93b650bd936f6f46a76b1e | |
parent | ca5dfb21da662266e48f3b1802d86f5842e10f30 (diff) | |
download | chromium_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.cc | 13 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.h | 3 | ||||
-rw-r--r-- | remoting/client/plugin/pepper_view.cc | 34 | ||||
-rw-r--r-- | remoting/client/plugin/pepper_view.h | 26 |
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_; |