blob: b1e04873cd35d5e8e5e14650bcb2837fb62b48a8 [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;
bsalomon@google.com230504d2012-09-27 16:04:54 +000035 fMSAASampleCount = 0;
jvanverth38c72152016-10-10 07:39:38 -070036 fDeepColor = false;
37 fActualColorBits = 0;
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);
yangsu@google.com688823f2011-08-30 19:14:13 +000046#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +000047 }
48
brianosman2d1ee792016-05-05 12:24:31 -070049 void setUpBackend(SampleWindow* win, int msaaSampleCount, bool deepColor) override {
bsalomon@google.com230504d2012-09-27 16:04:54 +000050 SkASSERT(SkOSWindow::kNone_BackEndType == fBackend);
51
52 fBackend = SkOSWindow::kNone_BackEndType;
53
54#if SK_SUPPORT_GPU
55 switch (win->getDeviceType()) {
bsalomon@google.com230504d2012-09-27 16:04:54 +000056 case SampleWindow::kRaster_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000057 break;
58 // these guys use the native backend
59 case SampleWindow::kGPU_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000060 fBackend = SkOSWindow::kNativeGL_BackEndType;
61 break;
62 default:
63 SkASSERT(false);
64 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000065 }
bsalomon@google.com64cc8102013-03-05 20:06:05 +000066 SkOSWindow::AttachmentInfo info;
brianosman2d1ee792016-05-05 12:24:31 -070067 bool result = win->attach(fBackend, msaaSampleCount, false, &info);
bsalomon@google.com230504d2012-09-27 16:04:54 +000068 if (!result) {
69 SkDebugf("Failed to initialize GL");
70 return;
yangsu@google.com688823f2011-08-30 19:14:13 +000071 }
bsalomon@google.com230504d2012-09-27 16:04:54 +000072 fMSAASampleCount = msaaSampleCount;
jvanverth38c72152016-10-10 07:39:38 -070073 fDeepColor = deepColor;
74 // Assume that we have at least 24-bit output, for backends that don't supply this data
75 fActualColorBits = SkTMax(info.fColorBits, 24);
bsalomon@google.com230504d2012-09-27 16:04:54 +000076
77 SkASSERT(NULL == fCurIntf);
78 switch (win->getDeviceType()) {
yangsu@google.com688823f2011-08-30 19:14:13 +000079 case SampleWindow::kRaster_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000080 fCurIntf = NULL;
81 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000082 case SampleWindow::kGPU_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000083 fCurIntf = GrGLCreateNativeInterface();
84 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000085 default:
bsalomon@google.com230504d2012-09-27 16:04:54 +000086 SkASSERT(false);
87 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000088 }
bsalomon@google.com230504d2012-09-27 16:04:54 +000089
90 SkASSERT(NULL == fCurContext);
91 if (SkOSWindow::kNone_BackEndType != fBackend) {
bsalomon@google.com365d7872013-02-07 17:01:39 +000092 fCurContext = GrContext::Create(kOpenGL_GrBackend,
93 (GrBackendContext) fCurIntf);
bsalomon@google.com230504d2012-09-27 16:04:54 +000094 }
95
96 if ((NULL == fCurContext || NULL == fCurIntf) &&
97 SkOSWindow::kNone_BackEndType != fBackend) {
98 // We need some context and interface to see results if we're using a GL backend
99 SkSafeUnref(fCurContext);
100 SkSafeUnref(fCurIntf);
101 SkDebugf("Failed to setup 3D");
mtklein18300a32016-03-16 13:53:35 -0700102 win->release();
bsalomon@google.com230504d2012-09-27 16:04:54 +0000103 }
104#endif // SK_SUPPORT_GPU
105 // call windowSizeChanged to create the render target
106 this->windowSizeChanged(win);
yangsu@google.com688823f2011-08-30 19:14:13 +0000107 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000108
mtklein36352bf2015-03-25 18:17:31 -0700109 void tearDownBackend(SampleWindow *win) override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000110#if SK_SUPPORT_GPU
111 SkSafeUnref(fCurContext);
112 fCurContext = NULL;
113
114 SkSafeUnref(fCurIntf);
115 fCurIntf = NULL;
116
jvanverth38c72152016-10-10 07:39:38 -0700117 fGpuSurface = nullptr;
bsalomon@google.com230504d2012-09-27 16:04:54 +0000118#endif
mtklein18300a32016-03-16 13:53:35 -0700119 win->release();
bsalomon@google.com230504d2012-09-27 16:04:54 +0000120 fBackend = SampleWindow::kNone_BackEndType;
121 }
reed@google.com5957f472012-10-01 20:31:56 +0000122
jvanverth38c72152016-10-10 07:39:38 -0700123 sk_sp<SkSurface> makeSurface(SampleWindow::DeviceType dType, SampleWindow* win) 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());
jvanverth38c72152016-10-10 07:39:38 -0700127 if (kRGBA_F16_SkColorType == win->info().colorType() || fActualColorBits > 24) {
128 // If we're rendering to F16, we need an off-screen surface - the current render
129 // target is most likely the wrong format.
130 //
131 // If we're using a deep (10-bit or higher) surface, we probably need an off-screen
132 // surface. 10-bit, in particular, has strange gamma behavior.
133 return SkSurface::MakeRenderTarget(fCurContext, SkBudgeted::kNo, win->info(),
134 fMSAASampleCount, &props);
135 } else {
136 return fGpuSurface;
137 }
yangsu@google.com688823f2011-08-30 19:14:13 +0000138 }
reedf0b17102014-10-22 13:06:00 -0700139#endif
jvanverth141a14e2016-07-26 13:33:07 -0700140 return nullptr;
yangsu@google.com688823f2011-08-30 19:14:13 +0000141 }
reedf0b17102014-10-22 13:06:00 -0700142
yangsu@google.com688823f2011-08-30 19:14:13 +0000143 virtual void publishCanvas(SampleWindow::DeviceType dType,
144 SkCanvas* canvas,
mtklein36352bf2015-03-25 18:17:31 -0700145 SampleWindow* win) override {
caryclark@google.com5987f582012-10-02 18:33:14 +0000146#if SK_SUPPORT_GPU
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000147 if (NULL != fCurContext) {
148 fCurContext->flush();
149 }
caryclark@google.com5987f582012-10-02 18:33:14 +0000150#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +0000151 win->present();
yangsu@google.com688823f2011-08-30 19:14:13 +0000152 }
jvanverth38c72152016-10-10 07:39:38 -0700153
mtklein36352bf2015-03-25 18:17:31 -0700154 void windowSizeChanged(SampleWindow* win) override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000155#if SK_SUPPORT_GPU
jvanverth38c72152016-10-10 07:39:38 -0700156 if (fCurContext) {
157 SampleWindow::AttachmentInfo attachmentInfo;
158 win->attach(fBackend, fMSAASampleCount, fDeepColor, &attachmentInfo);
159 fActualColorBits = SkTMax(attachmentInfo.fColorBits, 24);
160 fGpuSurface = win->makeGpuBackedSurface(attachmentInfo, fCurIntf, fCurContext);
yangsu@google.com688823f2011-08-30 19:14:13 +0000161 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000162#endif
yangsu@google.com688823f2011-08-30 19:14:13 +0000163 }
jvanverth38c72152016-10-10 07:39:38 -0700164
mtklein36352bf2015-03-25 18:17:31 -0700165 GrContext* getGrContext() override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000166#if SK_SUPPORT_GPU
167 return fCurContext;
168#else
169 return NULL;
170#endif
171 }
jvanverth38c72152016-10-10 07:39:38 -0700172
173 int numColorSamples() const override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000174#if SK_SUPPORT_GPU
jvanverth38c72152016-10-10 07:39:38 -0700175 return fMSAASampleCount;
bsalomon@google.com230504d2012-09-27 16:04:54 +0000176#else
jvanverth38c72152016-10-10 07:39:38 -0700177 return 0;
bsalomon@google.com230504d2012-09-27 16:04:54 +0000178#endif
bsalomon@google.com11959252012-04-06 20:13:38 +0000179 }
brianosman2d1ee792016-05-05 12:24:31 -0700180
181 int getColorBits() override {
jvanverth38c72152016-10-10 07:39:38 -0700182#if SK_SUPPORT_GPU
183 return fActualColorBits;
184#else
brianosman2d1ee792016-05-05 12:24:31 -0700185 return 24;
jvanverth38c72152016-10-10 07:39:38 -0700186#endif
brianosman2d1ee792016-05-05 12:24:31 -0700187 }
188
bsalomon@google.com230504d2012-09-27 16:04:54 +0000189 bool isUsingGL() const { return SkOSWindow::kNone_BackEndType != fBackend; }
jvanverth38c72152016-10-10 07:39:38 -0700190
yangsu@google.com688823f2011-08-30 19:14:13 +0000191private:
jvanverth38c72152016-10-10 07:39:38 -0700192
bsalomon@google.com230504d2012-09-27 16:04:54 +0000193#if SK_SUPPORT_GPU
194 GrContext* fCurContext;
195 const GrGLInterface* fCurIntf;
jvanverth38c72152016-10-10 07:39:38 -0700196 sk_sp<SkSurface> fGpuSurface;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000197 int fMSAASampleCount;
jvanverth38c72152016-10-10 07:39:38 -0700198 bool fDeepColor;
199 int fActualColorBits;
bsalomon@google.com230504d2012-09-27 16:04:54 +0000200#endif
201
202 SkOSWindow::SkBackEndTypes fBackend;
203
204 typedef SampleWindow::DeviceManager INHERITED;
yangsu@google.com688823f2011-08-30 19:14:13 +0000205};
206
207////////////////////////////////////////////////////////////////////////////////
208@implementation SkSampleUIView
209
210@synthesize fTitle, fRasterLayer, fGLLayer;
211
212#include "SkApplication.h"
213#include "SkEvent.h"
214#include "SkWindow.h"
215
yangsu@google.com688823f2011-08-30 19:14:13 +0000216struct FPSState {
217 static const int FRAME_COUNT = 60;
218
219 CFTimeInterval fNow0, fNow1;
220 CFTimeInterval fTime0, fTime1, fTotalTime;
221 int fFrameCounter;
yangsu@google.com688823f2011-08-30 19:14:13 +0000222 SkString str;
223 FPSState() {
224 fTime0 = fTime1 = fTotalTime = 0;
225 fFrameCounter = 0;
226 }
227
228 void startDraw() {
229 fNow0 = CACurrentMediaTime();
yangsu@google.com688823f2011-08-30 19:14:13 +0000230 }
231
232 void endDraw() {
233 fNow1 = CACurrentMediaTime();
yangsu@google.com688823f2011-08-30 19:14:13 +0000234 }
235
236 void flush(SkOSWindow* hwnd) {
237 CFTimeInterval now2 = CACurrentMediaTime();
238
239 fTime0 += fNow1 - fNow0;
240 fTime1 += now2 - fNow1;
241
242 if (++fFrameCounter == FRAME_COUNT) {
243 CFTimeInterval totalNow = CACurrentMediaTime();
244 fTotalTime = totalNow - fTotalTime;
245
246 //SkMSec ms0 = (int)(1000 * fTime0 / FRAME_COUNT);
247 //SkMSec msTotal = (int)(1000 * fTotalTime / FRAME_COUNT);
248 //str.printf(" ms: %d [%d], fps: %3.1f", msTotal, ms0,
249 // FRAME_COUNT / fTotalTime);
250 str.printf(" fps:%3.1f", FRAME_COUNT / fTotalTime);
251 hwnd->setTitle(NULL);
252 fTotalTime = totalNow;
253 fTime0 = fTime1 = 0;
254 fFrameCounter = 0;
255 }
256 }
257};
258
259static FPSState gFPS;
260
261#define FPS_StartDraw() gFPS.startDraw()
262#define FPS_EndDraw() gFPS.endDraw()
263#define FPS_Flush(wind) gFPS.flush(wind)
264
265///////////////////////////////////////////////////////////////////////////////
266
267- (id)initWithDefaults {
268 if (self = [super initWithDefaults]) {
269 fRedrawRequestPending = false;
270 fFPSState = new FPSState;
271
272#ifdef USE_GL_1
273 fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
274#else
275 fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
276#endif
277
278 if (!fGL.fContext || ![EAGLContext setCurrentContext:fGL.fContext])
279 {
280 [self release];
281 return nil;
282 }
283
284 // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
285 glGenFramebuffers(1, &fGL.fFramebuffer);
286 glBindFramebuffer(GL_FRAMEBUFFER, fGL.fFramebuffer);
287
288 glGenRenderbuffers(1, &fGL.fRenderbuffer);
289 glGenRenderbuffers(1, &fGL.fStencilbuffer);
290
291 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
292 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fGL.fRenderbuffer);
293
294 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fStencilbuffer);
295 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fGL.fStencilbuffer);
296
297 self.fGLLayer = [CAEAGLLayer layer];
298 fGLLayer.bounds = self.bounds;
299 fGLLayer.anchorPoint = CGPointMake(0, 0);
300 fGLLayer.opaque = TRUE;
301 [self.layer addSublayer:fGLLayer];
302 fGLLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
303 [NSNumber numberWithBool:NO],
304 kEAGLDrawablePropertyRetainedBacking,
305 SKGL_CONFIG,
306 kEAGLDrawablePropertyColorFormat,
307 nil];
308
309 self.fRasterLayer = [CALayer layer];
310 fRasterLayer.anchorPoint = CGPointMake(0, 0);
311 fRasterLayer.opaque = TRUE;
312 [self.layer addSublayer:fRasterLayer];
313
caryclark@google.com5987f582012-10-02 18:33:14 +0000314 NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"onOrderIn",
yangsu@google.com688823f2011-08-30 19:14:13 +0000315 [NSNull null], @"onOrderOut",
316 [NSNull null], @"sublayers",
317 [NSNull null], @"contents",
318 [NSNull null], @"bounds",
319 nil];
320 fGLLayer.actions = newActions;
321 fRasterLayer.actions = newActions;
322 [newActions release];
323
jvanverth44dcb8a2015-10-02 09:12:05 -0700324 // rebuild argc and argv from process info
325 NSArray* arguments = [[NSProcessInfo processInfo] arguments];
326 int argc = [arguments count];
327 char** argv = new char*[argc];
328 for (int i = 0; i < argc; ++i) {
329 NSString* arg = [arguments objectAtIndex:i];
330 int strlen = [arg lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
331 argv[i] = new char[strlen+1];
332 [arg getCString:argv[i] maxLength:strlen+1 encoding:NSUTF8StringEncoding];
333 }
334
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000335 fDevManager = new SkiOSDeviceManager(fGL.fFramebuffer);
jvanverth44dcb8a2015-10-02 09:12:05 -0700336 fWind = new SampleWindow(self, argc, argv, fDevManager);
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000337
kkinnunen973d92c2016-01-18 01:18:34 -0800338 fWind->resize(self.frame.size.width, self.frame.size.height);
jvanverth44dcb8a2015-10-02 09:12:05 -0700339
340 for (int i = 0; i < argc; ++i) {
341 delete [] argv[i];
342 }
343 delete [] argv;
yangsu@google.com688823f2011-08-30 19:14:13 +0000344 }
345 return self;
346}
347
348- (void)dealloc {
349 delete fDevManager;
350 delete fFPSState;
351 self.fRasterLayer = nil;
352 self.fGLLayer = nil;
353 [fGL.fContext release];
354 [super dealloc];
355}
356
357- (void)layoutSubviews {
358 int W, H;
359
360 // Allocate color buffer backing based on the current layer size
361 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
362 [fGL.fContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:fGLLayer];
363
364 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &fGL.fWidth);
365 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &fGL.fHeight);
366
367 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fStencilbuffer);
368 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, fGL.fWidth, fGL.fHeight);
369
370 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
371 NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
372 }
373
374 if (fDevManager->isUsingGL()) {
375 W = fGL.fWidth;
376 H = fGL.fHeight;
377 CGRect rect = CGRectMake(0, 0, W, H);
378 fGLLayer.bounds = rect;
379 }
380 else {
381 CGRect rect = self.bounds;
382 W = (int)CGRectGetWidth(rect);
383 H = (int)CGRectGetHeight(rect);
384 fRasterLayer.bounds = rect;
385 }
386
387 printf("---- layoutSubviews %d %d\n", W, H);
388 fWind->resize(W, H);
389 fWind->inval(NULL);
390}
391
392///////////////////////////////////////////////////////////////////////////////
393
394- (void)drawWithCanvas:(SkCanvas*)canvas {
395 fRedrawRequestPending = false;
396 fFPSState->startDraw();
397 fWind->draw(canvas);
398 fFPSState->endDraw();
399#ifdef FORCE_REDRAW
400 fWind->inval(NULL);
401#endif
402 fFPSState->flush(fWind);
403}
404
405- (void)drawInGL {
406 // This application only creates a single context which is already set current at this point.
407 // This call is redundant, but needed if dealing with multiple contexts.
408 [EAGLContext setCurrentContext:fGL.fContext];
409
410 // This application only creates a single default framebuffer which is already bound at this point.
411 // This call is redundant, but needed if dealing with multiple framebuffers.
412 glBindFramebuffer(GL_FRAMEBUFFER, fGL.fFramebuffer);
413
414 GLint scissorEnable;
415 glGetIntegerv(GL_SCISSOR_TEST, &scissorEnable);
416 glDisable(GL_SCISSOR_TEST);
417 glClearColor(0,0,0,0);
418 glClear(GL_COLOR_BUFFER_BIT);
419 if (scissorEnable) {
420 glEnable(GL_SCISSOR_TEST);
421 }
422 glViewport(0, 0, fGL.fWidth, fGL.fHeight);
423
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000424
jvanverth38c72152016-10-10 07:39:38 -0700425 sk_sp<SkSurface> surface(fWind->makeSurface());
reedf0b17102014-10-22 13:06:00 -0700426 SkCanvas* canvas = surface->getCanvas();
427
yangsu@google.com688823f2011-08-30 19:14:13 +0000428 // if we're not "retained", then we have to always redraw everything.
429 // This call forces us to ignore the fDirtyRgn, and draw everywhere.
430 // If we are "retained", we can skip this call (as the raster case does)
431 fWind->forceInvalAll();
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000432
reed@google.com5957f472012-10-01 20:31:56 +0000433 [self drawWithCanvas:canvas];
reedf0b17102014-10-22 13:06:00 -0700434
yangsu@google.com688823f2011-08-30 19:14:13 +0000435 // This application only creates a single color renderbuffer which is already bound at this point.
436 // This call is redundant, but needed if dealing with multiple renderbuffers.
437 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
438 [fGL.fContext presentRenderbuffer:GL_RENDERBUFFER];
yangsu@google.com688823f2011-08-30 19:14:13 +0000439}
440
441- (void)drawInRaster {
jvanverth38c72152016-10-10 07:39:38 -0700442 sk_sp<SkSurface> surface(fWind->makeSurface());
reedf0b17102014-10-22 13:06:00 -0700443 SkCanvas* canvas = surface->getCanvas();
reed@google.com5957f472012-10-01 20:31:56 +0000444 [self drawWithCanvas:canvas];
yangsu@google.com688823f2011-08-30 19:14:13 +0000445 CGImageRef cgimage = SkCreateCGImageRef(fWind->getBitmap());
446 fRasterLayer.contents = (id)cgimage;
447 CGImageRelease(cgimage);
448}
449
450- (void)forceRedraw {
451 if (fDevManager->isUsingGL())
452 [self drawInGL];
453 else
454 [self drawInRaster];
455}
456
457///////////////////////////////////////////////////////////////////////////////
458
459- (void)setSkTitle:(const char *)title {
460 NSString* text = [NSString stringWithUTF8String:title];
461 if ([text length] > 0)
462 self.fTitle = text;
463
464 if (fTitleItem && fTitle) {
465 fTitleItem.title = [NSString stringWithFormat:@"%@%@", fTitle,
466 [NSString stringWithUTF8String:fFPSState->str.c_str()]];
467 }
468}
469
470- (void)postInvalWithRect:(const SkIRect*)r {
471 if (!fRedrawRequestPending) {
472 fRedrawRequestPending = true;
473 bool gl = fDevManager->isUsingGL();
474 [CATransaction begin];
475 [CATransaction setAnimationDuration:0];
476 fRasterLayer.hidden = gl;
477 fGLLayer.hidden = !gl;
478 [CATransaction commit];
479 if (gl) {
480 [self performSelector:@selector(drawInGL) withObject:nil afterDelay:0];
481 }
482 else {
483 [self performSelector:@selector(drawInRaster) withObject:nil afterDelay:0];
484 [self setNeedsDisplay];
485 }
486 }
487}
488
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000489- (void)getAttachmentInfo:(SkOSWindow::AttachmentInfo*)info {
490 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
491 glGetRenderbufferParameteriv(GL_RENDERBUFFER,
492 GL_RENDERBUFFER_STENCIL_SIZE,
493 &info->fStencilBits);
494 glGetRenderbufferParameteriv(GL_RENDERBUFFER,
495 GL_RENDERBUFFER_SAMPLES_APPLE,
496 &info->fSampleCount);
497}
498
yangsu@google.com688823f2011-08-30 19:14:13 +0000499@end