diff options
Diffstat (limited to 'chromium/content/renderer/pepper')
35 files changed, 511 insertions, 133 deletions
diff --git a/chromium/content/renderer/pepper/message_channel.cc b/chromium/content/renderer/pepper/message_channel.cc index f14f0041969..4566631717e 100644 --- a/chromium/content/renderer/pepper/message_channel.cc +++ b/chromium/content/renderer/pepper/message_channel.cc @@ -12,7 +12,6 @@ #include "base/logging.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" -#include "content/renderer/pepper/host_array_buffer_var.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/pepper_try_catch.h" #include "content/renderer/pepper/plugin_module.h" @@ -27,20 +26,12 @@ #include "ppapi/shared_impl/var.h" #include "ppapi/shared_impl/var_tracker.h" #include "third_party/WebKit/public/web/WebDOMMessageEvent.h" -#include "third_party/WebKit/public/web/WebDocument.h" -#include "third_party/WebKit/public/web/WebElement.h" -#include "third_party/WebKit/public/web/WebLocalFrame.h" -#include "third_party/WebKit/public/web/WebNode.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" -#include "third_party/WebKit/public/web/WebSerializedScriptValue.h" #include "v8/include/v8.h" -using ppapi::ArrayBufferVar; using ppapi::PpapiGlobals; using ppapi::ScopedPPVar; using ppapi::StringVar; -using blink::WebElement; -using blink::WebDOMEvent; using blink::WebDOMMessageEvent; using blink::WebPluginContainer; using blink::WebSerializedScriptValue; diff --git a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc index 0a4bc6e3a53..6f39f0fb7d9 100644 --- a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc +++ b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc @@ -4,6 +4,7 @@ #include "content/renderer/pepper/mock_renderer_ppapi_host.h" +#include "content/public/renderer/render_view.h" #include "content/renderer/pepper/fake_pepper_plugin_instance.h" #include "ui/gfx/geometry/point.h" @@ -16,7 +17,10 @@ MockRendererPpapiHost::MockRendererPpapiHost(RenderView* render_view, render_view_(render_view), pp_instance_(instance), has_user_gesture_(false), - plugin_instance_(new FakePepperPluginInstance) {} + plugin_instance_(new FakePepperPluginInstance) { + if (render_view) + render_frame_ = render_view->GetMainRenderFrame(); +} MockRendererPpapiHost::~MockRendererPpapiHost() {} @@ -35,6 +39,8 @@ PepperPluginInstance* MockRendererPpapiHost::GetPluginInstance( RenderFrame* MockRendererPpapiHost::GetRenderFrameForInstance( PP_Instance instance) const { + if (instance == pp_instance_) + return render_frame_; return NULL; } diff --git a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h index 84e6ff4d253..30dd766ed26 100644 --- a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h +++ b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h @@ -65,6 +65,7 @@ class MockRendererPpapiHost : public RendererPpapiHost { ppapi::host::PpapiHost ppapi_host_; RenderView* render_view_; + RenderFrame* render_frame_; PP_Instance pp_instance_; bool has_user_gesture_; diff --git a/chromium/content/renderer/pepper/pepper_audio_controller.cc b/chromium/content/renderer/pepper/pepper_audio_controller.cc new file mode 100644 index 00000000000..88d80f11bd0 --- /dev/null +++ b/chromium/content/renderer/pepper/pepper_audio_controller.cc @@ -0,0 +1,77 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/pepper/pepper_audio_controller.h" + +#include "content/renderer/pepper/pepper_plugin_instance_impl.h" +#include "content/renderer/pepper/ppb_audio_impl.h" +#include "content/renderer/render_frame_impl.h" + +namespace content { + +PepperAudioController::PepperAudioController( + PepperPluginInstanceImpl* instance) + : instance_(instance) { + DCHECK(instance_); +} + +PepperAudioController::~PepperAudioController() { + if (instance_) + OnPepperInstanceDeleted(); +} + +void PepperAudioController::AddInstance(PPB_Audio_Impl* audio) { + if (!instance_) + return; + if (ppb_audios_.count(audio)) + return; + + if (ppb_audios_.empty()) { + RenderFrameImpl* render_frame = instance_->render_frame(); + if (render_frame) + render_frame->PepperStartsPlayback(instance_); + } + + ppb_audios_.insert(audio); +} + +void PepperAudioController::RemoveInstance(PPB_Audio_Impl* audio) { + if (!instance_) + return; + if (!ppb_audios_.count(audio)) + return; + + ppb_audios_.erase(audio); + + if (ppb_audios_.empty()) + NotifyPlaybackStopsOnEmpty(); +} + +void PepperAudioController::SetVolume(double volume) { + if (!instance_) + return; + + for (auto* ppb_audio : ppb_audios_) + ppb_audio->SetVolume(volume); +} + +void PepperAudioController::OnPepperInstanceDeleted() { + DCHECK(instance_); + + if (!ppb_audios_.empty()) + NotifyPlaybackStopsOnEmpty(); + + ppb_audios_.clear(); + instance_ = nullptr; +} + +void PepperAudioController::NotifyPlaybackStopsOnEmpty() { + DCHECK(instance_); + + RenderFrameImpl* render_frame = instance_->render_frame(); + if (render_frame) + render_frame->PepperStopsPlayback(instance_); +} + +} // namespace content diff --git a/chromium/content/renderer/pepper/pepper_audio_controller.h b/chromium/content/renderer/pepper/pepper_audio_controller.h new file mode 100644 index 00000000000..29241ab8e63 --- /dev/null +++ b/chromium/content/renderer/pepper/pepper_audio_controller.h @@ -0,0 +1,57 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_PEPPER_PEPPER_AUDIO_CONTROLLER_H_ +#define CONTENT_RENDERER_PEPPER_PEPPER_AUDIO_CONTROLLER_H_ + +#include <set> + +#include "base/macros.h" + +namespace content { + +class PepperPluginInstanceImpl; +class PPB_Audio_Impl; + +/** + * This class controls all the active audio instances of a Pepper instance. + * This class can only be a non-shareable member of PepperPluginInstanceImpl. + */ +class PepperAudioController { + public: + explicit PepperAudioController(PepperPluginInstanceImpl* instance); + virtual ~PepperAudioController(); + + // Adds an audio instance to the controller. + void AddInstance(PPB_Audio_Impl* audio); + + // Removes an audio instance from the controller. + void RemoveInstance(PPB_Audio_Impl* audio); + + // Sets the volume of all audio instances. + void SetVolume(double volume); + + // The pepper instance has been deleted. This method can only be called + // once. The controller will be invalidated after this call, and then all + // other methods will be no-op. + void OnPepperInstanceDeleted(); + + private: + // Notifies the RenderFrame that the playback has stopped. This method should + // only be called when |ppb_audios_| turns from non-empty to empty. + void NotifyPlaybackStopsOnEmpty(); + + // All active audio instances. + std::set<PPB_Audio_Impl*> ppb_audios_; + + // The Pepper instance which this controller is for. Will be null after + // OnPepperInstanceDeleted() is called. + PepperPluginInstanceImpl* instance_; + + DISALLOW_COPY_AND_ASSIGN(PepperAudioController); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_PEPPER_AUDIO_CONTROLLER_H_ diff --git a/chromium/content/renderer/pepper/pepper_browser_connection.cc b/chromium/content/renderer/pepper/pepper_browser_connection.cc index 43affea1374..19ba1cc7a35 100644 --- a/chromium/content/renderer/pepper/pepper_browser_connection.cc +++ b/chromium/content/renderer/pepper/pepper_browser_connection.cc @@ -96,4 +96,8 @@ int32_t PepperBrowserConnection::GetNextSequence() { return ret; } +void PepperBrowserConnection::OnDestruct() { + delete this; +} + } // namespace content diff --git a/chromium/content/renderer/pepper/pepper_browser_connection.h b/chromium/content/renderer/pepper/pepper_browser_connection.h index 6e5a3d692cb..07d1501c398 100644 --- a/chromium/content/renderer/pepper/pepper_browser_connection.h +++ b/chromium/content/renderer/pepper/pepper_browser_connection.h @@ -60,6 +60,9 @@ class PepperBrowserConnection void DidDeleteInProcessInstance(PP_Instance instance); private: + // RenderFrameObserver implementation. + void OnDestruct() override; + // Message handlers. void OnMsgCreateResourceHostsFromHostReply( int32_t sequence_number, diff --git a/chromium/content/renderer/pepper/pepper_compositor_host.cc b/chromium/content/renderer/pepper/pepper_compositor_host.cc index f16ef70ea4a..c2768361c0e 100644 --- a/chromium/content/renderer/pepper/pepper_compositor_host.cc +++ b/chromium/content/renderer/pepper/pepper_compositor_host.cc @@ -65,7 +65,7 @@ int32_t VerifyCommittedLayer(const ppapi::CompositorLayerData* old_layer, if (new_layer->texture) { if (old_layer) { // Make sure the old layer is a texture layer too. - if (!new_layer->texture) + if (!old_layer->texture) return PP_ERROR_BADARGUMENT; // The mailbox should be same, if the resource_id is not changed. if (new_layer->common.resource_id == old_layer->common.resource_id) { @@ -87,7 +87,7 @@ int32_t VerifyCommittedLayer(const ppapi::CompositorLayerData* old_layer, if (new_layer->image) { if (old_layer) { // Make sure the old layer is an image layer too. - if (!new_layer->image) + if (!old_layer->image) return PP_ERROR_BADARGUMENT; // The image data resource should be same, if the resource_id is not // changed. diff --git a/chromium/content/renderer/pepper/pepper_file_chooser_host.cc b/chromium/content/renderer/pepper/pepper_file_chooser_host.cc index b70ab83c3d1..f2f8be3b2e5 100644 --- a/chromium/content/renderer/pepper/pepper_file_chooser_host.cc +++ b/chromium/content/renderer/pepper/pepper_file_chooser_host.cc @@ -154,9 +154,10 @@ int32_t PepperFileChooserHost::OnShow( params.requestor = renderer_ppapi_host_->GetDocumentURL(pp_instance()); handler_ = new CompletionHandler(AsWeakPtr()); - RenderViewImpl* render_view = static_cast<RenderViewImpl*>( - renderer_ppapi_host_->GetRenderViewForInstance(pp_instance())); - if (!render_view || !render_view->runFileChooser(params, handler_)) { + RenderFrameImpl* render_frame = static_cast<RenderFrameImpl*>( + renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance())); + + if (!render_frame || !render_frame->runFileChooser(params, handler_)) { delete handler_; handler_ = NULL; return PP_ERROR_NOACCESS; diff --git a/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc b/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc index f74c0a181b3..d610636955d 100644 --- a/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc +++ b/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc @@ -3,10 +3,12 @@ // found in the LICENSE file. #include <stdint.h> +#include <tuple> #include "base/files/file_path.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "content/common/frame_messages.h" #include "content/common/view_messages.h" #include "content/public/common/file_chooser_file_info.h" #include "content/public/common/file_chooser_params.h" @@ -91,11 +93,11 @@ TEST_F(PepperFileChooserHostTest, Show) { // The render view should have sent a chooser request to the browser // (caught by the render thread's test message sink). const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching( - ViewHostMsg_RunFileChooser::ID); + FrameHostMsg_RunFileChooser::ID); ASSERT_TRUE(msg); - ViewHostMsg_RunFileChooser::Schema::Param call_msg_param; - ASSERT_TRUE(ViewHostMsg_RunFileChooser::Read(msg, &call_msg_param)); - const FileChooserParams& chooser_params = base::get<0>(call_msg_param); + FrameHostMsg_RunFileChooser::Schema::Param call_msg_param; + ASSERT_TRUE(FrameHostMsg_RunFileChooser::Read(msg, &call_msg_param)); + const FileChooserParams& chooser_params = std::get<0>(call_msg_param); // Basic validation of request. EXPECT_EQ(FileChooserParams::Open, chooser_params.mode); @@ -109,10 +111,11 @@ TEST_F(PepperFileChooserHostTest, Show) { selected_info.file_path = base::FilePath(FILE_PATH_LITERAL("myp\\ath/foo")); std::vector<content::FileChooserFileInfo> selected_info_vector; selected_info_vector.push_back(selected_info); - RenderViewImpl* view_impl = static_cast<RenderViewImpl*>(view_); - ViewMsg_RunFileChooserResponse response(view_impl->GetRoutingID(), - selected_info_vector); - EXPECT_TRUE(view_impl->OnMessageReceived(response)); + RenderFrameImpl* frame_impl = + static_cast<RenderFrameImpl*>(view_->GetMainRenderFrame()); + FrameMsg_RunFileChooserResponse response(frame_impl->GetRoutingID(), + selected_info_vector); + EXPECT_TRUE(frame_impl->OnMessageReceived(response)); // This should have sent the Pepper reply to our test sink. ppapi::proxy::ResourceMessageReplyParams reply_params; @@ -127,7 +130,7 @@ TEST_F(PepperFileChooserHostTest, Show) { ASSERT_TRUE( PpapiPluginMsg_FileChooser_ShowReply::Read(&reply_msg, &reply_msg_param)); const std::vector<ppapi::FileRefCreateInfo>& chooser_results = - base::get<0>(reply_msg_param); + std::get<0>(reply_msg_param); ASSERT_EQ(1u, chooser_results.size()); EXPECT_EQ(FilePathToUTF8(selected_info.display_name), chooser_results[0].display_name); diff --git a/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc b/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc index 478e90536d7..41c82fca255 100644 --- a/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc +++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc @@ -383,8 +383,6 @@ void PepperGraphics2DHost::ViewInitiatedPaint() { } } -void PepperGraphics2DHost::SetScale(float scale) { scale_ = scale; } - float PepperGraphics2DHost::GetScale() const { return scale_; } bool PepperGraphics2DHost::IsAlwaysOpaque() const { return is_always_opaque_; } diff --git a/chromium/content/renderer/pepper/pepper_graphics_2d_host.h b/chromium/content/renderer/pepper/pepper_graphics_2d_host.h index 6fb01c29e8f..e50b095d8c1 100644 --- a/chromium/content/renderer/pepper/pepper_graphics_2d_host.h +++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host.h @@ -85,7 +85,6 @@ class CONTENT_EXPORT PepperGraphics2DHost // These messages are used to send Flush callbacks to the plugin. void ViewInitiatedPaint(); - void SetScale(float scale); float GetScale() const; void SetLayerTransform(float scale, const PP_Point& transform); bool IsAlwaysOpaque() const; diff --git a/chromium/content/renderer/pepper/pepper_media_device_manager.cc b/chromium/content/renderer/pepper/pepper_media_device_manager.cc index 1b21f75c920..42abb0802af 100644 --- a/chromium/content/renderer/pepper/pepper_media_device_manager.cc +++ b/chromium/content/renderer/pepper/pepper_media_device_manager.cc @@ -61,12 +61,9 @@ int PepperMediaDeviceManager::EnumerateDevices( PepperMediaDeviceManager::FromPepperDeviceType(type), url::Origin(document_url.GetOrigin())); #else - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&PepperMediaDeviceManager::OnDevicesEnumerated, - AsWeakPtr(), - request_id, - StreamDeviceInfoArray())); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&PepperMediaDeviceManager::OnDevicesEnumerated, + AsWeakPtr(), request_id, StreamDeviceInfoArray())); #endif return request_id; @@ -109,11 +106,9 @@ int PepperMediaDeviceManager::OpenDevice(PP_DeviceType_Dev type, PepperMediaDeviceManager::FromPepperDeviceType(type), url::Origin(document_url.GetOrigin())); #else - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&PepperMediaDeviceManager::OnDeviceOpenFailed, - AsWeakPtr(), - request_id)); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&PepperMediaDeviceManager::OnDeviceOpenFailed, + AsWeakPtr(), request_id)); #endif return request_id; @@ -255,4 +250,8 @@ MediaStreamDispatcher* PepperMediaDeviceManager::GetMediaStreamDispatcher() return dispatcher; } +void PepperMediaDeviceManager::OnDestruct() { + delete this; +} + } // namespace content diff --git a/chromium/content/renderer/pepper/pepper_media_device_manager.h b/chromium/content/renderer/pepper/pepper_media_device_manager.h index 90d6dc09dcf..e0343bbd197 100644 --- a/chromium/content/renderer/pepper/pepper_media_device_manager.h +++ b/chromium/content/renderer/pepper/pepper_media_device_manager.h @@ -81,6 +81,9 @@ class PepperMediaDeviceManager private: explicit PepperMediaDeviceManager(RenderFrame* render_frame); + // RenderFrameObserver implementation. + void OnDestruct() override; + // Called by StopEnumerateDevices() after returing to the event loop, to avoid // a reentrancy problem. void StopEnumerateDevicesDelayed(int request_id); diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_output.cc b/chromium/content/renderer/pepper/pepper_platform_audio_output.cc index 1e9c74cc7e5..a8e7c433668 100644 --- a/chromium/content/renderer/pepper/pepper_platform_audio_output.cc +++ b/chromium/content/renderer/pepper/pepper_platform_audio_output.cc @@ -60,6 +60,17 @@ bool PepperPlatformAudioOutput::StopPlayback() { return false; } +bool PepperPlatformAudioOutput::SetVolume(double volume) { + if (ipc_) { + io_task_runner_->PostTask( + FROM_HERE, + base::Bind(&PepperPlatformAudioOutput::SetVolumeOnIOThread, + this, volume)); + return true; + } + return false; +} + void PepperPlatformAudioOutput::ShutDown() { // Called on the main thread to stop all audio callbacks. We must only change // the client on the main thread, and the delegates from the I/O thread. @@ -156,6 +167,12 @@ void PepperPlatformAudioOutput::StartPlaybackOnIOThread() { ipc_->PlayStream(); } +void PepperPlatformAudioOutput::SetVolumeOnIOThread(double volume) { + DCHECK(io_task_runner_->BelongsToCurrentThread()); + if (ipc_) + ipc_->SetVolume(volume); +} + void PepperPlatformAudioOutput::StopPlaybackOnIOThread() { DCHECK(io_task_runner_->BelongsToCurrentThread()); if (ipc_) diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_output.h b/chromium/content/renderer/pepper/pepper_platform_audio_output.h index ea8771d6f90..439dc2b7dc2 100644 --- a/chromium/content/renderer/pepper/pepper_platform_audio_output.h +++ b/chromium/content/renderer/pepper/pepper_platform_audio_output.h @@ -43,6 +43,10 @@ class PepperPlatformAudioOutput // is created or after the stream is closed. bool StopPlayback(); + // Sets the volume. Returns false on error or if called before the stream + // is created or after the stream is closed. + bool SetVolume(double volume); + // Closes the stream. Make sure to call this before the object is // destructed. void ShutDown(); @@ -74,6 +78,7 @@ class PepperPlatformAudioOutput void InitializeOnIOThread(const media::AudioParameters& params); void StartPlaybackOnIOThread(); void StopPlaybackOnIOThread(); + void SetVolumeOnIOThread(double volume); void ShutDownOnIOThread(); // The client to notify when the stream is created. THIS MUST ONLY BE diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc index 8810686bb43..2dfd47b0822 100644 --- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc @@ -35,6 +35,7 @@ #include "content/renderer/pepper/host_dispatcher_wrapper.h" #include "content/renderer/pepper/host_globals.h" #include "content/renderer/pepper/message_channel.h" +#include "content/renderer/pepper/pepper_audio_controller.h" #include "content/renderer/pepper/pepper_browser_connection.h" #include "content/renderer/pepper/pepper_compositor_host.h" #include "content/renderer/pepper/pepper_file_ref_renderer_host.h" @@ -529,6 +530,7 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl( isolate_(v8::Isolate::GetCurrent()), is_deleted_(false), initialized_(false), + audio_controller_(new PepperAudioController(this)), view_change_weak_ptr_factory_(this), weak_factory_(this) { pp_instance_ = HostGlobals::Get()->AddInstance(this); @@ -585,6 +587,8 @@ PepperPluginInstanceImpl::~PepperPluginInstanceImpl() { if (TrackedCallback::IsPending(lock_mouse_callback_)) lock_mouse_callback_->Abort(); + audio_controller_->OnPepperInstanceDeleted(); + if (render_frame_) render_frame_->PepperInstanceDeleted(this); @@ -684,7 +688,7 @@ void PepperPluginInstanceImpl::Delete() { // Force-unbind any Graphics. In the case of Graphics2D, if the plugin // leaks the graphics 2D, it may actually get cleaned up after our - // destruction, so we need its pointers to be up-to-date. + // destruction, so we need its pointers to be up to date. BindGraphics(pp_instance(), 0); container_ = NULL; } @@ -756,22 +760,63 @@ void PepperPluginInstanceImpl::ScrollRect(int dx, } } -void PepperPluginInstanceImpl::CommitBackingTexture() { +void PepperPluginInstanceImpl::CommitTextureMailbox( + const cc::TextureMailbox& texture_mailbox) { + if (committed_texture_.IsValid() && !IsTextureInUse(committed_texture_)) { + committed_texture_graphics_3d_->ReturnFrontBuffer( + committed_texture_.mailbox(), committed_texture_consumed_sync_token_, + false); + } + + committed_texture_ = texture_mailbox; + committed_texture_graphics_3d_ = bound_graphics_3d_; + committed_texture_consumed_sync_token_ = gpu::SyncToken(); + if (!texture_layer_) { UpdateLayer(true); return; } - gpu::Mailbox mailbox; - gpu::SyncToken sync_token; - bound_graphics_3d_->GetBackingMailbox(&mailbox, &sync_token); - DCHECK(!mailbox.IsZero()); - DCHECK(sync_token.HasData()); - texture_layer_->SetTextureMailboxWithoutReleaseCallback( - cc::TextureMailbox(mailbox, sync_token, GL_TEXTURE_2D)); + PassCommittedTextureToTextureLayer(); texture_layer_->SetNeedsDisplay(); } +void PepperPluginInstanceImpl::PassCommittedTextureToTextureLayer() { + DCHECK(bound_graphics_3d_); + + if (!committed_texture_.IsValid()) + return; + + std::unique_ptr<cc::SingleReleaseCallback> callback( + cc::SingleReleaseCallback::Create(base::Bind( + &PepperPluginInstanceImpl::FinishedConsumingCommittedTexture, + weak_factory_.GetWeakPtr(), committed_texture_, + committed_texture_graphics_3d_))); + + IncrementTextureReferenceCount(committed_texture_); + texture_layer_->SetTextureMailbox(committed_texture_, std::move(callback)); +} + +void PepperPluginInstanceImpl::FinishedConsumingCommittedTexture( + const cc::TextureMailbox& texture_mailbox, + scoped_refptr<PPB_Graphics3D_Impl> graphics_3d, + const gpu::SyncToken& sync_token, + bool is_lost) { + bool removed = DecrementTextureReferenceCount(texture_mailbox); + bool is_committed_texture = + committed_texture_.mailbox() == texture_mailbox.mailbox(); + + if (is_committed_texture && !is_lost) { + committed_texture_consumed_sync_token_ = sync_token; + return; + } + + if (removed && !is_committed_texture) { + graphics_3d->ReturnFrontBuffer(texture_mailbox.mailbox(), sync_token, + is_lost); + } +} + void PepperPluginInstanceImpl::InstanceCrashed() { // Force free all resources and vars. HostGlobals::Get()->InstanceCrashed(pp_instance()); @@ -843,6 +888,14 @@ bool PepperPluginInstanceImpl::Initialize( if (message_channel_) message_channel_->Start(); } + + if (success && + render_frame_ && + render_frame_->render_accessibility() && + LoadPdfInterface()) { + plugin_pdf_interface_->EnableAccessibility(pp_instance()); + } + initialized_ = success; return success; } @@ -1216,8 +1269,7 @@ PP_Var PepperPluginInstanceImpl::GetInstanceObject(v8::Isolate* isolate) { void PepperPluginInstanceImpl::ViewChanged( const gfx::Rect& window, const gfx::Rect& clip, - const gfx::Rect& unobscured, - const std::vector<gfx::Rect>& cut_outs_rects) { + const gfx::Rect& unobscured) { // WebKit can give weird (x,y) positions for empty clip rects (since the // position technically doesn't matter). But we want to make these // consistent since this is given to the plugin, so force everything to 0 @@ -1228,8 +1280,6 @@ void PepperPluginInstanceImpl::ViewChanged( unobscured_rect_ = unobscured; - cut_outs_rects_ = cut_outs_rects; - view_data_.rect = PP_FromGfxRect(window); view_data_.clip_rect = PP_FromGfxRect(clip); view_data_.device_scale = container_->deviceScaleFactor(); @@ -1251,9 +1301,7 @@ void PepperPluginInstanceImpl::ViewChanged( scroll_offset.height()); if (desired_fullscreen_state_ || view_data_.is_fullscreen) { - WebElement element = container_->element(); - WebDocument document = element.document(); - bool is_fullscreen_element = (element == document.fullScreenElement()); + bool is_fullscreen_element = container_->isFullscreenElement(); if (!view_data_.is_fullscreen && desired_fullscreen_state_ && render_frame()->GetRenderWidget()->is_fullscreen_granted() && is_fullscreen_element) { @@ -1424,12 +1472,13 @@ bool PepperPluginInstanceImpl::StartFind(const base::string16& search_text, PP_FromBool(case_sensitive))); } -void PepperPluginInstanceImpl::SelectFindResult(bool forward) { +void PepperPluginInstanceImpl::SelectFindResult(bool forward, int identifier) { // Keep a reference on the stack. See NOTE above. scoped_refptr<PepperPluginInstanceImpl> ref(this); - if (LoadFindInterface()) - plugin_find_interface_->SelectFindResult(pp_instance(), - PP_FromBool(forward)); + if (!LoadFindInterface()) + return; + find_identifier_ = identifier; + plugin_find_interface_->SelectFindResult(pp_instance(), PP_FromBool(forward)); } void PepperPluginInstanceImpl::StopFind() { @@ -1921,9 +1970,9 @@ bool PepperPluginInstanceImpl::SetFullscreen(bool fullscreen) { // so we will tweak plugin's attributes to support the expected behavior. KeepSizeAttributesBeforeFullscreen(); SetSizeAttributesForFullscreen(); - container_->element().requestFullScreen(); + container_->requestFullscreen(); } else { - container_->document().cancelFullScreen(); + container_->cancelFullscreen(); } return true; } @@ -2003,12 +2052,7 @@ void PepperPluginInstanceImpl::UpdateLayer(bool force_creation) { if (!container_) return; - gpu::Mailbox mailbox; - gpu::SyncToken sync_token; - if (bound_graphics_3d_.get()) { - bound_graphics_3d_->GetBackingMailbox(&mailbox, &sync_token); - } - bool want_3d_layer = !mailbox.IsZero() && sync_token.HasData(); + bool want_3d_layer = !!bound_graphics_3d_.get(); bool want_2d_layer = !!bound_graphics_2d_platform_; bool want_texture_layer = want_3d_layer || want_2d_layer; bool want_compositor_layer = !!bound_compositor_; @@ -2047,8 +2091,8 @@ void PepperPluginInstanceImpl::UpdateLayer(bool force_creation) { DCHECK(bound_graphics_3d_.get()); texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL); opaque = bound_graphics_3d_->IsOpaque(); - texture_layer_->SetTextureMailboxWithoutReleaseCallback( - cc::TextureMailbox(mailbox, sync_token, GL_TEXTURE_2D)); + + PassCommittedTextureToTextureLayer(); } else { DCHECK(bound_graphics_2d_platform_); texture_layer_ = cc::TextureLayer::CreateForMailbox(this); @@ -3340,4 +3384,47 @@ void PepperPluginInstanceImpl::ConvertDIPToViewport(gfx::Rect* rect) const { rect->set_height(rect->height() / viewport_to_dip_scale_); } +void PepperPluginInstanceImpl::IncrementTextureReferenceCount( + const cc::TextureMailbox& mailbox) { + auto it = + std::find_if(texture_ref_counts_.begin(), texture_ref_counts_.end(), + [&mailbox](const TextureMailboxRefCount& ref_count) { + return ref_count.first.mailbox() == mailbox.mailbox(); + }); + if (it == texture_ref_counts_.end()) { + texture_ref_counts_.push_back(std::make_pair(mailbox, 1)); + return; + } + + it->second++; +} + +bool PepperPluginInstanceImpl::DecrementTextureReferenceCount( + const cc::TextureMailbox& mailbox) { + auto it = + std::find_if(texture_ref_counts_.begin(), texture_ref_counts_.end(), + [&mailbox](const TextureMailboxRefCount& ref_count) { + return ref_count.first.mailbox() == mailbox.mailbox(); + }); + DCHECK(it != texture_ref_counts_.end()); + + if (it->second == 1) { + texture_ref_counts_.erase(it); + return true; + } + + it->second--; + return false; +} + +bool PepperPluginInstanceImpl::IsTextureInUse( + const cc::TextureMailbox& mailbox) const { + auto it = + std::find_if(texture_ref_counts_.begin(), texture_ref_counts_.end(), + [&mailbox](const TextureMailboxRefCount& ref_count) { + return ref_count.first.mailbox() == mailbox.mailbox(); + }); + return it != texture_ref_counts_.end(); +} + } // namespace content diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h index dd53679cc79..f3089f05042 100644 --- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h +++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h @@ -24,6 +24,7 @@ #include "cc/layers/content_layer_client.h" #include "cc/layers/layer.h" #include "cc/layers/texture_layer_client.h" +#include "cc/resources/texture_mailbox.h" #include "content/common/content_export.h" #include "content/public/renderer/pepper_plugin_instance.h" #include "content/public/renderer/plugin_instance_throttler.h" @@ -105,6 +106,7 @@ namespace content { class ContentDecryptorDelegate; class FullscreenContainer; class MessageChannel; +class PepperAudioController; class PepperCompositorHost; class PepperGraphics2DHost; class PluginInstanceThrottlerImpl; @@ -197,9 +199,18 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // slow path can also be triggered if there is an overlapping frame. void ScrollRect(int dx, int dy, const gfx::Rect& rect); - // Commit the backing texture to the screen once the side effects some - // rendering up to an offscreen SwapBuffers are visible. - void CommitBackingTexture(); + // Commit the texture mailbox to the screen. + void CommitTextureMailbox(const cc::TextureMailbox& texture_mailbox); + + // Passes the committed texture to |texture_layer_| and marks it as in use. + void PassCommittedTextureToTextureLayer(); + + // Callback when the compositor is finished consuming the committed texture. + void FinishedConsumingCommittedTexture( + const cc::TextureMailbox& texture_mailbox, + scoped_refptr<PPB_Graphics3D_Impl> graphics_3d, + const gpu::SyncToken& sync_token, + bool is_lost); // Called when the out-of-process plugin implementing this instance crashed. void InstanceCrashed(); @@ -219,8 +230,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl PP_Var GetInstanceObject(v8::Isolate* isolate); void ViewChanged(const gfx::Rect& window, const gfx::Rect& clip, - const gfx::Rect& unobscured, - const std::vector<gfx::Rect>& cut_outs_rects); + const gfx::Rect& unobscured); // Handlers for composition events. bool HandleCompositionStart(const base::string16& text); @@ -259,7 +269,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl bool StartFind(const base::string16& search_text, bool case_sensitive, int identifier); - void SelectFindResult(bool forward); + void SelectFindResult(bool forward, int identifier); void StopFind(); bool SupportsPrintInterface(); @@ -548,6 +558,10 @@ class CONTENT_EXPORT PepperPluginInstanceImpl void OnThrottleStateChange() override; void OnHiddenForPlaceholder(bool hidden) override; + PepperAudioController& audio_controller() { + return *audio_controller_; + } + private: friend class base::RefCounted<PepperPluginInstanceImpl>; friend class PpapiPluginInstanceTest; @@ -702,6 +716,28 @@ class CONTENT_EXPORT PepperPluginInstanceImpl void ConvertRectToDIP(PP_Rect* rect) const; void ConvertDIPToViewport(gfx::Rect* rect) const; + // Each time CommitTextureMailbox() is called, this instance is given + // ownership + // of a cc::TextureMailbox. This instance always needs to hold on to the most + // recently committed cc::TextureMailbox, since UpdateLayer() might require + // it. + // Since it is possible for a cc::TextureMailbox to be passed to + // texture_layer_ more than once, a reference counting mechanism is necessary + // to ensure that a cc::TextureMailbox isn't returned until all copies of it + // have been released by texture_layer_. + // + // This method should be called each time a cc::TextureMailbox is passed to + // |texture_layer_|. It increments an internal reference count. + void IncrementTextureReferenceCount(const cc::TextureMailbox& mailbox); + + // This method should be called each time |texture_layer_| finishes consuming + // a cc::TextureMailbox. It decrements an internal reference count. Returns + // whether the last reference was removed. + bool DecrementTextureReferenceCount(const cc::TextureMailbox& mailbox); + + // Whether a given cc::TextureMailbox is in use by |texture_layer_|. + bool IsTextureInUse(const cc::TextureMailbox& mailbox) const; + RenderFrameImpl* render_frame_; scoped_refptr<PluginModule> module_; std::unique_ptr<ppapi::PPP_Instance_Combined> instance_interface_; @@ -831,10 +867,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // Set to true if this plugin thinks it will always be on top. This allows us // to use a more optimized painting path in some cases. bool always_on_top_; - // Even if |always_on_top_| is true, the plugin is not fully visible if there - // are some cut-out areas (occupied by iframes higher in the stacking order). - // This information is used in the optimized painting path. - std::vector<gfx::Rect> cut_outs_rects_; // Implementation of PPB_FlashFullscreen. @@ -932,8 +964,27 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // The text that is currently selected in the plugin. base::string16 selected_text_; + // The most recently committed texture. This is kept around in case the layer + // needs to be regenerated. + cc::TextureMailbox committed_texture_; + + // The Graphics3D that produced the most recently committed texture. + scoped_refptr<PPB_Graphics3D_Impl> committed_texture_graphics_3d_; + + gpu::SyncToken committed_texture_consumed_sync_token_; + + // Holds the number of references |texture_layer_| has to any given + // cc::TextureMailbox. + // We expect there to be no more than 10 textures in use at a time. A + // std::vector will have better performance than a std::map. + using TextureMailboxRefCount = std::pair<cc::TextureMailbox, int>; + std::vector<TextureMailboxRefCount> texture_ref_counts_; + bool initialized_; + // The controller for all active audios of this pepper instance. + std::unique_ptr<PepperAudioController> audio_controller_; + // We use a weak ptr factory for scheduling DidChangeView events so that we // can tell whether updates are pending and consolidate them. When there's // already a weak ptr pending (HasWeakPtrs is true), code should update the diff --git a/chromium/content/renderer/pepper/pepper_url_loader_host.cc b/chromium/content/renderer/pepper/pepper_url_loader_host.cc index ac34ce9ca66..d8b75dda4aa 100644 --- a/chromium/content/renderer/pepper/pepper_url_loader_host.cc +++ b/chromium/content/renderer/pepper/pepper_url_loader_host.cc @@ -264,7 +264,9 @@ int32_t PepperURLLoaderHost::InternalOnHostMsgOpen( // The requests from the plugins with private permission which can bypass same // origin must skip the ServiceWorker. web_request.setSkipServiceWorker( - host()->permissions().HasPermission(ppapi::PERMISSION_PRIVATE)); + host()->permissions().HasPermission(ppapi::PERMISSION_PRIVATE) + ? blink::WebURLRequest::SkipServiceWorker::All + : blink::WebURLRequest::SkipServiceWorker::None); WebURLLoaderOptions options; if (has_universal_access_) { diff --git a/chromium/content/renderer/pepper/pepper_video_decoder_host.cc b/chromium/content/renderer/pepper/pepper_video_decoder_host.cc index 00fbe5d631b..3ca1c3b1b9f 100644 --- a/chromium/content/renderer/pepper/pepper_video_decoder_host.cc +++ b/chromium/content/renderer/pepper/pepper_video_decoder_host.cc @@ -149,7 +149,10 @@ int32_t PepperVideoDecoderHost::OnHostMsgInitialize( // it is okay to immediately send IPC messages. if (command_buffer->channel()) { decoder_.reset(new media::GpuVideoDecodeAcceleratorHost(command_buffer)); - if (decoder_->Initialize(profile_, this)) { + media::VideoDecodeAccelerator::Config vda_config(profile_); + vda_config.supported_output_formats.assign( + {media::PIXEL_FORMAT_XRGB, media::PIXEL_FORMAT_ARGB}); + if (decoder_->Initialize(vda_config, this)) { initialized_ = true; return PP_OK; } @@ -351,6 +354,7 @@ int32_t PepperVideoDecoderHost::OnHostMsgReset( void PepperVideoDecoderHost::ProvidePictureBuffers( uint32_t requested_num_of_buffers, + media::VideoPixelFormat format, uint32_t textures_per_buffer, const gfx::Size& dimensions, uint32_t texture_target) { diff --git a/chromium/content/renderer/pepper/pepper_video_decoder_host.h b/chromium/content/renderer/pepper/pepper_video_decoder_host.h index 308ba447598..e0f383a651b 100644 --- a/chromium/content/renderer/pepper/pepper_video_decoder_host.h +++ b/chromium/content/renderer/pepper/pepper_video_decoder_host.h @@ -73,6 +73,7 @@ class CONTENT_EXPORT PepperVideoDecoderHost // media::VideoDecodeAccelerator::Client implementation. void ProvidePictureBuffers(uint32_t requested_num_of_buffers, + media::VideoPixelFormat format, uint32_t textures_per_buffer, const gfx::Size& dimensions, uint32_t texture_target) override; diff --git a/chromium/content/renderer/pepper/pepper_video_encoder_host.cc b/chromium/content/renderer/pepper/pepper_video_encoder_host.cc index 8438c0f51d3..0d0997b5047 100644 --- a/chromium/content/renderer/pepper/pepper_video_encoder_host.cc +++ b/chromium/content/renderer/pepper/pepper_video_encoder_host.cc @@ -441,12 +441,14 @@ void PepperVideoEncoderHost::RequireBitstreamBuffers( } void PepperVideoEncoderHost::BitstreamBufferReady(int32_t buffer_id, - size_t payload_size, - bool key_frame) { + size_t payload_size, + bool key_frame, + base::TimeDelta /* timestamp */) { DCHECK(RenderThreadImpl::current()); DCHECK(shm_buffers_[buffer_id]->in_use); shm_buffers_[buffer_id]->in_use = false; + // TODO: Pass timestamp. Tracked in crbug/613984. host()->SendUnsolicitedReply( pp_resource(), PpapiPluginMsg_VideoEncoder_BitstreamBufferReady( @@ -527,10 +529,10 @@ bool PepperVideoEncoderHost::EnsureGpuChannel() { return false; command_buffer_ = gpu::CommandBufferProxyImpl::Create( - std::move(channel), gpu::kNullSurfaceHandle, gfx::Size(), nullptr, + std::move(channel), gpu::kNullSurfaceHandle, nullptr, gpu::GPU_STREAM_DEFAULT, gpu::GpuStreamPriority::NORMAL, gpu::gles2::ContextCreationAttribHelper(), GURL::EmptyGURL(), - gfx::PreferIntegratedGpu, base::ThreadTaskRunnerHandle::Get()); + base::ThreadTaskRunnerHandle::Get()); if (!command_buffer_) { Close(); return false; diff --git a/chromium/content/renderer/pepper/pepper_video_encoder_host.h b/chromium/content/renderer/pepper/pepper_video_encoder_host.h index 53b95069119..d3f8e2a4eb0 100644 --- a/chromium/content/renderer/pepper/pepper_video_encoder_host.h +++ b/chromium/content/renderer/pepper/pepper_video_encoder_host.h @@ -71,7 +71,8 @@ class CONTENT_EXPORT PepperVideoEncoderHost size_t output_buffer_size) override; void BitstreamBufferReady(int32_t bitstream_buffer_id, size_t payload_size, - bool key_frame) override; + bool key_frame, + base::TimeDelta timestamp) override; void NotifyError(media::VideoEncodeAccelerator::Error error) override; // ResourceHost implementation. diff --git a/chromium/content/renderer/pepper/pepper_webplugin_impl.cc b/chromium/content/renderer/pepper/pepper_webplugin_impl.cc index 813820319f5..3949db81188 100644 --- a/chromium/content/renderer/pepper/pepper_webplugin_impl.cc +++ b/chromium/content/renderer/pepper/pepper_webplugin_impl.cc @@ -9,7 +9,9 @@ #include <utility> #include "base/debug/crash_logging.h" -#include "base/message_loop/message_loop.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" #include "content/public/renderer/content_renderer_client.h" #include "content/renderer/pepper/message_channel.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" @@ -155,7 +157,7 @@ void PepperWebPluginImpl::destroy() { instance_ = nullptr; } - base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); + base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); } v8::Local<v8::Object> PepperWebPluginImpl::v8ScriptableObject( @@ -199,12 +201,8 @@ void PepperWebPluginImpl::updateGeometry( const WebVector<WebRect>& cut_outs_rects, bool is_visible) { plugin_rect_ = window_rect; - if (instance_ && !instance_->FlashIsFullscreenOrPending()) { - std::vector<gfx::Rect> cut_outs; - for (size_t i = 0; i < cut_outs_rects.size(); ++i) - cut_outs.push_back(cut_outs_rects[i]); - instance_->ViewChanged(plugin_rect_, clip_rect, unobscured_rect, cut_outs); - } + if (instance_ && !instance_->FlashIsFullscreenOrPending()) + instance_->ViewChanged(plugin_rect_, clip_rect, unobscured_rect); } void PepperWebPluginImpl::updateFocus(bool focused, @@ -271,8 +269,8 @@ bool PepperWebPluginImpl::startFind(const blink::WebString& search_text, return instance_->StartFind(search_text, case_sensitive, identifier); } -void PepperWebPluginImpl::selectFindResult(bool forward) { - instance_->SelectFindResult(forward); +void PepperWebPluginImpl::selectFindResult(bool forward, int identifier) { + instance_->SelectFindResult(forward, identifier); } void PepperWebPluginImpl::stopFind() { instance_->StopFind(); } diff --git a/chromium/content/renderer/pepper/pepper_webplugin_impl.h b/chromium/content/renderer/pepper/pepper_webplugin_impl.h index 49a0832c5ae..3de02b80c1a 100644 --- a/chromium/content/renderer/pepper/pepper_webplugin_impl.h +++ b/chromium/content/renderer/pepper/pepper_webplugin_impl.h @@ -70,7 +70,7 @@ class PepperWebPluginImpl : public blink::WebPlugin { bool startFind(const blink::WebString& search_text, bool case_sensitive, int identifier) override; - void selectFindResult(bool forward) override; + void selectFindResult(bool forward, int identifier) override; void stopFind() override; bool supportsPaginatedPrint() override; bool isPrintScalingDisabled() override; diff --git a/chromium/content/renderer/pepper/plugin_power_saver_helper.cc b/chromium/content/renderer/pepper/plugin_power_saver_helper.cc index 36d65e3f8fc..1879b7e9fe2 100644 --- a/chromium/content/renderer/pepper/plugin_power_saver_helper.cc +++ b/chromium/content/renderer/pepper/plugin_power_saver_helper.cc @@ -7,9 +7,11 @@ #include <string> #include "base/command_line.h" -#include "base/message_loop/message_loop.h" +#include "base/location.h" #include "base/metrics/histogram.h" +#include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" +#include "base/threading/thread_task_runner_handle.h" #include "content/common/frame_messages.h" #include "content/public/common/content_switches.h" #include "content/public/renderer/render_frame.h" @@ -66,6 +68,10 @@ bool PluginPowerSaverHelper::OnMessageReceived(const IPC::Message& message) { return handled; } +void PluginPowerSaverHelper::OnDestruct() { + delete this; +} + void PluginPowerSaverHelper::OnUpdatePluginContentOriginWhitelist( const std::set<url::Origin>& origin_whitelist) { origin_whitelist_ = origin_whitelist; @@ -76,8 +82,8 @@ void PluginPowerSaverHelper::OnUpdatePluginContentOriginWhitelist( if (origin_whitelist.count(it->content_origin)) { // Because the unthrottle callback may register another peripheral plugin // and invalidate our iterator, we cannot run it synchronously. - base::MessageLoop::current()->PostTask(FROM_HERE, - it->unthrottle_callback); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + it->unthrottle_callback); it = peripheral_plugins_.erase(it); } else { ++it; diff --git a/chromium/content/renderer/pepper/plugin_power_saver_helper.h b/chromium/content/renderer/pepper/plugin_power_saver_helper.h index 2f3bb442657..0de22ddf3b9 100644 --- a/chromium/content/renderer/pepper/plugin_power_saver_helper.h +++ b/chromium/content/renderer/pepper/plugin_power_saver_helper.h @@ -57,6 +57,7 @@ class CONTENT_EXPORT PluginPowerSaverHelper : public RenderFrameObserver { void DidCommitProvisionalLoad(bool is_new_navigation, bool is_same_page_navigation) override; bool OnMessageReceived(const IPC::Message& message) override; + void OnDestruct() override; void OnUpdatePluginContentOriginWhitelist( const std::set<url::Origin>& origin_whitelist); diff --git a/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc b/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc index d701c31b251..35b8388f88c 100644 --- a/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc +++ b/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <tuple> + #include "base/macros.h" #include "base/run_loop.h" #include "content/common/frame_messages.h" @@ -64,7 +66,7 @@ TEST_F(PluginPowerSaverHelperTest, TemporaryOriginWhitelist) { FrameHostMsg_PluginContentOriginAllowed::Param params; FrameHostMsg_PluginContentOriginAllowed::Read(msg, ¶ms); EXPECT_TRUE(url::Origin(GURL("http://other.com")) - .IsSameOriginWith(base::get<0>(params))); + .IsSameOriginWith(std::get<0>(params))); } TEST_F(PluginPowerSaverHelperTest, UnthrottleOnExPostFactoWhitelist) { diff --git a/chromium/content/renderer/pepper/ppb_audio_impl.cc b/chromium/content/renderer/pepper/ppb_audio_impl.cc index 98bf7637f4a..43426b5b5fa 100644 --- a/chromium/content/renderer/pepper/ppb_audio_impl.cc +++ b/chromium/content/renderer/pepper/ppb_audio_impl.cc @@ -5,11 +5,11 @@ #include "content/renderer/pepper/ppb_audio_impl.h" #include "base/logging.h" +#include "content/renderer/pepper/pepper_audio_controller.h" #include "content/renderer/pepper/pepper_platform_audio_output.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/plugin_instance_throttler_impl.h" #include "content/renderer/render_frame_impl.h" -#include "content/renderer/render_view_impl.h" #include "media/audio/audio_output_controller.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/ppb_audio.h" @@ -44,8 +44,11 @@ PPB_Audio_Impl::PPB_Audio_Impl(PP_Instance instance) PPB_Audio_Impl::~PPB_Audio_Impl() { PepperPluginInstanceImpl* instance = static_cast<PepperPluginInstanceImpl*>( PepperPluginInstance::Get(pp_instance())); - if (instance && instance->throttler()) { - instance->throttler()->RemoveObserver(this); + if (instance) { + if (instance->throttler()) { + instance->throttler()->RemoveObserver(this); + } + instance->audio_controller().RemoveInstance(this); } // Calling ShutDown() makes sure StreamCreated cannot be called anymore and @@ -83,6 +86,9 @@ PP_Bool PPB_Audio_Impl::StartPlayback() { return PP_TRUE; } + if (instance) + instance->audio_controller().AddInstance(this); + SetStartPlaybackState(); return PP_FromBool(audio_->StartPlayback()); } @@ -97,6 +103,11 @@ PP_Bool PPB_Audio_Impl::StopPlayback() { StartDeferredPlayback(); } + PepperPluginInstanceImpl* instance = static_cast<PepperPluginInstanceImpl*>( + PepperPluginInstance::Get(pp_instance())); + if (instance) + instance->audio_controller().RemoveInstance(this); + if (!playing()) return PP_TRUE; if (!audio_->StopPlayback()) @@ -173,8 +184,17 @@ void PPB_Audio_Impl::StartDeferredPlayback() { DCHECK(playback_throttled_); playback_throttled_ = false; + PepperPluginInstanceImpl* instance = static_cast<PepperPluginInstanceImpl*>( + PepperPluginInstance::Get(pp_instance())); + if (instance) + instance->audio_controller().AddInstance(this); + SetStartPlaybackState(); audio_->StartPlayback(); } +void PPB_Audio_Impl::SetVolume(double volume) { + if (audio_) + audio_->SetVolume(volume); +} } // namespace content diff --git a/chromium/content/renderer/pepper/ppb_audio_impl.h b/chromium/content/renderer/pepper/ppb_audio_impl.h index 311dfb9306c..e0618ffb29d 100644 --- a/chromium/content/renderer/pepper/ppb_audio_impl.h +++ b/chromium/content/renderer/pepper/ppb_audio_impl.h @@ -50,6 +50,8 @@ class PPB_Audio_Impl : public ppapi::Resource, int32_t GetSharedMemory(base::SharedMemory** shm, uint32_t* shm_size) override; + void SetVolume(double volume); + private: ~PPB_Audio_Impl() override; diff --git a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc index a908b6fbe0f..5e0b5f32641 100644 --- a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc +++ b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc @@ -28,6 +28,7 @@ #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" +#include "third_party/khronos/GLES2/gl2.h" using ppapi::thunk::EnterResourceNoLock; using ppapi::thunk::PPB_Graphics3D_API; @@ -114,6 +115,22 @@ void PPB_Graphics3D_Impl::EnsureWorkVisible() { command_buffer_->EnsureWorkVisible(); } +void PPB_Graphics3D_Impl::TakeFrontBuffer() { + if (!taken_front_buffer_.IsZero()) { + DLOG(ERROR) + << "TakeFrontBuffer should only be called once before DoSwapBuffers"; + return; + } + taken_front_buffer_ = GenerateMailbox(); + command_buffer_->TakeFrontBuffer(taken_front_buffer_); +} + +void PPB_Graphics3D_Impl::ReturnFrontBuffer(const gpu::Mailbox& mailbox, + const gpu::SyncToken& sync_token, + bool is_lost) { + command_buffer_->ReturnFrontBuffer(mailbox, sync_token, is_lost); +} + bool PPB_Graphics3D_Impl::BindToInstance(bool bind) { bound_to_instance_ = bind; return true; @@ -143,8 +160,10 @@ gpu::GpuControl* PPB_Graphics3D_Impl::GetGpuControl() { int32_t PPB_Graphics3D_Impl::DoSwapBuffers(const gpu::SyncToken& sync_token) { DCHECK(command_buffer_); - if (sync_token.HasData()) - sync_token_ = sync_token; + if (taken_front_buffer_.IsZero()) { + DLOG(ERROR) << "TakeFrontBuffer should be called before DoSwapBuffers"; + return PP_ERROR_FAILED; + } if (bound_to_instance_) { // If we are bound to the instance, we need to ask the compositor @@ -154,14 +173,18 @@ int32_t PPB_Graphics3D_Impl::DoSwapBuffers(const gpu::SyncToken& sync_token) { // // Don't need to check for NULL from GetPluginInstance since when we're // bound, we know our instance is valid. - HostGlobals::Get()->GetInstance(pp_instance())->CommitBackingTexture(); + cc::TextureMailbox texture_mailbox(taken_front_buffer_, sync_token, + GL_TEXTURE_2D); + taken_front_buffer_.SetZero(); + HostGlobals::Get() + ->GetInstance(pp_instance()) + ->CommitTextureMailbox(texture_mailbox); commit_pending_ = true; } else { // Wait for the command to complete on the GPU to allow for throttling. command_buffer_->SignalSyncToken( - sync_token_, - base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers, - weak_ptr_factory_.GetWeakPtr())); + sync_token, base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers, + weak_ptr_factory_.GetWeakPtr())); } return PP_OK_COMPLETIONPENDING; @@ -202,9 +225,9 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context, if (!channel) return false; - gfx::Size surface_size; + gpu::gles2::ContextCreationAttribHelper attrib_helper; std::vector<int32_t> attribs; - gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; + attrib_helper.gpu_preference = gl::PreferDiscreteGpu; // TODO(alokp): Change CommandBufferProxyImpl::Create() // interface to accept width and height in the attrib_list so that // we do not need to filter for width and height here. @@ -213,16 +236,16 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context, attr += 2) { switch (attr[0]) { case PP_GRAPHICS3DATTRIB_WIDTH: - surface_size.set_width(attr[1]); + attrib_helper.offscreen_framebuffer_size.set_width(attr[1]); break; case PP_GRAPHICS3DATTRIB_HEIGHT: - surface_size.set_height(attr[1]); + attrib_helper.offscreen_framebuffer_size.set_height(attr[1]); break; case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE: - gpu_preference = + attrib_helper.gpu_preference = (attr[1] == PP_GRAPHICS3DATTRIB_GPU_PREFERENCE_LOW_POWER) - ? gfx::PreferIntegratedGpu - : gfx::PreferDiscreteGpu; + ? gl::PreferIntegratedGpu + : gl::PreferDiscreteGpu; break; case PP_GRAPHICS3DATTRIB_ALPHA_SIZE: has_alpha_ = attr[1] > 0; @@ -235,7 +258,6 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context, } attribs.push_back(PP_GRAPHICS3DATTRIB_NONE); } - gpu::gles2::ContextCreationAttribHelper attrib_helper; if (!attrib_helper.Parse(attribs)) return false; @@ -247,10 +269,9 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context, } command_buffer_ = gpu::CommandBufferProxyImpl::Create( - std::move(channel), gpu::kNullSurfaceHandle, surface_size, share_buffer, - gpu::GPU_STREAM_DEFAULT, gpu::GpuStreamPriority::NORMAL, - attrib_helper, GURL::EmptyGURL(), gpu_preference, - base::ThreadTaskRunnerHandle::Get()); + std::move(channel), gpu::kNullSurfaceHandle, share_buffer, + gpu::GPU_STREAM_DEFAULT, gpu::GpuStreamPriority::NORMAL, attrib_helper, + GURL::EmptyGURL(), base::ThreadTaskRunnerHandle::Get()); if (!command_buffer_) return false; @@ -263,10 +284,6 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context, if (command_buffer_id) *command_buffer_id = command_buffer_->GetCommandBufferID(); - mailbox_ = gpu::Mailbox::Generate(); - if (!command_buffer_->ProduceFrontBuffer(mailbox_)) - return false; - return true; } @@ -344,4 +361,14 @@ void PPB_Graphics3D_Impl::SendContextLost() { ppp_graphics_3d->Graphics3DContextLost(this_pp_instance); } +gpu::Mailbox PPB_Graphics3D_Impl::GenerateMailbox() { + if (!mailboxes_to_reuse_.empty()) { + gpu::Mailbox mailbox = mailboxes_to_reuse_.back(); + mailboxes_to_reuse_.pop_back(); + return mailbox; + } + + return gpu::Mailbox::Generate(); +} + } // namespace content diff --git a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h index 8216f631b7e..abafd2c4b14 100644 --- a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h +++ b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h @@ -47,6 +47,10 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared, gpu::CommandBuffer::State WaitForGetOffsetInRange(int32_t start, int32_t end) override; void EnsureWorkVisible() override; + void TakeFrontBuffer() override; + void ReturnFrontBuffer(const gpu::Mailbox& mailbox, + const gpu::SyncToken& sync_token, + bool is_lost); // Binds/unbinds the graphics of this context with the associated instance. // Returns true if binding/unbinding is successful. @@ -59,11 +63,6 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared, // These messages are used to send Flush callbacks to the plugin. void ViewInitiatedPaint(); - void GetBackingMailbox(gpu::Mailbox* mailbox, gpu::SyncToken* sync_token) { - *mailbox = mailbox_; - *sync_token = sync_token_; - } - gpu::CommandBufferProxyImpl* GetCommandBufferProxy(); protected: @@ -92,6 +91,16 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared, // Notifications sent to plugin. void SendContextLost(); + // Reuses a mailbox if one is available, otherwise makes a new one. + gpu::Mailbox GenerateMailbox(); + + // A front buffer that was recently taken from the command buffer. This should + // be immediately consumed by DoSwapBuffers(). + gpu::Mailbox taken_front_buffer_; + + // Mailboxes that are no longer in use. + std::vector<gpu::Mailbox> mailboxes_to_reuse_; + // True if context is bound to instance. bool bound_to_instance_; // True when waiting for compositor to commit our backing texture. @@ -101,8 +110,6 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared, bool lost_context_ = false; #endif - gpu::Mailbox mailbox_; - gpu::SyncToken sync_token_; bool has_alpha_; std::unique_ptr<gpu::CommandBufferProxyImpl> command_buffer_; diff --git a/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc b/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc index 0f31ea09a21..360f5d4e3e5 100644 --- a/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc +++ b/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc @@ -239,6 +239,7 @@ void PPB_VideoDecoder_Impl::Destroy() { void PPB_VideoDecoder_Impl::ProvidePictureBuffers( uint32_t requested_num_of_buffers, + media::VideoPixelFormat format, uint32_t textures_per_buffer, const gfx::Size& dimensions, uint32_t texture_target) { diff --git a/chromium/content/renderer/pepper/ppb_video_decoder_impl.h b/chromium/content/renderer/pepper/ppb_video_decoder_impl.h index c0597a23211..635a5ce47e4 100644 --- a/chromium/content/renderer/pepper/ppb_video_decoder_impl.h +++ b/chromium/content/renderer/pepper/ppb_video_decoder_impl.h @@ -45,6 +45,7 @@ class PPB_VideoDecoder_Impl : public ppapi::PPB_VideoDecoder_Shared, // media::VideoDecodeAccelerator::Client implementation. void ProvidePictureBuffers(uint32_t requested_num_of_buffers, + media::VideoPixelFormat format, uint32_t textures_per_buffer, const gfx::Size& dimensions, uint32_t texture_target) override; diff --git a/chromium/content/renderer/pepper/video_encoder_shim.cc b/chromium/content/renderer/pepper/video_encoder_shim.cc index ab466b395da..0887863363b 100644 --- a/chromium/content/renderer/pepper/video_encoder_shim.cc +++ b/chromium/content/renderer/pepper/video_encoder_shim.cc @@ -487,7 +487,8 @@ void VideoEncoderShim::OnBitstreamBufferReady( bool key_frame) { DCHECK(RenderThreadImpl::current()); - host_->BitstreamBufferReady(bitstream_buffer_id, payload_size, key_frame); + host_->BitstreamBufferReady(bitstream_buffer_id, payload_size, key_frame, + frame->timestamp()); } void VideoEncoderShim::OnNotifyError( |