blob: 0d7a4db2bd170cc1015d8e2860e925e526c0435b [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
mtklein36352bf2015-03-25 18:17:31 -070043 void setUpBackend(SampleWindow* win, int msaaSampleCount) 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:
bsalomon@google.com230504d2012-09-27 16:04:54 +000056 fBackend = SkOSWindow::kNativeGL_BackEndType;
57 break;
58 default:
59 SkASSERT(false);
60 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000061 }
bsalomon@google.com64cc8102013-03-05 20:06:05 +000062 SkOSWindow::AttachmentInfo info;
63 bool result = win->attach(fBackend, msaaSampleCount, &info);
bsalomon@google.com230504d2012-09-27 16:04:54 +000064 if (!result) {
65 SkDebugf("Failed to initialize GL");
66 return;
yangsu@google.com688823f2011-08-30 19:14:13 +000067 }
bsalomon@google.com230504d2012-09-27 16:04:54 +000068 fMSAASampleCount = msaaSampleCount;
69
70 SkASSERT(NULL == fCurIntf);
71 switch (win->getDeviceType()) {
72 // these two don't use GL
yangsu@google.com688823f2011-08-30 19:14:13 +000073 case SampleWindow::kRaster_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000074 case SampleWindow::kPicture_DeviceType:
75 fCurIntf = NULL;
76 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000077 case SampleWindow::kGPU_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000078 fCurIntf = GrGLCreateNativeInterface();
79 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000080 default:
bsalomon@google.com230504d2012-09-27 16:04:54 +000081 SkASSERT(false);
82 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000083 }
bsalomon@google.com230504d2012-09-27 16:04:54 +000084
85 SkASSERT(NULL == fCurContext);
86 if (SkOSWindow::kNone_BackEndType != fBackend) {
bsalomon@google.com365d7872013-02-07 17:01:39 +000087 fCurContext = GrContext::Create(kOpenGL_GrBackend,
88 (GrBackendContext) fCurIntf);
bsalomon@google.com230504d2012-09-27 16:04:54 +000089 }
90
91 if ((NULL == fCurContext || NULL == fCurIntf) &&
92 SkOSWindow::kNone_BackEndType != fBackend) {
93 // We need some context and interface to see results if we're using a GL backend
94 SkSafeUnref(fCurContext);
95 SkSafeUnref(fCurIntf);
96 SkDebugf("Failed to setup 3D");
97 win->detach();
98 }
99#endif // SK_SUPPORT_GPU
100 // call windowSizeChanged to create the render target
101 this->windowSizeChanged(win);
yangsu@google.com688823f2011-08-30 19:14:13 +0000102 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000103
mtklein36352bf2015-03-25 18:17:31 -0700104 void tearDownBackend(SampleWindow *win) override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000105#if SK_SUPPORT_GPU
106 SkSafeUnref(fCurContext);
107 fCurContext = NULL;
108
109 SkSafeUnref(fCurIntf);
110 fCurIntf = NULL;
111
112 SkSafeUnref(fCurRenderTarget);
113 fCurRenderTarget = NULL;
114#endif
115 win->detach();
116 fBackend = SampleWindow::kNone_BackEndType;
117 }
reed@google.com5957f472012-10-01 20:31:56 +0000118
mtklein36352bf2015-03-25 18:17:31 -0700119 SkSurface* createSurface(SampleWindow::DeviceType dType, SampleWindow* win) override{
bsalomon@google.com230504d2012-09-27 16:04:54 +0000120#if SK_SUPPORT_GPU
reedf0b17102014-10-22 13:06:00 -0700121 if (SampleWindow::IsGpuDeviceType(dType) && fCurContext) {
122 SkSurfaceProps props(win->getSurfaceProps());
123 return SkSurface::NewRenderTargetDirect(fCurRenderTarget, &props);
yangsu@google.com688823f2011-08-30 19:14:13 +0000124 }
reedf0b17102014-10-22 13:06:00 -0700125#endif
reed@google.com5957f472012-10-01 20:31:56 +0000126 return NULL;
yangsu@google.com688823f2011-08-30 19:14:13 +0000127 }
reedf0b17102014-10-22 13:06:00 -0700128
yangsu@google.com688823f2011-08-30 19:14:13 +0000129 virtual void publishCanvas(SampleWindow::DeviceType dType,
130 SkCanvas* canvas,
mtklein36352bf2015-03-25 18:17:31 -0700131 SampleWindow* win) override {
caryclark@google.com5987f582012-10-02 18:33:14 +0000132#if SK_SUPPORT_GPU
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000133 if (NULL != fCurContext) {
134 fCurContext->flush();
135 }
caryclark@google.com5987f582012-10-02 18:33:14 +0000136#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +0000137 win->present();
yangsu@google.com688823f2011-08-30 19:14:13 +0000138 }
139
mtklein36352bf2015-03-25 18:17:31 -0700140 void windowSizeChanged(SampleWindow* win) override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000141#if SK_SUPPORT_GPU
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000142 if (NULL != fCurContext) {
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000143 SkOSWindow::AttachmentInfo info;
144
145 win->attach(fBackend, fMSAASampleCount, &info);
yangsu@google.com688823f2011-08-30 19:14:13 +0000146
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000147 glBindFramebuffer(GL_FRAMEBUFFER, fLayerFBO);
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000148 GrBackendRenderTargetDesc desc;
reed@google.com26deb232013-12-17 19:50:57 +0000149 desc.fWidth = SkScalarRoundToInt(win->width());
150 desc.fHeight = SkScalarRoundToInt(win->height());
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000151 desc.fConfig = kSkia8888_GrPixelConfig;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000152 desc.fRenderTargetHandle = fLayerFBO;
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000153 desc.fSampleCnt = info.fSampleCount;
154 desc.fStencilBits = info.fStencilBits;
155
bsalomon@google.com230504d2012-09-27 16:04:54 +0000156 SkSafeUnref(fCurRenderTarget);
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000157 fCurRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
yangsu@google.com688823f2011-08-30 19:14:13 +0000158 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000159#endif
yangsu@google.com688823f2011-08-30 19:14:13 +0000160 }
161
mtklein36352bf2015-03-25 18:17:31 -0700162 GrContext* getGrContext() override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000163#if SK_SUPPORT_GPU
164 return fCurContext;
165#else
166 return NULL;
167#endif
168 }
yangsu@google.com688823f2011-08-30 19:14:13 +0000169
mtklein36352bf2015-03-25 18:17:31 -0700170 GrRenderTarget* getGrRenderTarget() override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000171#if SK_SUPPORT_GPU
172 return fCurRenderTarget;
173#else
174 return NULL;
175#endif
bsalomon@google.com11959252012-04-06 20:13:38 +0000176 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000177
178 bool isUsingGL() const { return SkOSWindow::kNone_BackEndType != fBackend; }
179
yangsu@google.com688823f2011-08-30 19:14:13 +0000180private:
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000181
bsalomon@google.com230504d2012-09-27 16:04:54 +0000182#if SK_SUPPORT_GPU
183 GrContext* fCurContext;
184 const GrGLInterface* fCurIntf;
185 GrRenderTarget* fCurRenderTarget;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000186 int fMSAASampleCount;
187 GLint fLayerFBO;
bsalomon@google.com230504d2012-09-27 16:04:54 +0000188#endif
189
190 SkOSWindow::SkBackEndTypes fBackend;
191
192 typedef SampleWindow::DeviceManager INHERITED;
yangsu@google.com688823f2011-08-30 19:14:13 +0000193};
194
195////////////////////////////////////////////////////////////////////////////////
196@implementation SkSampleUIView
197
198@synthesize fTitle, fRasterLayer, fGLLayer;
199
200#include "SkApplication.h"
201#include "SkEvent.h"
202#include "SkWindow.h"
203
yangsu@google.com688823f2011-08-30 19:14:13 +0000204struct FPSState {
205 static const int FRAME_COUNT = 60;
206
207 CFTimeInterval fNow0, fNow1;
208 CFTimeInterval fTime0, fTime1, fTotalTime;
209 int fFrameCounter;
yangsu@google.com688823f2011-08-30 19:14:13 +0000210 SkString str;
211 FPSState() {
212 fTime0 = fTime1 = fTotalTime = 0;
213 fFrameCounter = 0;
214 }
215
216 void startDraw() {
217 fNow0 = CACurrentMediaTime();
yangsu@google.com688823f2011-08-30 19:14:13 +0000218 }
219
220 void endDraw() {
221 fNow1 = CACurrentMediaTime();
yangsu@google.com688823f2011-08-30 19:14:13 +0000222 }
223
224 void flush(SkOSWindow* hwnd) {
225 CFTimeInterval now2 = CACurrentMediaTime();
226
227 fTime0 += fNow1 - fNow0;
228 fTime1 += now2 - fNow1;
229
230 if (++fFrameCounter == FRAME_COUNT) {
231 CFTimeInterval totalNow = CACurrentMediaTime();
232 fTotalTime = totalNow - fTotalTime;
233
234 //SkMSec ms0 = (int)(1000 * fTime0 / FRAME_COUNT);
235 //SkMSec msTotal = (int)(1000 * fTotalTime / FRAME_COUNT);
236 //str.printf(" ms: %d [%d], fps: %3.1f", msTotal, ms0,
237 // FRAME_COUNT / fTotalTime);
238 str.printf(" fps:%3.1f", FRAME_COUNT / fTotalTime);
239 hwnd->setTitle(NULL);
240 fTotalTime = totalNow;
241 fTime0 = fTime1 = 0;
242 fFrameCounter = 0;
243 }
244 }
245};
246
247static FPSState gFPS;
248
249#define FPS_StartDraw() gFPS.startDraw()
250#define FPS_EndDraw() gFPS.endDraw()
251#define FPS_Flush(wind) gFPS.flush(wind)
252
253///////////////////////////////////////////////////////////////////////////////
254
255- (id)initWithDefaults {
256 if (self = [super initWithDefaults]) {
257 fRedrawRequestPending = false;
258 fFPSState = new FPSState;
259
260#ifdef USE_GL_1
261 fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
262#else
263 fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
264#endif
265
266 if (!fGL.fContext || ![EAGLContext setCurrentContext:fGL.fContext])
267 {
268 [self release];
269 return nil;
270 }
271
272 // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
273 glGenFramebuffers(1, &fGL.fFramebuffer);
274 glBindFramebuffer(GL_FRAMEBUFFER, fGL.fFramebuffer);
275
276 glGenRenderbuffers(1, &fGL.fRenderbuffer);
277 glGenRenderbuffers(1, &fGL.fStencilbuffer);
278
279 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
280 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fGL.fRenderbuffer);
281
282 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fStencilbuffer);
283 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fGL.fStencilbuffer);
284
285 self.fGLLayer = [CAEAGLLayer layer];
286 fGLLayer.bounds = self.bounds;
287 fGLLayer.anchorPoint = CGPointMake(0, 0);
288 fGLLayer.opaque = TRUE;
289 [self.layer addSublayer:fGLLayer];
290 fGLLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
291 [NSNumber numberWithBool:NO],
292 kEAGLDrawablePropertyRetainedBacking,
293 SKGL_CONFIG,
294 kEAGLDrawablePropertyColorFormat,
295 nil];
296
297 self.fRasterLayer = [CALayer layer];
298 fRasterLayer.anchorPoint = CGPointMake(0, 0);
299 fRasterLayer.opaque = TRUE;
300 [self.layer addSublayer:fRasterLayer];
301
caryclark@google.com5987f582012-10-02 18:33:14 +0000302 NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"onOrderIn",
yangsu@google.com688823f2011-08-30 19:14:13 +0000303 [NSNull null], @"onOrderOut",
304 [NSNull null], @"sublayers",
305 [NSNull null], @"contents",
306 [NSNull null], @"bounds",
307 nil];
308 fGLLayer.actions = newActions;
309 fRasterLayer.actions = newActions;
310 [newActions release];
311
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000312 fDevManager = new SkiOSDeviceManager(fGL.fFramebuffer);
caryclark@google.com5987f582012-10-02 18:33:14 +0000313 static char* kDummyArgv = const_cast<char*>("dummyExecutableName");
bsalomon@google.com230504d2012-09-27 16:04:54 +0000314 fWind = new SampleWindow(self, 1, &kDummyArgv, fDevManager);
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000315
commit-bot@chromium.orgb45c56e2014-02-18 23:32:05 +0000316 fWind->resize(self.frame.size.width, self.frame.size.height,
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +0000317 kN32_SkColorType);
yangsu@google.com688823f2011-08-30 19:14:13 +0000318 }
319 return self;
320}
321
322- (void)dealloc {
323 delete fDevManager;
324 delete fFPSState;
325 self.fRasterLayer = nil;
326 self.fGLLayer = nil;
327 [fGL.fContext release];
328 [super dealloc];
329}
330
331- (void)layoutSubviews {
332 int W, H;
333
334 // Allocate color buffer backing based on the current layer size
335 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
336 [fGL.fContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:fGLLayer];
337
338 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &fGL.fWidth);
339 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &fGL.fHeight);
340
341 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fStencilbuffer);
342 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, fGL.fWidth, fGL.fHeight);
343
344 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
345 NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
346 }
347
348 if (fDevManager->isUsingGL()) {
349 W = fGL.fWidth;
350 H = fGL.fHeight;
351 CGRect rect = CGRectMake(0, 0, W, H);
352 fGLLayer.bounds = rect;
353 }
354 else {
355 CGRect rect = self.bounds;
356 W = (int)CGRectGetWidth(rect);
357 H = (int)CGRectGetHeight(rect);
358 fRasterLayer.bounds = rect;
359 }
360
361 printf("---- layoutSubviews %d %d\n", W, H);
362 fWind->resize(W, H);
363 fWind->inval(NULL);
364}
365
366///////////////////////////////////////////////////////////////////////////////
367
368- (void)drawWithCanvas:(SkCanvas*)canvas {
369 fRedrawRequestPending = false;
370 fFPSState->startDraw();
371 fWind->draw(canvas);
372 fFPSState->endDraw();
373#ifdef FORCE_REDRAW
374 fWind->inval(NULL);
375#endif
376 fFPSState->flush(fWind);
377}
378
379- (void)drawInGL {
380 // This application only creates a single context which is already set current at this point.
381 // This call is redundant, but needed if dealing with multiple contexts.
382 [EAGLContext setCurrentContext:fGL.fContext];
383
384 // This application only creates a single default framebuffer which is already bound at this point.
385 // This call is redundant, but needed if dealing with multiple framebuffers.
386 glBindFramebuffer(GL_FRAMEBUFFER, fGL.fFramebuffer);
387
388 GLint scissorEnable;
389 glGetIntegerv(GL_SCISSOR_TEST, &scissorEnable);
390 glDisable(GL_SCISSOR_TEST);
391 glClearColor(0,0,0,0);
392 glClear(GL_COLOR_BUFFER_BIT);
393 if (scissorEnable) {
394 glEnable(GL_SCISSOR_TEST);
395 }
396 glViewport(0, 0, fGL.fWidth, fGL.fHeight);
397
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000398
reedf0b17102014-10-22 13:06:00 -0700399 SkAutoTUnref<SkSurface> surface(fWind->createSurface());
400 SkCanvas* canvas = surface->getCanvas();
401
yangsu@google.com688823f2011-08-30 19:14:13 +0000402 // if we're not "retained", then we have to always redraw everything.
403 // This call forces us to ignore the fDirtyRgn, and draw everywhere.
404 // If we are "retained", we can skip this call (as the raster case does)
405 fWind->forceInvalAll();
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000406
reed@google.com5957f472012-10-01 20:31:56 +0000407 [self drawWithCanvas:canvas];
reedf0b17102014-10-22 13:06:00 -0700408
yangsu@google.com688823f2011-08-30 19:14:13 +0000409 // This application only creates a single color renderbuffer which is already bound at this point.
410 // This call is redundant, but needed if dealing with multiple renderbuffers.
411 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
412 [fGL.fContext presentRenderbuffer:GL_RENDERBUFFER];
yangsu@google.com688823f2011-08-30 19:14:13 +0000413}
414
415- (void)drawInRaster {
reedf0b17102014-10-22 13:06:00 -0700416 SkAutoTUnref<SkSurface> surface(fWind->createSurface());
417 SkCanvas* canvas = surface->getCanvas();
reed@google.com5957f472012-10-01 20:31:56 +0000418 [self drawWithCanvas:canvas];
yangsu@google.com688823f2011-08-30 19:14:13 +0000419 CGImageRef cgimage = SkCreateCGImageRef(fWind->getBitmap());
420 fRasterLayer.contents = (id)cgimage;
421 CGImageRelease(cgimage);
422}
423
424- (void)forceRedraw {
425 if (fDevManager->isUsingGL())
426 [self drawInGL];
427 else
428 [self drawInRaster];
429}
430
431///////////////////////////////////////////////////////////////////////////////
432
433- (void)setSkTitle:(const char *)title {
434 NSString* text = [NSString stringWithUTF8String:title];
435 if ([text length] > 0)
436 self.fTitle = text;
437
438 if (fTitleItem && fTitle) {
439 fTitleItem.title = [NSString stringWithFormat:@"%@%@", fTitle,
440 [NSString stringWithUTF8String:fFPSState->str.c_str()]];
441 }
442}
443
444- (void)postInvalWithRect:(const SkIRect*)r {
445 if (!fRedrawRequestPending) {
446 fRedrawRequestPending = true;
447 bool gl = fDevManager->isUsingGL();
448 [CATransaction begin];
449 [CATransaction setAnimationDuration:0];
450 fRasterLayer.hidden = gl;
451 fGLLayer.hidden = !gl;
452 [CATransaction commit];
453 if (gl) {
454 [self performSelector:@selector(drawInGL) withObject:nil afterDelay:0];
455 }
456 else {
457 [self performSelector:@selector(drawInRaster) withObject:nil afterDelay:0];
458 [self setNeedsDisplay];
459 }
460 }
461}
462
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000463- (void)getAttachmentInfo:(SkOSWindow::AttachmentInfo*)info {
464 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
465 glGetRenderbufferParameteriv(GL_RENDERBUFFER,
466 GL_RENDERBUFFER_STENCIL_SIZE,
467 &info->fStencilBits);
468 glGetRenderbufferParameteriv(GL_RENDERBUFFER,
469 GL_RENDERBUFFER_SAMPLES_APPLE,
470 &info->fSampleCount);
471}
472
yangsu@google.com688823f2011-08-30 19:14:13 +0000473@end