• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
20 DEFINE_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 
application_init()29 void application_init() {
30     SkGraphics::Init();
31     SkEvent::Init();
32 }
33 
application_term()34 void application_term() {
35     SkEvent::Term();
36     SkGraphics::Term();
37 }
38 
SkExampleWindow(void * hwnd)39 SkExampleWindow::SkExampleWindow(void* hwnd)
40     : INHERITED(hwnd) {
41     fRegistry = SkExample::Registry::Head();
42     fCurrExample = fRegistry->factory()(this);
43 
44     if (FLAGS_match.count()) {
45         // 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 
tearDownBackend()53 void 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 
setupBackend(DeviceType type)68 bool SkExampleWindow::setupBackend(DeviceType type) {
69     fType = type;
70 
71     this->setColorType(kRGBA_8888_SkColorType);
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 
setupRenderTarget()94 void SkExampleWindow::setupRenderTarget() {
95     GrBackendRenderTargetDesc desc;
96     desc.fWidth = SkScalarRoundToInt(width());
97     desc.fHeight = SkScalarRoundToInt(height());
98     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 
createCanvas()112 SkCanvas* SkExampleWindow::createCanvas() {
113     if (fType == kGPU_DeviceType) {
114         if (NULL != fContext && NULL != fRenderTarget) {
115             SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(fContext, fRenderTarget));
116             return new SkCanvas(device);
117         }
118         tearDownBackend();
119         setupBackend(kRaster_DeviceType);
120     }
121     return INHERITED::createCanvas();
122 }
123 
draw(SkCanvas * canvas)124 void 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 
onSizeChange()145 void SkExampleWindow::onSizeChange() {
146     setupRenderTarget();
147 }
148 
149 #ifdef SK_BUILD_FOR_WIN
onHandleInval(const SkIRect & rect)150 void 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 
findNextMatch()160 bool 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);
170         if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, next->getName().c_str())) {
171             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 
onHandleChar(SkUnichar unichar)181 bool 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 
create_sk_window(void * hwnd,int argc,char ** argv)191 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
192     SkCommandLineFlags::Parse(argc, argv);
193     return new SkExampleWindow(hwnd);
194 }
195