--- /dev/null
+// Copyright 2015 Samsung Electronics. 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/browser/renderer_host/context_factory_efl.h"
+
+#include "base/bind.h"
+#include "base/cancelable_callback.h"
+#include "base/memory/ref_counted.h"
+#include "cc/output/gl_frame_data.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/output_surface.h"
+#include "cc/output/output_surface_client.h"
+#include "cc/resources/resource_format.h"
+#include "cc/resources/resource_provider.h"
+#include "cc/surfaces/surface_id_allocator.h"
+#include "cc/resources/transferable_resource.h"
+#include "content/public/common/content_switches.h"
+#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
+#include "content/browser/gpu/gpu_surface_tracker.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
+#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
+#include "content/common/gpu/gpu_process_launch_causes.h"
+#include "content/common/gpu/client/command_buffer_proxy_impl.h"
+#include "content/common/gpu/client/context_provider_command_buffer.h"
+#include "content/common/host_shared_bitmap_manager.h"
+#include "ui/gl/gl_shared_context_efl.h"
+#include "gpu/command_buffer/client/context_support.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "ui/compositor/reflector.h"
+#include "cc/blink/context_provider_web_context.h"
+
+using gpu::gles2::GLES2Interface;
+
+namespace {
+
+// TODO(venu.musham): Move this class into separate file.
+class MailboxOutputSurfaceEfl : public cc::OutputSurface {
+ public:
+ MailboxOutputSurfaceEfl(
+ const scoped_refptr<cc::ContextProvider>& context_provider,
+ base::WeakPtr<ui::ContextFactoryEfl> context_factory_efl,
+ cc::ResourceFormat format)
+ : cc::OutputSurface(context_provider),
+ swap_buffers_completion_callback_(
+ base::Bind(&MailboxOutputSurfaceEfl::OnSwapBuffersCompleted,
+ base::Unretained(this))),
+ context_factory_efl_(context_factory_efl),
+ fbo_(0),
+ is_backbuffer_discarded_(false),
+ texture_upload_pending_(false),
+ format_(format) {
+ pending_textures_.push_back(TransferableFrame());
+ capabilities_.max_frames_pending = 1;
+ capabilities_.uses_default_gl_framebuffer = false;
+ capabilities_.adjust_deadline_for_parent = false;
+ }
+ virtual ~MailboxOutputSurfaceEfl() {
+ DiscardBackbuffer();
+ while (!pending_textures_.empty()) {
+ if (pending_textures_.front().texture_id) {
+ context_provider_->ContextGL()->DeleteTextures(
+ 1, &pending_textures_.front().texture_id);
+ }
+ pending_textures_.pop_front();
+ }
+ }
+ virtual void EnsureBackbuffer() override {
+ is_backbuffer_discarded_ = false;
+
+ GLES2Interface* gl = context_provider_->ContextGL();
+
+ if (!current_backing_.texture_id) {
+ // Find a texture of matching size to recycle.
+ while (!returned_textures_.empty()) {
+ TransferableFrame& texture = returned_textures_.front();
+ if (texture.size == surface_size_) {
+ current_backing_ = texture;
+ if (current_backing_.sync_point)
+ gl->WaitSyncPointCHROMIUM(current_backing_.sync_point);
+ returned_textures_.pop();
+ break;
+ }
+
+ gl->DeleteTextures(1, &texture.texture_id);
+ returned_textures_.pop();
+ }
+
+ if (!current_backing_.texture_id) {
+ gl->GenTextures(1, ¤t_backing_.texture_id);
+ current_backing_.size = surface_size_;
+ gl->BindTexture(GL_TEXTURE_2D, current_backing_.texture_id);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl->TexImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(format_),
+ surface_size_.width(), surface_size_.height(), 0,
+ GLDataFormat(format_), GLDataType(format_), NULL);
+ gl->GenMailboxCHROMIUM(current_backing_.mailbox.name);
+ gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D,
+ current_backing_.mailbox.name);
+ texture_upload_pending_ = true;
+ }
+ }
+ }
+
+ virtual void DiscardBackbuffer() override {
+ is_backbuffer_discarded_ = true;
+
+ GLES2Interface* gl = context_provider_->ContextGL();
+
+ if (current_backing_.texture_id) {
+ gl->DeleteTextures(1, ¤t_backing_.texture_id);
+ current_backing_ = TransferableFrame();
+ }
+
+ while (!returned_textures_.empty()) {
+ const TransferableFrame& frame = returned_textures_.front();
+ gl->DeleteTextures(1, &frame.texture_id);
+ returned_textures_.pop();
+ }
+
+ if (fbo_) {
+ gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ gl->DeleteFramebuffers(1, &fbo_);
+ fbo_ = 0;
+ }
+ }
+
+ void Reshape(const gfx::Size& size, float scale_factor) {
+ if (size == surface_size_)
+ return;
+
+ surface_size_ = size;
+ device_scale_factor_ = scale_factor;
+ DiscardBackbuffer();
+ EnsureBackbuffer();
+ }
+
+ void BindFramebuffer() {
+ EnsureBackbuffer();
+ DCHECK(current_backing_.texture_id);
+
+ GLES2Interface* gl = context_provider_->ContextGL();
+
+ if (!fbo_)
+ gl->GenFramebuffers(1, &fbo_);
+ gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, current_backing_.texture_id, 0);
+ }
+
+ void DrawTexture(scoped_ptr<cc::GLFrameData> gl_frame_data) {
+ // Draw texture on RWHV
+ if (gl_frame_data) {
+ gpu::Mailbox pending_mailbox;
+ std::swap(gl_frame_data->mailbox, pending_mailbox);
+ context_factory_efl_->GetFrameFromMailbox(&pending_mailbox,
+ surface_size_);
+ }
+ }
+
+ void OnSwapAck(scoped_ptr<cc::GLFrameData> gl_frame_data) {
+ // Ignore message if it's a stale one coming from a different output surface
+ // (e.g. after a lost context).
+ if (!gl_frame_data->mailbox.IsZero()) {
+ DCHECK(!gl_frame_data->size.IsEmpty());
+ // The browser could be returning the oldest or any other pending texture
+ // if it decided to skip a frame.
+ std::deque<TransferableFrame>::iterator it;
+ for (it = pending_textures_.begin(); it != pending_textures_.end();
+ it++) {
+ DCHECK(!it->mailbox.IsZero());
+ if (!memcmp(it->mailbox.name, gl_frame_data->mailbox.name,
+ sizeof(it->mailbox.name))) {
+ DCHECK(it->size == gl_frame_data->size);
+ break;
+ }
+ }
+ DCHECK(it != pending_textures_.end());
+ it->sync_point = gl_frame_data->sync_point;
+
+ if (!is_backbuffer_discarded_) {
+ returned_textures_.push(*it);
+ } else {
+ context_provider_->ContextGL()->DeleteTextures(1, &it->texture_id);
+ }
+
+ pending_textures_.erase(it);
+ } else {
+ DCHECK(!pending_textures_.empty());
+ // The browser always keeps one texture as the frontbuffer.
+ // If it does not return a mailbox, it discarded the frontbuffer which is
+ // the oldest texture we sent.
+ uint32 texture_id = pending_textures_.front().texture_id;
+ if (texture_id)
+ context_provider_->ContextGL()->DeleteTextures(1, &texture_id);
+ pending_textures_.pop_front();
+ }
+
+ if (gl_frame_data) {
+ base::Closure closure =
+ base::Bind(&MailboxOutputSurfaceEfl::DrawTexture,
+ base::Unretained(this), base::Passed(&gl_frame_data));
+ base::MessageLoopProxy::current()->PostTask(FROM_HERE, closure);
+ }
+ client_->DidSwapBuffersComplete();
+ }
+
+ virtual void SwapBuffers(cc::CompositorFrame* frame) override {
+ DCHECK(frame->gl_frame_data);
+ DCHECK(!surface_size_.IsEmpty());
+ DCHECK(surface_size_ == current_backing_.size);
+ DCHECK(frame->gl_frame_data->size == current_backing_.size);
+ DCHECK(!current_backing_.mailbox.IsZero() ||
+ context_provider_->IsContextLost());
+
+ frame->gl_frame_data->mailbox = current_backing_.mailbox;
+
+ // Using glFinish call instead of glFlush, fixes black screen issue with
+ // static pages and IE Fish page.
+
+ // Black screen issue is seen on page in Note4 and XU3 devices.
+#if defined(TIZEN_V_3_0) && defined(OS_TIZEN)
+ context_provider_->ContextGL()->Finish();
+#else
+ if (texture_upload_pending_) {
+ context_provider_->ContextGL()->Finish();
+ texture_upload_pending_ = false;
+ } else {
+ context_provider_->ContextGL()->Flush();
+ }
+#endif
+
+ frame->gl_frame_data->sync_point =
+ context_provider_->ContextGL()->InsertSyncPointCHROMIUM();
+
+ base::Closure closure =
+ base::Bind(&MailboxOutputSurfaceEfl::OnSwapAck, base::Unretained(this),
+ base::Passed(&frame->gl_frame_data));
+ uint32 sync_point =
+ context_provider_->ContextGL()->InsertSyncPointCHROMIUM();
+ context_provider()->ContextSupport()->SignalSyncPoint(sync_point, closure);
+
+ client_->DidSwapBuffers();
+
+ pending_textures_.push_back(current_backing_);
+ current_backing_ = TransferableFrame();
+ }
+
+ virtual bool BindToClient(cc::OutputSurfaceClient* client) override {
+ if (!OutputSurface::BindToClient(client))
+ return false;
+ GetCommandBufferProxy()->SetSwapBuffersCompletionCallback(
+ swap_buffers_completion_callback_.callback());
+ return true;
+ }
+
+ size_t GetNumAcksPending() {
+ DCHECK(pending_textures_.size());
+ return pending_textures_.size() - 1;
+ }
+
+ private:
+ struct TransferableFrame {
+ TransferableFrame() : texture_id(0), sync_point(0) {}
+
+ TransferableFrame(uint32 texture_id,
+ const gpu::Mailbox& mailbox,
+ const gfx::Size size)
+ : texture_id(texture_id), mailbox(mailbox), size(size), sync_point(0) {}
+
+ uint32 texture_id;
+ gpu::Mailbox mailbox;
+ gfx::Size size;
+ uint32 sync_point;
+ };
+ content::CommandBufferProxyImpl* GetCommandBufferProxy() {
+ content::ContextProviderCommandBuffer* provider_command_buffer =
+ static_cast<content::ContextProviderCommandBuffer*>(
+ context_provider_.get());
+ content::CommandBufferProxyImpl* command_buffer_proxy =
+ provider_command_buffer->GetCommandBufferProxy();
+ DCHECK(command_buffer_proxy);
+ return command_buffer_proxy;
+ }
+
+ void OnSwapBuffersCompleted(
+ const std::vector<ui::LatencyInfo>& latency_info) {
+ content::RenderWidgetHostImpl::CompositorFrameDrawn(latency_info);
+ OutputSurface::OnSwapBuffersComplete();
+ }
+ base::CancelableCallback<void(const std::vector<ui::LatencyInfo>&)>
+ swap_buffers_completion_callback_;
+
+ scoped_refptr<base::MessageLoopProxy> main_thread_;
+ base::WeakPtr<ui::ContextFactoryEfl> context_factory_efl_;
+
+ TransferableFrame current_backing_;
+ std::deque<TransferableFrame> pending_textures_;
+ std::queue<TransferableFrame> returned_textures_;
+
+ uint32 fbo_;
+ bool is_backbuffer_discarded_;
+ bool texture_upload_pending_;
+ cc::ResourceFormat format_;
+};
+} // namespace
+
+namespace content {
+
+static scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
+CreateGpuProcessViewContext(
+ const scoped_refptr<GpuChannelHost>& gpu_channel_host,
+ const blink::WebGraphicsContext3D::Attributes attributes,
+ int surface_id) {
+ DCHECK(gpu_channel_host.get());
+
+ GURL url("chrome://gpu/Compositor::createContext3D");
+ bool lose_context_when_out_of_memory = true;
+ return make_scoped_ptr(new WebGraphicsContext3DCommandBufferImpl(
+ surface_id, url, gpu_channel_host.get(), attributes,
+ lose_context_when_out_of_memory,
+ WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(), NULL));
+}
+} // namespace content
+
+namespace ui {
+
+ContextFactoryEfl::ContextFactoryEfl(content::ContextFactoryDelegate* delegate,
+ int surface_id)
+ : delegate_(delegate),
+ surface_id_(surface_id),
+ next_surface_id_namespace_(1),
+ schedule_draw_factory_(this) {
+}
+
+void ContextFactoryEfl::GetFrameFromMailbox(gpu::Mailbox* mailbox,
+ gfx::Size size) {
+ delegate_->GetTextureFromMailbox(mailbox, size);
+}
+
+void ContextFactoryEfl::CreateOutputSurface(
+ base::WeakPtr<Compositor> compositor,
+ bool software_fallback) {
+ blink::WebGraphicsContext3D::Attributes attrs;
+ attrs.depth = false;
+ attrs.stencil = false;
+ attrs.antialias = false;
+ attrs.shareResources = true;
+ attrs.noAutomaticFlushes = true;
+
+ scoped_refptr<content::ContextProviderCommandBuffer> context_provider;
+ content::BrowserGpuChannelHostFactory* factory =
+ content::BrowserGpuChannelHostFactory::instance();
+ content::CauseForGpuLaunch cause = content::
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
+ scoped_refptr<content::GpuChannelHost> gpu_channel_host(
+ factory->EstablishGpuChannelSync(cause));
+ if (gpu_channel_host.get() && !gpu_channel_host->IsLost()) {
+ context_provider = content::ContextProviderCommandBuffer::Create(
+ CreateGpuProcessViewContext(gpu_channel_host, attrs, 0),
+ "BrowserCompositor");
+ }
+ if (!context_provider.get()) {
+ LOG(ERROR) << "Failed to create 3D context for compositor.";
+ compositor->SetOutputSurface(scoped_ptr<cc::OutputSurface>());
+ }
+
+ cc::ResourceFormat format = cc::RGBA_8888;
+ compositor->SetOutputSurface(make_scoped_ptr(new MailboxOutputSurfaceEfl(
+ context_provider, schedule_draw_factory_.GetWeakPtr(), format)));
+}
+
+scoped_refptr<Reflector> ContextFactoryEfl::CreateReflector(
+ Compositor* mirrored_compositor,
+ Layer* mirroring_layer) {
+ return new Reflector();
+}
+
+void ContextFactoryEfl::RemoveReflector(scoped_refptr<Reflector> reflector) {
+}
+
+void ContextFactoryEfl::OnLostMainThreadSharedContextInsideCallback() {
+}
+
+scoped_refptr<cc::ContextProvider>
+ContextFactoryEfl::SharedMainThreadContextProvider() {
+ if (shared_main_thread_contexts_.get())
+ return shared_main_thread_contexts_;
+
+ blink::WebGraphicsContext3D::Attributes attrs;
+ attrs.depth = false;
+ attrs.stencil = false;
+ attrs.antialias = false;
+ attrs.shareResources = true;
+ attrs.noAutomaticFlushes = true;
+
+ scoped_refptr<content::ContextProviderCommandBuffer> context_provider;
+ content::BrowserGpuChannelHostFactory* factory =
+ content::BrowserGpuChannelHostFactory::instance();
+ content::CauseForGpuLaunch cause = content::
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
+ scoped_refptr<content::GpuChannelHost> gpu_channel_host(
+ factory->EstablishGpuChannelSync(cause));
+ if (gpu_channel_host.get() && !gpu_channel_host->IsLost()) {
+ shared_main_thread_contexts_ = content::ContextProviderCommandBuffer::Create(
+ CreateGpuProcessViewContext(gpu_channel_host, attrs, 0),
+ "Offscreen-MainThread");
+ }
+
+ if (!shared_main_thread_contexts_->BindToCurrentThread())
+ shared_main_thread_contexts_ = NULL;
+ return shared_main_thread_contexts_;
+}
+
+void ContextFactoryEfl::RemoveCompositor(Compositor* compositor) {
+}
+
+bool ContextFactoryEfl::DoesCreateTestContexts() {
+ return false;
+}
+
+cc::SharedBitmapManager* ContextFactoryEfl::GetSharedBitmapManager() {
+ return content::HostSharedBitmapManager::current();
+}
+
+gpu::GpuMemoryBufferManager* ContextFactoryEfl::GetGpuMemoryBufferManager() {
+ return content::BrowserGpuMemoryBufferManager::current();
+}
+
+base::MessageLoopProxy* ContextFactoryEfl::GetCompositorMessageLoop() {
+ return NULL;
+}
+
+scoped_ptr<cc::SurfaceIdAllocator>
+ContextFactoryEfl::CreateSurfaceIdAllocator() {
+ return make_scoped_ptr(
+ new cc::SurfaceIdAllocator(next_surface_id_namespace_++));
+}
+
+} // namespace ui
--- /dev/null
+// Copyright 2015 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPOSITOR_CONTEXT_FACTORY_EFL_H_
+#define COMPOSITOR_CONTEXT_FACTORY_EFL_H_
+
+#include "ui/compositor/compositor.h"
+
+namespace content {
+class ContextProviderCommandBuffer;
+struct ContextFactoryDelegate {
+ // Updates new texture received from mailbox on evas gl surface
+ virtual void GetTextureFromMailbox(gpu::Mailbox* mailbox, gfx::Size size) = 0;
+};
+
+class RenderWidgetHostViewEfl;
+}
+
+namespace webkit {
+namespace gpu {
+class ContextProviderInProcess;
+}
+}
+
+namespace cc_blink{
+class ContextProviderWebContext;
+}
+
+namespace ui {
+
+class ContextFactoryEfl : public ContextFactory {
+ public:
+ ContextFactoryEfl(content::ContextFactoryDelegate* delegate, int surface_id);
+
+ void CreateOutputSurface(base::WeakPtr<Compositor> compositor,
+ bool software_fallback) override;
+
+ scoped_refptr<Reflector> CreateReflector(Compositor* mirrored_compositor,
+ Layer* mirroring_layer) override;
+
+ void RemoveReflector(scoped_refptr<Reflector> reflector) override;
+
+ scoped_refptr<cc::ContextProvider> SharedMainThreadContextProvider() override;
+
+ void RemoveCompositor(Compositor* compositor) override;
+
+ bool DoesCreateTestContexts() override;
+
+ cc::SharedBitmapManager* GetSharedBitmapManager() override;
+
+ gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
+
+ base::MessageLoopProxy* GetCompositorMessageLoop() override;
+
+ scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() override;
+
+ void SetSurfaceID(int surface_id, gfx::AcceleratedWidget widget);
+
+ void GetFrameFromMailbox(gpu::Mailbox* mailbox, gfx::Size size);
+
+ void OnLostMainThreadSharedContextInsideCallback();
+
+ // Resize the display corresponding to this compositor to a particular size.
+ void ResizeDisplay(ui::Compositor* compositor,
+ const gfx::Size& size) override {};
+
+ private:
+ content::ContextFactoryDelegate* delegate_;
+ int surface_id_;
+ uint32_t next_surface_id_namespace_;
+ base::WeakPtrFactory<ContextFactoryEfl> schedule_draw_factory_;
+ scoped_refptr<content::ContextProviderCommandBuffer> shared_main_thread_contexts_;
+};
+
+} // namespace ui
+
+#endif // COMPOSITOR_CONTEXT_FACTORY_EFL_H_
#include "base/trace_event/trace_event.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
+#include "base/thread_task_runner_handle.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "content/common/view_messages.h"
+#include "content/browser/compositor/resize_lock.h"
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/im_context_efl.h"
#include "content/browser/renderer_host/edge_effect.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
+#include "content/browser/renderer_host/context_factory_efl.h"
#include "content/browser/renderer_host/disambiguation_popup_efl.h"
#include "content/browser/renderer_host/web_event_factory_efl.h"
#include "content/browser/renderer_host/input/web_input_event_util.h"
#include "content/common/cursors/webcursor_efl.h"
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
#include "content/public/browser/screen_orientation_dispatcher_host.h"
-#include "content/public/common/content_switches.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/context_factory.h"
#include "content/public/browser/render_process_host.h"
+#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "media/base/video_util.h"
#include "skia/ext/image_operations.h"
#include "ui/events/gestures/gesture_provider_aura.h"
#undef private
#include "ui/events/gestures/gesture_recognizer_impl_efl.h"
+#include "ui/compositor/compositor.h"
#include "ui/gfx/display.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/geometry/rect.h"
selection_acked_on_tap_(false),
was_scrolled_(false),
web_contents_(web_contents),
- single_tap_performed_(false) {
+ single_tap_performed_(false),
+ root_layer_(new ui::Layer(ui::LAYER_SOLID_COLOR)),
+ delegated_frame_host_(new DelegatedFrameHost(this)) {
SetDoubleTapSupportEnabled(touch_events_enabled_);
host_->SetView(this);
+ set_layer_owner_delegate(delegated_frame_host_.get());
+
static bool scale_factor_initialized = false;
if (!scale_factor_initialized) {
std::vector<ui::ScaleFactor> supported_scale_factors;
initializeProgram();
evas_gl_initialized_ = true;
+
+ context_factory_.reset(new ui::ContextFactoryEfl(this, host_->surface_id()));
+ compositor_.reset(new ui::Compositor(GetNativeViewId(),
+ context_factory_.get(),
+ base::ThreadTaskRunnerHandle::Get()));
+ compositor_->SetRootLayer(root_layer_.get());
+ gfx::Size size = GetViewBoundsInPix().size();
+ root_layer_->SetBounds(gfx::Rect(0, 0, size.width(), size.height()));
+ compositor_->SetScaleAndSize(device_scale_factor_, size);
+ compositor_->SetVisible(true);
+}
+
+void RenderWidgetHostViewEfl::ResizeCompositorLayer(int width, int height) {
+ root_layer_->SetBounds(gfx::Rect(0, 0, width, height));
+ compositor_->SetScaleAndSize(device_scale_factor_, gfx::Size(width, height));
}
void RenderWidgetHostViewEfl::CreateNativeSurface(int width, int height) {
host_->SendScreenRects();
host_->WasResized();
//}
+ gfx::Size bounds = GetViewBoundsInPix().size();
+ root_layer_->SetBounds(gfx::Rect(0, 0, bounds.width(), bounds.height()));
+ compositor_->SetScaleAndSize(device_scale_factor_, bounds);
}
void RenderWidgetHostViewEfl::SetBounds(const gfx::Rect& rect) {
- // FIXME: ditto.
- NOTIMPLEMENTED();
+ host_->WasResized();
+ delegated_frame_host_->WasResized();
}
gfx::Vector2dF RenderWidgetHostViewEfl::GetLastScrollOffset() const {
- // FIXME: Aura RWHV sets last_scroll_offset_ in OnSwapCompositorFrame()
- // Other ways to get scroll offset are already removed.
- // We need to switch to the ui::Compositor ASAP!
return last_scroll_offset_;
}
}
bool RenderWidgetHostViewEfl::IsSurfaceAvailableForCopy() const {
- return false;
+ return delegated_frame_host_->CanCopyToBitmap();
}
void RenderWidgetHostViewEfl::Show() {
}
void RenderWidgetHostViewEfl::SetIsLoading(bool is_loading) {
- is_loading_ = is_loading;
UpdateCursor(WebCursor());
if (disambiguation_popup_)
disambiguation_popup_->Dismiss();
void RenderWidgetHostViewEfl::CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
const gfx::Size& output_size,
- const ReadbackRequestCallback& callback,
+ ReadbackRequestCallback& callback,
const SkColorType color_type) {
- NOTIMPLEMENTED();
+ // FIXME(venu.musham): should find a way to do it effectively.
+ delegated_frame_host_->CopyFromCompositingSurface(src_subrect, output_size,
+ callback, color_type);
}
void RenderWidgetHostViewEfl::GetSnapshotAsync(const gfx::Rect& snapshot_area, int request_id) {
// CopyFromCompositingSurfaceToVideoFrame implementation borrowed from Aura port
bool RenderWidgetHostViewEfl::CanSubscribeFrame() const {
- return true;
+ return delegated_frame_host_->CanSubscribeFrame();
}
void RenderWidgetHostViewEfl::BeginFrameSubscription(
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
- frame_subscriber_ = subscriber.Pass();
+ delegated_frame_host_->BeginFrameSubscription(subscriber.Pass());
}
void RenderWidgetHostViewEfl::EndFrameSubscription() {
- idle_frame_subscriber_textures_.clear();
- frame_subscriber_.reset();
+ delegated_frame_host_->EndFrameSubscription();
}
void RenderWidgetHostViewEfl::DidOverscroll(const DidOverscrollParams& params) {
}
bool RenderWidgetHostViewEfl::CanCopyToVideoFrame() const {
- return false;
+ return delegated_frame_host_->CanCopyToVideoFrame();
}
bool RenderWidgetHostViewEfl::HasAcceleratedSurface(const gfx::Size&) {
evas_object_geometry_set(thiz->content_image_elm_host_, x, y, width, height);
evas_object_image_size_set(thiz->content_image_, width, height);
thiz->CreateNativeSurface(width, height);
+ thiz->ResizeCompositorLayer(width, height);
thiz->host_->WasResized();
}
// texture_manager.h with efl GL API wrappers.
extern GLuint GetTextureIdFromTexture(gpu::gles2::Texture* texture);
+void RenderWidgetHostViewEfl::GetTextureFromMailbox(gpu::Mailbox* mailbox,
+ gfx::Size surface_size) {
+ gpu::gles2::MailboxManager* manager = GLSharedContextEfl::GetMailboxManager();
+ gpu::gles2::Texture* texture = manager->ConsumeTexture(*mailbox);
+ if (texture != NULL) {
+ surface_size_ = surface_size;
+ texture_id_ = GetTextureIdFromTexture(texture);
+ evas_object_image_pixels_dirty_set(content_image_, true);
+ evas_render(evas_);
+ }
+}
+
void RenderWidgetHostViewEfl::OnSwapCompositorFrame(
uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) {
cc::CompositorFrameAck ack;
-
- // TODO(prashant.n): Delegated and software frames not supported. So with
+ // TODO(prashant.n): Software frames not supported. So with
// those frames black screen will appear.
+ last_scroll_offset_ = frame->metadata.root_scroll_offset;
+
if (frame->gl_frame_data) {
ack.gl_frame_data = frame->gl_frame_data.Pass();
surface_size_ = ack.gl_frame_data->size;
ack.gl_frame_data->sync_point = 0;
} else if (frame->delegated_frame_data) {
- LOG(ERROR) << "Delegated frame is not supported.";
- cc::TransferableResource::ReturnResources(
- frame->delegated_frame_data->resource_list,
- &ack.resources);
+ // ack is sent by delegated frame host
+ delegated_frame_host_->SwapDelegatedFrame(
+ output_surface_id, frame->delegated_frame_data.Pass(),
+ frame->metadata.device_scale_factor, frame->metadata.latency_info);
+ return;
} else if (frame->software_frame_data) {
LOG(ERROR) << "Software frame is not supported.";
ack.last_software_frame_id = frame->software_frame_data->id;
return gfx::Rect();
}
+///////////////////////////////////////////////////////////////////////////
+// DelegatedFrameHost, public:
+
+ui::Layer* RenderWidgetHostViewEfl::DelegatedFrameHostGetLayer() const {
+ return root_layer_.get();
+}
+
+bool RenderWidgetHostViewEfl::DelegatedFrameHostIsVisible() const {
+ return !host_->is_hidden();
+}
+
+gfx::Size RenderWidgetHostViewEfl::DelegatedFrameHostDesiredSizeInDIP() const{
+ gfx::Rect bounds = GetViewBoundsInPix();
+ return bounds.size();
+}
+
+bool RenderWidgetHostViewEfl::DelegatedFrameCanCreateResizeLock() const {
+ // On Windows and Linux, holding pointer moves will not help throttling
+ // resizes.
+ // TODO(piman): on Windows we need to block (nested message loop?) the
+ // WM_SIZE event. On Linux we need to throttle at the WM level using
+ // _NET_WM_SYNC_REQUESTm .
+ return false;
+}
+
+scoped_ptr<ResizeLock>
+RenderWidgetHostViewEfl::DelegatedFrameHostCreateResizeLock(
+ bool defer_compositor_lock) {
+ ResizeLock* lock = NULL;
+ return scoped_ptr<ResizeLock>(lock);
+}
+
+void RenderWidgetHostViewEfl::DelegatedFrameHostResizeLockWasReleased() {
+ host_->WasResized();
+}
+
+void RenderWidgetHostViewEfl::DelegatedFrameHostSendCompositorSwapAck(
+ int output_surface_id,
+ const cc::CompositorFrameAck& ack) {
+ host_->Send(new ViewMsg_SwapCompositorFrameAck(host_->GetRoutingID(),
+ output_surface_id, ack));
+}
+
+void RenderWidgetHostViewEfl::DelegatedFrameHostSendReclaimCompositorResources(
+ int output_surface_id,
+ const cc::CompositorFrameAck& ack) {
+ host_->Send(new ViewMsg_ReclaimCompositorResources(host_->GetRoutingID(),
+ output_surface_id, ack));
+}
+
+void RenderWidgetHostViewEfl::DelegatedFrameHostOnLostCompositorResources() {
+ host_->ScheduleComposite();
+}
+
+void RenderWidgetHostViewEfl::DelegatedFrameHostUpdateVSyncParameters(
+ const base::TimeTicks& timebase,
+ const base::TimeDelta& interval) {
+ host_->UpdateVSyncParameters(timebase, interval);
+}
} // namespace content
#include "cc/resources/single_release_callback.h"
#include "cc/resources/texture_mailbox.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "content/browser/compositor/delegated_frame_host.h"
#include "content/browser/compositor/image_transport_factory.h"
#include "content/browser/compositor/owned_mailbox.h"
+#include "content/browser/renderer_host/context_factory_efl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "ui/base/ime/composition_text.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/base/selection/selection_controller_efl.h"
+#include "ui/compositor/layer_owner.h"
#include "ui/events/gestures/gesture_types.h"
#include "ui/events/gestures/gesture_recognizer.h"
#include "ui/events/gestures/motion_event_aura.h"
struct ViewHostMsg_HitTestAsyncReply_Params;
namespace ui {
+class Compositor;
class GestureEvent;
class TouchEvent;
}
// RenderWidgetHostView class hierarchy described in render_widget_host_view.h.
class RenderWidgetHostViewEfl
- : public RenderWidgetHostViewBase,
- public ui::GestureConsumer,
- public ui::GestureEventHelper,
- public base::SupportsWeakPtr<RenderWidgetHostViewEfl>,
- public IPC::Sender {
+ : public RenderWidgetHostViewBase,
+ public DelegatedFrameHostClient,
+ public ContextFactoryDelegate,
+ public ui::LayerOwner,
+ public ui::GestureConsumer,
+ public ui::GestureEventHelper,
+ public base::SupportsWeakPtr<RenderWidgetHostViewEfl>,
+ public IPC::Sender {
public:
explicit RenderWidgetHostViewEfl(RenderWidgetHost*, WebContents& web_contents);
void set_magnifier(bool status);
void Init_EvasGL(int width, int height);
+ void ResizeCompositorLayer(int width, int height);
void CreateNativeSurface(int width, int height);
void SetEvasHandler(scoped_refptr<EvasEventHandler> evas_event_handler);
void* user_data);
void OnSnapshotDataReceived(SkBitmap bitmap, int snapshotId);
+ // DelegatedFrameHostClient implementation.
+ ui::Layer* DelegatedFrameHostGetLayer() const override;
+ bool DelegatedFrameHostIsVisible() const override;
+ scoped_ptr<ResizeLock> DelegatedFrameHostCreateResizeLock(
+ bool defer_compositor_lock) override;
+ bool DelegatedFrameCanCreateResizeLock() const override;
+ gfx::Size DelegatedFrameHostDesiredSizeInDIP() const override;
+ void DelegatedFrameHostResizeLockWasReleased() override;
+ void DelegatedFrameHostSendCompositorSwapAck(
+ int output_surface_id,
+ const cc::CompositorFrameAck& ack) override;
+ void DelegatedFrameHostSendReclaimCompositorResources(
+ int output_surface_id,
+ const cc::CompositorFrameAck& ack) override;
+ void DelegatedFrameHostOnLostCompositorResources() override;
+ void DelegatedFrameHostUpdateVSyncParameters(
+ const base::TimeTicks& timebase,
+ const base::TimeDelta& interval) override;
+
protected:
friend class RenderWidgetHostView;
void PaintTextureToSurface(GLuint texture_id);
+ // overrides ContextFactoryDelegate
+ void GetTextureFromMailbox(gpu::Mailbox* mailbox,
+ gfx::Size surface_size) override;
+
RenderWidgetHostImpl* host_;
IMContextEfl* im_context_;
Evas* evas_;
scoped_ptr<bool> restore_showing_large_handle_on_gesture_end_;
IDMap<ScreenshotCapturedCallback, IDMapOwnPointer> screen_capture_cb_map_;
+ scoped_ptr<ui::Compositor> compositor_;
+ scoped_ptr<ui::Layer> root_layer_;
+ scoped_ptr<DelegatedFrameHost> delegated_frame_host_;
+ scoped_ptr<ui::ContextFactory> context_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewEfl);
};
'browser/web_contents/web_drag_source_efl.cc',
'browser/tracing/tracing_controller_efl.h',
'browser/tracing/tracing_controller_efl.cc',
+ 'browser/renderer_host/context_factory_efl.h',
+ 'browser/renderer_host/context_factory_efl.cc',
'browser/renderer_host/disambiguation_popup_efl.h',
'browser/renderer_host/disambiguation_popup_efl.cc',
'browser/renderer_host/edge_effect.h',
#include "cc/base/switches.h"
#include "content/common/paths_efl.h"
#include "content/public/common/content_switches.h"
+#include "ui/compositor/compositor_switches.h"
#include "ui/gfx/screen_efl.h"
#include "ui/gfx/switches.h"
#include "ui/gl/gl_switches.h"
void AppendPortParams(base::CommandLine& cmdline) {
cmdline.AppendSwitchASCII(switches::kUseGL,
gfx::kGLImplementationEGLName);
- cmdline.AppendSwitch(cc::switches::kCompositeToMailbox);
cmdline.AppendSwitch(switches::kInProcessGPU);
- cmdline.AppendSwitch(switches::kDisableDelegatedRenderer);
+ cmdline.AppendSwitch(switches::kUIDisableThreadedCompositing);
+ cmdline.AppendSwitch(switches::kEnableDelegatedRenderer);
}
} // namespace efl