Chromium Code Reviews| Index: webkit/plugins/ppapi/ppapi_plugin_instance.cc |
| diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.cc b/webkit/plugins/ppapi/ppapi_plugin_instance.cc |
| index 9229d102a419e8d467b161b69b6faa3f921bcffc..6f720a6ed97816b2c5e085cf7a3c02a6d30ca855 100644 |
| --- a/webkit/plugins/ppapi/ppapi_plugin_instance.cc |
| +++ b/webkit/plugins/ppapi/ppapi_plugin_instance.cc |
| @@ -27,7 +27,10 @@ |
| #include "ppapi/c/private/ppp_instance_private.h" |
| #include "ppapi/shared_impl/ppb_input_event_shared.h" |
| #include "ppapi/shared_impl/ppb_url_util_shared.h" |
| +#include "ppapi/shared_impl/ppb_view_shared.h" |
| #include "ppapi/shared_impl/ppp_instance_combined.h" |
| +#include "ppapi/shared_impl/resource.h" |
| +#include "ppapi/shared_impl/scoped_pp_resource.h" |
| #include "ppapi/shared_impl/time_conversion.h" |
| #include "ppapi/shared_impl/var.h" |
| #include "ppapi/thunk/enter.h" |
| @@ -52,6 +55,7 @@ |
| #include "webkit/plugins/ppapi/common.h" |
| #include "webkit/plugins/ppapi/event_conversion.h" |
| #include "webkit/plugins/ppapi/fullscreen_container.h" |
| +#include "webkit/plugins/ppapi/gfx_conversion.h" |
| #include "webkit/plugins/ppapi/host_globals.h" |
| #include "webkit/plugins/ppapi/message_channel.h" |
| #include "webkit/plugins/ppapi/npapi_glue.h" |
| @@ -91,6 +95,8 @@ using base::StringPrintf; |
| using ppapi::InputEventData; |
| using ppapi::PPB_InputEvent_Shared; |
| using ppapi::PpapiGlobals; |
| +using ppapi::PPB_View_Shared; |
| +using ppapi::ScopedPPResource; |
| using ppapi::StringVar; |
| using ppapi::thunk::EnterResourceNoLock; |
| using ppapi::thunk::PPB_Buffer_API; |
| @@ -99,6 +105,7 @@ using ppapi::thunk::PPB_Graphics3D_API; |
| using ppapi::thunk::PPB_ImageData_API; |
| using ppapi::thunk::PPB_Instance_FunctionAPI; |
| using ppapi::Var; |
| +using ppapi::ViewData; |
| using WebKit::WebBindings; |
| using WebKit::WebCanvas; |
| using WebKit::WebConsoleMessage; |
| @@ -219,11 +226,6 @@ COMPILE_ASSERT_MATCHING_ENUM(TypeGrabbing, PP_CURSORTYPE_GRABBING); |
| // Do not assert WebCursorInfo::TypeCustom == PP_CURSORTYPE_CUSTOM; |
| // PP_CURSORTYPE_CUSTOM is pinned to allow new cursor types. |
| -void RectToPPRect(const gfx::Rect& input, PP_Rect* output) { |
| - *output = PP_MakeRectFromXYWH(input.x(), input.y(), |
| - input.width(), input.height()); |
| -} |
| - |
| // Sets |*security_origin| to be the WebKit security origin associated with the |
| // document containing the given plugin instance. On success, returns true. If |
| // the instance is invalid, returns false and |*security_origin| will be |
| @@ -253,6 +255,18 @@ PluginInstance* PluginInstance::Create1_0(PluginDelegate* delegate, |
| new ::ppapi::PPP_Instance_Combined(*instance)); |
| } |
| +// static |
| +PluginInstance* PluginInstance::Create1_1(PluginDelegate* delegate, |
| + PluginModule* module, |
| + const void* ppp_instance_if_1_1) { |
| + const PPP_Instance_1_1* instance = |
| + static_cast<const PPP_Instance_1_1*>(ppp_instance_if_1_1); |
| + return new PluginInstance( |
| + delegate, |
| + module, |
| + new ::ppapi::PPP_Instance_Combined(*instance)); |
| +} |
| + |
| PluginInstance::PluginInstance( |
| PluginDelegate* delegate, |
| PluginModule* module, |
| @@ -264,6 +278,7 @@ PluginInstance::PluginInstance( |
| container_(NULL), |
| full_frame_(false), |
| sent_did_change_view_(false), |
| + suppress_did_change_view_(false), |
| has_webkit_focus_(false), |
| has_content_area_focus_(false), |
| find_identifier_(-1), |
| @@ -368,7 +383,8 @@ void PluginInstance::InvalidateRect(const gfx::Rect& rect) { |
| else |
| fullscreen_container_->InvalidateRect(rect); |
| } else { |
| - if (!container_ || position_.IsEmpty()) |
| + if (!container_ || |
| + view_data_.rect.size.width == 0 || view_data_.rect.size.height == 0) |
| return; // Nothing to do. |
| if (rect.IsEmpty()) |
| container_->invalidate(); |
| @@ -630,7 +646,9 @@ bool PluginInstance::IsPluginAcceptingCompositionEvents() const { |
| gfx::Rect PluginInstance::GetCaretBounds() const { |
| if (!text_input_caret_set_) { |
| // If it is never set by the plugin, use the bottom left corner. |
| - return gfx::Rect(position().x(), position().y()+position().height(), 0, 0); |
| + return gfx::Rect(view_data_.rect.point.x, |
| + view_data_.rect.point.y + view_data_.rect.size.height, |
| + 0, 0); |
| } |
| // TODO(kinaba) Take CSS transformation into accont. |
| @@ -639,7 +657,7 @@ gfx::Rect PluginInstance::GetCaretBounds() const { |
| // passed to IME. Currently, we pass only the caret rectangle because |
| // it is the only information supported uniformly in Chromium. |
| gfx::Rect caret(text_input_caret_); |
| - caret.Offset(position().origin()); |
| + caret.Offset(view_data_.rect.point.x, view_data_.rect.point.y); |
| return caret; |
| } |
| @@ -720,41 +738,41 @@ void PluginInstance::ViewChanged(const gfx::Rect& position, |
| if (!clip.IsEmpty()) |
| new_clip = clip; |
| - // Don't notify the plugin if we've already sent these same params before. |
| - if (sent_did_change_view_ && position == position_ && new_clip == clip_) |
| - return; |
| + ViewData previous_view = view_data_; |
| + |
| + view_data_.rect = PP_FromGfxRect(position); |
| + view_data_.clip_rect = PP_FromGfxRect(clip); |
| - if (desired_fullscreen_state_ || fullscreen_) { |
| + if (desired_fullscreen_state_ || view_data_.is_fullscreen) { |
| WebElement element = container_->element(); |
| WebDocument document = element.document(); |
| bool is_fullscreen_element = (element == document.fullScreenElement()); |
| - if (!fullscreen_ && desired_fullscreen_state_ && |
| + if (!view_data_.is_fullscreen && desired_fullscreen_state_ && |
| delegate()->IsInFullscreenMode() && is_fullscreen_element) { |
| // Entered fullscreen. Only possible via SetFullscreen(). |
| - fullscreen_ = true; |
| - } else if (fullscreen_ && !is_fullscreen_element) { |
| + view_data_.is_fullscreen = true; |
| + } else if (view_data_.is_fullscreen && !is_fullscreen_element) { |
| // Exited fullscreen. Possible via SetFullscreen() or F11/link, |
| // so desired_fullscreen_state might be out-of-date. |
| desired_fullscreen_state_ = false; |
| - fullscreen_ = false; |
| + view_data_.is_fullscreen = false; |
| + |
| + // This operation will cause the plugin to re-layout which will send more |
| + // DidChangeView updates. Schedule an asynchronous update and suppress |
| + // notifications until that completes to avoid sending intermediate sizes |
| + // to the plugins. |
| + ScheduleAsyncDidChangeView(previous_view); |
| + |
| // Reset the size attributes that we hacked to fill in the screen and |
| // retrigger ViewChanged. Make sure we don't forward duplicates of |
| // this view to the plugin. |
| ResetSizeAttributesAfterFullscreen(); |
| - SetSentDidChangeView(position, new_clip); |
| - MessageLoop::current()->PostTask( |
| - FROM_HERE, base::Bind(&PluginInstance::ReportGeometry, this)); |
| return; |
| } |
| } |
| - SetSentDidChangeView(position, new_clip); |
| flash_fullscreen_ = (fullscreen_container_ != NULL); |
| - |
| - PP_Rect pp_position, pp_clip; |
| - RectToPPRect(position_, &pp_position); |
| - RectToPPRect(clip_, &pp_clip); |
| - instance_interface_->DidChangeView(pp_instance(), &pp_position, &pp_clip); |
| + SendDidChangeView(previous_view); |
| } |
| void PluginInstance::SetWebKitFocus(bool has_focus) { |
| @@ -812,11 +830,12 @@ bool PluginInstance::GetBitmapForOptimizedPluginPaint( |
| // store when seeing if we cover the given paint bounds, since the backing |
| // store could be smaller than the declared plugin area. |
| PPB_ImageData_Impl* image_data = GetBoundGraphics2D()->image_data(); |
| - gfx::Rect plugin_backing_store_rect(position_.origin(), |
| - gfx::Size(image_data->width(), |
| - image_data->height())); |
| - gfx::Rect clip_page(clip_); |
| - clip_page.Offset(position_.origin()); |
| + gfx::Rect plugin_backing_store_rect( |
| + PP_ToGfxPoint(view_data_.rect.point), |
| + gfx::Size(image_data->width(), image_data->height())); |
| + |
| + gfx::Rect clip_page = PP_ToGfxRect(view_data_.clip_rect); |
| + clip_page.Offset(PP_ToGfxPoint(view_data_.rect.point)); |
| gfx::Rect plugin_paint_rect = plugin_backing_store_rect.Intersect(clip_page); |
| if (!plugin_paint_rect.Contains(paint_bounds)) |
| return false; |
| @@ -993,6 +1012,38 @@ bool PluginInstance::PluginHasFocus() const { |
| return has_webkit_focus_ && has_content_area_focus_; |
| } |
| +void PluginInstance::ScheduleAsyncDidChangeView( |
| + const ::ppapi::ViewData& previous_view) { |
| + if (suppress_did_change_view_) |
| + return; // Already scheduled. |
| + suppress_did_change_view_ = true; |
| + MessageLoop::current()->PostTask( |
| + FROM_HERE, base::Bind(&PluginInstance::SendAsyncDidChangeView, |
| + this, previous_view)); |
| +} |
| + |
| +void PluginInstance::SendAsyncDidChangeView(const ViewData& previous_view) { |
| + DCHECK(suppress_did_change_view_); |
| + suppress_did_change_view_ = false; |
| + SendDidChangeView(previous_view); |
| +} |
| + |
| +void PluginInstance::SendDidChangeView(const ViewData& previous_view) { |
| + if (suppress_did_change_view_ || |
| + (sent_did_change_view_ && previous_view.Equals(view_data_))) |
| + return; // Nothing to update. |
| + |
| + sent_did_change_view_ = true; |
|
dmichael (off chromium)
2011/12/20 19:01:34
Maybe sent_initial_did_change_view_ would be a bet
|
| + ScopedPPResource resource( |
| + ScopedPPResource::PassRef(), |
| + (new PPB_View_Shared(PPB_View_Shared::InitAsImpl(), |
| + pp_instance(), view_data_))->GetReference()); |
| + |
| + instance_interface_->DidChangeView(pp_instance(), resource, |
| + &view_data_.rect, |
| + &view_data_.clip_rect); |
| +} |
| + |
| void PluginInstance::ReportGeometry() { |
| // If this call was delayed, we may have transitioned back to fullscreen in |
| // the mean time, so only report the geometry if we are actually in normal |
| @@ -1045,7 +1096,7 @@ int PluginInstance::PrintBegin(const gfx::Rect& printable_area, |
| int num_pages = 0; |
| PP_PrintSettings_Dev print_settings; |
| - RectToPPRect(printable_area, &print_settings.printable_area); |
| + print_settings.printable_area = PP_FromGfxRect(printable_area); |
| print_settings.dpi = printer_dpi; |
| print_settings.orientation = PP_PRINTORIENTATION_NORMAL; |
| print_settings.grayscale = PP_FALSE; |
| @@ -1582,8 +1633,8 @@ void PluginInstance::SimulateInputEvent(const InputEventData& input_event) { |
| std::vector<linked_ptr<WebInputEvent> > events = |
| CreateSimulatedWebInputEvents( |
| input_event, |
| - position().x() + position().width() / 2, |
| - position().y() + position().height() / 2); |
| + view_data_.rect.point.x + view_data_.rect.size.width / 2, |
| + view_data_.rect.point.y + view_data_.rect.size.height / 2); |
| for (std::vector<linked_ptr<WebInputEvent> >::iterator it = events.begin(); |
| it != events.end(); ++it) { |
| web_view->handleInputEvent(*it->get()); |
| @@ -1656,6 +1707,15 @@ PP_Bool PluginInstance::IsFullFrame(PP_Instance instance) { |
| return PP_FromBool(full_frame()); |
| } |
| +PP_Resource PluginInstance::GetView(PP_Instance instance) { |
| + return (new PPB_View_Shared(PPB_View_Shared::InitAsImpl(), instance, |
| + view_data_))->GetReference(); |
|
dmichael (off chromium)
2011/12/20 19:01:34
Don't think you need this one anymore
|
| +} |
| + |
| +const ViewData* PluginInstance::GetViewData(PP_Instance instance) { |
| + return &view_data_; |
| +} |
| + |
| PP_Var PluginInstance::GetWindowObject(PP_Instance instance) { |
| if (!container_) |
| return PP_MakeUndefined(); |
| @@ -1779,10 +1839,6 @@ void PluginInstance::SelectedFindResultChanged(PP_Instance instance, |
| delegate_->SelectedFindResultChanged(find_identifier_, index); |
| } |
| -PP_Bool PluginInstance::IsFullscreen(PP_Instance instance) { |
| - return PP_FromBool(fullscreen_); |
| -} |
| - |
| PP_Bool PluginInstance::FlashIsFullscreen(PP_Instance instance) { |
| return PP_FromBool(flash_fullscreen_); |
| } |
| @@ -1957,13 +2013,6 @@ bool PluginInstance::CanAccessMainFrame() const { |
| main_document.securityOrigin()); |
| } |
| -void PluginInstance::SetSentDidChangeView(const gfx::Rect& position, |
| - const gfx::Rect& clip) { |
| - sent_did_change_view_ = true; |
| - position_ = position; |
| - clip_ = clip; |
| -} |
| - |
| void PluginInstance::KeepSizeAttributesBeforeFullscreen() { |
| WebElement element = container_->element(); |
| width_before_fullscreen_ = element.getAttribute(WebString::fromUTF8(kWidth)); |