Update //mojo/skia to 68d50d71c802b3f56aa535d9403e20804b11ef52

This commit is contained in:
Adam Barth 2016-01-27 22:19:10 -08:00
parent e7119fb4fa
commit 4d246f47d2
15 changed files with 606 additions and 122 deletions

View File

@ -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",
]
}

View File

@ -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<GLContext> gl_context)
: gl_context_(gl_context) {
DCHECK(gl_context_);
gl_context_->AddObserver(this);
Scope scope(this);
skia::RefPtr<GrGLInterface> interface =
skia::AdoptRef(skia_bindings::CreateMojoSkiaGLBinding());
::skia::RefPtr<GrGLInterface> interface =
::skia::AdoptRef(CreateMojoSkiaGLBinding());
DCHECK(interface);
context_ = skia::AdoptRef(GrContext::Create(
gr_context_ = ::skia::AdoptRef(GrContext::Create(
kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(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

View File

@ -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<GLContext>& 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<GLContext> gl_context);
~GaneshContext() override;
void MakeCurrent();
GrContext* gr() const {
DCHECK(InScope());
return context_.get();
}
// Gets the underlying GL context.
const base::WeakPtr<GLContext>& gl_context() const { return gl_context_; }
private:
bool InScope() const;
void OnContextLost() override;
void ReleaseContext();
void EnterScope();
void ExitScope();
base::WeakPtr<GLContext> gl_context_;
skia::RefPtr<GrContext> context_;
::skia::RefPtr<GrContext> 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_

View File

@ -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 <GLES2/gl2.h>
#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

View File

@ -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<SkSurface> surface_;
DISALLOW_COPY_AND_ASSIGN(GaneshFramebufferSurface);
};
} // namespace skia
} // namespace mojo
#endif // MOJO_SKIA_GANESH_FRAMEBUFFER_SURFACE_H_

View File

@ -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<base::Closure*>(data);
release_callback->Run();
delete release_callback;
}
} // namespace
::skia::RefPtr<SkImage> 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<GrBackendObject>(&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<GrBackendObject>(&info);
return context->textureProvider()->wrapBackendTexture(desc,
kAdopt_GrWrapOwnership);
}
} // namespace skia
} // namespace mojo

View File

@ -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 <GLES2/gl2.h>
#include <GLES2/gl2extmojo.h>
#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<SkImage> 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_

View File

@ -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<GLTexture> 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<GLTexture> GaneshSurface::TakeTexture() {
surface_.clear();
return texture_.Pass();
}
} // namespace mojo

View File

@ -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<GLTexture> texture);
~GaneshSurface();
SkCanvas* canvas() const { return surface_->getCanvas(); }
scoped_ptr<GLTexture> TakeTexture();
private:
scoped_ptr<GLTexture> texture_;
skia::RefPtr<SkSurface> surface_;
DISALLOW_COPY_AND_ASSIGN(GaneshSurface);
};
} // namespace mojo
#endif // MOJO_SKIA_GANESH_SURFACE_H_

View File

@ -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 <GLES2/gl2.h>
#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<GLTexture> 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<GrBackendObject>(&info);
surface_ = ::skia::AdoptRef(
SkSurface::NewFromBackendTexture(scope.gr_context(), desc, nullptr));
DCHECK(surface_);
}
GaneshTextureSurface::~GaneshTextureSurface() {}
std::unique_ptr<GLTexture> GaneshTextureSurface::TakeTexture() {
surface_.clear();
return std::move(texture_);
}
} // namespace skia
} // namespace mojo

View File

@ -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 <memory>
#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<GLTexture> 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<GLTexture> TakeTexture();
private:
std::unique_ptr<GLTexture> texture_;
::skia::RefPtr<SkSurface> surface_;
DISALLOW_COPY_AND_ASSIGN(GaneshTextureSurface);
};
} // namespace skia
} // namespace mojo
#endif // MOJO_SKIA_GANESH_TEXTURE_SURFACE_H_

View File

@ -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

View File

@ -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_

View File

@ -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<SkPoint, mojo::Point>::Convert(const mojo::Point& input) {
return SkPoint::Make(input.x, input.y);
}
mojo::Point TypeConverter<mojo::Point, SkPoint>::Convert(const SkPoint& input) {
mojo::Point output;
output.x = input.x();
output.y = input.y();
return output;
}
SkRect TypeConverter<SkRect, mojo::Rect>::Convert(const mojo::Rect& input) {
return SkRect::MakeXYWH(input.x, input.y, input.width, input.height);
}
mojo::Rect TypeConverter<mojo::Rect, SkRect>::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<SkRRect, mojo::RRect>::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<mojo::RRect, SkRRect>::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<SkMatrix, mojo::TransformPtr>::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<mojo::TransformPtr, SkMatrix>::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

View File

@ -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<SkPoint, mojo::Point> {
static SkPoint Convert(const mojo::Point& input);
};
template <>
struct TypeConverter<mojo::Point, SkPoint> {
static mojo::Point Convert(const SkPoint& input);
};
template <>
struct TypeConverter<SkRect, mojo::Rect> {
static SkRect Convert(const mojo::Rect& input);
};
template <>
struct TypeConverter<mojo::Rect, SkRect> {
static mojo::Rect Convert(const SkRect& input);
};
template <>
struct TypeConverter<SkRRect, mojo::RRect> {
static SkRRect Convert(const mojo::RRect& input);
};
template <>
struct TypeConverter<mojo::RRect, SkRRect> {
static mojo::RRect Convert(const SkRRect& input);
};
// Note: This transformation is lossy since Transform is 4x4 whereas
// SkMatrix is only 3x3.
template <>
struct TypeConverter<SkMatrix, mojo::TransformPtr> {
static SkMatrix Convert(const mojo::TransformPtr& input);
};
template <>
struct TypeConverter<mojo::TransformPtr, SkMatrix> {
static mojo::TransformPtr Convert(const SkMatrix& input);
};
} // namespace mojo
#endif // MOJO_SKIA_TYPE_CONVERTERS_H_