Commit 94bc2ccf authored by wez@chromium.org's avatar wez@chromium.org

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
parent ca5dfb21
......@@ -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()));
......
......@@ -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;
......
......@@ -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_));
}
......
......@@ -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_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment