blob: 15b24d0e5cb8a95c76024c53d85112c3220b69b0 [file] [log] [blame]
sglez@google.com43f2b2c2013-07-24 17:48:03 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 *
8 */
9
10#include "SkExample.h"
11
12#include "gl/GrGLUtil.h"
13#include "gl/GrGLDefines.h"
14#include "gl/GrGLInterface.h"
15#include "SkApplication.h"
16#include "SkCommandLineFlags.h"
17#include "SkGpuDevice.h"
18#include "SkGraphics.h"
19
20DEFINE_string2(match, m, NULL, "[~][^]substring[$] [...] of test name to run.\n" \
21 "Multiple matches may be separated by spaces.\n" \
22 "~ causes a matching test to always be skipped\n" \
23 "^ requires the start of the test to match\n" \
24 "$ requires the end of the test to match\n" \
25 "^ and $ requires an exact match\n" \
26 "If a test does not match any list entry,\n" \
27 "it is skipped unless some list entry starts with ~");
28
29void application_init() {
30 SkGraphics::Init();
31 SkEvent::Init();
32}
33
34void application_term() {
35 SkEvent::Term();
36 SkGraphics::Term();
37}
38
39SkExampleWindow::SkExampleWindow(void* hwnd)
40 : INHERITED(hwnd) {
41 fRegistry = SkExample::Registry::Head();
42 fCurrExample = fRegistry->factory()(this);
43
44 if (FLAGS_match.count()) {
sglez@google.com43f2b2c2013-07-24 17:48:03 +000045 // Start with the a matching sample if possible.
46 bool found = this->findNextMatch();
47 if (!found) {
48 SkDebugf("No matching SkExample found.\n");
49 }
50 }
51}
52
53void SkExampleWindow::tearDownBackend() {
54 if (kGPU_DeviceType == fType) {
55 SkSafeUnref(fContext);
56 fContext = NULL;
57
58 SkSafeUnref(fInterface);
59 fInterface = NULL;
60
61 SkSafeUnref(fRenderTarget);
62 fRenderTarget = NULL;
63
64 detach();
65 }
66}
67
68bool SkExampleWindow::setupBackend(DeviceType type) {
69 fType = type;
70
71 this->setConfig(SkBitmap::kARGB_8888_Config);
72 this->setVisibleP(true);
73 this->setClipToBounds(false);
74
75 bool result = attach(kNativeGL_BackEndType, 0 /*msaa*/, &fAttachmentInfo);
76 if (false == result) {
77 SkDebugf("Not possible to create backend.\n");
78 detach();
79 return false;
80 }
81
82 fInterface = GrGLCreateNativeInterface();
83
84 SkASSERT(NULL != fInterface);
85
86 fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInterface);
87 SkASSERT(NULL != fContext);
88
89 setupRenderTarget();
90
91 return true;
92}
93
94void SkExampleWindow::setupRenderTarget() {
95 GrBackendRenderTargetDesc desc;
reed@google.come1ca7052013-12-17 19:22:07 +000096 desc.fWidth = SkScalarRoundToInt(width());
97 desc.fHeight = SkScalarRoundToInt(height());
sglez@google.com43f2b2c2013-07-24 17:48:03 +000098 desc.fConfig = kSkia8888_GrPixelConfig;
99 desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
100 desc.fSampleCnt = fAttachmentInfo.fSampleCount;
101 desc.fStencilBits = fAttachmentInfo.fStencilBits;
102
103 GrGLint buffer;
104 GR_GL_GetIntegerv(fInterface, GR_GL_FRAMEBUFFER_BINDING, &buffer);
105 desc.fRenderTargetHandle = buffer;
106
107 fRenderTarget = fContext->wrapBackendRenderTarget(desc);
108
109 fContext->setRenderTarget(fRenderTarget);
110}
111
112SkCanvas* SkExampleWindow::createCanvas() {
113 if (fType == kGPU_DeviceType) {
114 if (NULL != fContext && NULL != fRenderTarget) {
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000115 SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(fContext, fRenderTarget));
sglez@google.com43f2b2c2013-07-24 17:48:03 +0000116 return new SkCanvas(device);
117 }
118 tearDownBackend();
119 setupBackend(kRaster_DeviceType);
120 }
121 return INHERITED::createCanvas();
122}
123
124void SkExampleWindow::draw(SkCanvas* canvas) {
125 if (NULL != fCurrExample) {
126 fCurrExample->draw(canvas);
127 }
128 if (fType == kGPU_DeviceType) {
129
130 SkASSERT(NULL != fContext);
131 fContext->flush();
132 }
133 if (fType == kRaster_DeviceType) {
134 // need to send the raster bits to the (gpu) window
135 fContext->setRenderTarget(fRenderTarget);
136 const SkBitmap& bm = getBitmap();
137 fRenderTarget->writePixels(0, 0, bm.width(), bm.height(),
138 kSkia8888_GrPixelConfig,
139 bm.getPixels(),
140 bm.rowBytes());
141 }
142 INHERITED::present();
143}
144
145void SkExampleWindow::onSizeChange() {
146 setupRenderTarget();
147}
148
149#ifdef SK_BUILD_FOR_WIN
150void SkExampleWindow::onHandleInval(const SkIRect& rect) {
151 RECT winRect;
152 winRect.top = rect.top();
153 winRect.bottom = rect.bottom();
154 winRect.right = rect.right();
155 winRect.left = rect.left();
156 InvalidateRect((HWND)this->getHWND(), &winRect, false);
157}
158#endif
159
160bool SkExampleWindow::findNextMatch() {
161 bool found = false;
162 // Avoid infinite loop by knowing where we started.
163 const SkExample::Registry* begin = fRegistry;
164 while (!found) {
165 fRegistry = fRegistry->next();
166 if (NULL == fRegistry) { // Reached the end of the registered samples. GOTO head.
167 fRegistry = SkExample::Registry::Head();
168 }
169 SkExample* next = fRegistry->factory()(this);
commit-bot@chromium.orga6f37e72013-08-30 15:52:46 +0000170 if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, next->getName().c_str())) {
sglez@google.com43f2b2c2013-07-24 17:48:03 +0000171 fCurrExample = next;
172 found = true;
173 }
174 if (begin == fRegistry) { // We looped through every sample without finding anything.
175 break;
176 }
177 }
178 return found;
179}
180
181bool SkExampleWindow::onHandleChar(SkUnichar unichar) {
182 if ('n' == unichar) {
183 bool found = findNextMatch();
184 if (!found) {
185 SkDebugf("No SkExample that matches your query\n");
186 }
187 }
188 return true;
189}
190
191SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
192 SkCommandLineFlags::Parse(argc, argv);
193 return new SkExampleWindow(hwnd);
194}