mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Teach SkyShell how to draw with Ganesh
This CL adds support to SkyShell for drawing with Ganesh. Currently, we don't actually create any SkPictures to draw, but that will come in a later CL. R=eseidel@chromium.org Review URL: https://codereview.chromium.org/891143002
This commit is contained in:
parent
db0e9021c9
commit
3b32bd6a72
@ -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",
|
||||
]
|
||||
|
||||
42
shell/gpu/ganesh_context.cc
Normal file
42
shell/gpu/ganesh_context.cc
Normal file
@ -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<gfx::GLContext> gl_context)
|
||||
: gl_context_(gl_context) {
|
||||
skia::RefPtr<GrGLInterface> interface =
|
||||
skia::AdoptRef(gfx::CreateInProcessSkiaGLBinding());
|
||||
DCHECK(interface);
|
||||
|
||||
gr_context_ = skia::AdoptRef(GrContext::Create(
|
||||
kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(interface.get())));
|
||||
DCHECK(gr_context_);
|
||||
gr_context_->setResourceCacheLimits(kMaxGaneshResourceCacheCount,
|
||||
kMaxGaneshResourceCacheBytes);
|
||||
}
|
||||
|
||||
GaneshContext::~GaneshContext() {
|
||||
}
|
||||
|
||||
} // namespace shell
|
||||
} // namespace sky
|
||||
37
shell/gpu/ganesh_context.h
Normal file
37
shell/gpu/ganesh_context.h
Normal file
@ -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<gfx::GLContext> gl_context);
|
||||
~GaneshContext();
|
||||
|
||||
GrContext* gr() const { return gr_context_.get(); }
|
||||
|
||||
private:
|
||||
scoped_refptr<gfx::GLContext> gl_context_;
|
||||
skia::RefPtr<GrContext> gr_context_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(GaneshContext);
|
||||
};
|
||||
|
||||
} // namespace shell
|
||||
} // namespace sky
|
||||
|
||||
#endif // SKY_SHELL_GPU_GANESH_CONTEXT_H_
|
||||
30
shell/gpu/ganesh_surface.cc
Normal file
30
shell/gpu/ganesh_surface.cc
Normal file
@ -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
|
||||
39
shell/gpu/ganesh_surface.h
Normal file
39
shell/gpu/ganesh_surface.h
Normal file
@ -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<SkSurface> surface_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(GaneshSurface);
|
||||
};
|
||||
|
||||
} // namespace shell
|
||||
} // namespace sky
|
||||
|
||||
#endif // SKY_SHELL_GPU_GANESH_SURFACE_H_
|
||||
71
shell/gpu/rasterizer.cc
Normal file
71
shell/gpu/rasterizer.cc
Normal file
@ -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> 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<SkPicture> 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
|
||||
56
shell/gpu/rasterizer.h
Normal file
56
shell/gpu/rasterizer.h
Normal file
@ -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<Rasterizer> GetWeakPtr();
|
||||
|
||||
void Init(gfx::AcceleratedWidget widget);
|
||||
void Draw(skia::RefPtr<SkPicture> picture);
|
||||
|
||||
private:
|
||||
bool CreateGLContext();
|
||||
void EnsureGaneshSurface(const gfx::Size& size);
|
||||
|
||||
scoped_refptr<gfx::GLShareGroup> share_group_;
|
||||
scoped_refptr<gfx::GLSurface> surface_;
|
||||
scoped_refptr<gfx::GLContext> context_;
|
||||
|
||||
scoped_ptr<GaneshContext> ganesh_context_;
|
||||
scoped_ptr<GaneshSurface> ganesh_surface_;
|
||||
|
||||
base::WeakPtrFactory<Rasterizer> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Rasterizer);
|
||||
};
|
||||
|
||||
} // namespace shell
|
||||
} // namespace sky
|
||||
|
||||
#endif // SKY_SHELL_GPU_RASTERIZER_H_
|
||||
@ -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> 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
|
||||
@ -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<GPUDriver> GetWeakPtr();
|
||||
|
||||
void Init(gfx::AcceleratedWidget widget);
|
||||
|
||||
private:
|
||||
scoped_refptr<gfx::GLShareGroup> share_group_;
|
||||
scoped_refptr<gfx::GLSurface> surface_;
|
||||
scoped_refptr<gfx::GLContext> context_;
|
||||
|
||||
base::WeakPtrFactory<GPUDriver> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(GPUDriver);
|
||||
};
|
||||
|
||||
} // namespace shell
|
||||
} // namespace sky
|
||||
|
||||
#endif // SKY_SHELL_GPU_DRIVER_H_
|
||||
@ -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() {
|
||||
|
||||
@ -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<base::Thread> gpu_thread_;
|
||||
|
||||
scoped_ptr<SkyView> view_;
|
||||
scoped_ptr<GPUDriver> gpu_driver_;
|
||||
scoped_ptr<Rasterizer> rasterizer_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Shell);
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user