Remove duplicate files from ios-darwin and darwin (#384)
* Remove duplicate files from platform/ios/platform/darwin and platform/darwin There are duplicated files between platform/iOS/platform/darwin/src and platform/darwin/src ``` src/headless_backend_cgl.mm src/image.mm src/string_nsstring.mm src/headless_backend_eagl.mm src/number_format.mm src/local_glyph_rasterizer.mm src/logging_nslog.mm src/nsthread.mm src/collator.mm src/CFHandle.hpp include/mbgl/util/image+MGLAdditions.hpp src/timer.cpp src/run_loop.cpp src/async_task.cpp src/gl_functions.cpp ``` There are three files which are not the exact same diff even ``` src/local_glyph_rasterizer.mm src/nsthread.mm src/collator.mm ``` Uniformly it seems like all platform/iOS/platform/darwin/src files should be removed keeping the platform/darwin/src versions. I believe these files should have been deleted with a previous change of some kind and are otherwise not referenced. * update
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
CFHandle is a minimal wrapper designed to hold and release CoreFoundation-style handles
|
||||
It is non-transferrable: wrap it in something like a unique_ptr if you need to pass it around,
|
||||
or just use unique_ptr with a custom deleter.
|
||||
CFHandle has no special treatment for null handles -- be careful not to let it hold a null
|
||||
handle if the behavior of the Releaser isn't defined for null.
|
||||
|
||||
ex:
|
||||
using CFDataHandle = CFHandle<CFDataRef, CFTypeRef, CFRelease>;
|
||||
|
||||
CFDataHandle data(CFDataCreateWithBytesNoCopy(
|
||||
kCFAllocatorDefault, reinterpret_cast<const unsigned char*>(source.data()), source.size(),
|
||||
kCFAllocatorNull));
|
||||
*/
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename HandleType, typename ReleaserArgumentType, void (*Releaser)(ReleaserArgumentType)>
|
||||
struct CFHandle {
|
||||
CFHandle(HandleType handle_): handle(handle_) {}
|
||||
~CFHandle() { Releaser(handle); }
|
||||
HandleType operator*() { return handle; }
|
||||
operator bool() { return handle; }
|
||||
private:
|
||||
HandleType handle;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
#include <mbgl/util/async_task.hpp>
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
class AsyncTask::Impl {
|
||||
public:
|
||||
Impl(std::function<void()>&& fn)
|
||||
: task(std::move(fn)),
|
||||
loop(CFRunLoopGetCurrent()) {
|
||||
CFRunLoopSourceContext context = {
|
||||
0,
|
||||
this,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
perform
|
||||
};
|
||||
source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
|
||||
CFRunLoopAddSource(loop, source, kCFRunLoopCommonModes);
|
||||
}
|
||||
|
||||
~Impl() {
|
||||
CFRunLoopSourceInvalidate(source);
|
||||
CFRelease(source);
|
||||
}
|
||||
|
||||
void maySend() {
|
||||
if (!queued.test_and_set()) {
|
||||
CFRunLoopSourceSignal(source);
|
||||
CFRunLoopWakeUp(loop);
|
||||
}
|
||||
}
|
||||
|
||||
void runTask() {
|
||||
queued.clear();
|
||||
task();
|
||||
}
|
||||
|
||||
private:
|
||||
static void perform(void* info) {
|
||||
reinterpret_cast<Impl*>(info)->runTask();
|
||||
}
|
||||
|
||||
std::function<void()> task;
|
||||
std::atomic_flag queued = ATOMIC_FLAG_INIT;
|
||||
|
||||
CFRunLoopRef loop;
|
||||
CFRunLoopSourceRef source;
|
||||
};
|
||||
|
||||
AsyncTask::AsyncTask(std::function<void()>&& fn)
|
||||
: impl(std::make_unique<Impl>(std::move(fn))) {
|
||||
}
|
||||
|
||||
AsyncTask::~AsyncTask() = default;
|
||||
|
||||
void AsyncTask::send() {
|
||||
impl->maySend();
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
@@ -1,67 +0,0 @@
|
||||
#include <mbgl/i18n/collator.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
class Collator::Impl {
|
||||
public:
|
||||
Impl(bool caseSensitive, bool diacriticSensitive, optional<std::string> locale_)
|
||||
: options((caseSensitive ? 0 : NSCaseInsensitiveSearch) |
|
||||
(diacriticSensitive ? 0 : NSDiacriticInsensitiveSearch))
|
||||
, locale(locale_ ?
|
||||
[[NSLocale alloc] initWithLocaleIdentifier:@((*locale_).c_str())] :
|
||||
[NSLocale currentLocale])
|
||||
{}
|
||||
|
||||
bool operator==(const Impl& other) const {
|
||||
return options == other.options &&
|
||||
[[locale localeIdentifier] isEqualToString:[other.locale localeIdentifier]];
|
||||
}
|
||||
|
||||
int compare(const std::string& lhs, const std::string& rhs) const {
|
||||
NSString* nsLhs = @(lhs.c_str());
|
||||
NSString* nsRhs = @(rhs.c_str());
|
||||
// Limiting the compare range to the length of the LHS seems weird, but
|
||||
// experimentally we've checked that if LHS is a prefix of RHS compare returns -1
|
||||
// https://developer.apple.com/documentation/foundation/nsstring/1414561-compare
|
||||
NSRange compareRange = NSMakeRange(0, nsLhs.length);
|
||||
|
||||
return static_cast<int>([nsLhs compare:nsRhs options:options range:compareRange locale:locale]);
|
||||
}
|
||||
|
||||
std::string resolvedLocale() const {
|
||||
// Following documentation at:
|
||||
// https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html#//apple_ref/doc/uid/10000171i-CH15-SW9
|
||||
// We expect NSLocale to accept BCP 47 tags as localeIdentifier inputs, but the output format
|
||||
// may append the region tag with an "_". Changing that to a "-" makes the identifier BCP 47 compliant.
|
||||
// Experimentally, "zh-Hans-HK" and "zh-Hans_HK" both round trip -- if the second is used by
|
||||
// `currentLocale`, we don't want to return the underscore.
|
||||
return [[locale localeIdentifier] stringByReplacingOccurrencesOfString:@"_" withString:@"-"].UTF8String;
|
||||
}
|
||||
private:
|
||||
NSStringCompareOptions options;
|
||||
NSLocale* locale;
|
||||
};
|
||||
|
||||
Collator::Collator(bool caseSensitive, bool diacriticSensitive, optional<std::string> locale_)
|
||||
: impl(std::make_shared<Impl>(caseSensitive, diacriticSensitive, std::move(locale_)))
|
||||
{}
|
||||
|
||||
bool Collator::operator==(const Collator& other) const {
|
||||
return *impl == *(other.impl);
|
||||
}
|
||||
|
||||
int Collator::compare(const std::string& lhs, const std::string& rhs) const {
|
||||
return impl->compare(lhs, rhs);
|
||||
}
|
||||
|
||||
std::string Collator::resolvedLocale() const {
|
||||
return impl->resolvedLocale();
|
||||
}
|
||||
|
||||
} // namespace platform
|
||||
} // namespace mbgl
|
||||
@@ -1,180 +0,0 @@
|
||||
#include <mbgl/platform/gl_functions.hpp>
|
||||
|
||||
#include "TargetConditionals.h"
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#elif TARGET_OS_SIMULATOR
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#elif TARGET_OS_MAC
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glext.h>
|
||||
#else
|
||||
#error Unsupported Apple platform
|
||||
#endif
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
void (* const glActiveTexture)(GLenum) = ::glActiveTexture;
|
||||
void (* const glAttachShader)(GLuint, GLuint) = ::glAttachShader;
|
||||
void (* const glBindAttribLocation)(GLuint, GLuint, const GLchar *) = ::glBindAttribLocation;
|
||||
void (* const glBindBuffer)(GLenum, GLuint) = ::glBindBuffer;
|
||||
void (* const glBindFramebuffer)(GLenum, GLuint) = ::glBindFramebuffer;
|
||||
void (* const glBindRenderbuffer)(GLenum, GLuint) = ::glBindRenderbuffer;
|
||||
void (* const glBindTexture)(GLenum, GLuint) = ::glBindTexture;
|
||||
void (* const glBlendColor)(GLfloat, GLfloat, GLfloat, GLfloat) = ::glBlendColor;
|
||||
void (* const glBlendEquation)(GLenum) = ::glBlendEquation;
|
||||
void (* const glBlendEquationSeparate)(GLenum, GLenum) = ::glBlendEquationSeparate;
|
||||
void (* const glBlendFunc)(GLenum, GLenum) = ::glBlendFunc;
|
||||
void (* const glBlendFuncSeparate)(GLenum, GLenum, GLenum, GLenum) = ::glBlendFuncSeparate;
|
||||
void (* const glBufferData)(GLenum, GLsizeiptr, const void *, GLenum) = ::glBufferData;
|
||||
void (* const glBufferSubData)(GLenum, GLintptr, GLsizeiptr, const void *) = ::glBufferSubData;
|
||||
GLenum (* const glCheckFramebufferStatus)(GLenum) = ::glCheckFramebufferStatus;
|
||||
void (* const glClear)(GLbitfield) = ::glClear;
|
||||
void (* const glClearColor)(GLfloat, GLfloat, GLfloat, GLfloat) = ::glClearColor;
|
||||
#if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR && TARGET_OS_MAC
|
||||
void (* const glClearDepthf)(GLfloat) = [](GLfloat depth) { return ::glClearDepth(depth); };
|
||||
#else
|
||||
void (* const glClearDepthf)(GLfloat) = ::glClearDepthf;
|
||||
#endif
|
||||
void (* const glClearStencil)(GLint) = ::glClearStencil;
|
||||
void (* const glColorMask)(GLboolean, GLboolean, GLboolean, GLboolean) = ::glColorMask;
|
||||
void (* const glCompileShader)(GLuint) = ::glCompileShader;
|
||||
void (* const glCompressedTexImage2D)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const void *) = ::glCompressedTexImage2D;
|
||||
void (* const glCompressedTexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const void *) = ::glCompressedTexSubImage2D;
|
||||
void (* const glCopyTexImage2D)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint) = ::glCopyTexImage2D;
|
||||
void (* const glCopyTexSubImage2D)(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei) = ::glCopyTexSubImage2D;
|
||||
GLuint (* const glCreateProgram)() = ::glCreateProgram;
|
||||
GLuint (* const glCreateShader)(GLenum) = ::glCreateShader;
|
||||
void (* const glCullFace)(GLenum) = ::glCullFace;
|
||||
void (* const glDeleteBuffers)(GLsizei, const GLuint *) = ::glDeleteBuffers;
|
||||
void (* const glDeleteFramebuffers)(GLsizei, const GLuint *) = ::glDeleteFramebuffers;
|
||||
void (* const glDeleteProgram)(GLuint) = ::glDeleteProgram;
|
||||
void (* const glDeleteRenderbuffers)(GLsizei, const GLuint *) = ::glDeleteRenderbuffers;
|
||||
void (* const glDeleteShader)(GLuint) = ::glDeleteShader;
|
||||
void (* const glDeleteTextures)(GLsizei, const GLuint *) = ::glDeleteTextures;
|
||||
void (* const glDepthFunc)(GLenum) = ::glDepthFunc;
|
||||
void (* const glDepthMask)(GLboolean) = ::glDepthMask;
|
||||
#if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR && TARGET_OS_MAC
|
||||
void (* const glDepthRangef)(GLfloat, GLfloat) = [](GLfloat nearVal, GLfloat farVal) { return ::glDepthRange(nearVal, farVal); };
|
||||
#else
|
||||
void (* const glDepthRangef)(GLfloat, GLfloat) = ::glDepthRangef;
|
||||
#endif
|
||||
void (* const glDetachShader)(GLuint, GLuint) = ::glDetachShader;
|
||||
void (* const glDisable)(GLenum) = ::glDisable;
|
||||
void (* const glDisableVertexAttribArray)(GLuint) = ::glDisableVertexAttribArray;
|
||||
void (* const glDrawArrays)(GLenum, GLint, GLsizei) = ::glDrawArrays;
|
||||
void (* const glDrawElements)(GLenum, GLsizei, GLenum, const void *) = ::glDrawElements;
|
||||
void (* const glEnable)(GLenum) = ::glEnable;
|
||||
void (* const glEnableVertexAttribArray)(GLuint) = ::glEnableVertexAttribArray;
|
||||
void (* const glFinish)() = ::glFinish;
|
||||
void (* const glFlush)() = ::glFlush;
|
||||
void (* const glFramebufferRenderbuffer)(GLenum, GLenum, GLenum, GLuint) = ::glFramebufferRenderbuffer;
|
||||
void (* const glFramebufferTexture2D)(GLenum, GLenum, GLenum, GLuint, GLint) = ::glFramebufferTexture2D;
|
||||
void (* const glFrontFace)(GLenum) = ::glFrontFace;
|
||||
void (* const glGenBuffers)(GLsizei, GLuint *) = ::glGenBuffers;
|
||||
void (* const glGenerateMipmap)(GLenum) = ::glGenerateMipmap;
|
||||
void (* const glGenFramebuffers)(GLsizei, GLuint *) = ::glGenFramebuffers;
|
||||
void (* const glGenRenderbuffers)(GLsizei, GLuint *) = ::glGenRenderbuffers;
|
||||
void (* const glGenTextures)(GLsizei, GLuint *) = ::glGenTextures;
|
||||
void (* const glGetActiveAttrib)(GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *) = ::glGetActiveAttrib;
|
||||
void (* const glGetActiveUniform)(GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *) = ::glGetActiveUniform;
|
||||
void (* const glGetAttachedShaders)(GLuint, GLsizei, GLsizei *, GLuint *) = ::glGetAttachedShaders;
|
||||
GLint (* const glGetAttribLocation)(GLuint, const GLchar *) = ::glGetAttribLocation;
|
||||
void (* const glGetBooleanv)(GLenum, GLboolean *) = ::glGetBooleanv;
|
||||
void (* const glGetBufferParameteriv)(GLenum, GLenum, GLint *) = ::glGetBufferParameteriv;
|
||||
GLenum (* const glGetError)() = ::glGetError;
|
||||
void (* const glGetFloatv)(GLenum, GLfloat *) = ::glGetFloatv;
|
||||
void (* const glGetFramebufferAttachmentParameteriv)(GLenum, GLenum, GLenum, GLint *) = ::glGetFramebufferAttachmentParameteriv;
|
||||
void (* const glGetIntegerv)(GLenum, GLint *) = ::glGetIntegerv;
|
||||
void (* const glGetProgramInfoLog)(GLuint, GLsizei, GLsizei *, GLchar *) = ::glGetProgramInfoLog;
|
||||
void (* const glGetProgramiv)(GLuint, GLenum, GLint *) = ::glGetProgramiv;
|
||||
void (* const glGetRenderbufferParameteriv)(GLenum, GLenum, GLint *) = ::glGetRenderbufferParameteriv;
|
||||
void (* const glGetShaderInfoLog)(GLuint, GLsizei, GLsizei *, GLchar *) = ::glGetShaderInfoLog;
|
||||
void (* const glGetShaderiv)(GLuint, GLenum, GLint *) = ::glGetShaderiv;
|
||||
void (* const glGetShaderSource)(GLuint, GLsizei, GLsizei *, GLchar *) = ::glGetShaderSource;
|
||||
const GLubyte *(*glGetString)(GLenum) = ::glGetString;
|
||||
void (* const glGetTexParameterfv)(GLenum, GLenum, GLfloat *) = ::glGetTexParameterfv;
|
||||
void (* const glGetTexParameteriv)(GLenum, GLenum, GLint *) = ::glGetTexParameteriv;
|
||||
void (* const glGetUniformfv)(GLuint, GLint, GLfloat *) = ::glGetUniformfv;
|
||||
void (* const glGetUniformiv)(GLuint, GLint, GLint *) = ::glGetUniformiv;
|
||||
GLint (* const glGetUniformLocation)(GLuint, const GLchar *) = ::glGetUniformLocation;
|
||||
void (* const glGetVertexAttribfv)(GLuint, GLenum, GLfloat *) = ::glGetVertexAttribfv;
|
||||
void (* const glGetVertexAttribiv)(GLuint, GLenum, GLint *) = ::glGetVertexAttribiv;
|
||||
void (* const glGetVertexAttribPointerv)(GLuint, GLenum, void **) = ::glGetVertexAttribPointerv;
|
||||
void (* const glHint)(GLenum, GLenum) = ::glHint;
|
||||
GLboolean (* const glIsBuffer)(GLuint) = ::glIsBuffer;
|
||||
GLboolean (* const glIsEnabled)(GLenum) = ::glIsEnabled;
|
||||
GLboolean (* const glIsFramebuffer)(GLuint) = ::glIsFramebuffer;
|
||||
GLboolean (* const glIsProgram)(GLuint) = ::glIsProgram;
|
||||
GLboolean (* const glIsRenderbuffer)(GLuint) = ::glIsRenderbuffer;
|
||||
GLboolean (* const glIsShader)(GLuint) = ::glIsShader;
|
||||
GLboolean (* const glIsTexture)(GLuint) = ::glIsTexture;
|
||||
void (* const glLineWidth)(GLfloat) = ::glLineWidth;
|
||||
void (* const glLinkProgram)(GLuint) = ::glLinkProgram;
|
||||
void (* const glPixelStorei)(GLenum, GLint) = ::glPixelStorei;
|
||||
void (* const glPolygonOffset)(GLfloat, GLfloat) = ::glPolygonOffset;
|
||||
void (* const glReadPixels)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, void *) = ::glReadPixels;
|
||||
void (* const glRenderbufferStorage)(GLenum, GLenum, GLsizei, GLsizei) = ::glRenderbufferStorage;
|
||||
void (* const glSampleCoverage)(GLfloat, GLboolean) = ::glSampleCoverage;
|
||||
void (* const glScissor)(GLint, GLint, GLsizei, GLsizei) = ::glScissor;
|
||||
void (* const glShaderSource)(GLuint, GLsizei, const GLchar * const*, const GLint *) = ::glShaderSource;
|
||||
void (* const glStencilFunc)(GLenum, GLint, GLuint) = ::glStencilFunc;
|
||||
void (* const glStencilFuncSeparate)(GLenum, GLenum, GLint, GLuint) = ::glStencilFuncSeparate;
|
||||
void (* const glStencilMask)(GLuint) = ::glStencilMask;
|
||||
void (* const glStencilMaskSeparate)(GLenum, GLuint) = ::glStencilMaskSeparate;
|
||||
void (* const glStencilOp)(GLenum, GLenum, GLenum) = ::glStencilOp;
|
||||
void (* const glStencilOpSeparate)(GLenum, GLenum, GLenum, GLenum) = ::glStencilOpSeparate;
|
||||
void (* const glTexImage2D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const void *) = ::glTexImage2D;
|
||||
void (* const glTexParameterf)(GLenum, GLenum, GLfloat) = ::glTexParameterf;
|
||||
void (* const glTexParameterfv)(GLenum, GLenum, const GLfloat *) = ::glTexParameterfv;
|
||||
void (* const glTexParameteri)(GLenum, GLenum, GLint) = ::glTexParameteri;
|
||||
void (* const glTexParameteriv)(GLenum, GLenum, const GLint *) = ::glTexParameteriv;
|
||||
void (* const glTexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const void *) = ::glTexSubImage2D;
|
||||
void (* const glUniform1f)(GLint, GLfloat) = ::glUniform1f;
|
||||
void (* const glUniform1fv)(GLint, GLsizei, const GLfloat *) = ::glUniform1fv;
|
||||
void (* const glUniform1i)(GLint, GLint) = ::glUniform1i;
|
||||
void (* const glUniform1iv)(GLint, GLsizei, const GLint *) = ::glUniform1iv;
|
||||
void (* const glUniform2f)(GLint, GLfloat, GLfloat) = ::glUniform2f;
|
||||
void (* const glUniform2fv)(GLint, GLsizei, const GLfloat *) = ::glUniform2fv;
|
||||
void (* const glUniform2i)(GLint, GLint, GLint) = ::glUniform2i;
|
||||
void (* const glUniform2iv)(GLint, GLsizei, const GLint *) = ::glUniform2iv;
|
||||
void (* const glUniform3f)(GLint, GLfloat, GLfloat, GLfloat) = ::glUniform3f;
|
||||
void (* const glUniform3fv)(GLint, GLsizei, const GLfloat *) = ::glUniform3fv;
|
||||
void (* const glUniform3i)(GLint, GLint, GLint, GLint) = ::glUniform3i;
|
||||
void (* const glUniform3iv)(GLint, GLsizei, const GLint *) = ::glUniform3iv;
|
||||
void (* const glUniform4f)(GLint, GLfloat, GLfloat, GLfloat, GLfloat) = ::glUniform4f;
|
||||
void (* const glUniform4fv)(GLint, GLsizei, const GLfloat *) = ::glUniform4fv;
|
||||
void (* const glUniform4i)(GLint, GLint, GLint, GLint, GLint) = ::glUniform4i;
|
||||
void (* const glUniform4iv)(GLint, GLsizei, const GLint *) = ::glUniform4iv;
|
||||
void (* const glUniformMatrix2fv)(GLint, GLsizei, GLboolean, const GLfloat *) = ::glUniformMatrix2fv;
|
||||
void (* const glUniformMatrix3fv)(GLint, GLsizei, GLboolean, const GLfloat *) = ::glUniformMatrix3fv;
|
||||
void (* const glUniformMatrix4fv)(GLint, GLsizei, GLboolean, const GLfloat *) = ::glUniformMatrix4fv;
|
||||
void (* const glUseProgram)(GLuint) = ::glUseProgram;
|
||||
void (* const glValidateProgram)(GLuint) = ::glValidateProgram;
|
||||
void (* const glVertexAttrib1f)(GLuint, GLfloat) = ::glVertexAttrib1f;
|
||||
void (* const glVertexAttrib1fv)(GLuint, const GLfloat *) = ::glVertexAttrib1fv;
|
||||
void (* const glVertexAttrib2f)(GLuint, GLfloat, GLfloat) = ::glVertexAttrib2f;
|
||||
void (* const glVertexAttrib2fv)(GLuint, const GLfloat *) = ::glVertexAttrib2fv;
|
||||
void (* const glVertexAttrib3f)(GLuint, GLfloat, GLfloat, GLfloat) = ::glVertexAttrib3f;
|
||||
void (* const glVertexAttrib3fv)(GLuint, const GLfloat *) = ::glVertexAttrib3fv;
|
||||
void (* const glVertexAttrib4f)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat) = ::glVertexAttrib4f;
|
||||
void (* const glVertexAttrib4fv)(GLuint, const GLfloat *) = ::glVertexAttrib4fv;
|
||||
void (* const glVertexAttribPointer)(GLuint, GLint, GLenum, GLboolean, GLsizei, const void *) = ::glVertexAttribPointer;
|
||||
void (* const glViewport)(GLint, GLint, GLsizei, GLsizei) = ::glViewport;
|
||||
|
||||
#ifndef MBGL_USE_GLES2
|
||||
void (* const glDrawPixels)(GLsizei, GLsizei, GLenum, GLenum, const GLvoid *) = ::glDrawPixels;
|
||||
void (* const glGetDoublev)(GLenum, GLdouble *) = ::glGetDoublev;
|
||||
void (* const glPixelTransferf)(GLenum, GLfloat) = ::glPixelTransferf;
|
||||
void (* const glPixelZoom)(GLfloat, GLfloat) = ::glPixelZoom;
|
||||
void (* const glPointSize)(GLfloat) = ::glPointSize;
|
||||
void (* const glRasterPos4d)(GLdouble, GLdouble, GLdouble, GLdouble) = ::glRasterPos4d;
|
||||
#endif
|
||||
|
||||
} // namespace platform
|
||||
} // namespace mbgl
|
||||
@@ -1,127 +0,0 @@
|
||||
#include <mbgl/gl/headless_backend.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
// This class provides a singleton that contains information about the pixel format used for
|
||||
// instantiating new headless rendering contexts.
|
||||
class CGLDisplayConfig {
|
||||
private:
|
||||
// Key for singleton construction.
|
||||
struct Key { explicit Key() = default; };
|
||||
|
||||
public:
|
||||
CGLDisplayConfig(Key) {
|
||||
// TODO: test if OpenGL 4.1 with GL_ARB_ES2_compatibility is supported
|
||||
// If it is, use kCGLOGLPVersion_3_2_Core and enable that extension.
|
||||
CGLPixelFormatAttribute attributes[] = {
|
||||
kCGLPFAOpenGLProfile, static_cast<CGLPixelFormatAttribute>(kCGLOGLPVersion_Legacy),
|
||||
// Not adding kCGLPFAAccelerated, as this will make headless rendering impossible when running in VMs.
|
||||
kCGLPFAClosestPolicy,
|
||||
kCGLPFAAccumSize, static_cast<CGLPixelFormatAttribute>(32),
|
||||
kCGLPFAColorSize, static_cast<CGLPixelFormatAttribute>(24),
|
||||
kCGLPFAAlphaSize, static_cast<CGLPixelFormatAttribute>(8),
|
||||
kCGLPFADepthSize, static_cast<CGLPixelFormatAttribute>(16),
|
||||
kCGLPFAStencilSize, static_cast<CGLPixelFormatAttribute>(8),
|
||||
kCGLPFASupportsAutomaticGraphicsSwitching,
|
||||
kCGLPFAAllowOfflineRenderers, // Allows using the integrated GPU
|
||||
static_cast<CGLPixelFormatAttribute>(0)
|
||||
};
|
||||
|
||||
GLint num;
|
||||
// TODO: obtain all configurations and choose the best one.
|
||||
const CGLError error = CGLChoosePixelFormat(attributes, &pixelFormat, &num);
|
||||
if (error != kCGLNoError) {
|
||||
throw std::runtime_error(std::string("Error choosing pixel format:") + CGLErrorString(error) + "\n");
|
||||
}
|
||||
if (num <= 0) {
|
||||
throw std::runtime_error("No pixel formats found.");
|
||||
}
|
||||
}
|
||||
|
||||
~CGLDisplayConfig() {
|
||||
const CGLError error = CGLDestroyPixelFormat(pixelFormat);
|
||||
if (error != kCGLNoError) {
|
||||
Log::Error(Event::OpenGL, std::string("Error destroying pixel format:") + CGLErrorString(error));
|
||||
}
|
||||
}
|
||||
|
||||
static std::shared_ptr<const CGLDisplayConfig> create() {
|
||||
static std::weak_ptr<const CGLDisplayConfig> instance;
|
||||
auto shared = instance.lock();
|
||||
if (!shared) {
|
||||
instance = shared = std::make_shared<CGLDisplayConfig>(Key{});
|
||||
}
|
||||
return shared;
|
||||
}
|
||||
|
||||
public:
|
||||
CGLPixelFormatObj pixelFormat = nullptr;
|
||||
};
|
||||
|
||||
class CGLBackendImpl : public HeadlessBackend::Impl {
|
||||
public:
|
||||
CGLBackendImpl() {
|
||||
CGLError error = CGLCreateContext(cglDisplay->pixelFormat, nullptr, &glContext);
|
||||
if (error != kCGLNoError) {
|
||||
throw std::runtime_error(std::string("Error creating GL context object:") +
|
||||
CGLErrorString(error) + "\n");
|
||||
}
|
||||
|
||||
error = CGLEnable(glContext, kCGLCEMPEngine);
|
||||
if (error != kCGLNoError) {
|
||||
throw std::runtime_error(std::string("Error enabling OpenGL multithreading:") +
|
||||
CGLErrorString(error) + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
~CGLBackendImpl() final {
|
||||
CGLDestroyContext(glContext);
|
||||
}
|
||||
|
||||
gl::ProcAddress getExtensionFunctionPointer(const char* name) final {
|
||||
static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
|
||||
if (!framework) {
|
||||
throw std::runtime_error("Failed to load OpenGL framework.");
|
||||
}
|
||||
|
||||
return reinterpret_cast<gl::ProcAddress>(CFBundleGetFunctionPointerForName(
|
||||
framework, (__bridge CFStringRef)[NSString stringWithUTF8String:name]));
|
||||
}
|
||||
|
||||
void activateContext() final {
|
||||
CGLError error = CGLSetCurrentContext(glContext);
|
||||
if (error != kCGLNoError) {
|
||||
throw std::runtime_error(std::string("Switching OpenGL context failed:") +
|
||||
CGLErrorString(error) + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void deactivateContext() final {
|
||||
CGLError error = CGLSetCurrentContext(nullptr);
|
||||
if (error != kCGLNoError) {
|
||||
throw std::runtime_error(std::string("Removing OpenGL context failed:") +
|
||||
CGLErrorString(error) + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const std::shared_ptr<const CGLDisplayConfig> cglDisplay = CGLDisplayConfig::create();
|
||||
CGLContextObj glContext = nullptr;
|
||||
};
|
||||
|
||||
void HeadlessBackend::createImpl() {
|
||||
assert(!impl);
|
||||
impl = std::make_unique<CGLBackendImpl>();
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -1,51 +0,0 @@
|
||||
#include <mbgl/gl/headless_backend.hpp>
|
||||
|
||||
#include <OpenGLES/EAGL.h>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
class EAGLBackendImpl : public HeadlessBackend::Impl {
|
||||
public:
|
||||
EAGLBackendImpl() {
|
||||
glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
|
||||
if (glContext == nil) {
|
||||
throw std::runtime_error("Error creating GL context object");
|
||||
}
|
||||
glContext.multiThreaded = YES;
|
||||
}
|
||||
|
||||
// Required for ARC to deallocate correctly.
|
||||
~EAGLBackendImpl() final = default;
|
||||
|
||||
gl::ProcAddress getExtensionFunctionPointer(const char* name) final {
|
||||
static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengles"));
|
||||
if (!framework) {
|
||||
throw std::runtime_error("Failed to load OpenGL framework.");
|
||||
}
|
||||
|
||||
return reinterpret_cast<gl::ProcAddress>(CFBundleGetFunctionPointerForName(
|
||||
framework, (__bridge CFStringRef)[NSString stringWithUTF8String:name]));
|
||||
}
|
||||
|
||||
void activateContext() final {
|
||||
[EAGLContext setCurrentContext:glContext];
|
||||
}
|
||||
|
||||
void deactivateContext() final {
|
||||
[EAGLContext setCurrentContext:nil];
|
||||
}
|
||||
|
||||
private:
|
||||
EAGLContext* glContext = nullptr;
|
||||
};
|
||||
|
||||
void HeadlessBackend::createImpl() {
|
||||
assert(!impl);
|
||||
impl = std::make_unique<EAGLBackendImpl>();
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -1,95 +0,0 @@
|
||||
#include <mbgl/util/image+MGLAdditions.hpp>
|
||||
|
||||
#import <ImageIO/ImageIO.h>
|
||||
|
||||
#import "CFHandle.hpp"
|
||||
|
||||
using CGImageHandle = CFHandle<CGImageRef, CGImageRef, CGImageRelease>;
|
||||
using CFDataHandle = CFHandle<CFDataRef, CFTypeRef, CFRelease>;
|
||||
using CGImageSourceHandle = CFHandle<CGImageSourceRef, CFTypeRef, CFRelease>;
|
||||
using CGDataProviderHandle = CFHandle<CGDataProviderRef, CGDataProviderRef, CGDataProviderRelease>;
|
||||
using CGColorSpaceHandle = CFHandle<CGColorSpaceRef, CGColorSpaceRef, CGColorSpaceRelease>;
|
||||
using CGContextHandle = CFHandle<CGContextRef, CGContextRef, CGContextRelease>;
|
||||
|
||||
CGImageRef CGImageCreateWithMGLPremultipliedImage(mbgl::PremultipliedImage&& src) {
|
||||
// We're converting the PremultipliedImage's backing store to a CGDataProvider, and are taking
|
||||
// over ownership of the memory.
|
||||
CGDataProviderHandle provider(CGDataProviderCreateWithData(
|
||||
NULL, src.data.get(), src.bytes(), [](void*, const void* data, size_t) {
|
||||
delete[] reinterpret_cast<const decltype(src.data)::element_type*>(data);
|
||||
}));
|
||||
if (!provider) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// If we successfully created the provider, it will take over management of the memory segment.
|
||||
src.data.release();
|
||||
|
||||
CGColorSpaceHandle colorSpace(CGColorSpaceCreateDeviceRGB());
|
||||
if (!colorSpace) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
constexpr const size_t bitsPerComponent = 8;
|
||||
constexpr const size_t bytesPerPixel = 4;
|
||||
constexpr const size_t bitsPerPixel = bitsPerComponent * bytesPerPixel;
|
||||
const size_t bytesPerRow = bytesPerPixel * src.size.width;
|
||||
|
||||
return CGImageCreate(src.size.width, src.size.height, bitsPerComponent, bitsPerPixel,
|
||||
bytesPerRow, *colorSpace,
|
||||
kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast, *provider,
|
||||
NULL, false, kCGRenderingIntentDefault);
|
||||
}
|
||||
|
||||
mbgl::PremultipliedImage MGLPremultipliedImageFromCGImage(CGImageRef src) {
|
||||
const size_t width = CGImageGetWidth(src);
|
||||
const size_t height = CGImageGetHeight(src);
|
||||
|
||||
mbgl::PremultipliedImage image({ static_cast<uint32_t>(width), static_cast<uint32_t>(height) });
|
||||
|
||||
CGColorSpaceHandle colorSpace(CGColorSpaceCreateDeviceRGB());
|
||||
if (!colorSpace) {
|
||||
throw std::runtime_error("CGColorSpaceCreateDeviceRGB failed");
|
||||
}
|
||||
|
||||
constexpr const size_t bitsPerComponent = 8;
|
||||
constexpr const size_t bytesPerPixel = 4;
|
||||
const size_t bytesPerRow = bytesPerPixel * width;
|
||||
|
||||
CGContextHandle context(CGBitmapContextCreate(
|
||||
image.data.get(), width, height, bitsPerComponent, bytesPerRow, *colorSpace,
|
||||
kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast));
|
||||
if (!context) {
|
||||
throw std::runtime_error("CGBitmapContextCreate failed");
|
||||
}
|
||||
|
||||
CGContextSetBlendMode(*context, kCGBlendModeCopy);
|
||||
CGContextDrawImage(*context, CGRectMake(0, 0, width, height), src);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
PremultipliedImage decodeImage(const std::string& source) {
|
||||
CFDataHandle data(CFDataCreateWithBytesNoCopy(
|
||||
kCFAllocatorDefault, reinterpret_cast<const unsigned char*>(source.data()), source.size(),
|
||||
kCFAllocatorNull));
|
||||
if (!data) {
|
||||
throw std::runtime_error("CFDataCreateWithBytesNoCopy failed");
|
||||
}
|
||||
|
||||
CGImageSourceHandle imageSource(CGImageSourceCreateWithData(*data, NULL));
|
||||
if (!imageSource) {
|
||||
throw std::runtime_error("CGImageSourceCreateWithData failed");
|
||||
}
|
||||
|
||||
CGImageHandle image(CGImageSourceCreateImageAtIndex(*imageSource, 0, NULL));
|
||||
if (!image) {
|
||||
throw std::runtime_error("CGImageSourceCreateImageAtIndex failed");
|
||||
}
|
||||
|
||||
return MGLPremultipliedImageFromCGImage(*image);
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -1,175 +0,0 @@
|
||||
#include <mbgl/text/local_glyph_rasterizer.hpp>
|
||||
#include <mbgl/util/i18n.hpp>
|
||||
#include <mbgl/util/platform.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreText/CoreText.h>
|
||||
#import <ImageIO/ImageIO.h>
|
||||
|
||||
#import "CFHandle.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
/*
|
||||
Darwin implementation of LocalGlyphRasterizer:
|
||||
Draws CJK glyphs using locally available fonts.
|
||||
|
||||
Mirrors GL JS implementation in that:
|
||||
- Only CJK glyphs are drawn locally (because we can guess their metrics effectively)
|
||||
* Render size/metrics determined experimentally by rendering a few different fonts
|
||||
- Configuration is done at map creation time by setting a "font family"
|
||||
* JS uses a CSS font-family, this uses kCTFontFamilyNameAttribute which has
|
||||
somewhat different behavior.
|
||||
|
||||
Further improvements are possible:
|
||||
- GL JS heuristically determines a font weight based on the strings included in
|
||||
the FontStack. Android follows a simpler heuristic that just picks up the
|
||||
"Bold" property from the FontStack. Although both should be possible with CoreText,
|
||||
our initial implementation couldn't reliably control the font-weight, so we're
|
||||
skipping that functionality on darwin.
|
||||
(See commit history for attempted implementation)
|
||||
- If we could reliably extract glyph metrics, we wouldn't be limited to CJK glyphs
|
||||
- We could push the font configuration down to individual style layers, which would
|
||||
allow any current style to be reproducible using local fonts.
|
||||
- Instead of just exposing "font family" as a configuration, we could expose a richer
|
||||
CTFontDescriptor configuration option (although we'd have to override font size to
|
||||
make sure it stayed at 24pt).
|
||||
- Because Apple exposes glyph paths via `CTFontCreatePathForGlyph` we could potentially
|
||||
render directly to SDF instead of going through TinySDF -- although it's not clear
|
||||
how much of an improvement it would be.
|
||||
*/
|
||||
|
||||
using CGColorSpaceHandle = CFHandle<CGColorSpaceRef, CGColorSpaceRef, CGColorSpaceRelease>;
|
||||
using CGContextHandle = CFHandle<CGContextRef, CGContextRef, CGContextRelease>;
|
||||
using CFStringRefHandle = CFHandle<CFStringRef, CFTypeRef, CFRelease>;
|
||||
using CFAttributedStringRefHandle = CFHandle<CFAttributedStringRef, CFTypeRef, CFRelease>;
|
||||
using CFDictionaryRefHandle = CFHandle<CFDictionaryRef, CFTypeRef, CFRelease>;
|
||||
using CTFontDescriptorRefHandle = CFHandle<CTFontDescriptorRef, CFTypeRef, CFRelease>;
|
||||
using CTLineRefHandle = CFHandle<CTLineRef, CFTypeRef, CFRelease>;
|
||||
|
||||
class LocalGlyphRasterizer::Impl {
|
||||
public:
|
||||
Impl(const optional<std::string> fontFamily_)
|
||||
: fontFamily(fontFamily_)
|
||||
, fontHandle(NULL)
|
||||
{}
|
||||
|
||||
~Impl() {
|
||||
if (fontHandle) {
|
||||
CFRelease(fontHandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CTFontRef getFont() {
|
||||
if (!fontFamily) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!fontHandle) {
|
||||
NSDictionary *fontAttributes = @{
|
||||
(NSString *)kCTFontSizeAttribute: [NSNumber numberWithFloat:24.0],
|
||||
(NSString *)kCTFontFamilyNameAttribute: [[NSString alloc] initWithCString:fontFamily->c_str() encoding:NSUTF8StringEncoding]
|
||||
};
|
||||
|
||||
CTFontDescriptorRefHandle descriptor(CTFontDescriptorCreateWithAttributes((CFDictionaryRef)fontAttributes));
|
||||
fontHandle = CTFontCreateWithFontDescriptor(*descriptor, 0.0, NULL);
|
||||
if (!fontHandle) {
|
||||
throw std::runtime_error("CTFontCreateWithFontDescriptor failed");
|
||||
}
|
||||
}
|
||||
return fontHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
optional<std::string> fontFamily;
|
||||
CTFontRef fontHandle;
|
||||
};
|
||||
|
||||
LocalGlyphRasterizer::LocalGlyphRasterizer(const optional<std::string> fontFamily)
|
||||
: impl(std::make_unique<Impl>(fontFamily))
|
||||
{}
|
||||
|
||||
LocalGlyphRasterizer::~LocalGlyphRasterizer()
|
||||
{}
|
||||
|
||||
bool LocalGlyphRasterizer::canRasterizeGlyph(const FontStack&, GlyphID glyphID) {
|
||||
return util::i18n::allowsFixedWidthGlyphGeneration(glyphID) && impl->getFont();
|
||||
}
|
||||
|
||||
PremultipliedImage drawGlyphBitmap(GlyphID glyphID, CTFontRef font, Size size) {
|
||||
PremultipliedImage rgbaBitmap(size);
|
||||
|
||||
CFStringRefHandle string(CFStringCreateWithCharacters(NULL, reinterpret_cast<UniChar*>(&glyphID), 1));
|
||||
|
||||
CGColorSpaceHandle colorSpace(CGColorSpaceCreateDeviceRGB());
|
||||
if (!colorSpace) {
|
||||
throw std::runtime_error("CGColorSpaceCreateDeviceRGB failed");
|
||||
}
|
||||
|
||||
constexpr const size_t bitsPerComponent = 8;
|
||||
constexpr const size_t bytesPerPixel = 4;
|
||||
const size_t bytesPerRow = bytesPerPixel * size.width;
|
||||
|
||||
CGContextHandle context(CGBitmapContextCreate(
|
||||
rgbaBitmap.data.get(),
|
||||
size.width,
|
||||
size.height,
|
||||
bitsPerComponent,
|
||||
bytesPerRow,
|
||||
*colorSpace,
|
||||
kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast));
|
||||
if (!context) {
|
||||
throw std::runtime_error("CGBitmapContextCreate failed");
|
||||
}
|
||||
|
||||
CFStringRef keys[] = { kCTFontAttributeName };
|
||||
CFTypeRef values[] = { font };
|
||||
|
||||
CFDictionaryRefHandle attributes(
|
||||
CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys,
|
||||
(const void**)&values, sizeof(keys) / sizeof(keys[0]),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks));
|
||||
|
||||
CFAttributedStringRefHandle attrString(CFAttributedStringCreate(kCFAllocatorDefault, *string, *attributes));
|
||||
CTLineRefHandle line(CTLineCreateWithAttributedString(*attrString));
|
||||
|
||||
// Start drawing a little bit below the top of the bitmap
|
||||
CGContextSetTextPosition(*context, 0.0, 5.0);
|
||||
CTLineDraw(*line, *context);
|
||||
|
||||
return rgbaBitmap;
|
||||
}
|
||||
|
||||
Glyph LocalGlyphRasterizer::rasterizeGlyph(const FontStack&, GlyphID glyphID) {
|
||||
Glyph fixedMetrics;
|
||||
CTFontRef font = impl->getFont();
|
||||
if (!font) {
|
||||
return fixedMetrics;
|
||||
}
|
||||
|
||||
fixedMetrics.id = glyphID;
|
||||
|
||||
Size size(35, 35);
|
||||
|
||||
fixedMetrics.metrics.width = size.width;
|
||||
fixedMetrics.metrics.height = size.height;
|
||||
fixedMetrics.metrics.left = 3;
|
||||
fixedMetrics.metrics.top = -1;
|
||||
fixedMetrics.metrics.advance = 24;
|
||||
|
||||
PremultipliedImage rgbaBitmap = drawGlyphBitmap(glyphID, font, size);
|
||||
|
||||
// Copy alpha values from RGBA bitmap into the AlphaImage output
|
||||
fixedMetrics.bitmap = AlphaImage(size);
|
||||
for (uint32_t i = 0; i < size.width * size.height; i++) {
|
||||
fixedMetrics.bitmap.data[i] = rgbaBitmap.data[4 * i + 3];
|
||||
}
|
||||
|
||||
return fixedMetrics;
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -1,14 +0,0 @@
|
||||
#include <mbgl/util/logging.hpp>
|
||||
#include <mbgl/util/enum.hpp>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
void Log::platformRecord(EventSeverity severity, const std::string &msg) {
|
||||
NSString *message =
|
||||
[[NSString alloc] initWithBytes:msg.data() length:msg.size() encoding:NSUTF8StringEncoding];
|
||||
NSLog(@"[%s] %@", Enum<EventSeverity>::toString(severity), message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <mbgl/util/platform.hpp>
|
||||
#include <mbgl/platform/thread.hpp>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
std::string getCurrentThreadName() {
|
||||
char name[32] = "unknown";
|
||||
pthread_getname_np(pthread_self(), name, sizeof(name));
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
void setCurrentThreadName(const std::string& name) {
|
||||
std::string qualifiedName = "com.mapbox.mbgl." + name;
|
||||
pthread_setname_np(qualifiedName.c_str());
|
||||
}
|
||||
|
||||
void makeThreadLowPriority() {
|
||||
[[NSThread currentThread] setThreadPriority:0.0];
|
||||
}
|
||||
|
||||
void attachThread() {
|
||||
}
|
||||
|
||||
void detachThread() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <mbgl/i18n/number_format.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
std::string formatNumber(double number, const std::string& localeId, const std::string& currency,
|
||||
uint8_t minFractionDigits, uint8_t maxFractionDigits) {
|
||||
|
||||
static NSNumberFormatter *numberFormatter;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
numberFormatter = [[NSNumberFormatter alloc] init];
|
||||
});
|
||||
|
||||
numberFormatter.locale = !localeId.empty() ? [NSLocale localeWithLocaleIdentifier:@(localeId.c_str())] : nil;
|
||||
numberFormatter.currencyCode = !currency.empty() ? @(currency.c_str()) : nil;
|
||||
if (currency.empty()) {
|
||||
numberFormatter.minimumFractionDigits = minFractionDigits;
|
||||
numberFormatter.maximumFractionDigits = maxFractionDigits;
|
||||
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
|
||||
} else {
|
||||
// Reset fraction digits to NSNumberFormatter's default values, so that the
|
||||
// system will choose formatting based on number formatter locale.
|
||||
numberFormatter.minimumFractionDigits = 0;
|
||||
numberFormatter.maximumFractionDigits = 0;
|
||||
numberFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
|
||||
}
|
||||
NSString *formatted = [numberFormatter stringFromNumber:@(number)];
|
||||
std::string result = std::string([formatted UTF8String]);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace platform
|
||||
} // namespace mbgl
|
||||
@@ -1,49 +0,0 @@
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mbgl/util/async_task.hpp>
|
||||
#include <mbgl/actor/scheduler.hpp>
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
class RunLoop::Impl {
|
||||
public:
|
||||
std::unique_ptr<AsyncTask> async;
|
||||
};
|
||||
|
||||
RunLoop* RunLoop::Get() {
|
||||
assert(static_cast<RunLoop*>(Scheduler::GetCurrent()));
|
||||
return static_cast<RunLoop*>(Scheduler::GetCurrent());
|
||||
}
|
||||
|
||||
RunLoop::RunLoop(Type)
|
||||
: impl(std::make_unique<Impl>()) {
|
||||
assert(!Scheduler::GetCurrent());
|
||||
Scheduler::SetCurrent(this);
|
||||
impl->async = std::make_unique<AsyncTask>(std::bind(&RunLoop::process, this));
|
||||
}
|
||||
|
||||
RunLoop::~RunLoop() {
|
||||
Scheduler::SetCurrent(nullptr);
|
||||
}
|
||||
|
||||
void RunLoop::wake() {
|
||||
impl->async->send();
|
||||
}
|
||||
|
||||
void RunLoop::run() {
|
||||
CFRunLoopRun();
|
||||
}
|
||||
|
||||
void RunLoop::runOnce() {
|
||||
wake();
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
|
||||
}
|
||||
|
||||
void RunLoop::stop() {
|
||||
invoke([&] { CFRunLoopStop(CFRunLoopGetCurrent()); });
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
@@ -1,31 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <mbgl/util/platform.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
std::string uppercase(const std::string &string) {
|
||||
NSString *original = [[NSString alloc] initWithBytesNoCopy:const_cast<char *>(string.data())
|
||||
length:string.size()
|
||||
encoding:NSUTF8StringEncoding
|
||||
freeWhenDone:NO];
|
||||
NSString *uppercase = [original uppercaseString];
|
||||
const std::string result{[uppercase cStringUsingEncoding : NSUTF8StringEncoding],
|
||||
[uppercase lengthOfBytesUsingEncoding:NSUTF8StringEncoding]};
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string lowercase(const std::string &string) {
|
||||
NSString *original = [[NSString alloc] initWithBytesNoCopy:const_cast<char *>(string.data())
|
||||
length:string.size()
|
||||
encoding:NSUTF8StringEncoding
|
||||
freeWhenDone:NO];
|
||||
NSString *lowercase = [original lowercaseString];
|
||||
const std::string result{[lowercase cStringUsingEncoding : NSUTF8StringEncoding],
|
||||
[lowercase lengthOfBytesUsingEncoding:NSUTF8StringEncoding]};
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace platform
|
||||
} // namespace mbgl
|
||||
@@ -1,60 +0,0 @@
|
||||
#include <mbgl/util/timer.hpp>
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
CFTimeInterval toCFTimeInterval(Duration duration) {
|
||||
return std::chrono::duration<CFTimeInterval>(duration).count();
|
||||
}
|
||||
|
||||
CFAbsoluteTime toCFAbsoluteTime(Duration duration) {
|
||||
return CFAbsoluteTimeGetCurrent() + toCFTimeInterval(duration);
|
||||
}
|
||||
|
||||
class Timer::Impl {
|
||||
public:
|
||||
Impl(Duration timeout, Duration repeat, std::function<void()>&& fn)
|
||||
: task(std::move(fn)),
|
||||
loop(CFRunLoopGetCurrent()) {
|
||||
CFRunLoopTimerContext context = {
|
||||
0,
|
||||
this,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
};
|
||||
timer = CFRunLoopTimerCreate(kCFAllocatorDefault, toCFAbsoluteTime(timeout), toCFTimeInterval(repeat), 0, 0, perform, &context);
|
||||
CFRunLoopAddTimer(loop, timer, kCFRunLoopDefaultMode);
|
||||
}
|
||||
|
||||
~Impl() {
|
||||
CFRunLoopRemoveTimer(loop, timer, kCFRunLoopDefaultMode);
|
||||
CFRelease(timer);
|
||||
}
|
||||
|
||||
private:
|
||||
static void perform(CFRunLoopTimerRef, void* info) {
|
||||
reinterpret_cast<Impl*>(info)->task();
|
||||
}
|
||||
|
||||
std::function<void()> task;
|
||||
|
||||
CFRunLoopRef loop;
|
||||
CFRunLoopTimerRef timer;
|
||||
};
|
||||
|
||||
Timer::Timer() = default;
|
||||
Timer::~Timer() = default;
|
||||
|
||||
void Timer::start(Duration timeout, Duration repeat, std::function<void()>&& cb) {
|
||||
impl = std::make_unique<Impl>(timeout, repeat, std::move(cb));
|
||||
}
|
||||
|
||||
void Timer::stop() {
|
||||
impl.reset();
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
Reference in New Issue
Block a user