diff --git a/shell/BUILD.gn b/shell/BUILD.gn index 80c894f3f3e..3494b85863d 100644 --- a/shell/BUILD.gn +++ b/shell/BUILD.gn @@ -23,8 +23,12 @@ generate_jni("jni_headers") { shared_library("sky_shell") { sources = [ - "gpu_driver.cc", - "gpu_driver.h", + "gpu/ganesh_context.cc", + "gpu/ganesh_context.h", + "gpu/ganesh_surface.cc", + "gpu/ganesh_surface.h", + "gpu/rasterizer.cc", + "gpu/rasterizer.h", "library_loader.cc", "shell.cc", "shell.h", @@ -39,6 +43,8 @@ shared_library("sky_shell") { deps = [ "//base", "//build/config/sanitizers:deps", + "//skia", + "//ui/gfx/geometry", "//ui/gl", ":jni_headers", ] diff --git a/shell/gpu/ganesh_context.cc b/shell/gpu/ganesh_context.cc new file mode 100644 index 00000000000..77833b34c76 --- /dev/null +++ b/shell/gpu/ganesh_context.cc @@ -0,0 +1,42 @@ +// Copyright 2015 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 "sky/shell/gpu/ganesh_context.h" + +#include "base/logging.h" +#include "third_party/skia/include/gpu/gl/GrGLInterface.h" +#include "ui/gl/gl_bindings_skia_in_process.h" + +namespace sky { +namespace shell { +namespace { + +// The limit of the number of GPU resources we hold in the GrContext's +// GPU cache. +const int kMaxGaneshResourceCacheCount = 2048; + +// The limit of the bytes allocated toward GPU resources in the GrContext's +// GPU cache. +const size_t kMaxGaneshResourceCacheBytes = 96 * 1024 * 1024; + +} // namespace + +GaneshContext::GaneshContext(scoped_refptr gl_context) + : gl_context_(gl_context) { + skia::RefPtr interface = + skia::AdoptRef(gfx::CreateInProcessSkiaGLBinding()); + DCHECK(interface); + + gr_context_ = skia::AdoptRef(GrContext::Create( + kOpenGL_GrBackend, reinterpret_cast(interface.get()))); + DCHECK(gr_context_); + gr_context_->setResourceCacheLimits(kMaxGaneshResourceCacheCount, + kMaxGaneshResourceCacheBytes); +} + +GaneshContext::~GaneshContext() { +} + +} // namespace shell +} // namespace sky diff --git a/shell/gpu/ganesh_context.h b/shell/gpu/ganesh_context.h new file mode 100644 index 00000000000..b35158ed3ec --- /dev/null +++ b/shell/gpu/ganesh_context.h @@ -0,0 +1,37 @@ +// Copyright 2015 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 SKY_SHELL_GPU_GANESH_CONTEXT_H_ +#define SKY_SHELL_GPU_GANESH_CONTEXT_H_ + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "skia/ext/refptr.h" +#include "third_party/skia/include/gpu/GrContext.h" +#include "ui/gl/gl_context.h" + +namespace sky { +namespace shell { + +// GaneshContext holds the top-level context object for Ganesh (known as +// GrContext). We construct the GrContext using the OpenGL interface provided by +// gfx::GLContext. +class GaneshContext { + public: + explicit GaneshContext(scoped_refptr gl_context); + ~GaneshContext(); + + GrContext* gr() const { return gr_context_.get(); } + + private: + scoped_refptr gl_context_; + skia::RefPtr gr_context_; + + DISALLOW_COPY_AND_ASSIGN(GaneshContext); +}; + +} // namespace shell +} // namespace sky + +#endif // SKY_SHELL_GPU_GANESH_CONTEXT_H_ diff --git a/shell/gpu/ganesh_surface.cc b/shell/gpu/ganesh_surface.cc new file mode 100644 index 00000000000..fb15738d374 --- /dev/null +++ b/shell/gpu/ganesh_surface.cc @@ -0,0 +1,30 @@ +// Copyright 2015 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 "sky/shell/gpu/ganesh_surface.h" + +#include "base/logging.h" +#include "third_party/skia/include/gpu/GrContext.h" + +namespace sky { +namespace shell { + +GaneshSurface::GaneshSurface(GaneshContext* context, const gfx::Size& size) { + GrBackendRenderTargetDesc desc; + desc.fWidth = size.width(); + desc.fHeight = size.height(); + desc.fConfig = kSkia8888_GrPixelConfig; + desc.fOrigin = kTopLeft_GrSurfaceOrigin; + + auto target = skia::AdoptRef(context->gr()->wrapBackendRenderTarget(desc)); + DCHECK(target); + surface_ = skia::AdoptRef(SkSurface::NewRenderTargetDirect(target.get())); + DCHECK(surface_); +} + +GaneshSurface::~GaneshSurface() { +} + +} // namespace shell +} // namespace sky diff --git a/shell/gpu/ganesh_surface.h b/shell/gpu/ganesh_surface.h new file mode 100644 index 00000000000..9a6ef1490fd --- /dev/null +++ b/shell/gpu/ganesh_surface.h @@ -0,0 +1,39 @@ +// Copyright 2015 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 SKY_SHELL_GPU_GANESH_SURFACE_H_ +#define SKY_SHELL_GPU_GANESH_SURFACE_H_ + +#include "base/memory/scoped_ptr.h" +#include "skia/ext/refptr.h" +#include "sky/shell/gpu/ganesh_context.h" +#include "third_party/skia/include/core/SkSurface.h" +#include "ui/gfx/geometry/size.h" + +namespace sky { +namespace shell { + +// GaneshSurface holds an SkSurface configured to render with Ganesh. Using the +// provided GaneshContext, GaneshSurface wraps an SkSurface around FBO 0 so that +// you can use |canvas()| to draw to FBO 0. +class GaneshSurface { + public: + GaneshSurface(GaneshContext* context, const gfx::Size& size); + ~GaneshSurface(); + + SkCanvas* canvas() const { return surface_->getCanvas(); } + gfx::Size size() const { + return gfx::Size(surface_->width(), surface_->height()); + } + + private: + skia::RefPtr surface_; + + DISALLOW_COPY_AND_ASSIGN(GaneshSurface); +}; + +} // namespace shell +} // namespace sky + +#endif // SKY_SHELL_GPU_GANESH_SURFACE_H_ diff --git a/shell/gpu/rasterizer.cc b/shell/gpu/rasterizer.cc new file mode 100644 index 00000000000..8e4b49282e3 --- /dev/null +++ b/shell/gpu/rasterizer.cc @@ -0,0 +1,71 @@ +// Copyright 2015 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 "sky/shell/gpu/rasterizer.h" + +#include "sky/shell/gpu/ganesh_context.h" +#include "sky/shell/gpu/ganesh_surface.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkPicture.h" +#include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_context.h" +#include "ui/gl/gl_share_group.h" +#include "ui/gl/gl_surface.h" + +namespace sky { +namespace shell { +namespace { + +gfx::Size GetSize(SkPicture* picture) { + const SkRect& rect = picture->cullRect(); + return gfx::Size(rect.width(), rect.height()); +} + +} // namespace + +Rasterizer::Rasterizer() : weak_factory_(this) { +} + +Rasterizer::~Rasterizer() { +} + +base::WeakPtr Rasterizer::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + +void Rasterizer::Init(gfx::AcceleratedWidget widget) { + share_group_ = make_scoped_refptr(new gfx::GLShareGroup()); + surface_ = gfx::GLSurface::CreateViewGLSurface(widget); + CHECK(surface_) << "GLSurface required."; + CHECK(CreateGLContext()) << "GLContext required."; +} + +void Rasterizer::Draw(skia::RefPtr picture) { + // TODO(abarth): We should handle losing the GL context. + CHECK(context_->MakeCurrent(surface_.get())); + EnsureGaneshSurface(GetSize(picture.get())); + + SkCanvas* canvas = ganesh_surface_->canvas(); + canvas->drawPicture(picture.get()); + canvas->flush(); + + surface_->SwapBuffers(); +} + +bool Rasterizer::CreateGLContext() { + context_ = gfx::GLContext::CreateGLContext(share_group_.get(), surface_.get(), + gfx::PreferIntegratedGpu); + if (!context_) + return false; + ganesh_context_.reset(new GaneshContext(context_.get())); + return true; +} + +void Rasterizer::EnsureGaneshSurface(const gfx::Size& size) { + if (!ganesh_surface_ || ganesh_surface_->size() != size) + ganesh_surface_.reset(new GaneshSurface(ganesh_context_.get(), size)); +} + +} // namespace shell +} // namespace sky diff --git a/shell/gpu/rasterizer.h b/shell/gpu/rasterizer.h new file mode 100644 index 00000000000..302e38d9e3c --- /dev/null +++ b/shell/gpu/rasterizer.h @@ -0,0 +1,56 @@ +// Copyright 2015 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 SKY_SHELL_GPU_RASTERIZER_H_ +#define SKY_SHELL_GPU_RASTERIZER_H_ + +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "skia/ext/refptr.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/native_widget_types.h" + +class SkPicture; + +namespace gfx { +class GLContext; +class GLShareGroup; +class GLSurface; +} + +namespace sky { +namespace shell { +class GaneshContext; +class GaneshSurface; + +class Rasterizer { + public: + explicit Rasterizer(); + ~Rasterizer(); + + base::WeakPtr GetWeakPtr(); + + void Init(gfx::AcceleratedWidget widget); + void Draw(skia::RefPtr picture); + + private: + bool CreateGLContext(); + void EnsureGaneshSurface(const gfx::Size& size); + + scoped_refptr share_group_; + scoped_refptr surface_; + scoped_refptr context_; + + scoped_ptr ganesh_context_; + scoped_ptr ganesh_surface_; + + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(Rasterizer); +}; + +} // namespace shell +} // namespace sky + +#endif // SKY_SHELL_GPU_RASTERIZER_H_ diff --git a/shell/gpu_driver.cc b/shell/gpu_driver.cc deleted file mode 100644 index 3101f8e1137..00000000000 --- a/shell/gpu_driver.cc +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2015 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 "sky/shell/gpu_driver.h" - -#include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_context.h" -#include "ui/gl/gl_share_group.h" -#include "ui/gl/gl_surface.h" - -namespace sky { -namespace shell { - -GPUDriver::GPUDriver() : weak_factory_(this) { -} - -GPUDriver::~GPUDriver() { -} - -base::WeakPtr GPUDriver::GetWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - -void GPUDriver::Init(gfx::AcceleratedWidget widget) { - share_group_ = make_scoped_refptr(new gfx::GLShareGroup()); - - surface_ = gfx::GLSurface::CreateViewGLSurface(widget); - CHECK(surface_) << "GLSurface required."; - - context_ = gfx::GLContext::CreateGLContext(share_group_.get(), surface_.get(), - gfx::PreferIntegratedGpu); - CHECK(context_) << "GLContext required."; - - CHECK(context_->MakeCurrent(surface_.get())); - - glClearColor(0.0, 1.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - surface_->SwapBuffers(); -} - -} // namespace shell -} // namespace sky diff --git a/shell/gpu_driver.h b/shell/gpu_driver.h deleted file mode 100644 index 5201dcbaf24..00000000000 --- a/shell/gpu_driver.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015 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 SKY_SHELL_GPU_DRIVER_H_ -#define SKY_SHELL_GPU_DRIVER_H_ - -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "ui/gfx/native_widget_types.h" - -namespace gfx { -class GLContext; -class GLShareGroup; -class GLSurface; -} - -namespace sky { -namespace shell { - -class GPUDriver { - public: - explicit GPUDriver(); - ~GPUDriver(); - - base::WeakPtr GetWeakPtr(); - - void Init(gfx::AcceleratedWidget widget); - - private: - scoped_refptr share_group_; - scoped_refptr surface_; - scoped_refptr context_; - - base::WeakPtrFactory weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(GPUDriver); -}; - -} // namespace shell -} // namespace sky - -#endif // SKY_SHELL_GPU_DRIVER_H_ diff --git a/shell/shell.cc b/shell/shell.cc index 3a465d008fa..757a9e91c2e 100644 --- a/shell/shell.cc +++ b/shell/shell.cc @@ -22,7 +22,7 @@ Shell::~Shell() { void Shell::Init() { gpu_thread_.reset(new base::Thread("gpu_thread")); gpu_thread_->Start(); - gpu_driver_.reset(new GPUDriver()); + rasterizer_.reset(new Rasterizer()); view_.reset(new SkyView(this)); view_->Init(); @@ -31,7 +31,7 @@ void Shell::Init() { void Shell::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) { gpu_thread_->message_loop()->PostTask( FROM_HERE, - base::Bind(&GPUDriver::Init, gpu_driver_->GetWeakPtr(), widget)); + base::Bind(&Rasterizer::Init, rasterizer_->GetWeakPtr(), widget)); } void Shell::OnDestroyed() { diff --git a/shell/shell.h b/shell/shell.h index fdf65f959a2..eb69f669b06 100644 --- a/shell/shell.h +++ b/shell/shell.h @@ -8,7 +8,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "sky/shell/gpu_driver.h" +#include "sky/shell/gpu/rasterizer.h" #include "sky/shell/sky_view.h" namespace base { @@ -35,7 +35,7 @@ class Shell : public SkyView::Delegate { scoped_ptr gpu_thread_; scoped_ptr view_; - scoped_ptr gpu_driver_; + scoped_ptr rasterizer_; DISALLOW_COPY_AND_ASSIGN(Shell); };