Commit 944dd5fe authored by K. Moon's avatar K. Moon Committed by Commit Bot

Migrate PDF painting to use abstract Graphics

Switches the painting code in pdf/ to use the new abstract Graphics API,
instead of using pp::Graphics2D directly. This eliminates direct
dependencies on Pepper in the painting code.

Bug: 1099020
Change-Id: Ib848d6824fa0cedd5737d56ceae9927754348cdd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2321706Reviewed-by: default avatarHenrique Nakashima <hnakashima@chromium.org>
Commit-Queue: K. Moon <kmoon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#792478}
parent 79ff6542
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "pdf/pdf_features.h" #include "pdf/pdf_features.h"
#include "pdf/ppapi_migration/bitmap.h" #include "pdf/ppapi_migration/bitmap.h"
#include "pdf/ppapi_migration/geometry_conversions.h" #include "pdf/ppapi_migration/geometry_conversions.h"
#include "pdf/ppapi_migration/graphics.h"
#include "ppapi/c/dev/ppb_cursor_control_dev.h" #include "ppapi/c/dev/ppb_cursor_control_dev.h"
#include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/ppb_pdf.h" #include "ppapi/c/private/ppb_pdf.h"
...@@ -974,13 +975,15 @@ void OutOfProcessInstance::StopFind() { ...@@ -974,13 +975,15 @@ void OutOfProcessInstance::StopFind() {
SetTickmarks(tickmarks_); SetTickmarks(tickmarks_);
} }
pp::Graphics2D OutOfProcessInstance::CreatePaintGraphics( std::unique_ptr<Graphics> OutOfProcessInstance::CreatePaintGraphics(
const gfx::Size& size) { const gfx::Size& size) {
return pp::Graphics2D(this, PPSizeFromSize(size), /*is_always_opaque=*/true); auto graphics = std::make_unique<PepperGraphics>(this, size);
DCHECK(!graphics->pepper_graphics().is_null());
return graphics;
} }
bool OutOfProcessInstance::BindPaintGraphics(pp::Graphics2D& graphics) { bool OutOfProcessInstance::BindPaintGraphics(Graphics& graphics) {
return BindGraphics(graphics); return BindGraphics(static_cast<PepperGraphics&>(graphics).pepper_graphics());
} }
void OutOfProcessInstance::OnPaint(const std::vector<gfx::Rect>& paint_rects, void OutOfProcessInstance::OnPaint(const std::vector<gfx::Rect>& paint_rects,
......
...@@ -36,13 +36,13 @@ class Vector2d; ...@@ -36,13 +36,13 @@ class Vector2d;
} // namespace gfx } // namespace gfx
namespace pp { namespace pp {
class Graphics2D;
class Size; class Size;
class TextInput_Dev; class TextInput_Dev;
} // namespace pp } // namespace pp
namespace chrome_pdf { namespace chrome_pdf {
class Graphics;
class PaintReadyRect; class PaintReadyRect;
class OutOfProcessInstance : public pp::Instance, class OutOfProcessInstance : public pp::Instance,
...@@ -68,8 +68,8 @@ class OutOfProcessInstance : public pp::Instance, ...@@ -68,8 +68,8 @@ class OutOfProcessInstance : public pp::Instance,
void StopFind() override; void StopFind() override;
// pp::PaintManager::Client implementation. // pp::PaintManager::Client implementation.
pp::Graphics2D CreatePaintGraphics(const gfx::Size& size) override; std::unique_ptr<Graphics> CreatePaintGraphics(const gfx::Size& size) override;
bool BindPaintGraphics(pp::Graphics2D& graphics) override; bool BindPaintGraphics(Graphics& graphics) override;
void OnPaint(const std::vector<gfx::Rect>& paint_rects, void OnPaint(const std::vector<gfx::Rect>& paint_rects,
std::vector<PaintReadyRect>* ready, std::vector<PaintReadyRect>* ready,
std::vector<gfx::Rect>* pending) override; std::vector<gfx::Rect>* pending) override;
......
...@@ -10,13 +10,15 @@ ...@@ -10,13 +10,15 @@
#include <algorithm> #include <algorithm>
#include "base/auto_reset.h" #include "base/auto_reset.h"
#include "base/check_op.h" #include "base/bind.h"
#include "base/callback.h"
#include "base/check.h"
#include "pdf/paint_ready_rect.h" #include "pdf/paint_ready_rect.h"
#include "pdf/ppapi_migration/callback.h"
#include "pdf/ppapi_migration/geometry_conversions.h" #include "pdf/ppapi_migration/geometry_conversions.h"
#include "ppapi/c/pp_errors.h" #include "pdf/ppapi_migration/graphics.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/module.h" #include "ppapi/cpp/module.h"
#include "ppapi/cpp/point.h"
#include "ppapi/cpp/rect.h"
#include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
...@@ -24,22 +26,8 @@ ...@@ -24,22 +26,8 @@
namespace chrome_pdf { namespace chrome_pdf {
namespace {
// Not part of ppapi_migration because `gfx::Vector2d` only needs to be
// converted to `pp::Point` at the boundary with `pp::Graphics2D`.
pp::Point ToPepperPoint(const gfx::Vector2d& vector) {
return pp::Point(vector.x(), vector.y());
}
} // namespace
PaintManager::PaintManager(Client* client) : client_(client) { PaintManager::PaintManager(Client* client) : client_(client) {
DCHECK(client_); DCHECK(client_);
// 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);
} }
PaintManager::~PaintManager() = default; PaintManager::~PaintManager() = default;
...@@ -98,11 +86,10 @@ void PaintManager::SetTransform(float scale, ...@@ -98,11 +86,10 @@ void PaintManager::SetTransform(float scale,
const gfx::Point& origin, const gfx::Point& origin,
const gfx::Vector2d& translate, const gfx::Vector2d& translate,
bool schedule_flush) { bool schedule_flush) {
if (graphics_.is_null()) if (!graphics_)
return; return;
graphics_.SetLayerTransform(scale, PPPointFromPoint(origin), graphics_->SetLayerTransform(scale, origin, translate);
ToPepperPoint(translate));
if (!schedule_flush) if (!schedule_flush)
return; return;
...@@ -119,7 +106,7 @@ void PaintManager::ClearTransform() { ...@@ -119,7 +106,7 @@ void PaintManager::ClearTransform() {
} }
void PaintManager::Invalidate() { void PaintManager::Invalidate() {
if (graphics_.is_null() && !has_pending_resize_) if (!graphics_ && !has_pending_resize_)
return; return;
EnsureCallbackPending(); EnsureCallbackPending();
...@@ -129,7 +116,7 @@ void PaintManager::Invalidate() { ...@@ -129,7 +116,7 @@ void PaintManager::Invalidate() {
void PaintManager::InvalidateRect(const gfx::Rect& rect) { void PaintManager::InvalidateRect(const gfx::Rect& rect) {
DCHECK(!in_paint_); DCHECK(!in_paint_);
if (graphics_.is_null() && !has_pending_resize_) if (!graphics_ && !has_pending_resize_)
return; return;
// Clip the rect to the device area. // Clip the rect to the device area.
...@@ -146,7 +133,7 @@ void PaintManager::ScrollRect(const gfx::Rect& clip_rect, ...@@ -146,7 +133,7 @@ void PaintManager::ScrollRect(const gfx::Rect& clip_rect,
const gfx::Vector2d& amount) { const gfx::Vector2d& amount) {
DCHECK(!in_paint_); DCHECK(!in_paint_);
if (graphics_.is_null() && !has_pending_resize_) if (!graphics_ && !has_pending_resize_)
return; return;
EnsureCallbackPending(); EnsureCallbackPending();
...@@ -175,7 +162,9 @@ void PaintManager::EnsureCallbackPending() { ...@@ -175,7 +162,9 @@ void PaintManager::EnsureCallbackPending() {
return; return;
pp::Module::Get()->core()->CallOnMainThread( pp::Module::Get()->core()->CallOnMainThread(
0, callback_factory_.NewCallback(&PaintManager::OnManualCallbackComplete), 0,
PPCompletionCallbackFromResultCallback(base::BindOnce(
&PaintManager::OnManualCallbackComplete, weak_factory_.GetWeakPtr())),
0); 0);
manual_callback_pending_ = true; manual_callback_pending_ = true;
} }
...@@ -193,27 +182,28 @@ void PaintManager::DoPaint() { ...@@ -193,27 +182,28 @@ void PaintManager::DoPaint() {
// However, the bind must not happen until afterward since we don't want to // 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 // have an unpainted device bound. The needs_binding flag tells us whether to
// do this later. // do this later.
//
// Note that |has_pending_resize_| will always be set on the first DoPaint().
DCHECK(graphics_ || has_pending_resize_);
if (has_pending_resize_) { if (has_pending_resize_) {
plugin_size_ = pending_size_; plugin_size_ = pending_size_;
// Extra call to pp_size() required here because the operator for converting
// to PP_Size is non-const.
const gfx::Size old_size = SizeFromPPSize(graphics_.size().pp_size());
// Only create a new graphics context if the current context isn't big // 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 // enough or if it is far too big. This avoids creating a new context if
// we only resize by a small amount. // we only resize by a small amount.
gfx::Size old_size = graphics_ ? graphics_->size() : gfx::Size();
gfx::Size new_size = GetNewContextSize(old_size, pending_size_); gfx::Size new_size = GetNewContextSize(old_size, pending_size_);
if (old_size != new_size) { if (old_size != new_size || !graphics_) {
graphics_ = client_->CreatePaintGraphics(new_size); graphics_ = client_->CreatePaintGraphics(new_size);
graphics_need_to_be_bound_ = true; graphics_need_to_be_bound_ = true;
// Since we're binding a new one, all of the callbacks have been canceled. // Since we're binding a new one, all of the callbacks have been canceled.
manual_callback_pending_ = false; manual_callback_pending_ = false;
flush_pending_ = false; flush_pending_ = false;
callback_factory_.CancelAll(); weak_factory_.InvalidateWeakPtrs();
} }
if (pending_device_scale_ != 1.0) if (pending_device_scale_ != 1.0)
graphics_.SetScale(1.0 / pending_device_scale_); graphics_->SetScale(1.0 / pending_device_scale_);
device_scale_ = pending_device_scale_; device_scale_ = pending_device_scale_;
// This must be cleared before calling into the plugin since it may do // This must be cleared before calling into the plugin since it may do
...@@ -235,10 +225,8 @@ void PaintManager::DoPaint() { ...@@ -235,10 +225,8 @@ void PaintManager::DoPaint() {
aggregator_.ClearPendingUpdate(); aggregator_.ClearPendingUpdate();
// Apply any scroll first. // Apply any scroll first.
if (update.has_scroll) { if (update.has_scroll)
graphics_.Scroll(PPRectFromRect(update.scroll_rect), graphics_->Scroll(update.scroll_rect, update.scroll_delta);
ToPepperPoint(update.scroll_delta));
}
view_size_changed_waiting_for_paint_ = false; view_size_changed_waiting_for_paint_ = false;
} else { } else {
...@@ -267,8 +255,7 @@ void PaintManager::DoPaint() { ...@@ -267,8 +255,7 @@ void PaintManager::DoPaint() {
} }
for (const auto& ready_rect : ready_now) { for (const auto& ready_rect : ready_now) {
graphics_.PaintImageData(ready_rect.image_data(), pp::Point(), graphics_->PaintImage(ready_rect.image(), ready_rect.rect());
PPRectFromRect(ready_rect.rect()));
} }
Flush(); Flush();
...@@ -276,33 +263,16 @@ void PaintManager::DoPaint() { ...@@ -276,33 +263,16 @@ void PaintManager::DoPaint() {
first_paint_ = false; first_paint_ = false;
if (graphics_need_to_be_bound_) { if (graphics_need_to_be_bound_) {
client_->BindPaintGraphics(graphics_); client_->BindPaintGraphics(*graphics_);
graphics_need_to_be_bound_ = false; graphics_need_to_be_bound_ = false;
} }
} }
void PaintManager::Flush() { void PaintManager::Flush() {
flush_requested_ = false; flush_requested_ = false;
flush_pending_ = graphics_->Flush(base::BindOnce(
int32_t result = graphics_.Flush( &PaintManager::OnFlushComplete, weak_factory_.GetWeakPtr()));
callback_factory_.NewCallback(&PaintManager::OnFlushComplete)); DCHECK(flush_pending_);
// 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_NE(PP_ERROR_INPROGRESS, result);
if (result == PP_OK_COMPLETIONPENDING) {
flush_pending_ = true;
} else {
DCHECK_EQ(PP_OK, result); // Catch all other errors in debug mode.
}
} }
void PaintManager::OnFlushComplete(int32_t) { void PaintManager::OnFlushComplete(int32_t) {
......
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
#include <stdint.h> #include <stdint.h>
#include <memory>
#include <vector> #include <vector>
#include "base/memory/weak_ptr.h"
#include "pdf/paint_aggregator.h" #include "pdf/paint_aggregator.h"
#include "ppapi/cpp/graphics_2d.h"
#include "ppapi/utility/completion_callback_factory.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
namespace gfx { namespace gfx {
...@@ -22,6 +22,8 @@ class Vector2d; ...@@ -22,6 +22,8 @@ class Vector2d;
namespace chrome_pdf { namespace chrome_pdf {
class Graphics;
// Custom PaintManager for the PDF plugin. This is branched from the Pepper // Custom PaintManager for the PDF plugin. This is branched from the Pepper
// version. The difference is that this supports progressive rendering of dirty // version. The difference is that this supports progressive rendering of dirty
// rects, where multiple calls to the rendering engine are needed. It also // rects, where multiple calls to the rendering engine are needed. It also
...@@ -33,13 +35,14 @@ class PaintManager { ...@@ -33,13 +35,14 @@ class PaintManager {
public: public:
class Client { class Client {
public: public:
// Creates a new, unbound `pp::Graphics2D` for the paint manager, with the // Creates a new, unbound `Graphics` for the paint manager, with the given
// given |size| and always-opaque rendering. // |size| and always-opaque rendering.
virtual pp::Graphics2D CreatePaintGraphics(const gfx::Size& size) = 0; virtual std::unique_ptr<Graphics> CreatePaintGraphics(
const gfx::Size& size) = 0;
// Binds a `pp::Graphics2D` created by `CreatePaintGraphics()`, returning // Binds a `Graphics` created by `CreatePaintGraphics()`, returning `true`
// `true` if binding was successful. // if binding was successful.
virtual bool BindPaintGraphics(pp::Graphics2D& graphics) = 0; virtual bool BindPaintGraphics(Graphics& graphics) = 0;
// Paints the given invalid area of the plugin to the given graphics // Paints the given invalid area of the plugin to the given graphics
// device. Returns true if anything was painted. // device. Returns true if anything was painted.
...@@ -147,11 +150,8 @@ class PaintManager { ...@@ -147,11 +150,8 @@ class PaintManager {
// Non-owning pointer. See the constructor. // Non-owning pointer. See the constructor.
Client* const client_; Client* const client_;
pp::CompletionCallbackFactory<PaintManager> callback_factory_; // This graphics device will be null if no graphics has been set yet.
std::unique_ptr<Graphics> graphics_;
// This graphics device will be is_null() if no graphics has been manually
// set yet.
pp::Graphics2D graphics_;
PaintAggregator aggregator_; PaintAggregator aggregator_;
...@@ -178,6 +178,8 @@ class PaintManager { ...@@ -178,6 +178,8 @@ class PaintManager {
// True when the view size just changed and we're waiting for a paint. // True when the view size just changed and we're waiting for a paint.
bool view_size_changed_waiting_for_paint_ = false; bool view_size_changed_waiting_for_paint_ = false;
base::WeakPtrFactory<PaintManager> weak_factory_{this};
}; };
} // namespace chrome_pdf } // namespace chrome_pdf
......
...@@ -13,9 +13,12 @@ namespace chrome_pdf { ...@@ -13,9 +13,12 @@ namespace chrome_pdf {
PaintReadyRect::PaintReadyRect(const pp::Rect& rect, PaintReadyRect::PaintReadyRect(const pp::Rect& rect,
const pp::ImageData& image_data, const pp::ImageData& image_data,
bool flush_now) bool flush_now)
: rect_(RectFromPPRect(rect)), : rect_(RectFromPPRect(rect)), image_(image_data), flush_now_(flush_now) {}
image_data_(image_data),
flush_now_(flush_now) {} PaintReadyRect::PaintReadyRect(const gfx::Rect& rect,
const SkBitmap& bitmap,
bool flush_now)
: rect_(rect), image_(bitmap), flush_now_(flush_now) {}
PaintReadyRect::PaintReadyRect(const PaintReadyRect& other) = default; PaintReadyRect::PaintReadyRect(const PaintReadyRect& other) = default;
......
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
#ifndef PDF_PAINT_READY_RECT_H_ #ifndef PDF_PAINT_READY_RECT_H_
#define PDF_PAINT_READY_RECT_H_ #define PDF_PAINT_READY_RECT_H_
#include "ppapi/cpp/image_data.h" #include "pdf/ppapi_migration/image.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
class SkBitmap;
namespace pp { namespace pp {
class ImageData;
class Rect; class Rect;
} // namespace pp } // namespace pp
...@@ -22,6 +25,10 @@ class PaintReadyRect { ...@@ -22,6 +25,10 @@ class PaintReadyRect {
PaintReadyRect(const pp::Rect& rect, PaintReadyRect(const pp::Rect& rect,
const pp::ImageData& image_data, const pp::ImageData& image_data,
bool flush_now = false); bool flush_now = false);
PaintReadyRect(const gfx::Rect& rect,
const SkBitmap& bitmap,
bool flush_now = false);
PaintReadyRect(const PaintReadyRect& other); PaintReadyRect(const PaintReadyRect& other);
PaintReadyRect& operator=(const PaintReadyRect& other); PaintReadyRect& operator=(const PaintReadyRect& other);
~PaintReadyRect(); ~PaintReadyRect();
...@@ -29,7 +36,7 @@ class PaintReadyRect { ...@@ -29,7 +36,7 @@ class PaintReadyRect {
const gfx::Rect& rect() const { return rect_; } const gfx::Rect& rect() const { return rect_; }
void set_rect(const gfx::Rect& rect) { rect_ = rect; } void set_rect(const gfx::Rect& rect) { rect_ = rect; }
const pp::ImageData& image_data() const { return image_data_; } const Image& image() const { return image_; }
// Whether to flush to screen immediately; otherwise, when the rest of the // Whether to flush to screen immediately; otherwise, when the rest of the
// plugin viewport is ready. // plugin viewport is ready.
...@@ -37,7 +44,7 @@ class PaintReadyRect { ...@@ -37,7 +44,7 @@ class PaintReadyRect {
private: private:
gfx::Rect rect_; gfx::Rect rect_;
pp::ImageData image_data_; Image image_;
bool flush_now_; bool flush_now_;
}; };
......
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