| Index: bench/benchmain.cpp | 
| diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp | 
| index 7aeeba63e8b73daa18f80ba02588e36045f04ffc..f86d603ba650f1092feed847e02e8784dd2fc131 100644 | 
| --- a/bench/benchmain.cpp | 
| +++ b/bench/benchmain.cpp | 
| @@ -782,6 +782,8 @@ int tool_main(int argc, char** argv) { | 
| for (int x = 0; x < configs.count(); ++x) { | 
| int configIndex = configs[x]; | 
|  | 
| +            bool setupFailed = false; | 
| + | 
| if (kNonRendering_Backend == gConfigs[configIndex].fBackend) { | 
| if (bench->isRendering()) { | 
| continue; | 
| @@ -816,156 +818,164 @@ int tool_main(int argc, char** argv) { | 
|  | 
| if (kNonRendering_Backend != backend) { | 
| device = make_device(outConfig, dim, backend, sampleCount, context); | 
| - | 
| -                switch(benchMode) { | 
| -                    case kDeferredSilent_benchModes: | 
| -                    case kDeferred_benchModes: | 
| -                        canvas = | 
| +                if (NULL == device) { | 
| +                    SkString error; | 
| +                    error.printf("Device creation failure for config %s. Will skip.\n", configName); | 
| +                    logger.logError(error.c_str()); | 
| +                    setupFailed = true; | 
| +                } else { | 
| +                    switch(benchMode) { | 
| +                        case kDeferredSilent_benchModes: | 
| +                        case kDeferred_benchModes: | 
| +                            canvas = | 
| #if SK_DEFERRED_CANVAS_USES_FACTORIES | 
| -                            SkDeferredCanvas::Create(device); | 
| +                                SkDeferredCanvas::Create(device); | 
| #else | 
| -                            SkNEW_ARGS(SkDeferredCanvas, (device)); | 
| +                                SkNEW_ARGS(SkDeferredCanvas, (device)); | 
| #endif | 
| -                        break; | 
| -                    case kRecord_benchModes: | 
| -                        canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY, | 
| -                            SkPicture::kUsePathBoundsForClip_RecordingFlag); | 
| -                        canvas->ref(); | 
| -                        break; | 
| -                    case kPictureRecord_benchModes: { | 
| -                        // This sets up picture-to-picture recording. | 
| -                        // The C++ drawing calls for the benchmark are recorded into | 
| -                        // pictureRecordFrom. As the benchmark, we will time how | 
| -                        // long it takes to playback pictureRecordFrom into | 
| -                        // pictureRecordTo. | 
| -                        SkCanvas* tempCanvas = pictureRecordFrom.beginRecording(dim.fX, dim.fY, | 
| -                            SkPicture::kUsePathBoundsForClip_RecordingFlag); | 
| -                        bench->draw(tempCanvas); | 
| -                        pictureRecordFrom.endRecording(); | 
| -                        canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY, | 
| -                            SkPicture::kUsePathBoundsForClip_RecordingFlag); | 
| -                        canvas->ref(); | 
| -                        break; | 
| +                            break; | 
| +                        case kRecord_benchModes: | 
| +                            canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY, | 
| +                                SkPicture::kUsePathBoundsForClip_RecordingFlag); | 
| +                            canvas->ref(); | 
| +                            break; | 
| +                        case kPictureRecord_benchModes: { | 
| +                            // This sets up picture-to-picture recording. | 
| +                            // The C++ drawing calls for the benchmark are recorded into | 
| +                            // pictureRecordFrom. As the benchmark, we will time how | 
| +                            // long it takes to playback pictureRecordFrom into | 
| +                            // pictureRecordTo. | 
| +                            SkCanvas* tempCanvas = pictureRecordFrom.beginRecording(dim.fX, dim.fY, | 
| +                                SkPicture::kUsePathBoundsForClip_RecordingFlag); | 
| +                            bench->draw(tempCanvas); | 
| +                            pictureRecordFrom.endRecording(); | 
| +                            canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY, | 
| +                                SkPicture::kUsePathBoundsForClip_RecordingFlag); | 
| +                            canvas->ref(); | 
| +                            break; | 
| +                        } | 
| +                        case kNormal_benchModes: | 
| +                            canvas = new SkCanvas(device); | 
| +                            break; | 
| +                        default: | 
| +                            SkASSERT(0); | 
| } | 
| -                    case kNormal_benchModes: | 
| -                        canvas = new SkCanvas(device); | 
| -                        break; | 
| -                    default: | 
| -                        SkASSERT(0); | 
| +                    device->unref(); | 
| +                    canvas->clear(SK_ColorWHITE); | 
| } | 
| -                device->unref(); | 
| -                canvas->clear(SK_ColorWHITE); | 
| } | 
| SkAutoUnref canvasUnref(canvas); | 
| - | 
| -            if (NULL != canvas) { | 
| -                if (doClip) { | 
| -                    performClip(canvas, dim.fX, dim.fY); | 
| -                } | 
| -                if (doScale) { | 
| -                    performScale(canvas, dim.fX, dim.fY); | 
| -                } | 
| -                if (doRotate) { | 
| -                    performRotate(canvas, dim.fX, dim.fY); | 
| +            if (!setupFailed) { | 
| +                if (NULL != canvas) { | 
| +                    if (doClip) { | 
| +                        performClip(canvas, dim.fX, dim.fY); | 
| +                    } | 
| +                    if (doScale) { | 
| +                        performScale(canvas, dim.fX, dim.fY); | 
| +                    } | 
| +                    if (doRotate) { | 
| +                        performRotate(canvas, dim.fX, dim.fY); | 
| +                    } | 
| } | 
| -            } | 
|  | 
| -            if (!loggedBenchStart) { | 
| -                loggedBenchStart = true; | 
| -                SkString str; | 
| -                str.printf("running bench [%d %d] %28s", dim.fX, dim.fY, bench->getName()); | 
| -                logger.logProgress(str); | 
| -            } | 
| +                if (!loggedBenchStart) { | 
| +                    loggedBenchStart = true; | 
| +                    SkString str; | 
| +                    str.printf("running bench [%d %d] %28s", dim.fX, dim.fY, bench->getName()); | 
| +                    logger.logProgress(str); | 
| +                } | 
|  | 
| -            // warm up caches if needed | 
| -            if (repeatDraw > 1 && NULL != canvas) { | 
| +                // warm up caches if needed | 
| +                if (repeatDraw > 1 && NULL != canvas) { | 
| #if SK_SUPPORT_GPU | 
| -                // purge the GPU resources to reduce variance | 
| -                if (NULL != context) { | 
| -                    context->freeGpuResources(); | 
| -                } | 
| +                    // purge the GPU resources to reduce variance | 
| +                    if (NULL != context) { | 
| +                        context->freeGpuResources(); | 
| +                    } | 
| #endif | 
| -                SkAutoCanvasRestore acr(canvas, true); | 
| -                if (benchMode == kPictureRecord_benchModes) { | 
| -                    pictureRecordFrom.draw(canvas); | 
| -                } else { | 
| -                    bench->draw(canvas); | 
| -                } | 
| +                    SkAutoCanvasRestore acr(canvas, true); | 
| +                    if (benchMode == kPictureRecord_benchModes) { | 
| +                        pictureRecordFrom.draw(canvas); | 
| +                    } else { | 
| +                        bench->draw(canvas); | 
| +                    } | 
|  | 
| -                if (kDeferredSilent_benchModes == benchMode) { | 
| -                    static_cast<SkDeferredCanvas*>(canvas)->silentFlush(); | 
| -                } else { | 
| -                    canvas->flush(); | 
| -                } | 
| +                    if (kDeferredSilent_benchModes == benchMode) { | 
| +                        static_cast<SkDeferredCanvas*>(canvas)->silentFlush(); | 
| +                    } else { | 
| +                        canvas->flush(); | 
| +                    } | 
| #if SK_SUPPORT_GPU | 
| -                if (NULL != context) { | 
| -                    context->flush(); | 
| -                    SK_GL(*glContext, Finish()); | 
| -                } | 
| +                    if (NULL != context) { | 
| +                        context->flush(); | 
| +                        SK_GL(*glContext, Finish()); | 
| +                    } | 
| #endif | 
| -            } | 
| - | 
| -            // record timer values for each repeat, and their sum | 
| -            TimerData timerData(perIterTimeformat, normalTimeFormat); | 
| -            for (int i = 0; i < repeatDraw; i++) { | 
| -                if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) { | 
| -                    // This will clear the recorded commands so that they do not | 
| -                    // accumulate. | 
| -                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY, | 
| -                        SkPicture::kUsePathBoundsForClip_RecordingFlag); | 
| } | 
|  | 
| -                timer->start(bench->getDurationScale()); | 
| -                if (NULL != canvas) { | 
| -                    canvas->save(); | 
| -                } | 
| -                if (benchMode == kPictureRecord_benchModes) { | 
| -                    pictureRecordFrom.draw(canvas); | 
| -                } else { | 
| -                    bench->draw(canvas); | 
| -                } | 
| +                // record timer values for each repeat, and their sum | 
| +                TimerData timerData(perIterTimeformat, normalTimeFormat); | 
| +                for (int i = 0; i < repeatDraw; i++) { | 
| +                    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) { | 
| +                        // This will clear the recorded commands so that they do not | 
| +                        // accumulate. | 
| +                        canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY, | 
| +                            SkPicture::kUsePathBoundsForClip_RecordingFlag); | 
| +                    } | 
|  | 
| -                if (kDeferredSilent_benchModes == benchMode) { | 
| -                    static_cast<SkDeferredCanvas*>(canvas)->silentFlush(); | 
| -                } else if (NULL != canvas) { | 
| -                    canvas->flush(); | 
| -                } | 
| +                    timer->start(bench->getDurationScale()); | 
| +                    if (NULL != canvas) { | 
| +                        canvas->save(); | 
| +                    } | 
| +                    if (benchMode == kPictureRecord_benchModes) { | 
| +                        pictureRecordFrom.draw(canvas); | 
| +                    } else { | 
| +                        bench->draw(canvas); | 
| +                    } | 
|  | 
| -                if (NULL != canvas) { | 
| -                    canvas->restore(); | 
| -                } | 
| +                    if (kDeferredSilent_benchModes == benchMode) { | 
| +                        static_cast<SkDeferredCanvas*>(canvas)->silentFlush(); | 
| +                    } else if (NULL != canvas) { | 
| +                        canvas->flush(); | 
| +                    } | 
|  | 
| -                // stop the truncated timer after the last canvas call but | 
| -                // don't wait for all the GL calls to complete | 
| -                timer->truncatedEnd(); | 
| +                    if (NULL != canvas) { | 
| +                        canvas->restore(); | 
| +                    } | 
| + | 
| +                    // stop the truncated timer after the last canvas call but | 
| +                    // don't wait for all the GL calls to complete | 
| +                    timer->truncatedEnd(); | 
| #if SK_SUPPORT_GPU | 
| -                if (NULL != glContext) { | 
| -                    context->flush(); | 
| -                    SK_GL(*glContext, Finish()); | 
| -                } | 
| +                    if (NULL != glContext) { | 
| +                        context->flush(); | 
| +                        SK_GL(*glContext, Finish()); | 
| +                    } | 
| #endif | 
| -                // stop the inclusive and gpu timers once all the GL calls | 
| -                // have completed | 
| -                timer->end(); | 
| +                    // stop the inclusive and gpu timers once all the GL calls | 
| +                    // have completed | 
| +                    timer->end(); | 
|  | 
| -                timerData.appendTimes(timer, repeatDraw - 1 == i); | 
| +                    timerData.appendTimes(timer, repeatDraw - 1 == i); | 
|  | 
| +                } | 
| +                if (repeatDraw > 1) { | 
| +                    SkString result = timerData.getResult( | 
| +                                        logPerIter, printMin, repeatDraw, configName, | 
| +                                        timerWall, truncatedTimerWall, timerCpu, | 
| +                                        truncatedTimerCpu, | 
| +                                        timerGpu && NULL != context); | 
| +                    logger.logProgress(result); | 
| +                } | 
| +                if (outDir.size() > 0 && kNonRendering_Backend != backend) { | 
| +                    saveFile(bench->getName(), configName, outDir.c_str(), | 
| +                             device->accessBitmap(false)); | 
| +                } | 
| } | 
| -            if (repeatDraw > 1) { | 
| -                SkString result = timerData.getResult(logPerIter, printMin, repeatDraw, configName, | 
| -                                                      timerWall, truncatedTimerWall, timerCpu, | 
| -                                                      truncatedTimerCpu, | 
| -                                                      timerGpu && NULL != context); | 
| -                logger.logProgress(result); | 
| -            } | 
| -            if (outDir.size() > 0 && kNonRendering_Backend != backend) { | 
| -                saveFile(bench->getName(), configName, outDir.c_str(), | 
| -                         device->accessBitmap(false)); | 
| +            if (loggedBenchStart) { | 
| +                logger.logProgress(SkString("\n")); | 
| } | 
| } | 
| -        if (loggedBenchStart) { | 
| -            logger.logProgress(SkString("\n")); | 
| -        } | 
| } | 
| #if SK_SUPPORT_GPU | 
| #if GR_CACHE_STATS | 
|  |