blob: 31624a9736f348057e2401b7f021fbc5eecfcfe2 [file] [log] [blame]
// Copyright 2013 The Flutter 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 <assert.h>
#include <stdio.h>
#define GLFW_INCLUDE_NONE
#include "GLFW/glfw3.h"
#define GLFW_EXPOSE_NATIVE_COCOA
#import "GLFW/glfw3native.h"
#include "impeller.h"
#include <AppKit/AppKit.h>
#include <Metal/Metal.h>
#include <QuartzCore/QuartzCore.h>
void GLFWErrorCallback(int error, const char* description) {
// NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
fprintf(stderr, "GLFW Error (%d): %s\n", error, description);
fflush(stderr);
}
int main(int argc, char const* argv[]) {
glfwSetErrorCallback(GLFWErrorCallback);
[[maybe_unused]] int result = glfwInit();
assert(result == GLFW_TRUE);
if (glfwGetPlatform() != GLFW_PLATFORM_COCOA) {
// NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
fprintf(stderr,
"Metal is only available on macOS. Please try either Vulkan or "
"OpenGL (ES).\n");
fflush(stderr);
return -1;
}
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window =
glfwCreateWindow(800, 600, "Impeller Example (Metal)", NULL, NULL);
assert(window != NULL);
int framebuffer_width, framebuffer_height;
glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
ImpellerContext context = ImpellerContextCreateMetalNew(IMPELLER_VERSION);
assert(context != NULL);
// This example assumes Automatic Reference Counting (ARC) in Objective-C is
// enabled.
NSWindow* cocoa_window = glfwGetCocoaWindow(window);
assert(cocoa_window != NULL);
CAMetalLayer* layer = [CAMetalLayer layer];
layer.framebufferOnly = NO;
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
layer.device = MTLCreateSystemDefaultDevice();
cocoa_window.contentView.layer = layer;
cocoa_window.contentView.wantsLayer = YES;
ImpellerDisplayList dl = NULL;
{
ImpellerDisplayListBuilder builder = ImpellerDisplayListBuilderNew(NULL);
ImpellerPaint paint = ImpellerPaintNew();
// Clear the background to a white color.
ImpellerColor clear_color = {1.0, 1.0, 1.0, 1.0};
ImpellerPaintSetColor(paint, &clear_color);
ImpellerDisplayListBuilderDrawPaint(builder, paint);
// Draw a red box.
ImpellerColor box_color = {1.0, 0.0, 0.0, 1.0};
ImpellerPaintSetColor(paint, &box_color);
ImpellerRect box_rect = {10, 10, 100, 100};
ImpellerDisplayListBuilderDrawRect(builder, &box_rect, paint);
dl = ImpellerDisplayListBuilderCreateDisplayListNew(builder);
ImpellerPaintRelease(paint);
ImpellerDisplayListBuilderRelease(builder);
}
assert(dl != NULL);
while (!glfwWindowShouldClose(window)) {
glfwWaitEvents();
// React to window resizes.
layer.drawableSize = layer.bounds.size;
ImpellerSurface surface = ImpellerSurfaceCreateWrappedMetalDrawableNew(
context, (__bridge void*)layer.nextDrawable);
assert(surface != NULL);
ImpellerSurfaceDrawDisplayList(surface, dl);
ImpellerSurfacePresent(surface);
ImpellerSurfaceRelease(surface);
}
ImpellerDisplayListRelease(dl);
ImpellerContextRelease(context);
glfwMakeContextCurrent(NULL);
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}