• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "GLFW/glfw3.h"
9 #include <stdlib.h>
10 #include <stdio.h>
11 
12 #include "GrContext.h"
13 
14 #include "SkCanvas.h"
15 #include "SkImage.h"
16 #include "SkRSXform.h"
17 #include "SkSurface.h"
18 #include "Timer.h"
19 
20 GrContext* sContext = nullptr;
21 SkSurface* sSurface = nullptr;
22 
error_callback(int error,const char * description)23 static void error_callback(int error, const char* description) {
24     fputs(description, stderr);
25 }
26 
key_callback(GLFWwindow * window,int key,int scancode,int action,int mods)27 static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
28     if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
29         glfwSetWindowShouldClose(window, GL_TRUE);
30 }
31 
32 
init_skia(int w,int h)33 static void init_skia(int w, int h) {
34     sContext = GrContext::Create(kOpenGL_GrBackend, 0);
35 
36     GrBackendRenderTargetDesc desc;
37     desc.fWidth = w;
38     desc.fHeight = h;
39     desc.fConfig = kSkia8888_GrPixelConfig;
40     desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
41     desc.fSampleCnt = 1;
42     desc.fStencilBits = 0;
43     desc.fRenderTargetHandle = 0;  // assume default framebuffer
44 
45     sSurface = SkSurface::MakeFromBackendRenderTarget(sContext, desc, nullptr, nullptr).release();
46 }
47 
cleanup_skia()48 static void cleanup_skia() {
49     delete sSurface;
50     delete sContext;
51 }
52 
53 const int kGrid = 100;
54 const int kWidth = 960;
55 const int kHeight = 640;
56 
main(void)57 int main(void) {
58     GLFWwindow* window;
59     glfwSetErrorCallback(error_callback);
60     if (!glfwInit()) {
61         exit(EXIT_FAILURE);
62     }
63 
64     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
65     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
66     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
67     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
68     glfwWindowHint(GLFW_SRGB_CAPABLE, GL_TRUE);
69 
70     window = glfwCreateWindow(kWidth, kHeight, "Simple example", NULL, NULL);
71     if (!window) {
72         glfwTerminate();
73         exit(EXIT_FAILURE);
74     }
75     glfwMakeContextCurrent(window);
76 
77     init_skia(kWidth, kHeight);
78 
79     sk_sp<SkImage> atlas;
80     SkRSXform   xform[kGrid*kGrid+1];
81     SkRect      tex[kGrid*kGrid+1];
82     WallTimer   timer;
83     float       times[32];
84     int         currentTime;
85 
86     sk_sp<SkData> imageData(SkData::MakeFromFileName("ship.png"));
87     atlas.reset(SkImage::NewFromEncoded(imageData.get()));
88     if (!atlas) {
89         SkDebugf("\nCould not decode file ship.png\n");
90 
91         cleanup_skia();
92         glfwDestroyWindow(window);
93         glfwTerminate();
94         exit(EXIT_FAILURE);
95     }
96 
97     SkScalar anchorX = atlas->width()*0.5f;
98     SkScalar anchorY = atlas->height()*0.5f;
99     int currIndex = 0;
100     for (int x = 0; x < kGrid; x++) {
101         for (int y = 0; y < kGrid; y++) {
102             float xPos = (x / (kGrid - 1.0)) * kWidth;
103             float yPos = (y / (kGrid - 1.0)) * kWidth;
104 
105             tex[currIndex] = SkRect::MakeLTRB(0.0f, 0.0f, atlas->width(), atlas->height());
106             xform[currIndex] = SkRSXform::MakeFromRadians(2.0f, SK_ScalarPI*0.5f,
107                                                           xPos, yPos, anchorX, anchorY);
108             currIndex++;
109         }
110     }
111     tex[currIndex] = SkRect::MakeLTRB(0.0f, 0.0f, atlas->width(), atlas->height());
112     xform[currIndex] = SkRSXform::MakeFromRadians(2.0f, SK_ScalarPI*0.5f,
113                                                   kWidth*0.5f, kHeight*0.5f, anchorX, anchorY);
114 
115     currentTime = 0;
116 
117     glfwSwapInterval(1);
118     glfwSetKeyCallback(window, key_callback);
119 
120     // Draw to the surface via its SkCanvas.
121     SkCanvas* canvas = sSurface->getCanvas();   // We don't manage this pointer's lifetime.
122     SkPaint paint;
123     paint.setFilterQuality(kLow_SkFilterQuality);
124     paint.setColor(SK_ColorWHITE);
125     paint.setTextSize(15.0f);
126 
127     while (!glfwWindowShouldClose(window)) {
128         const float kCosDiff = 0.99984769515f;
129         const float kSinDiff = 0.01745240643f;
130 
131         timer.start();
132 
133         glfwPollEvents();
134 
135         float meanTime = 0.0f;
136         for (int i = 0; i < 32; ++i) {
137             meanTime += times[i];
138         }
139         meanTime /= 32.f;
140         char outString[64];
141         float fps = 1000.f/meanTime;
142         sprintf(outString, "fps: %f ms: %f", fps, meanTime);
143 
144         for (int i = 0; i < kGrid*kGrid+1; ++i) {
145             SkScalar c = xform[i].fSCos;
146             SkScalar s = xform[i].fSSin;
147 
148             SkScalar dx = c*anchorX - s*anchorY;
149             SkScalar dy = s*anchorX + c*anchorY;
150 
151             xform[i].fSCos = kCosDiff*c - kSinDiff*s;
152             xform[i].fSSin = kSinDiff*c + kCosDiff*s;
153 
154             dx -= xform[i].fSCos*anchorX - xform[i].fSSin*anchorY;
155             dy -= xform[i].fSSin*anchorX + xform[i].fSCos*anchorY;
156             xform[i].fTx += dx;
157             xform[i].fTy += dy;
158         }
159 
160         canvas->clear(SK_ColorBLACK);
161         canvas->drawAtlas(atlas, xform, tex, nullptr, kGrid*kGrid+1, SkXfermode::kSrcOver_Mode,
162                           nullptr, &paint);
163         canvas->drawText(outString, strlen(outString), 100.f, 100.f, paint);
164 
165         canvas->flush();
166 
167         timer.end();
168         times[currentTime] = (float)(timer.fWall);
169         currentTime = (currentTime + 1) & 0x1f;
170 
171         glfwSwapBuffers(window);
172     }
173 
174     cleanup_skia();
175 
176     glfwDestroyWindow(window);
177     glfwTerminate();
178     exit(EXIT_SUCCESS);
179 }
180