diff --git a/mojo/skia/BUILD.gn b/mojo/skia/BUILD.gn index a5021095c40..60baa2f9920 100644 --- a/mojo/skia/BUILD.gn +++ b/mojo/skia/BUILD.gn @@ -6,8 +6,14 @@ source_set("skia") { sources = [ "ganesh_context.cc", "ganesh_context.h", - "ganesh_surface.cc", - "ganesh_surface.h", + "ganesh_framebuffer_surface.cc", + "ganesh_framebuffer_surface.h", + "ganesh_image_factory.cc", + "ganesh_image_factory.h", + "ganesh_texture_surface.cc", + "ganesh_texture_surface.h", + "type_converters.cc", + "type_converters.h", ] deps = [ @@ -15,6 +21,8 @@ source_set("skia") { "//base", "//mojo/gpu", "//mojo/public/c/gpu", + "//mojo/public/c/gpu:MGL", + "//mojo/services/geometry/interfaces", "//skia", ] } @@ -26,6 +34,7 @@ source_set("skia_bindings") { ] deps = [ "//mojo/public/c/gpu", + "//mojo/public/c/gpu:GLES2", "//skia", ] } diff --git a/mojo/skia/ganesh_context.cc b/mojo/skia/ganesh_context.cc index b0da5aa66f3..735a902ca49 100644 --- a/mojo/skia/ganesh_context.cc +++ b/mojo/skia/ganesh_context.cc @@ -9,61 +9,80 @@ #include "third_party/skia/include/gpu/gl/GrGLInterface.h" namespace mojo { -namespace { +namespace skia { // The limit of the number of GPU resources we hold in the GrContext's // GPU cache. -const int kMaxGaneshResourceCacheCount = 2048; +constexpr 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; - -} - -GaneshContext::Scope::Scope(GaneshContext* context) - : previous_(MGLGetCurrentContext()) { - context->gl_context_->MakeCurrent(); -} - -GaneshContext::Scope::~Scope() { - MGLMakeCurrent(previous_); -} +constexpr size_t kMaxGaneshResourceCacheBytes = 96 * 1024 * 1024; GaneshContext::GaneshContext(base::WeakPtr gl_context) : gl_context_(gl_context) { DCHECK(gl_context_); gl_context_->AddObserver(this); + Scope scope(this); - skia::RefPtr interface = - skia::AdoptRef(skia_bindings::CreateMojoSkiaGLBinding()); + ::skia::RefPtr interface = + ::skia::AdoptRef(CreateMojoSkiaGLBinding()); DCHECK(interface); - context_ = skia::AdoptRef(GrContext::Create( + gr_context_ = ::skia::AdoptRef(GrContext::Create( kOpenGL_GrBackend, reinterpret_cast(interface.get()))); - DCHECK(context_); - context_->setResourceCacheLimits(kMaxGaneshResourceCacheCount, - kMaxGaneshResourceCacheBytes); + DCHECK(gr_context_); + + gr_context_->setResourceCacheLimits(kMaxGaneshResourceCacheCount, + kMaxGaneshResourceCacheBytes); } GaneshContext::~GaneshContext() { - if (context_) { - Scope scope(this); - context_.clear(); - } - if (gl_context_.get()) + if (gl_context_) gl_context_->RemoveObserver(this); -} -bool GaneshContext::InScope() const { - return gl_context_->IsCurrent(); + ReleaseContext(); } void GaneshContext::OnContextLost() { - context_->abandonContext(); - context_.clear(); + ReleaseContext(); +} + +void GaneshContext::ReleaseContext() { + Scope(this); + gr_context_->abandonContext(); + gr_context_.clear(); gl_context_.reset(); } +void GaneshContext::EnterScope() { + CHECK(!scope_entered_); + scope_entered_ = true; + + if (gl_context_) { + previous_mgl_context_ = MGLGetCurrentContext(); + gl_context_->MakeCurrent(); + + // Reset the Ganesh context when entering its scope in case the caller + // performed low-level GL operations which might interfere with Ganesh's + // state expectations. + if (gr_context_) + gr_context_->resetContext(); + } +} + +void GaneshContext::ExitScope() { + CHECK(scope_entered_); + scope_entered_ = false; + + // Flush the Ganesh context when exiting its scope. + if (gr_context_) + gr_context_->flush(); + + MGLMakeCurrent(previous_mgl_context_); + previous_mgl_context_ = MGL_NO_CONTEXT; +} + +} // namespace skia } // namespace mojo diff --git a/mojo/skia/ganesh_context.h b/mojo/skia/ganesh_context.h index f1d5d86aa67..e3f72db4237 100644 --- a/mojo/skia/ganesh_context.h +++ b/mojo/skia/ganesh_context.h @@ -6,43 +6,85 @@ #define MOJO_SKIA_GANESH_CONTEXT_H_ #include "base/basictypes.h" -#include "base/memory/ref_counted.h" +#include "base/logging.h" +#include "base/memory/weak_ptr.h" #include "mojo/gpu/gl_context.h" #include "skia/ext/refptr.h" #include "third_party/skia/include/gpu/GrContext.h" namespace mojo { +namespace skia { +// Binds a Ganesh rendering context to a GL context. +// +// This object is not thread-safe. class GaneshContext : public GLContext::Observer { public: + // RAII style helper for executing code within a Ganesh environment. + // + // Note that Ganesh assumes that it owns the state of the GL Context + // for the duration while the scope is active. Take care not to perform + // any significant low-level GL operations while in the Ganesh scope + // which might disrupt what Ganesh is doing! + // + // Recursively entering the scope of a particular GaneshContext is not + // allowed. class Scope { public: - explicit Scope(GaneshContext* context); - ~Scope(); + // Upon entry to the scope, makes the GL context active and resets + // the Ganesh context state. + explicit Scope(GaneshContext* context) : context_(context) { + DCHECK(context_); + context_->EnterScope(); + } + + // Upon exit from the scope, flushes the Ganesh context state and + // restores the prior GL context. + ~Scope() { context_->ExitScope(); } + + // Gets the underlying GL context, may be null if the context was lost. + // + // Be careful when manipulating the GL context from within a Ganesh + // scope since the Ganesh renderer caches GL state. Queries are safe + // but operations which modify the state of the GL context, such as binding + // textures, should be followed by a call to |GrContext::resetContext| + // before performing other Ganesh related actions within the scope. + const base::WeakPtr& gl_context() const { + return context_->gl_context_; + } + + // Gets the Ganesh rendering context, may be null if the context was lost. + GrContext* gr_context() const { return context_->gr_context_.get(); } private: - MGLContext previous_; + GaneshContext* context_; + + DISALLOW_COPY_AND_ASSIGN(Scope); }; explicit GaneshContext(base::WeakPtr gl_context); ~GaneshContext() override; - void MakeCurrent(); - GrContext* gr() const { - DCHECK(InScope()); - return context_.get(); - } + // Gets the underlying GL context. + const base::WeakPtr& gl_context() const { return gl_context_; } private: - bool InScope() const; void OnContextLost() override; + void ReleaseContext(); + + void EnterScope(); + void ExitScope(); base::WeakPtr gl_context_; - skia::RefPtr context_; + ::skia::RefPtr gr_context_; + + bool scope_entered_ = false; + MGLContext previous_mgl_context_ = MGL_NO_CONTEXT; DISALLOW_COPY_AND_ASSIGN(GaneshContext); }; +} // namespace skia } // namespace mojo #endif // MOJO_SKIA_GANESH_CONTEXT_H_ diff --git a/mojo/skia/ganesh_framebuffer_surface.cc b/mojo/skia/ganesh_framebuffer_surface.cc new file mode 100644 index 00000000000..c8ad676b8df --- /dev/null +++ b/mojo/skia/ganesh_framebuffer_surface.cc @@ -0,0 +1,44 @@ +// 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 "mojo/skia/ganesh_framebuffer_surface.h" + +#include + +#include "base/logging.h" + +namespace mojo { +namespace skia { + +GaneshFramebufferSurface::GaneshFramebufferSurface( + const GaneshContext::Scope& scope) { + GLint samples = 0; + glGetIntegerv(GL_SAMPLES, &samples); + GLint stencil_bits = 0; + glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); + GLint framebuffer_binding = 0; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer_binding); + GLint viewport[4] = {0, 0, 0, 0}; + glGetIntegerv(GL_VIEWPORT, viewport); + DCHECK(viewport[2] > 0); + DCHECK(viewport[3] > 0); + + GrBackendRenderTargetDesc desc; + desc.fWidth = viewport[2]; + desc.fHeight = viewport[3]; + desc.fConfig = kSkia8888_GrPixelConfig; + desc.fOrigin = kBottomLeft_GrSurfaceOrigin; + desc.fSampleCnt = samples; + desc.fStencilBits = stencil_bits; + desc.fRenderTargetHandle = framebuffer_binding; + + surface_ = ::skia::AdoptRef( + SkSurface::NewFromBackendRenderTarget(scope.gr_context(), desc, nullptr)); + DCHECK(surface_); +} + +GaneshFramebufferSurface::~GaneshFramebufferSurface() {} + +} // namespace skia +} // namespace mojo diff --git a/mojo/skia/ganesh_framebuffer_surface.h b/mojo/skia/ganesh_framebuffer_surface.h new file mode 100644 index 00000000000..99ab1497100 --- /dev/null +++ b/mojo/skia/ganesh_framebuffer_surface.h @@ -0,0 +1,38 @@ +// 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 MOJO_SKIA_GANESH_FRAMEBUFFER_SURFACE_H_ +#define MOJO_SKIA_GANESH_FRAMEBUFFER_SURFACE_H_ + +#include "base/macros.h" +#include "mojo/skia/ganesh_context.h" +#include "skia/ext/refptr.h" +#include "third_party/skia/include/core/SkSurface.h" + +namespace mojo { +namespace skia { + +// This class represents an SkSurface backed by a GL framebuffer, which is +// appropriate for use with Ganesh. This is useful for rendering Skia +// commands directly to the display framebuffer. +class GaneshFramebufferSurface { + public: + // Creates a surface that wraps the currently bound GL framebuffer. + // The size of the surface is determined by querying the current viewport. + explicit GaneshFramebufferSurface(const GaneshContext::Scope& scope); + ~GaneshFramebufferSurface(); + + SkSurface* surface() const { return surface_.get(); } + SkCanvas* canvas() const { return surface_->getCanvas(); } + + private: + ::skia::RefPtr surface_; + + DISALLOW_COPY_AND_ASSIGN(GaneshFramebufferSurface); +}; + +} // namespace skia +} // namespace mojo + +#endif // MOJO_SKIA_GANESH_FRAMEBUFFER_SURFACE_H_ diff --git a/mojo/skia/ganesh_image_factory.cc b/mojo/skia/ganesh_image_factory.cc new file mode 100644 index 00000000000..5300d99f40e --- /dev/null +++ b/mojo/skia/ganesh_image_factory.cc @@ -0,0 +1,95 @@ +// 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 GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES +#endif + +#include "mojo/skia/ganesh_image_factory.h" + +#include "base/logging.h" +#include "third_party/skia/include/core/SkImage.h" +#include "third_party/skia/include/gpu/GrContext.h" +#include "third_party/skia/include/gpu/GrTextureProvider.h" +#include "third_party/skia/include/gpu/gl/GrGLTypes.h" + +namespace mojo { +namespace skia { +namespace { +void ReleaseThunk(void* data) { + auto release_callback = static_cast(data); + release_callback->Run(); + delete release_callback; +} +} // namespace + +::skia::RefPtr CreateImageFromTexture( + const GaneshContext::Scope& scope, + uint32_t texture_id, + uint32_t width, + uint32_t height, + const base::Closure& release_callback) { + DCHECK(texture_id); + DCHECK(width); + DCHECK(height); + + // TODO(jeffbrown): Give the caller more control over these parameters. + GrGLTextureInfo info; + info.fTarget = GL_TEXTURE_2D; + info.fID = texture_id; + + GrBackendTextureDesc desc; + desc.fFlags = kRenderTarget_GrBackendTextureFlag; + desc.fWidth = width; + desc.fHeight = height; + desc.fConfig = kSkia8888_GrPixelConfig; + desc.fOrigin = kTopLeft_GrSurfaceOrigin; + desc.fTextureHandle = reinterpret_cast(&info); + return ::skia::AdoptRef(SkImage::NewFromTexture( + scope.gr_context(), desc, kPremul_SkAlphaType, &ReleaseThunk, + new base::Closure(release_callback))); +} + +MailboxTextureImageGenerator::MailboxTextureImageGenerator( + const GLbyte mailbox_name[GL_MAILBOX_SIZE_CHROMIUM], + GLuint sync_point, + uint32_t width, + uint32_t height) + : SkImageGenerator(SkImageInfo::MakeN32Premul(width, height)), + sync_point_(sync_point) { + DCHECK(mailbox_name); + memcpy(mailbox_name_, mailbox_name, GL_MAILBOX_SIZE_CHROMIUM); +} + +MailboxTextureImageGenerator::~MailboxTextureImageGenerator() {} + +GrTexture* MailboxTextureImageGenerator::onGenerateTexture( + GrContext* context, + const SkIRect* subset) { + if (sync_point_) + glWaitSyncPointCHROMIUM(sync_point_); + + GLuint texture_id = + glCreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox_name_); + if (!texture_id) + return nullptr; + + // TODO(jeffbrown): Give the caller more control over these parameters. + GrGLTextureInfo info; + info.fTarget = GL_TEXTURE_2D; + info.fID = texture_id; + + GrBackendTextureDesc desc; + desc.fFlags = kRenderTarget_GrBackendTextureFlag; + desc.fWidth = getInfo().width(); + desc.fHeight = getInfo().height(); + desc.fConfig = kSkia8888_GrPixelConfig; + desc.fOrigin = kTopLeft_GrSurfaceOrigin; + desc.fTextureHandle = reinterpret_cast(&info); + return context->textureProvider()->wrapBackendTexture(desc, + kAdopt_GrWrapOwnership); +} + +} // namespace skia +} // namespace mojo diff --git a/mojo/skia/ganesh_image_factory.h b/mojo/skia/ganesh_image_factory.h new file mode 100644 index 00000000000..ae4bfc037b1 --- /dev/null +++ b/mojo/skia/ganesh_image_factory.h @@ -0,0 +1,56 @@ +// 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 MOJO_SKIA_GANESH_IMAGE_FACTORY_H_ +#define MOJO_SKIA_GANESH_IMAGE_FACTORY_H_ + +#include +#include + +#include "base/callback.h" +#include "mojo/skia/ganesh_context.h" +#include "skia/ext/refptr.h" +#include "third_party/skia/include/core/SkImageGenerator.h" + +class SkImage; + +namespace mojo { +namespace skia { + +// Creates an SkImage from a GL texture. +// The underlying texture must be kept alive for as long as the SkImage exists. +// Invokes |release_callback| when the SkImage is deleted. +::skia::RefPtr CreateImageFromTexture( + const GaneshContext::Scope& scope, + uint32_t texture_id, + uint32_t width, + uint32_t height, + const base::Closure& release_callback); + +// Generates backing content for SkImages from a texture mailbox. +// If |sync_point| is non-zero, inserts a sync point into the command stream +// before the image is first drawn. +// It is the responsibility of the client of this class to ensure that +// the mailbox name is valid at the time when the image is being drawn. +class MailboxTextureImageGenerator : public SkImageGenerator { + public: + MailboxTextureImageGenerator( + const GLbyte mailbox_name[GL_MAILBOX_SIZE_CHROMIUM], + GLuint sync_point, + uint32_t width, + uint32_t height); + ~MailboxTextureImageGenerator() override; + + GrTexture* onGenerateTexture(GrContext* context, + const SkIRect* subset) override; + + private: + GLbyte mailbox_name_[GL_MAILBOX_SIZE_CHROMIUM]; + GLuint sync_point_; +}; + +} // namespace skia +} // namespace mojo + +#endif // MOJO_SKIA_GANESH_IMAGE_FACTORY_H_ diff --git a/mojo/skia/ganesh_surface.cc b/mojo/skia/ganesh_surface.cc deleted file mode 100644 index 11fe502cb82..00000000000 --- a/mojo/skia/ganesh_surface.cc +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2014 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 "mojo/skia/ganesh_surface.h" - -namespace mojo { - -GaneshSurface::GaneshSurface(GaneshContext* context, - scoped_ptr texture) - : texture_(texture.Pass()) { - GrBackendTextureDesc desc; - desc.fFlags = kRenderTarget_GrBackendTextureFlag; - desc.fWidth = texture_->size().width; - desc.fHeight = texture_->size().height; - desc.fConfig = kSkia8888_GrPixelConfig; - desc.fOrigin = kTopLeft_GrSurfaceOrigin; - desc.fTextureHandle = texture_->texture_id(); - DCHECK(texture_->texture_id()); - - auto gr_texture = skia::AdoptRef( - context->gr()->textureProvider()->wrapBackendTexture(desc)); - DCHECK(gr_texture); - surface_ = skia::AdoptRef( - SkSurface::NewRenderTargetDirect(gr_texture->asRenderTarget())); - DCHECK(surface_); -} - -GaneshSurface::~GaneshSurface() { -} - -scoped_ptr GaneshSurface::TakeTexture() { - surface_.clear(); - return texture_.Pass(); -} - -} // namespace mojo diff --git a/mojo/skia/ganesh_surface.h b/mojo/skia/ganesh_surface.h deleted file mode 100644 index 11d90eeeb68..00000000000 --- a/mojo/skia/ganesh_surface.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2014 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 MOJO_SKIA_GANESH_SURFACE_H_ -#define MOJO_SKIA_GANESH_SURFACE_H_ - -#include "base/memory/scoped_ptr.h" -#include "mojo/gpu/gl_texture.h" -#include "mojo/skia/ganesh_context.h" -#include "skia/ext/refptr.h" -#include "third_party/skia/include/core/SkSurface.h" - -namespace mojo { - -// This class represents an SkSurface backed by a GL texture, which is -// appropriate for use with Ganesh. Note: There's a name collision with -// mojo::Surface, which is a different concept. -class GaneshSurface { - public: - GaneshSurface(GaneshContext* context, scoped_ptr texture); - ~GaneshSurface(); - - SkCanvas* canvas() const { return surface_->getCanvas(); } - scoped_ptr TakeTexture(); - - private: - scoped_ptr texture_; - skia::RefPtr surface_; - - DISALLOW_COPY_AND_ASSIGN(GaneshSurface); -}; - -} // namespace mojo - -#endif // MOJO_SKIA_GANESH_SURFACE_H_ diff --git a/mojo/skia/ganesh_texture_surface.cc b/mojo/skia/ganesh_texture_surface.cc new file mode 100644 index 00000000000..f58d3ad1d70 --- /dev/null +++ b/mojo/skia/ganesh_texture_surface.cc @@ -0,0 +1,49 @@ +// Copyright 2014 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 "mojo/skia/ganesh_texture_surface.h" + +#include + +#include "base/logging.h" +#include "mojo/gpu/gl_texture.h" +#include "third_party/skia/include/gpu/gl/GrGLTypes.h" + +namespace mojo { +namespace skia { + +GaneshTextureSurface::GaneshTextureSurface(const GaneshContext::Scope& scope, + std::unique_ptr texture) + : texture_(std::move(texture)) { + DCHECK(texture_); + DCHECK(texture_->texture_id()); + DCHECK(texture_->size().width > 0); + DCHECK(texture_->size().height > 0); + GrGLTextureInfo info; + info.fTarget = GL_TEXTURE_2D; + info.fID = texture_->texture_id(); + + GrBackendTextureDesc desc; + desc.fFlags = kRenderTarget_GrBackendTextureFlag; + desc.fOrigin = kTopLeft_GrSurfaceOrigin; + desc.fWidth = texture_->size().width; + desc.fHeight = texture_->size().height; + desc.fConfig = kSkia8888_GrPixelConfig; + desc.fSampleCnt = 0; + desc.fTextureHandle = reinterpret_cast(&info); + + surface_ = ::skia::AdoptRef( + SkSurface::NewFromBackendTexture(scope.gr_context(), desc, nullptr)); + DCHECK(surface_); +} + +GaneshTextureSurface::~GaneshTextureSurface() {} + +std::unique_ptr GaneshTextureSurface::TakeTexture() { + surface_.clear(); + return std::move(texture_); +} + +} // namespace skia +} // namespace mojo diff --git a/mojo/skia/ganesh_texture_surface.h b/mojo/skia/ganesh_texture_surface.h new file mode 100644 index 00000000000..3cf4c363c03 --- /dev/null +++ b/mojo/skia/ganesh_texture_surface.h @@ -0,0 +1,46 @@ +// Copyright 2014 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 MOJO_SKIA_GANESH_TEXTURE_SURFACE_H_ +#define MOJO_SKIA_GANESH_TEXTURE_SURFACE_H_ + +#include + +#include "base/macros.h" +#include "mojo/skia/ganesh_context.h" +#include "skia/ext/refptr.h" +#include "third_party/skia/include/core/SkSurface.h" + +namespace mojo { +class GLTexture; + +namespace skia { + +// This class represents an SkSurface backed by a GL texture, which is +// appropriate for use with Ganesh. This is useful for rendering Skia +// commands to a texture. +class GaneshTextureSurface { + public: + // Creates a surface that wraps the specified GL texture. + GaneshTextureSurface(const GaneshContext::Scope& scope, + std::unique_ptr texture); + ~GaneshTextureSurface(); + + SkSurface* surface() const { return surface_.get(); } + SkCanvas* canvas() const { return surface_->getCanvas(); } + + // Destroys the surface and returns its underlying texture. + std::unique_ptr TakeTexture(); + + private: + std::unique_ptr texture_; + ::skia::RefPtr surface_; + + DISALLOW_COPY_AND_ASSIGN(GaneshTextureSurface); +}; + +} // namespace skia +} // namespace mojo + +#endif // MOJO_SKIA_GANESH_TEXTURE_SURFACE_H_ diff --git a/mojo/skia/gl_bindings_skia.cc b/mojo/skia/gl_bindings_skia.cc index d692c436c6b..4ca10bd3a8d 100644 --- a/mojo/skia/gl_bindings_skia.cc +++ b/mojo/skia/gl_bindings_skia.cc @@ -12,14 +12,13 @@ #include "mojo/public/c/gpu/GLES2/gl2extmojo.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" -namespace skia_bindings { +namespace mojo { +namespace skia { GrGLInterface* CreateMojoSkiaGLBinding() { GrGLInterface* interface = new GrGLInterface; interface->fStandard = kGLES_GrGLStandard; - interface->fExtensions.init(kGLES_GrGLStandard, - glGetString, - nullptr, + interface->fExtensions.init(kGLES_GrGLStandard, glGetString, nullptr, glGetIntegerv); GrGLInterface::Functions* functions = &interface->fFunctions; @@ -145,8 +144,11 @@ GrGLInterface* CreateMojoSkiaGLBinding() { functions->fBindUniformLocation = glBindUniformLocationCHROMIUM; functions->fBlitFramebuffer = nullptr; // TODO: Implement. functions->fGenerateMipmap = glGenerateMipmap; + functions->fMatrixLoadf = nullptr; // TODO: Implement. + functions->fMatrixLoadIdentity = nullptr; // TODO: Implement. return interface; } } // namespace skia +} // namespace mojo diff --git a/mojo/skia/gl_bindings_skia.h b/mojo/skia/gl_bindings_skia.h index 524edc261f5..3eba0f9e3ae 100644 --- a/mojo/skia/gl_bindings_skia.h +++ b/mojo/skia/gl_bindings_skia.h @@ -9,12 +9,14 @@ struct GrGLInterface; -namespace skia_bindings { +namespace mojo { +namespace skia { // The GPU back-end for skia requires pointers to GL functions. This function // returns a binding for skia-gpu to the Mojo C GL entry points. GrGLInterface* CreateMojoSkiaGLBinding(); -} // namespace skia_bindings +} // namespace skia +} // namespace mojo #endif // MOJO_SKIA_GL_BINDINGS_SKIA_H_ diff --git a/mojo/skia/type_converters.cc b/mojo/skia/type_converters.cc new file mode 100644 index 00000000000..ddc9687e55e --- /dev/null +++ b/mojo/skia/type_converters.cc @@ -0,0 +1,99 @@ +// 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 "mojo/skia/type_converters.h" + +namespace mojo { + +SkPoint TypeConverter::Convert(const mojo::Point& input) { + return SkPoint::Make(input.x, input.y); +} + +mojo::Point TypeConverter::Convert(const SkPoint& input) { + mojo::Point output; + output.x = input.x(); + output.y = input.y(); + return output; +} + +SkRect TypeConverter::Convert(const mojo::Rect& input) { + return SkRect::MakeXYWH(input.x, input.y, input.width, input.height); +} + +mojo::Rect TypeConverter::Convert(const SkRect& input) { + mojo::Rect output; + output.x = input.x(); + output.y = input.y(); + output.width = input.width(); + output.height = input.height(); + return output; +} + +SkRRect TypeConverter::Convert(const mojo::RRect& input) { + SkVector radii[4] = { + {input.top_left_radius_x, input.top_left_radius_y}, + {input.top_right_radius_x, input.top_right_radius_y}, + {input.bottom_left_radius_x, input.bottom_left_radius_y}, + {input.bottom_right_radius_x, input.bottom_right_radius_y}}; + SkRRect output; + output.setRectRadii( + SkRect::MakeXYWH(input.x, input.y, input.width, input.height), radii); + return output; +} + +mojo::RRect TypeConverter::Convert(const SkRRect& input) { + mojo::RRect output; + output.x = input.rect().x(); + output.y = input.rect().y(); + output.width = input.rect().width(); + output.height = input.rect().height(); + output.top_left_radius_x = input.radii(SkRRect::kUpperLeft_Corner).x(); + output.top_left_radius_y = input.radii(SkRRect::kUpperLeft_Corner).y(); + output.top_right_radius_x = input.radii(SkRRect::kUpperRight_Corner).x(); + output.top_right_radius_y = input.radii(SkRRect::kUpperRight_Corner).y(); + output.bottom_left_radius_x = input.radii(SkRRect::kLowerLeft_Corner).x(); + output.bottom_left_radius_y = input.radii(SkRRect::kLowerLeft_Corner).y(); + output.bottom_right_radius_x = input.radii(SkRRect::kLowerRight_Corner).x(); + output.bottom_right_radius_y = input.radii(SkRRect::kLowerRight_Corner).y(); + return output; +} + +SkMatrix TypeConverter::Convert( + const mojo::TransformPtr& input) { + if (!input) + return SkMatrix::I(); + + // Drop 3D components during conversion from 4x4 to 3x3. + SkMatrix output; + output.setAll(input->matrix[0], input->matrix[1], input->matrix[3], + input->matrix[4], input->matrix[5], input->matrix[7], + input->matrix[12], input->matrix[13], input->matrix[15]); + return output; +} + +mojo::TransformPtr TypeConverter::Convert( + const SkMatrix& input) { + // Expand 3x3 to 4x4. + auto output = mojo::Transform::New(); + output->matrix.resize(16u); + output->matrix[0] = input[0]; + output->matrix[1] = input[1]; + output->matrix[2] = 0.f; + output->matrix[3] = input[2]; + output->matrix[4] = input[3]; + output->matrix[5] = input[4]; + output->matrix[6] = 0.f; + output->matrix[7] = input[5]; + output->matrix[8] = 0.f; + output->matrix[9] = 0.f; + output->matrix[10] = 1.f; + output->matrix[11] = 0.f; + output->matrix[12] = input[6]; + output->matrix[13] = input[7]; + output->matrix[14] = 0.f; + output->matrix[15] = input[8]; + return output.Pass(); +} + +} // namespace mojo diff --git a/mojo/skia/type_converters.h b/mojo/skia/type_converters.h new file mode 100644 index 00000000000..6f18878b68f --- /dev/null +++ b/mojo/skia/type_converters.h @@ -0,0 +1,56 @@ +// 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 MOJO_SKIA_TYPE_CONVERTERS_H_ +#define MOJO_SKIA_TYPE_CONVERTERS_H_ + +#include "mojo/services/geometry/interfaces/geometry.mojom.h" +#include "third_party/skia/include/core/SkMatrix.h" +#include "third_party/skia/include/core/SkPoint.h" +#include "third_party/skia/include/core/SkRRect.h" +#include "third_party/skia/include/core/SkRect.h" + +namespace mojo { + +template <> +struct TypeConverter { + static SkPoint Convert(const mojo::Point& input); +}; +template <> +struct TypeConverter { + static mojo::Point Convert(const SkPoint& input); +}; + +template <> +struct TypeConverter { + static SkRect Convert(const mojo::Rect& input); +}; +template <> +struct TypeConverter { + static mojo::Rect Convert(const SkRect& input); +}; + +template <> +struct TypeConverter { + static SkRRect Convert(const mojo::RRect& input); +}; +template <> +struct TypeConverter { + static mojo::RRect Convert(const SkRRect& input); +}; + +// Note: This transformation is lossy since Transform is 4x4 whereas +// SkMatrix is only 3x3. +template <> +struct TypeConverter { + static SkMatrix Convert(const mojo::TransformPtr& input); +}; +template <> +struct TypeConverter { + static mojo::TransformPtr Convert(const SkMatrix& input); +}; + +} // namespace mojo + +#endif // MOJO_SKIA_TYPE_CONVERTERS_H_