diff options
author | mtklein <mtklein@chromium.org> | 2015-08-28 11:51:06 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-28 11:51:07 -0700 |
commit | e0f06a47522b81d9d81485bfd5c8e3333211db5a (patch) | |
tree | 379316514dc3af1039172188be37d2cb182501ea /cmake | |
parent | fd0eca2583cca2b13a241af753d8e689cb3b4b54 (diff) |
Example CMake build for Skia.
This works only on Mac, probably only on 64-bit,
and doesn't support SkCodec.
BUG=skia:4269
Review URL: https://codereview.chromium.org/1319543003
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/.gitignore | 11 | ||||
-rw-r--r-- | cmake/CMakeLists.txt | 178 | ||||
-rw-r--r-- | cmake/README.md | 27 | ||||
-rw-r--r-- | cmake/example.cpp | 91 |
4 files changed, 307 insertions, 0 deletions
diff --git a/cmake/.gitignore b/cmake/.gitignore new file mode 100644 index 0000000000..8c39254a4f --- /dev/null +++ b/cmake/.gitignore @@ -0,0 +1,11 @@ +*.swp + +*.ninja +.ninja* +CMakeCache.txt +CMakeFiles +cmake_install.cmake + +libskia.dylib +example +example.png diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt new file mode 100644 index 0000000000..91785a344a --- /dev/null +++ b/cmake/CMakeLists.txt @@ -0,0 +1,178 @@ +# Boilerplate. +cmake_minimum_required (VERSION 3.3) # The latest version as I write this. May be too strict. +project (skimake) +set (CMAKE_CXX_STANDARD 11) + +# Default to Release mode. We're mainly targeting Skia users, not Skia developers. +if (NOT CMAKE_BUILD_TYPE) + set (CMAKE_BUILD_TYPE Release) +endif () + +# To first approximation, the Skia library comprises all .cpp files under src/. +file (GLOB_RECURSE srcs ../src/*.cpp) + +function (find_include_dirs out) + file (GLOB_RECURSE headers ${ARGV}) + foreach (path ${headers}) + get_filename_component (dir ${path} PATH) + list (APPEND include_dirs ${dir}) + endforeach() + list (REMOVE_DUPLICATES include_dirs) + set (${out} ${include_dirs} PARENT_SCOPE) +endfunction() + +# We need src/ directories and include/private on our path when building Skia. +# Users should be able to use Skia with only include/ directories that are not include/private. +find_include_dirs(private_includes ../src/*.h ../include/private/*.h) +find_include_dirs(public_includes ../include/*.h) +list (REMOVE_ITEM public_includes ${private_includes}) # Easiest way to exclude private. + +# These guys are third_party but provided by a Skia checkout. +list (APPEND srcs ../third_party/etc1/etc1.cpp ../third_party/ktx/ktx.cpp) +list (APPEND private_includes ../third_party/etc1 ../third_party/ktx) + +function (remove_srcs) + file (GLOB_RECURSE to_remove ${ARGV}) + list (REMOVE_ITEM srcs ${to_remove}) + set (srcs ${srcs} PARENT_SCOPE) +endfunction() + +# This file is empty and is only used to trick GYP. +remove_srcs (../src/core/SkForceCPlusPlusLinking.cpp) +# This file forces linking for all our supported image decoders. We're more fine-grained. +remove_srcs (../src/images/SkForceLinking.cpp) + +# Skia sure ships a lot of code no one uses. +remove_srcs (../src/animator/* ../src/*nacl* ../src/svg/* ../src/views/* ../src/xml/*) + +# Some files only contain code in Debug mode. This quiets down some linker warnings. +if (NOT CMAKE_BUILD_TYPE EQUAL Debug) + remove_srcs (../src/core/SkDebug.cpp ../src/utils/SkDumpCanvas.cpp) +endif() + +# Remove OS-specific source files. +if (NOT WIN32) + remove_srcs(../src/utils/win/* ../src/*_win*.cpp ../src/*xps* ../src/gpu/gl/angle/* ../src/*WIC* ../src/*DWRITE*) +endif() +if (NOT LINUX) + remove_srcs(../src/*linux* ../src/*FreeType* ../src/*FontConfig* ../src/*FontMgr_custom*) +endif() +if (NOT ANDROID) + remove_srcs(../src/*android* ../src/*hwui*) +endif() + +# Remove processor-specific source files. +if (NOT CMAKE_SYSTEM_PROCESSOR EQUAL ARM) + remove_srcs(../src/*arm* ../src/*ARM* ../src/*neon* ../src/*NEON*) +endif() +if (NOT CMAKE_SYSTEM_PROCESSOR EQUAL MIPS) + remove_srcs(../src/*mips* ../src/*MIPS*) +endif() + +# Make our ports choices. +remove_srcs( + ../src/*moz* # We're probably not Mozilla. + ../src/gpu/GrContextFactory.cpp # For internal testing only. + ../src/gpu/gl/GrGLCreateNativeInterface_none.cpp + ../src/gpu/gl/GrGLDefaultInterface_none.cpp + ../src/gpu/gl/SkCreatePlatformGLContext*.cpp # For internal testing only. + ../src/gpu/gl/command_buffer/* + ../src/gpu/gl/egl/* + ../src/gpu/gl/glx/* + ../src/gpu/gl/iOS/* + ../src/gpu/gl/mesa/* + ../src/images/SkImageDecoder_FactoryDefault.cpp + ../src/opts/SkBitmapProcState_opts_none.cpp + ../src/opts/SkBlitMask_opts_none.cpp + ../src/opts/SkBlitRow_opts_none.cpp + ../src/ports/SkFontMgr_empty_factory.cpp + ../src/ports/SkGlobalInitialization_chromium.cpp + ../src/ports/SkImageDecoder_empty.cpp + ../src/ports/SkImageGenerator_none.cpp + ../src/ports/SkTLS_none.cpp + ../src/utils/SkThreadUtils_pthread_other.cpp + ) + +remove_srcs(../src/codec/*) # TODO: Requires Chromium's libjpeg-turbo, and incompatible giflib. + +# Certain files must be compiled with support for SSSE3 or SSE4.1 intrinsics. +file (GLOB_RECURSE ssse3_srcs ../src/*ssse3*.cpp ../src/*SSSE3*.cpp) +file (GLOB_RECURSE sse41_srcs ../src/*sse4*.cpp ../src/*SSE4*.cpp) +set_source_files_properties(${ssse3_srcs} PROPERTIES COMPILE_FLAGS -mssse3) +set_source_files_properties(${sse41_srcs} PROPERTIES COMPILE_FLAGS -msse4.1) + +# Detect our optional dependencies. +# If we can't find them, don't build the parts of Skia that use them. + +find_package (GIF) +find_package (JPEG) +find_package (LUA) +find_package (PNG) +find_package (ZLIB) +# No find_package for libwebp as far as I can tell, so simulate it here. +find_path (WEBP_INCLUDE_DIRS "webp/decode.h") +find_library (WEBP_LIBRARIES webp) + +if (NOT GIF_FOUND) + remove_srcs(../src/images/*gif*) +endif() +if (NOT JPEG_FOUND) + remove_srcs(../src/images/*jpeg*) +endif() +if (NOT LUA_FOUND) + remove_srcs(../src/utils/*lua*) +endif() +if (NOT PNG_FOUND) + remove_srcs(../src/images/*png*) +endif() +if (NOT ZLIB_FOUND) + remove_srcs(../src/pdf/*.cpp ../src/doc/SkDocument_PDF.cpp) +else() + remove_srcs(../src/doc/SkDocument_PDF_None.cpp) +endif() +if (NOT WEBP_INCLUDE_DIRS OR NOT WEBP_LIBRARIES) + remove_srcs(../src/images/*webp*) +endif() + +if (APPLE) + find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices) +endif() + +# This is our main output, libskia.so. +# We mostly build an .so here because it helps test we've linked everything, +# not so much that we think Skia is a good candidate to ship as a shared library. +add_library (skia SHARED ${srcs}) + +target_compile_definitions(skia + PUBLIC + PRIVATE -DSKIA_DLL) + +target_include_directories(skia + PUBLIC ${public_includes} + PRIVATE ${private_includes} + ${GIF_INCLUDE_DIRS} + ${JPEG_INCLUDE_DIRS} + ${LUA_INCLUDE_DIRS} + ${PNG_INCLUDE_DIRS} + ${WEBP_INCLUDE_DIRS} + ${ZLIB_INCLUDE_DIRS}) + +target_link_libraries(skia + PUBLIC + PRIVATE ${APPLICATION_SERVICES_FRAMEWORK} + ${GIF_LIBRARIES} + ${JPEG_LIBRARIES} + ${LUA_LIBRARIES} + ${PNG_LIBRARIES} + ${WEBP_LIBRARIES} + ${ZLIB_LIBRARIES}) + +set_target_properties(skia PROPERTIES + COMPILE_FLAGS "-fno-exceptions -fno-rtti -Wno-deprecated-declarations" + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN true) + +# Now build a simple example app that uses Skia via libskia.so. +find_package(OpenGL REQUIRED) +add_executable(example example.cpp) +target_link_libraries(example skia ${OPENGL_LIBRARIES}) diff --git a/cmake/README.md b/cmake/README.md new file mode 100644 index 0000000000..36c1c3d20c --- /dev/null +++ b/cmake/README.md @@ -0,0 +1,27 @@ +CMake build for Skia +==================== +This directory contains experiemental CMake build files for Skia. +They are primarily targeted at building Skia as it would be shipped, +not at day-to-day Skia development. + +Quickstart +---------- + $ cd skia/cmake + $ cmake . -G Ninja # Other CMake generators should work fine. + $ ninja + $ ls -l libskia.* example + $ ./example + $ open example.png +If that works, you should see "Hello World!" with a green-to-purple gradient. + +Currently supported platforms +----------------------------- + (None. This is still super experimental.) + +Currently maybe-kinda-working platforms +--------------------------------------- + - x86-64 Mac OS X built with Clang (i.e. mtklein's laptop). + +Caveats +------- + - SkCodec, Skia's new image decoder library, does not yet build. diff --git a/cmake/example.cpp b/cmake/example.cpp new file mode 100644 index 0000000000..ea10bed759 --- /dev/null +++ b/cmake/example.cpp @@ -0,0 +1,91 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "../include/core/SkCanvas.h" +#include "../include/core/SkData.h" +#include "../include/core/SkSurface.h" +#include "../include/effects/SkGradientShader.h" +#include "../include/gpu/GrContext.h" + +// These headers are just handy for writing this example file. Nothing Skia specific. +#include <cstdlib> +#include <ctime> +#include <fstream> +#include <iostream> +#include <memory> + +#if defined(__APPLE__) + #include <OpenGL/OpenGL.h> + static void setup_gl_context() { + // This is not meant to represent good form. It's just a quick hack to get us going. + CGLPixelFormatAttribute attributes[] = { (CGLPixelFormatAttribute)0 }; + CGLPixelFormatObj format; + GLint npix; + CGLChoosePixelFormat(attributes, &format, &npix); + CGLContextObj context; + CGLCreateContext(format, nullptr, &context); + CGLSetCurrentContext(context); + CGLReleasePixelFormat(format); + } +#endif + +// Most pointers returned by Skia are derived from SkRefCnt, +// meaning we need to call ->unref() on them when done rather than delete them. +template <typename T> std::shared_ptr<T> adopt(T* ptr) { + return std::shared_ptr<T>(ptr, [](T* p) { p->unref(); }); +} + +static std::shared_ptr<SkSurface> create_raster_surface(int w, int h) { + std::cout << "Using raster surface" << std::endl; + return adopt(SkSurface::NewRasterN32Premul(w, h)); +} + +static std::shared_ptr<SkSurface> create_opengl_surface(int w, int h) { + std::cout << "Using opengl surface" << std::endl; + std::shared_ptr<GrContext> grContext = adopt(GrContext::Create(kOpenGL_GrBackend, 0)); + return adopt(SkSurface::NewRenderTarget(grContext.get(), + SkSurface::kNo_Budgeted, + SkImageInfo::MakeN32Premul(w,h))); +} + +int main(int, char**) { + setup_gl_context(); + srand(time(nullptr)); + std::shared_ptr<SkSurface> surface = (rand() % 2) ? create_raster_surface(320, 240) + : create_opengl_surface(320, 240); + + // Create a left-to-right green-to-purple gradient shader. + SkPoint pts[] = { {0,0}, {320,240} }; + SkColor colors[] = { 0xFF00FF00, 0xFFFF00FF }; + std::shared_ptr<SkShader> shader = adopt( + SkGradientShader::CreateLinear(pts, colors, nullptr, 2, SkShader::kRepeat_TileMode)); + + // Our text will draw with this paint: size 24, antialiased, with the shader. + SkPaint paint; + paint.setTextSize(24); + paint.setAntiAlias(true); + paint.setShader(shader.get()); + + // Draw to the surface via its SkCanvas. + SkCanvas* canvas = surface->getCanvas(); // We don't manage this pointer's lifetime. + static const char* msg = "Hello world!"; + canvas->clear(SK_ColorWHITE); + canvas->drawText(msg, strlen(msg), 90,120, paint); + + // Grab a snapshot of the surface as an immutable SkImage. + std::shared_ptr<SkImage> image = adopt(surface->newImageSnapshot()); + // Encode that image as a .png into a blob in memory. + std::shared_ptr<SkData> png = adopt(image->encode(SkImageEncoder::kPNG_Type, 100)); + + // This code is no longer Skia-specific. We just dump the .png to disk. Any way works. + static const char* path = "example.png"; + std::ofstream(path, std::ios::out | std::ios::binary) + .write((const char*)png->data(), png->size()); + std::cout << "Wrote " << path << std::endl; + + return 0; +} |