blob: 6234739e07212cf7e71904e18a700d046caf360b [file] [log] [blame]
yangsu@google.com688823f2011-08-30 19:14:13 +00001#import "SkSampleUIView.h"
2
yangsu@google.com688823f2011-08-30 19:14:13 +00003#define SKGL_CONFIG kEAGLColorFormatRGB565
4//#define SKGL_CONFIG kEAGLColorFormatRGBA8
5
6#define FORCE_REDRAW
7
caryclark@google.com5987f582012-10-02 18:33:14 +00008#include "SkCanvas.h"
9#include "SkCGUtils.h"
reedf0b17102014-10-22 13:06:00 -070010#include "SkSurface.h"
caryclark@google.com5987f582012-10-02 18:33:14 +000011#include "SampleApp.h"
12
13#if SK_SUPPORT_GPU
yangsu@google.com688823f2011-08-30 19:14:13 +000014//#define USE_GL_1
15#define USE_GL_2
16
tomhudson@google.com02f90e82012-02-14 15:43:01 +000017#include "gl/GrGLInterface.h"
caryclark@google.com5987f582012-10-02 18:33:14 +000018#include "GrContext.h"
yangsu@google.com688823f2011-08-30 19:14:13 +000019#include "SkGpuDevice.h"
caryclark@google.com5987f582012-10-02 18:33:14 +000020#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +000021
yangsu@google.com688823f2011-08-30 19:14:13 +000022class SkiOSDeviceManager : public SampleWindow::DeviceManager {
23public:
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +000024 SkiOSDeviceManager(GLint layerFBO) {
bsalomon@google.com230504d2012-09-27 16:04:54 +000025#if SK_SUPPORT_GPU
26 fCurContext = NULL;
27 fCurIntf = NULL;
28 fCurRenderTarget = NULL;
29 fMSAASampleCount = 0;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +000030 fLayerFBO = layerFBO;
bsalomon@google.com230504d2012-09-27 16:04:54 +000031#endif
32 fBackend = SkOSWindow::kNone_BackEndType;
yangsu@google.com688823f2011-08-30 19:14:13 +000033 }
34
bsalomon@google.com230504d2012-09-27 16:04:54 +000035 virtual ~SkiOSDeviceManager() {
36#if SK_SUPPORT_GPU
37 SkSafeUnref(fCurContext);
38 SkSafeUnref(fCurIntf);
39 SkSafeUnref(fCurRenderTarget);
yangsu@google.com688823f2011-08-30 19:14:13 +000040#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +000041 }
42
mtklein72c9faa2015-01-09 10:06:39 -080043 void setUpBackend(SampleWindow* win, int msaaSampleCount) SK_OVERRIDE {
bsalomon@google.com230504d2012-09-27 16:04:54 +000044 SkASSERT(SkOSWindow::kNone_BackEndType == fBackend);
45
46 fBackend = SkOSWindow::kNone_BackEndType;
47
48#if SK_SUPPORT_GPU
49 switch (win->getDeviceType()) {
50 // these two don't use GL
51 case SampleWindow::kRaster_DeviceType:
52 case SampleWindow::kPicture_DeviceType:
53 break;
54 // these guys use the native backend
55 case SampleWindow::kGPU_DeviceType:
56 case SampleWindow::kNullGPU_DeviceType:
57 fBackend = SkOSWindow::kNativeGL_BackEndType;
58 break;
59 default:
60 SkASSERT(false);
61 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000062 }
bsalomon@google.com64cc8102013-03-05 20:06:05 +000063 SkOSWindow::AttachmentInfo info;
64 bool result = win->attach(fBackend, msaaSampleCount, &info);
bsalomon@google.com230504d2012-09-27 16:04:54 +000065 if (!result) {
66 SkDebugf("Failed to initialize GL");
67 return;
yangsu@google.com688823f2011-08-30 19:14:13 +000068 }
bsalomon@google.com230504d2012-09-27 16:04:54 +000069 fMSAASampleCount = msaaSampleCount;
70
71 SkASSERT(NULL == fCurIntf);
72 switch (win->getDeviceType()) {
73 // these two don't use GL
yangsu@google.com688823f2011-08-30 19:14:13 +000074 case SampleWindow::kRaster_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000075 case SampleWindow::kPicture_DeviceType:
76 fCurIntf = NULL;
77 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000078 case SampleWindow::kGPU_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000079 fCurIntf = GrGLCreateNativeInterface();
80 break;
81 case SampleWindow::kNullGPU_DeviceType:
82 fCurIntf = GrGLCreateNullInterface();
83 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000084 default:
bsalomon@google.com230504d2012-09-27 16:04:54 +000085 SkASSERT(false);
86 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000087 }
bsalomon@google.com230504d2012-09-27 16:04:54 +000088
89 SkASSERT(NULL == fCurContext);
90 if (SkOSWindow::kNone_BackEndType != fBackend) {
bsalomon@google.com365d7872013-02-07 17:01:39 +000091 fCurContext = GrContext::Create(kOpenGL_GrBackend,
92 (GrBackendContext) fCurIntf);
bsalomon@google.com230504d2012-09-27 16:04:54 +000093 }
94
95 if ((NULL == fCurContext || NULL == fCurIntf) &&
96 SkOSWindow::kNone_BackEndType != fBackend) {
97 // We need some context and interface to see results if we're using a GL backend
98 SkSafeUnref(fCurContext);
99 SkSafeUnref(fCurIntf);
100 SkDebugf("Failed to setup 3D");
101 win->detach();
102 }
103#endif // SK_SUPPORT_GPU
104 // call windowSizeChanged to create the render target
105 this->windowSizeChanged(win);
yangsu@google.com688823f2011-08-30 19:14:13 +0000106 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000107
mtklein72c9faa2015-01-09 10:06:39 -0800108 void tearDownBackend(SampleWindow *win) SK_OVERRIDE {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000109#if SK_SUPPORT_GPU
110 SkSafeUnref(fCurContext);
111 fCurContext = NULL;
112
113 SkSafeUnref(fCurIntf);
114 fCurIntf = NULL;
115
116 SkSafeUnref(fCurRenderTarget);
117 fCurRenderTarget = NULL;
118#endif
119 win->detach();
120 fBackend = SampleWindow::kNone_BackEndType;
121 }
reed@google.com5957f472012-10-01 20:31:56 +0000122
mtklein72c9faa2015-01-09 10:06:39 -0800123 SkSurface* createSurface(SampleWindow::DeviceType dType, SampleWindow* win) SK_OVERRIDE{
bsalomon@google.com230504d2012-09-27 16:04:54 +0000124#if SK_SUPPORT_GPU
reedf0b17102014-10-22 13:06:00 -0700125 if (SampleWindow::IsGpuDeviceType(dType) && fCurContext) {
126 SkSurfaceProps props(win->getSurfaceProps());
127 return SkSurface::NewRenderTargetDirect(fCurRenderTarget, &props);
yangsu@google.com688823f2011-08-30 19:14:13 +0000128 }
reedf0b17102014-10-22 13:06:00 -0700129#endif
reed@google.com5957f472012-10-01 20:31:56 +0000130 return NULL;
yangsu@google.com688823f2011-08-30 19:14:13 +0000131 }
reedf0b17102014-10-22 13:06:00 -0700132
yangsu@google.com688823f2011-08-30 19:14:13 +0000133 virtual void publishCanvas(SampleWindow::DeviceType dType,
134 SkCanvas* canvas,
bsalomon@google.com230504d2012-09-27 16:04:54 +0000135 SampleWindow* win) SK_OVERRIDE {
caryclark@google.com5987f582012-10-02 18:33:14 +0000136#if SK_SUPPORT_GPU
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000137 if (NULL != fCurContext) {
138 fCurContext->flush();
139 }
caryclark@google.com5987f582012-10-02 18:33:14 +0000140#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +0000141 win->present();
yangsu@google.com688823f2011-08-30 19:14:13 +0000142 }
143
mtklein72c9faa2015-01-09 10:06:39 -0800144 void windowSizeChanged(SampleWindow* win) SK_OVERRIDE {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000145#if SK_SUPPORT_GPU
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000146 if (NULL != fCurContext) {
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000147 SkOSWindow::AttachmentInfo info;
148
149 win->attach(fBackend, fMSAASampleCount, &info);
yangsu@google.com688823f2011-08-30 19:14:13 +0000150
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000151 glBindFramebuffer(GL_FRAMEBUFFER, fLayerFBO);
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000152 GrBackendRenderTargetDesc desc;
reed@google.com26deb232013-12-17 19:50:57 +0000153 desc.fWidth = SkScalarRoundToInt(win->width());
154 desc.fHeight = SkScalarRoundToInt(win->height());
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000155 desc.fConfig = kSkia8888_GrPixelConfig;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000156 desc.fRenderTargetHandle = fLayerFBO;
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000157 desc.fSampleCnt = info.fSampleCount;
158 desc.fStencilBits = info.fStencilBits;
159
bsalomon@google.com230504d2012-09-27 16:04:54 +0000160 SkSafeUnref(fCurRenderTarget);
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000161 fCurRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
yangsu@google.com688823f2011-08-30 19:14:13 +0000162 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000163#endif
yangsu@google.com688823f2011-08-30 19:14:13 +0000164 }
165
mtklein72c9faa2015-01-09 10:06:39 -0800166 GrContext* getGrContext() SK_OVERRIDE {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000167#if SK_SUPPORT_GPU
168 return fCurContext;
169#else
170 return NULL;
171#endif
172 }
yangsu@google.com688823f2011-08-30 19:14:13 +0000173
mtklein72c9faa2015-01-09 10:06:39 -0800174 GrRenderTarget* getGrRenderTarget() SK_OVERRIDE {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000175#if SK_SUPPORT_GPU
176 return fCurRenderTarget;
177#else
178 return NULL;
179#endif
bsalomon@google.com11959252012-04-06 20:13:38 +0000180 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000181
182 bool isUsingGL() const { return SkOSWindow::kNone_BackEndType != fBackend; }
183
yangsu@google.com688823f2011-08-30 19:14:13 +0000184private:
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000185
bsalomon@google.com230504d2012-09-27 16:04:54 +0000186#if SK_SUPPORT_GPU
187 GrContext* fCurContext;
188 const GrGLInterface* fCurIntf;
189 GrRenderTarget* fCurRenderTarget;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000190 int fMSAASampleCount;
191 GLint fLayerFBO;
bsalomon@google.com230504d2012-09-27 16:04:54 +0000192#endif
193
194 SkOSWindow::SkBackEndTypes fBackend;
195
196 typedef SampleWindow::DeviceManager INHERITED;
yangsu@google.com688823f2011-08-30 19:14:13 +0000197};
198
199////////////////////////////////////////////////////////////////////////////////
200@implementation SkSampleUIView
201
202@synthesize fTitle, fRasterLayer, fGLLayer;
203
204#include "SkApplication.h"
205#include "SkEvent.h"
206#include "SkWindow.h"
207
yangsu@google.com688823f2011-08-30 19:14:13 +0000208struct FPSState {
209 static const int FRAME_COUNT = 60;
210
211 CFTimeInterval fNow0, fNow1;
212 CFTimeInterval fTime0, fTime1, fTotalTime;
213 int fFrameCounter;
yangsu@google.com688823f2011-08-30 19:14:13 +0000214 SkString str;
215 FPSState() {
216 fTime0 = fTime1 = fTotalTime = 0;
217 fFrameCounter = 0;
218 }
219
220 void startDraw() {
221 fNow0 = CACurrentMediaTime();
yangsu@google.com688823f2011-08-30 19:14:13 +0000222 }
223
224 void endDraw() {
225 fNow1 = CACurrentMediaTime();
yangsu@google.com688823f2011-08-30 19:14:13 +0000226 }
227
228 void flush(SkOSWindow* hwnd) {
229 CFTimeInterval now2 = CACurrentMediaTime();
230
231 fTime0 += fNow1 - fNow0;
232 fTime1 += now2 - fNow1;
233
234 if (++fFrameCounter == FRAME_COUNT) {
235 CFTimeInterval totalNow = CACurrentMediaTime();
236 fTotalTime = totalNow - fTotalTime;
237
238 //SkMSec ms0 = (int)(1000 * fTime0 / FRAME_COUNT);
239 //SkMSec msTotal = (int)(1000 * fTotalTime / FRAME_COUNT);
240 //str.printf(" ms: %d [%d], fps: %3.1f", msTotal, ms0,
241 // FRAME_COUNT / fTotalTime);
242 str.printf(" fps:%3.1f", FRAME_COUNT / fTotalTime);
243 hwnd->setTitle(NULL);
244 fTotalTime = totalNow;
245 fTime0 = fTime1 = 0;
246 fFrameCounter = 0;
247 }
248 }
249};
250
251static FPSState gFPS;
252
253#define FPS_StartDraw() gFPS.startDraw()
254#define FPS_EndDraw() gFPS.endDraw()
255#define FPS_Flush(wind) gFPS.flush(wind)
256
257///////////////////////////////////////////////////////////////////////////////
258
259- (id)initWithDefaults {
260 if (self = [super initWithDefaults]) {
261 fRedrawRequestPending = false;
262 fFPSState = new FPSState;
263
264#ifdef USE_GL_1
265 fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
266#else
267 fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
268#endif
269
270 if (!fGL.fContext || ![EAGLContext setCurrentContext:fGL.fContext])
271 {
272 [self release];
273 return nil;
274 }
275
276 // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
277 glGenFramebuffers(1, &fGL.fFramebuffer);
278 glBindFramebuffer(GL_FRAMEBUFFER, fGL.fFramebuffer);
279
280 glGenRenderbuffers(1, &fGL.fRenderbuffer);
281 glGenRenderbuffers(1, &fGL.fStencilbuffer);
282
283 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
284 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fGL.fRenderbuffer);
285
286 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fStencilbuffer);
287 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fGL.fStencilbuffer);
288
289 self.fGLLayer = [CAEAGLLayer layer];
290 fGLLayer.bounds = self.bounds;
291 fGLLayer.anchorPoint = CGPointMake(0, 0);
292 fGLLayer.opaque = TRUE;
293 [self.layer addSublayer:fGLLayer];
294 fGLLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
295 [NSNumber numberWithBool:NO],
296 kEAGLDrawablePropertyRetainedBacking,
297 SKGL_CONFIG,
298 kEAGLDrawablePropertyColorFormat,
299 nil];
300
301 self.fRasterLayer = [CALayer layer];
302 fRasterLayer.anchorPoint = CGPointMake(0, 0);
303 fRasterLayer.opaque = TRUE;
304 [self.layer addSublayer:fRasterLayer];
305
caryclark@google.com5987f582012-10-02 18:33:14 +0000306 NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"onOrderIn",
yangsu@google.com688823f2011-08-30 19:14:13 +0000307 [NSNull null], @"onOrderOut",
308 [NSNull null], @"sublayers",
309 [NSNull null], @"contents",
310 [NSNull null], @"bounds",
311 nil];
312 fGLLayer.actions = newActions;
313 fRasterLayer.actions = newActions;
314 [newActions release];
315
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000316 fDevManager = new SkiOSDeviceManager(fGL.fFramebuffer);
caryclark@google.com5987f582012-10-02 18:33:14 +0000317 static char* kDummyArgv = const_cast<char*>("dummyExecutableName");
bsalomon@google.com230504d2012-09-27 16:04:54 +0000318 fWind = new SampleWindow(self, 1, &kDummyArgv, fDevManager);
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000319
commit-bot@chromium.orgb45c56e2014-02-18 23:32:05 +0000320 fWind->resize(self.frame.size.width, self.frame.size.height,
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +0000321 kN32_SkColorType);
yangsu@google.com688823f2011-08-30 19:14:13 +0000322 }
323 return self;
324}
325
326- (void)dealloc {
327 delete fDevManager;
328 delete fFPSState;
329 self.fRasterLayer = nil;
330 self.fGLLayer = nil;
331 [fGL.fContext release];
332 [super dealloc];
333}
334
335- (void)layoutSubviews {
336 int W, H;
337
338 // Allocate color buffer backing based on the current layer size
339 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
340 [fGL.fContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:fGLLayer];
341
342 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &fGL.fWidth);
343 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &fGL.fHeight);
344
345 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fStencilbuffer);
346 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, fGL.fWidth, fGL.fHeight);
347
348 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
349 NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
350 }
351
352 if (fDevManager->isUsingGL()) {
353 W = fGL.fWidth;
354 H = fGL.fHeight;
355 CGRect rect = CGRectMake(0, 0, W, H);
356 fGLLayer.bounds = rect;
357 }
358 else {
359 CGRect rect = self.bounds;
360 W = (int)CGRectGetWidth(rect);
361 H = (int)CGRectGetHeight(rect);
362 fRasterLayer.bounds = rect;
363 }
364
365 printf("---- layoutSubviews %d %d\n", W, H);
366 fWind->resize(W, H);
367 fWind->inval(NULL);
368}
369
370///////////////////////////////////////////////////////////////////////////////
371
372- (void)drawWithCanvas:(SkCanvas*)canvas {
373 fRedrawRequestPending = false;
374 fFPSState->startDraw();
375 fWind->draw(canvas);
376 fFPSState->endDraw();
377#ifdef FORCE_REDRAW
378 fWind->inval(NULL);
379#endif
380 fFPSState->flush(fWind);
381}
382
383- (void)drawInGL {
384 // This application only creates a single context which is already set current at this point.
385 // This call is redundant, but needed if dealing with multiple contexts.
386 [EAGLContext setCurrentContext:fGL.fContext];
387
388 // This application only creates a single default framebuffer which is already bound at this point.
389 // This call is redundant, but needed if dealing with multiple framebuffers.
390 glBindFramebuffer(GL_FRAMEBUFFER, fGL.fFramebuffer);
391
392 GLint scissorEnable;
393 glGetIntegerv(GL_SCISSOR_TEST, &scissorEnable);
394 glDisable(GL_SCISSOR_TEST);
395 glClearColor(0,0,0,0);
396 glClear(GL_COLOR_BUFFER_BIT);
397 if (scissorEnable) {
398 glEnable(GL_SCISSOR_TEST);
399 }
400 glViewport(0, 0, fGL.fWidth, fGL.fHeight);
401
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000402
reedf0b17102014-10-22 13:06:00 -0700403 SkAutoTUnref<SkSurface> surface(fWind->createSurface());
404 SkCanvas* canvas = surface->getCanvas();
405
yangsu@google.com688823f2011-08-30 19:14:13 +0000406 // if we're not "retained", then we have to always redraw everything.
407 // This call forces us to ignore the fDirtyRgn, and draw everywhere.
408 // If we are "retained", we can skip this call (as the raster case does)
409 fWind->forceInvalAll();
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000410
reed@google.com5957f472012-10-01 20:31:56 +0000411 [self drawWithCanvas:canvas];
reedf0b17102014-10-22 13:06:00 -0700412
yangsu@google.com688823f2011-08-30 19:14:13 +0000413 // This application only creates a single color renderbuffer which is already bound at this point.
414 // This call is redundant, but needed if dealing with multiple renderbuffers.
415 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
416 [fGL.fContext presentRenderbuffer:GL_RENDERBUFFER];
yangsu@google.com688823f2011-08-30 19:14:13 +0000417}
418
419- (void)drawInRaster {
reedf0b17102014-10-22 13:06:00 -0700420 SkAutoTUnref<SkSurface> surface(fWind->createSurface());
421 SkCanvas* canvas = surface->getCanvas();
reed@google.com5957f472012-10-01 20:31:56 +0000422 [self drawWithCanvas:canvas];
yangsu@google.com688823f2011-08-30 19:14:13 +0000423 CGImageRef cgimage = SkCreateCGImageRef(fWind->getBitmap());
424 fRasterLayer.contents = (id)cgimage;
425 CGImageRelease(cgimage);
426}
427
428- (void)forceRedraw {
429 if (fDevManager->isUsingGL())
430 [self drawInGL];
431 else
432 [self drawInRaster];
433}
434
435///////////////////////////////////////////////////////////////////////////////
436
437- (void)setSkTitle:(const char *)title {
438 NSString* text = [NSString stringWithUTF8String:title];
439 if ([text length] > 0)
440 self.fTitle = text;
441
442 if (fTitleItem && fTitle) {
443 fTitleItem.title = [NSString stringWithFormat:@"%@%@", fTitle,
444 [NSString stringWithUTF8String:fFPSState->str.c_str()]];
445 }
446}
447
448- (void)postInvalWithRect:(const SkIRect*)r {
449 if (!fRedrawRequestPending) {
450 fRedrawRequestPending = true;
451 bool gl = fDevManager->isUsingGL();
452 [CATransaction begin];
453 [CATransaction setAnimationDuration:0];
454 fRasterLayer.hidden = gl;
455 fGLLayer.hidden = !gl;
456 [CATransaction commit];
457 if (gl) {
458 [self performSelector:@selector(drawInGL) withObject:nil afterDelay:0];
459 }
460 else {
461 [self performSelector:@selector(drawInRaster) withObject:nil afterDelay:0];
462 [self setNeedsDisplay];
463 }
464 }
465}
466
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000467- (void)getAttachmentInfo:(SkOSWindow::AttachmentInfo*)info {
468 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
469 glGetRenderbufferParameteriv(GL_RENDERBUFFER,
470 GL_RENDERBUFFER_STENCIL_SIZE,
471 &info->fStencilBits);
472 glGetRenderbufferParameteriv(GL_RENDERBUFFER,
473 GL_RENDERBUFFER_SAMPLES_APPLE,
474 &info->fSampleCount);
475}
476
yangsu@google.com688823f2011-08-30 19:14:13 +0000477@end