blob: c0e27d6805a3c4d635b6f33359fb02f063827432 [file] [log] [blame]
reeda1e41c62015-04-09 13:43:22 -07001/*
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
yangsu@google.com688823f2011-08-30 19:14:13 +00008#import "SkSampleUIView.h"
9
reeda1e41c62015-04-09 13:43:22 -070010//#define SKGL_CONFIG kEAGLColorFormatRGB565
11#define SKGL_CONFIG kEAGLColorFormatRGBA8
yangsu@google.com688823f2011-08-30 19:14:13 +000012
13#define FORCE_REDRAW
14
caryclark@google.com5987f582012-10-02 18:33:14 +000015#include "SkCanvas.h"
16#include "SkCGUtils.h"
reedf0b17102014-10-22 13:06:00 -070017#include "SkSurface.h"
caryclark@google.com5987f582012-10-02 18:33:14 +000018#include "SampleApp.h"
19
20#if SK_SUPPORT_GPU
yangsu@google.com688823f2011-08-30 19:14:13 +000021//#define USE_GL_1
22#define USE_GL_2
23
tomhudson@google.com02f90e82012-02-14 15:43:01 +000024#include "gl/GrGLInterface.h"
caryclark@google.com5987f582012-10-02 18:33:14 +000025#include "GrContext.h"
yangsu@google.com688823f2011-08-30 19:14:13 +000026#include "SkGpuDevice.h"
caryclark@google.com5987f582012-10-02 18:33:14 +000027#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +000028
yangsu@google.com688823f2011-08-30 19:14:13 +000029class SkiOSDeviceManager : public SampleWindow::DeviceManager {
30public:
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +000031 SkiOSDeviceManager(GLint layerFBO) {
bsalomon@google.com230504d2012-09-27 16:04:54 +000032#if SK_SUPPORT_GPU
33 fCurContext = NULL;
34 fCurIntf = NULL;
35 fCurRenderTarget = NULL;
36 fMSAASampleCount = 0;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +000037 fLayerFBO = layerFBO;
bsalomon@google.com230504d2012-09-27 16:04:54 +000038#endif
39 fBackend = SkOSWindow::kNone_BackEndType;
yangsu@google.com688823f2011-08-30 19:14:13 +000040 }
41
bsalomon@google.com230504d2012-09-27 16:04:54 +000042 virtual ~SkiOSDeviceManager() {
43#if SK_SUPPORT_GPU
44 SkSafeUnref(fCurContext);
45 SkSafeUnref(fCurIntf);
46 SkSafeUnref(fCurRenderTarget);
yangsu@google.com688823f2011-08-30 19:14:13 +000047#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +000048 }
49
mtklein36352bf2015-03-25 18:17:31 -070050 void setUpBackend(SampleWindow* win, int msaaSampleCount) override {
bsalomon@google.com230504d2012-09-27 16:04:54 +000051 SkASSERT(SkOSWindow::kNone_BackEndType == fBackend);
52
53 fBackend = SkOSWindow::kNone_BackEndType;
54
55#if SK_SUPPORT_GPU
56 switch (win->getDeviceType()) {
57 // these two don't use GL
58 case SampleWindow::kRaster_DeviceType:
59 case SampleWindow::kPicture_DeviceType:
60 break;
61 // these guys use the native backend
62 case SampleWindow::kGPU_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000063 fBackend = SkOSWindow::kNativeGL_BackEndType;
64 break;
65 default:
66 SkASSERT(false);
67 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000068 }
bsalomon@google.com64cc8102013-03-05 20:06:05 +000069 SkOSWindow::AttachmentInfo info;
70 bool result = win->attach(fBackend, msaaSampleCount, &info);
bsalomon@google.com230504d2012-09-27 16:04:54 +000071 if (!result) {
72 SkDebugf("Failed to initialize GL");
73 return;
yangsu@google.com688823f2011-08-30 19:14:13 +000074 }
bsalomon@google.com230504d2012-09-27 16:04:54 +000075 fMSAASampleCount = msaaSampleCount;
76
77 SkASSERT(NULL == fCurIntf);
78 switch (win->getDeviceType()) {
79 // these two don't use GL
yangsu@google.com688823f2011-08-30 19:14:13 +000080 case SampleWindow::kRaster_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000081 case SampleWindow::kPicture_DeviceType:
82 fCurIntf = NULL;
83 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000084 case SampleWindow::kGPU_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000085 fCurIntf = GrGLCreateNativeInterface();
86 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000087 default:
bsalomon@google.com230504d2012-09-27 16:04:54 +000088 SkASSERT(false);
89 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000090 }
bsalomon@google.com230504d2012-09-27 16:04:54 +000091
92 SkASSERT(NULL == fCurContext);
93 if (SkOSWindow::kNone_BackEndType != fBackend) {
bsalomon@google.com365d7872013-02-07 17:01:39 +000094 fCurContext = GrContext::Create(kOpenGL_GrBackend,
95 (GrBackendContext) fCurIntf);
bsalomon@google.com230504d2012-09-27 16:04:54 +000096 }
97
98 if ((NULL == fCurContext || NULL == fCurIntf) &&
99 SkOSWindow::kNone_BackEndType != fBackend) {
100 // We need some context and interface to see results if we're using a GL backend
101 SkSafeUnref(fCurContext);
102 SkSafeUnref(fCurIntf);
103 SkDebugf("Failed to setup 3D");
104 win->detach();
105 }
106#endif // SK_SUPPORT_GPU
107 // call windowSizeChanged to create the render target
108 this->windowSizeChanged(win);
yangsu@google.com688823f2011-08-30 19:14:13 +0000109 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000110
mtklein36352bf2015-03-25 18:17:31 -0700111 void tearDownBackend(SampleWindow *win) override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000112#if SK_SUPPORT_GPU
113 SkSafeUnref(fCurContext);
114 fCurContext = NULL;
115
116 SkSafeUnref(fCurIntf);
117 fCurIntf = NULL;
118
119 SkSafeUnref(fCurRenderTarget);
120 fCurRenderTarget = NULL;
121#endif
122 win->detach();
123 fBackend = SampleWindow::kNone_BackEndType;
124 }
reed@google.com5957f472012-10-01 20:31:56 +0000125
mtklein36352bf2015-03-25 18:17:31 -0700126 SkSurface* createSurface(SampleWindow::DeviceType dType, SampleWindow* win) override{
bsalomon@google.com230504d2012-09-27 16:04:54 +0000127#if SK_SUPPORT_GPU
reedf0b17102014-10-22 13:06:00 -0700128 if (SampleWindow::IsGpuDeviceType(dType) && fCurContext) {
129 SkSurfaceProps props(win->getSurfaceProps());
130 return SkSurface::NewRenderTargetDirect(fCurRenderTarget, &props);
yangsu@google.com688823f2011-08-30 19:14:13 +0000131 }
reedf0b17102014-10-22 13:06:00 -0700132#endif
reed@google.com5957f472012-10-01 20:31:56 +0000133 return NULL;
yangsu@google.com688823f2011-08-30 19:14:13 +0000134 }
reedf0b17102014-10-22 13:06:00 -0700135
yangsu@google.com688823f2011-08-30 19:14:13 +0000136 virtual void publishCanvas(SampleWindow::DeviceType dType,
137 SkCanvas* canvas,
mtklein36352bf2015-03-25 18:17:31 -0700138 SampleWindow* win) override {
caryclark@google.com5987f582012-10-02 18:33:14 +0000139#if SK_SUPPORT_GPU
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000140 if (NULL != fCurContext) {
141 fCurContext->flush();
142 }
caryclark@google.com5987f582012-10-02 18:33:14 +0000143#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +0000144 win->present();
yangsu@google.com688823f2011-08-30 19:14:13 +0000145 }
146
mtklein36352bf2015-03-25 18:17:31 -0700147 void windowSizeChanged(SampleWindow* win) override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000148#if SK_SUPPORT_GPU
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000149 if (NULL != fCurContext) {
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000150 SkOSWindow::AttachmentInfo info;
151
152 win->attach(fBackend, fMSAASampleCount, &info);
yangsu@google.com688823f2011-08-30 19:14:13 +0000153
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000154 glBindFramebuffer(GL_FRAMEBUFFER, fLayerFBO);
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000155 GrBackendRenderTargetDesc desc;
reed@google.com26deb232013-12-17 19:50:57 +0000156 desc.fWidth = SkScalarRoundToInt(win->width());
157 desc.fHeight = SkScalarRoundToInt(win->height());
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000158 desc.fConfig = kSkia8888_GrPixelConfig;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000159 desc.fRenderTargetHandle = fLayerFBO;
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000160 desc.fSampleCnt = info.fSampleCount;
161 desc.fStencilBits = info.fStencilBits;
162
bsalomon@google.com230504d2012-09-27 16:04:54 +0000163 SkSafeUnref(fCurRenderTarget);
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000164 fCurRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
yangsu@google.com688823f2011-08-30 19:14:13 +0000165 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000166#endif
yangsu@google.com688823f2011-08-30 19:14:13 +0000167 }
168
mtklein36352bf2015-03-25 18:17:31 -0700169 GrContext* getGrContext() override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000170#if SK_SUPPORT_GPU
171 return fCurContext;
172#else
173 return NULL;
174#endif
175 }
yangsu@google.com688823f2011-08-30 19:14:13 +0000176
mtklein36352bf2015-03-25 18:17:31 -0700177 GrRenderTarget* getGrRenderTarget() override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000178#if SK_SUPPORT_GPU
179 return fCurRenderTarget;
180#else
181 return NULL;
182#endif
bsalomon@google.com11959252012-04-06 20:13:38 +0000183 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000184
185 bool isUsingGL() const { return SkOSWindow::kNone_BackEndType != fBackend; }
186
yangsu@google.com688823f2011-08-30 19:14:13 +0000187private:
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000188
bsalomon@google.com230504d2012-09-27 16:04:54 +0000189#if SK_SUPPORT_GPU
190 GrContext* fCurContext;
191 const GrGLInterface* fCurIntf;
192 GrRenderTarget* fCurRenderTarget;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000193 int fMSAASampleCount;
194 GLint fLayerFBO;
bsalomon@google.com230504d2012-09-27 16:04:54 +0000195#endif
196
197 SkOSWindow::SkBackEndTypes fBackend;
198
199 typedef SampleWindow::DeviceManager INHERITED;
yangsu@google.com688823f2011-08-30 19:14:13 +0000200};
201
202////////////////////////////////////////////////////////////////////////////////
203@implementation SkSampleUIView
204
205@synthesize fTitle, fRasterLayer, fGLLayer;
206
207#include "SkApplication.h"
208#include "SkEvent.h"
209#include "SkWindow.h"
210
yangsu@google.com688823f2011-08-30 19:14:13 +0000211struct FPSState {
212 static const int FRAME_COUNT = 60;
213
214 CFTimeInterval fNow0, fNow1;
215 CFTimeInterval fTime0, fTime1, fTotalTime;
216 int fFrameCounter;
yangsu@google.com688823f2011-08-30 19:14:13 +0000217 SkString str;
218 FPSState() {
219 fTime0 = fTime1 = fTotalTime = 0;
220 fFrameCounter = 0;
221 }
222
223 void startDraw() {
224 fNow0 = CACurrentMediaTime();
yangsu@google.com688823f2011-08-30 19:14:13 +0000225 }
226
227 void endDraw() {
228 fNow1 = CACurrentMediaTime();
yangsu@google.com688823f2011-08-30 19:14:13 +0000229 }
230
231 void flush(SkOSWindow* hwnd) {
232 CFTimeInterval now2 = CACurrentMediaTime();
233
234 fTime0 += fNow1 - fNow0;
235 fTime1 += now2 - fNow1;
236
237 if (++fFrameCounter == FRAME_COUNT) {
238 CFTimeInterval totalNow = CACurrentMediaTime();
239 fTotalTime = totalNow - fTotalTime;
240
241 //SkMSec ms0 = (int)(1000 * fTime0 / FRAME_COUNT);
242 //SkMSec msTotal = (int)(1000 * fTotalTime / FRAME_COUNT);
243 //str.printf(" ms: %d [%d], fps: %3.1f", msTotal, ms0,
244 // FRAME_COUNT / fTotalTime);
245 str.printf(" fps:%3.1f", FRAME_COUNT / fTotalTime);
246 hwnd->setTitle(NULL);
247 fTotalTime = totalNow;
248 fTime0 = fTime1 = 0;
249 fFrameCounter = 0;
250 }
251 }
252};
253
254static FPSState gFPS;
255
256#define FPS_StartDraw() gFPS.startDraw()
257#define FPS_EndDraw() gFPS.endDraw()
258#define FPS_Flush(wind) gFPS.flush(wind)
259
260///////////////////////////////////////////////////////////////////////////////
261
262- (id)initWithDefaults {
263 if (self = [super initWithDefaults]) {
264 fRedrawRequestPending = false;
265 fFPSState = new FPSState;
266
267#ifdef USE_GL_1
268 fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
269#else
270 fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
271#endif
272
273 if (!fGL.fContext || ![EAGLContext setCurrentContext:fGL.fContext])
274 {
275 [self release];
276 return nil;
277 }
278
279 // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
280 glGenFramebuffers(1, &fGL.fFramebuffer);
281 glBindFramebuffer(GL_FRAMEBUFFER, fGL.fFramebuffer);
282
283 glGenRenderbuffers(1, &fGL.fRenderbuffer);
284 glGenRenderbuffers(1, &fGL.fStencilbuffer);
285
286 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
287 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fGL.fRenderbuffer);
288
289 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fStencilbuffer);
290 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fGL.fStencilbuffer);
291
292 self.fGLLayer = [CAEAGLLayer layer];
293 fGLLayer.bounds = self.bounds;
294 fGLLayer.anchorPoint = CGPointMake(0, 0);
295 fGLLayer.opaque = TRUE;
296 [self.layer addSublayer:fGLLayer];
297 fGLLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
298 [NSNumber numberWithBool:NO],
299 kEAGLDrawablePropertyRetainedBacking,
300 SKGL_CONFIG,
301 kEAGLDrawablePropertyColorFormat,
302 nil];
303
304 self.fRasterLayer = [CALayer layer];
305 fRasterLayer.anchorPoint = CGPointMake(0, 0);
306 fRasterLayer.opaque = TRUE;
307 [self.layer addSublayer:fRasterLayer];
308
caryclark@google.com5987f582012-10-02 18:33:14 +0000309 NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"onOrderIn",
yangsu@google.com688823f2011-08-30 19:14:13 +0000310 [NSNull null], @"onOrderOut",
311 [NSNull null], @"sublayers",
312 [NSNull null], @"contents",
313 [NSNull null], @"bounds",
314 nil];
315 fGLLayer.actions = newActions;
316 fRasterLayer.actions = newActions;
317 [newActions release];
318
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000319 fDevManager = new SkiOSDeviceManager(fGL.fFramebuffer);
caryclark@google.com5987f582012-10-02 18:33:14 +0000320 static char* kDummyArgv = const_cast<char*>("dummyExecutableName");
bsalomon@google.com230504d2012-09-27 16:04:54 +0000321 fWind = new SampleWindow(self, 1, &kDummyArgv, fDevManager);
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000322
commit-bot@chromium.orgb45c56e2014-02-18 23:32:05 +0000323 fWind->resize(self.frame.size.width, self.frame.size.height,
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +0000324 kN32_SkColorType);
yangsu@google.com688823f2011-08-30 19:14:13 +0000325 }
326 return self;
327}
328
329- (void)dealloc {
330 delete fDevManager;
331 delete fFPSState;
332 self.fRasterLayer = nil;
333 self.fGLLayer = nil;
334 [fGL.fContext release];
335 [super dealloc];
336}
337
338- (void)layoutSubviews {
339 int W, H;
340
341 // Allocate color buffer backing based on the current layer size
342 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
343 [fGL.fContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:fGLLayer];
344
345 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &fGL.fWidth);
346 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &fGL.fHeight);
347
348 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fStencilbuffer);
349 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, fGL.fWidth, fGL.fHeight);
350
351 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
352 NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
353 }
354
355 if (fDevManager->isUsingGL()) {
356 W = fGL.fWidth;
357 H = fGL.fHeight;
358 CGRect rect = CGRectMake(0, 0, W, H);
359 fGLLayer.bounds = rect;
360 }
361 else {
362 CGRect rect = self.bounds;
363 W = (int)CGRectGetWidth(rect);
364 H = (int)CGRectGetHeight(rect);
365 fRasterLayer.bounds = rect;
366 }
367
368 printf("---- layoutSubviews %d %d\n", W, H);
369 fWind->resize(W, H);
370 fWind->inval(NULL);
371}
372
373///////////////////////////////////////////////////////////////////////////////
374
375- (void)drawWithCanvas:(SkCanvas*)canvas {
376 fRedrawRequestPending = false;
377 fFPSState->startDraw();
378 fWind->draw(canvas);
379 fFPSState->endDraw();
380#ifdef FORCE_REDRAW
381 fWind->inval(NULL);
382#endif
383 fFPSState->flush(fWind);
384}
385
386- (void)drawInGL {
387 // This application only creates a single context which is already set current at this point.
388 // This call is redundant, but needed if dealing with multiple contexts.
389 [EAGLContext setCurrentContext:fGL.fContext];
390
391 // This application only creates a single default framebuffer which is already bound at this point.
392 // This call is redundant, but needed if dealing with multiple framebuffers.
393 glBindFramebuffer(GL_FRAMEBUFFER, fGL.fFramebuffer);
394
395 GLint scissorEnable;
396 glGetIntegerv(GL_SCISSOR_TEST, &scissorEnable);
397 glDisable(GL_SCISSOR_TEST);
398 glClearColor(0,0,0,0);
399 glClear(GL_COLOR_BUFFER_BIT);
400 if (scissorEnable) {
401 glEnable(GL_SCISSOR_TEST);
402 }
403 glViewport(0, 0, fGL.fWidth, fGL.fHeight);
404
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000405
reedf0b17102014-10-22 13:06:00 -0700406 SkAutoTUnref<SkSurface> surface(fWind->createSurface());
407 SkCanvas* canvas = surface->getCanvas();
408
yangsu@google.com688823f2011-08-30 19:14:13 +0000409 // if we're not "retained", then we have to always redraw everything.
410 // This call forces us to ignore the fDirtyRgn, and draw everywhere.
411 // If we are "retained", we can skip this call (as the raster case does)
412 fWind->forceInvalAll();
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000413
reed@google.com5957f472012-10-01 20:31:56 +0000414 [self drawWithCanvas:canvas];
reedf0b17102014-10-22 13:06:00 -0700415
yangsu@google.com688823f2011-08-30 19:14:13 +0000416 // This application only creates a single color renderbuffer which is already bound at this point.
417 // This call is redundant, but needed if dealing with multiple renderbuffers.
418 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
419 [fGL.fContext presentRenderbuffer:GL_RENDERBUFFER];
yangsu@google.com688823f2011-08-30 19:14:13 +0000420}
421
422- (void)drawInRaster {
reedf0b17102014-10-22 13:06:00 -0700423 SkAutoTUnref<SkSurface> surface(fWind->createSurface());
424 SkCanvas* canvas = surface->getCanvas();
reed@google.com5957f472012-10-01 20:31:56 +0000425 [self drawWithCanvas:canvas];
yangsu@google.com688823f2011-08-30 19:14:13 +0000426 CGImageRef cgimage = SkCreateCGImageRef(fWind->getBitmap());
427 fRasterLayer.contents = (id)cgimage;
428 CGImageRelease(cgimage);
429}
430
431- (void)forceRedraw {
432 if (fDevManager->isUsingGL())
433 [self drawInGL];
434 else
435 [self drawInRaster];
436}
437
438///////////////////////////////////////////////////////////////////////////////
439
440- (void)setSkTitle:(const char *)title {
441 NSString* text = [NSString stringWithUTF8String:title];
442 if ([text length] > 0)
443 self.fTitle = text;
444
445 if (fTitleItem && fTitle) {
446 fTitleItem.title = [NSString stringWithFormat:@"%@%@", fTitle,
447 [NSString stringWithUTF8String:fFPSState->str.c_str()]];
448 }
449}
450
451- (void)postInvalWithRect:(const SkIRect*)r {
452 if (!fRedrawRequestPending) {
453 fRedrawRequestPending = true;
454 bool gl = fDevManager->isUsingGL();
455 [CATransaction begin];
456 [CATransaction setAnimationDuration:0];
457 fRasterLayer.hidden = gl;
458 fGLLayer.hidden = !gl;
459 [CATransaction commit];
460 if (gl) {
461 [self performSelector:@selector(drawInGL) withObject:nil afterDelay:0];
462 }
463 else {
464 [self performSelector:@selector(drawInRaster) withObject:nil afterDelay:0];
465 [self setNeedsDisplay];
466 }
467 }
468}
469
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000470- (void)getAttachmentInfo:(SkOSWindow::AttachmentInfo*)info {
471 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
472 glGetRenderbufferParameteriv(GL_RENDERBUFFER,
473 GL_RENDERBUFFER_STENCIL_SIZE,
474 &info->fStencilBits);
475 glGetRenderbufferParameteriv(GL_RENDERBUFFER,
476 GL_RENDERBUFFER_SAMPLES_APPLE,
477 &info->fSampleCount);
478}
479
yangsu@google.com688823f2011-08-30 19:14:13 +0000480@end