本文整理汇总了C++中GrContext::flush方法的典型用法代码示例。如果您正苦于以下问题:C++ GrContext::flush方法的具体用法?C++ GrContext::flush怎么用?C++ GrContext::flush使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GrContext
的用法示例。
在下文中一共展示了GrContext::flush方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: target
DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(VertexAttributeCount, reporter, ctxInfo) {
GrContext* context = ctxInfo.fGrContext;
GrTextureDesc desc;
desc.fHeight = 1;
desc.fWidth = 1;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fConfig = kRGBA_8888_GrPixelConfig;
SkAutoTUnref<GrTexture> target(context->textureProvider()->createTexture(desc,
SkBudgeted::kYes));
if (!target) {
ERRORF(reporter, "Could not create render target.");
return;
}
SkAutoTUnref<GrDrawContext> dc(context->drawContext(target->asRenderTarget()));
if (!dc) {
ERRORF(reporter, "Could not create draw context.");
return;
}
int attribCnt = context->caps()->maxVertexAttributes();
if (!attribCnt) {
ERRORF(reporter, "No attributes allowed?!");
return;
}
context->flush();
context->resetGpuStats();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
SkAutoTUnref<GrDrawBatch> batch;
GrPipelineBuilder pb;
pb.setRenderTarget(target->asRenderTarget());
// This one should succeed.
batch.reset(new Batch(attribCnt));
dc->drawContextPriv().testingOnly_drawBatch(pb, batch);
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 1);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
context->resetGpuStats();
// This one should fail.
batch.reset(new Batch(attribCnt+1));
dc->drawContextPriv().testingOnly_drawBatch(pb, batch);
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 1);
#endif
}
示例2: SkPaint
// Tests that MIP maps are created and invalidated as expected when drawing to and from GrTextures.
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureMipMapInvalidationTest, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
if (!context->priv().caps()->mipMapSupport()) {
return;
}
auto isMipped = [] (SkSurface* surf) {
const GrTexture* texture = surf->makeImageSnapshot()->getTexture();
return GrMipMapped::kYes == texture->texturePriv().mipMapped();
};
auto mipsAreDirty = [] (SkSurface* surf) {
return surf->makeImageSnapshot()->getTexture()->texturePriv().mipMapsAreDirty();
};
auto info = SkImageInfo::MakeN32Premul(256, 256);
for (auto allocateMips : {false, true}) {
auto surf1 = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 0,
kBottomLeft_GrSurfaceOrigin, nullptr,
allocateMips);
auto surf2 = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info);
// Draw something just in case we ever had a solid color optimization
surf1->getCanvas()->drawCircle(128, 128, 50, SkPaint());
surf1->flush();
// No mipmaps initially
REPORTER_ASSERT(reporter, isMipped(surf1.get()) == allocateMips);
// Painting with downscale and medium filter quality should result in mipmap creation
// Flush the context rather than the canvas as flushing the canvas triggers MIP level
// generation.
SkPaint paint;
paint.setFilterQuality(kMedium_SkFilterQuality);
surf2->getCanvas()->scale(0.2f, 0.2f);
surf2->getCanvas()->drawImage(surf1->makeImageSnapshot(), 0, 0, &paint);
context->flush();
REPORTER_ASSERT(reporter, isMipped(surf1.get()) == allocateMips);
REPORTER_ASSERT(reporter, !allocateMips || !mipsAreDirty(surf1.get()));
// Changing the contents of the surface should invalidate the mipmap, but not de-allocate
surf1->getCanvas()->drawCircle(128, 128, 100, SkPaint());
context->flush();
REPORTER_ASSERT(reporter, isMipped(surf1.get()) == allocateMips);
REPORTER_ASSERT(reporter, mipsAreDirty(surf1.get()));
}
}
示例3: TextBlobCacheOverBudgetCB
void GrContext::TextBlobCacheOverBudgetCB(void* data) {
SkASSERT(data);
// Unlike the GrResourceCache, TextBlobs are drawn at the SkGpuDevice level, therefore they
// cannot use fFlushTorReduceCacheSize because it uses AutoCheckFlush. The solution is to move
// drawText calls to below the GrContext level, but this is not trivial because they call
// drawPath on SkGpuDevice
GrContext* context = reinterpret_cast<GrContext*>(data);
context->flush();
}
示例4: drawContext
DEF_GPUTEST_FOR_ALL_CONTEXTS(VertexAttributeCount, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
1, 1, kRGBA_8888_GrPixelConfig));
if (!drawContext) {
ERRORF(reporter, "Could not create draw context.");
return;
}
int attribCnt = context->caps()->maxVertexAttributes();
if (!attribCnt) {
ERRORF(reporter, "No attributes allowed?!");
return;
}
context->flush();
context->resetGpuStats();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
SkAutoTUnref<GrDrawBatch> batch;
GrPaint grPaint;
// This one should succeed.
batch.reset(new Batch(attribCnt));
drawContext->drawContextPriv().testingOnly_drawBatch(grPaint, batch);
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 1);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
context->resetGpuStats();
// This one should fail.
batch.reset(new Batch(attribCnt+1));
drawContext->drawContextPriv().testingOnly_drawBatch(grPaint, batch);
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 1);
#endif
}
示例5: while
RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, trimMemory) {
DisplayInfo displayInfo = renderThread.mainDisplayInfo();
GrContext* grContext = renderThread.getGrContext();
ASSERT_TRUE(grContext != nullptr);
// create pairs of offscreen render targets and images until we exceed the
// backgroundCacheSizeLimit
std::vector<sk_sp<SkSurface>> surfaces;
while (getCacheUsage(grContext) <= renderThread.cacheManager().getBackgroundCacheSize()) {
SkImageInfo info = SkImageInfo::MakeA8(displayInfo.w, displayInfo.h);
sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info);
surface->getCanvas()->drawColor(SK_AlphaTRANSPARENT);
grContext->flush();
surfaces.push_back(surface);
}
// create an image and pin it so that we have something with a unique key in the cache
sk_sp<Bitmap> bitmap =
Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(displayInfo.w, displayInfo.h));
sk_sp<SkColorFilter> filter;
sk_sp<SkImage> image = bitmap->makeImage(&filter);
ASSERT_TRUE(SkImage_pinAsTexture(image.get(), grContext));
// attempt to trim all memory while we still hold strong refs
renderThread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
ASSERT_TRUE(0 == grContext->getResourceCachePurgeableBytes());
// free the surfaces
for (size_t i = 0; i < surfaces.size(); i++) {
ASSERT_TRUE(surfaces[i]->unique());
surfaces[i].reset();
}
// unpin the image which should add a unique purgeable key to the cache
SkImage_unpinAsTexture(image.get(), grContext);
// verify that we have enough purgeable bytes
const size_t purgeableBytes = grContext->getResourceCachePurgeableBytes();
ASSERT_TRUE(renderThread.cacheManager().getBackgroundCacheSize() < purgeableBytes);
// UI hidden and make sure only some got purged (unique should remain)
renderThread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::UiHidden);
ASSERT_TRUE(0 < grContext->getResourceCachePurgeableBytes());
ASSERT_TRUE(renderThread.cacheManager().getBackgroundCacheSize() > getCacheUsage(grContext));
// complete and make sure all get purged
renderThread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
ASSERT_TRUE(0 == grContext->getResourceCachePurgeableBytes());
}
示例6: renderTargetContext
DEF_GPUTEST_FOR_ALL_CONTEXTS(VertexAttributeCount, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
sk_sp<GrRenderTargetContext> renderTargetContext(context->makeDeferredRenderTargetContext(
SkBackingFit::kApprox,
1, 1, kRGBA_8888_GrPixelConfig,
nullptr));
if (!renderTargetContext) {
ERRORF(reporter, "Could not create render target context.");
return;
}
int attribCnt = context->caps()->maxVertexAttributes();
if (!attribCnt) {
ERRORF(reporter, "No attributes allowed?!");
return;
}
context->flush();
context->resetGpuStats();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
GrPaint grPaint;
// This one should succeed.
renderTargetContext->priv().testingOnly_addDrawOp(Op::Make(attribCnt));
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 1);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
context->resetGpuStats();
renderTargetContext->priv().testingOnly_addDrawOp(Op::Make(attribCnt + 1));
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 1);
#endif
}
示例7: rtc
DEF_GPUTEST_FOR_ALL_CONTEXTS(TessellatingPathRendererTests, reporter, ctxInfo) {
GrContext* ctx = ctxInfo.grContext();
sk_sp<GrRenderTargetContext> rtc(ctx->makeDeferredRenderTargetContext(
SkBackingFit::kApprox, 800, 800, kRGBA_8888_GrPixelConfig, nullptr, 1, GrMipMapped::kNo,
kTopLeft_GrSurfaceOrigin));
if (!rtc) {
return;
}
ctx->flush();
// Adding discard to appease vulkan validation warning about loading uninitialized data on draw
rtc->discard();
test_path(ctx, rtc.get(), create_path_0());
test_path(ctx, rtc.get(), create_path_1());
test_path(ctx, rtc.get(), create_path_2());
test_path(ctx, rtc.get(), create_path_3());
test_path(ctx, rtc.get(), create_path_4());
test_path(ctx, rtc.get(), create_path_5());
test_path(ctx, rtc.get(), create_path_6());
test_path(ctx, rtc.get(), create_path_7());
test_path(ctx, rtc.get(), create_path_8());
test_path(ctx, rtc.get(), create_path_9());
test_path(ctx, rtc.get(), create_path_10());
test_path(ctx, rtc.get(), create_path_11());
test_path(ctx, rtc.get(), create_path_12());
test_path(ctx, rtc.get(), create_path_13());
test_path(ctx, rtc.get(), create_path_14());
test_path(ctx, rtc.get(), create_path_15());
test_path(ctx, rtc.get(), create_path_16());
SkMatrix nonInvertibleMatrix = SkMatrix::MakeScale(0, 0);
std::unique_ptr<GrFragmentProcessor> fp(create_linear_gradient_processor(ctx));
test_path(ctx, rtc.get(), create_path_17(), nonInvertibleMatrix, GrAAType::kCoverage,
std::move(fp));
test_path(ctx, rtc.get(), create_path_18());
test_path(ctx, rtc.get(), create_path_19());
test_path(ctx, rtc.get(), create_path_20(), SkMatrix(), GrAAType::kCoverage);
test_path(ctx, rtc.get(), create_path_21(), SkMatrix(), GrAAType::kCoverage);
test_path(ctx, rtc.get(), create_path_22());
test_path(ctx, rtc.get(), create_path_23());
test_path(ctx, rtc.get(), create_path_24());
test_path(ctx, rtc.get(), create_path_25(), SkMatrix(), GrAAType::kCoverage);
test_path(ctx, rtc.get(), create_path_26(), SkMatrix(), GrAAType::kCoverage);
test_path(ctx, rtc.get(), create_path_27(), SkMatrix(), GrAAType::kCoverage);
test_path(ctx, rtc.get(), create_path_28(), SkMatrix(), GrAAType::kCoverage);
test_path(ctx, rtc.get(), create_path_29());
}
示例8: getGpuStats
void SKPBench::getGpuStats(SkCanvas* canvas, SkTArray<SkString>* keys, SkTArray<double>* values) {
#if SK_SUPPORT_GPU
// we do a special single draw and then dump the key / value pairs
GrContext* context = canvas->getGrContext();
if (!context) {
return;
}
// TODO refactor this out if we want to test other subclasses of skpbench
context->flush();
context->freeGpuResources();
context->resetContext();
context->getGpu()->resetShaderCacheForTesting();
draw_pic_for_stats(canvas, context, fPic, keys, values, "first_frame");
// draw second frame
draw_pic_for_stats(canvas, context, fPic, keys, values, "second_frame");
#endif
}
示例9: rtc
DEF_GPUTEST_FOR_ALL_CONTEXTS(TessellatingPathRendererTests, reporter, ctxInfo) {
GrContext* ctx = ctxInfo.grContext();
sk_sp<GrRenderTargetContext> rtc(ctx->makeDeferredRenderTargetContext(
SkBackingFit::kApprox,
800, 800,
kRGBA_8888_GrPixelConfig,
nullptr,
0,
kTopLeft_GrSurfaceOrigin));
if (!rtc) {
return;
}
ctx->flush();
test_path(ctx, rtc.get(), create_path_0());
test_path(ctx, rtc.get(), create_path_1());
test_path(ctx, rtc.get(), create_path_2());
test_path(ctx, rtc.get(), create_path_3());
test_path(ctx, rtc.get(), create_path_4());
test_path(ctx, rtc.get(), create_path_5());
test_path(ctx, rtc.get(), create_path_6());
test_path(ctx, rtc.get(), create_path_7());
test_path(ctx, rtc.get(), create_path_8());
test_path(ctx, rtc.get(), create_path_9());
test_path(ctx, rtc.get(), create_path_10());
test_path(ctx, rtc.get(), create_path_11());
test_path(ctx, rtc.get(), create_path_12());
test_path(ctx, rtc.get(), create_path_13());
test_path(ctx, rtc.get(), create_path_14());
test_path(ctx, rtc.get(), create_path_15());
test_path(ctx, rtc.get(), create_path_16());
SkMatrix nonInvertibleMatrix = SkMatrix::MakeScale(0, 0);
sk_sp<GrFragmentProcessor> fp(create_linear_gradient_processor(ctx));
test_path(ctx, rtc.get(), create_path_17(), nonInvertibleMatrix, GrAAType::kCoverage, fp);
test_path(ctx, rtc.get(), create_path_18());
test_path(ctx, rtc.get(), create_path_19());
test_path(ctx, rtc.get(), create_path_20(), SkMatrix(), GrAAType::kCoverage);
test_path(ctx, rtc.get(), create_path_21(), SkMatrix(), GrAAType::kCoverage);
test_path(ctx, rtc.get(), create_path_22());
}
示例10: updateTextureRect
void LayerTextureUpdaterSkPicture::updateTextureRect(GraphicsContext3D* compositorContext, TextureAllocator* allocator, ManagedTexture* texture, const IntRect& sourceRect, const IntRect& destRect)
{
ASSERT(!m_context || m_context == compositorContext);
m_context = compositorContext;
if (m_createFrameBuffer) {
deleteFrameBuffer();
createFrameBuffer();
m_createFrameBuffer = false;
}
if (!m_fbo)
return;
// Bind texture.
context()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
texture->framebufferTexture2D(context(), allocator);
ASSERT(context()->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) == GraphicsContext3D::FRAMEBUFFER_COMPLETE);
// Make sure SKIA uses the correct GL context.
context()->makeContextCurrent();
GrContext* skiaContext = m_context->grContext();
// Notify SKIA to sync its internal GL state.
skiaContext->resetContext();
m_canvas->save();
m_canvas->clipRect(SkRect(destRect));
// Translate the origin of contentRect to that of destRect.
// Note that destRect is defined relative to sourceRect.
m_canvas->translate(contentRect().x() - sourceRect.x() + destRect.x(),
contentRect().y() - sourceRect.y() + destRect.y());
m_canvas->drawPicture(m_picture);
m_canvas->restore();
// Flush SKIA context so that all the rendered stuff appears on the texture.
skiaContext->flush();
// Unbind texture.
context()->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, 0, 0);
context()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
}
示例11: ASSERT
bool Canvas2DLayerBridge::prepareMailbox(WebExternalTextureMailbox* outMailbox, WebExternalBitmap* bitmap)
{
ASSERT(isAccelerated());
if (m_destructionInProgress) {
// It can be hit in the following sequence.
// 1. Canvas draws something.
// 2. The compositor begins the frame.
// 3. Javascript makes a context be lost.
// 4. Here.
return false;
}
if (bitmap) {
// Using accelerated 2d canvas with software renderer, which
// should only happen in tests that use fake graphics contexts
// or in Android WebView in software mode. In this case, we do
// not care about producing any results for this canvas.
skipQueuedDrawCommands();
m_lastImageId = 0;
return false;
}
if (!checkSurfaceValid())
return false;
WebGraphicsContext3D* webContext = context();
RefPtr<SkImage> image = newImageSnapshot(PreferAcceleration);
// Early exit if canvas was not drawn to since last prepareMailbox
GLenum filter = m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR;
if (image->uniqueID() == m_lastImageId && filter == m_lastFilter)
return false;
m_lastImageId = image->uniqueID();
m_lastFilter = filter;
{
MailboxInfo tmp;
tmp.m_image = image;
tmp.m_parentLayerBridge = this;
m_mailboxes.prepend(tmp);
}
MailboxInfo& mailboxInfo = m_mailboxes.first();
mailboxInfo.m_mailbox.nearestNeighbor = filter == GL_NEAREST;
GrContext* grContext = m_contextProvider->grContext();
if (!grContext)
return true; // for testing: skip gl stuff when using a mock graphics context.
// Need to flush skia's internal queue because texture is about to be accessed directly
grContext->flush();
ASSERT(image->getTexture());
// Because of texture sharing with the compositor, we must invalidate
// the state cached in skia so that the deferred copy on write
// in SkSurface_Gpu does not make any false assumptions.
mailboxInfo.m_image->getTexture()->textureParamsModified();
webContext->bindTexture(GL_TEXTURE_2D, mailboxInfo.m_image->getTexture()->getTextureHandle());
webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Re-use the texture's existing mailbox, if there is one.
if (image->getTexture()->getCustomData()) {
ASSERT(image->getTexture()->getCustomData()->size() == sizeof(mailboxInfo.m_mailbox.name));
memcpy(&mailboxInfo.m_mailbox.name[0], image->getTexture()->getCustomData()->data(), sizeof(mailboxInfo.m_mailbox.name));
} else {
context()->genMailboxCHROMIUM(mailboxInfo.m_mailbox.name);
RefPtr<SkData> mailboxNameData = adoptRef(SkData::NewWithCopy(&mailboxInfo.m_mailbox.name[0], sizeof(mailboxInfo.m_mailbox.name)));
image->getTexture()->setCustomData(mailboxNameData.get());
webContext->produceTextureCHROMIUM(GL_TEXTURE_2D, mailboxInfo.m_mailbox.name);
}
if (isHidden()) {
// With hidden canvases, we release the SkImage immediately because
// there is no need for animations to be double buffered.
mailboxInfo.m_image.clear();
} else {
// FIXME: We'd rather insert a syncpoint than perform a flush here,
// but currentlythe canvas will flicker if we don't flush here.
webContext->flush();
// mailboxInfo.m_mailbox.syncPoint = webContext->insertSyncPoint();
}
webContext->bindTexture(GL_TEXTURE_2D, 0);
// Because we are changing the texture binding without going through skia,
// we must dirty the context.
grContext->resetContext(kTextureBinding_GrGLBackendState);
*outMailbox = mailboxInfo.m_mailbox;
return true;
}
示例12: tool_main
//.........这里部分代码省略.........
if ((benchMode == kRecord_BenchMode || benchMode == kPictureRecord_BenchMode)) {
// Clear the recorded commands so that they do not accumulate.
canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY)));
}
timer.start();
// Inner loop that allows us to break the run into smaller
// chunks (e.g. frames). This is especially useful for the GPU
// as we can flush and/or swap buffers to keep the GPU from
// queuing up too much work.
for (int loopCount = loopsPerIter; loopCount > 0; ) {
// Save and restore around each call to draw() to guarantee a pristine canvas.
SkAutoCanvasRestore saveRestore(canvas, true/*also save*/);
int loops;
if (frameIntervalComputed && loopCount > loopsPerFrame) {
loops = loopsPerFrame;
loopCount -= loopsPerFrame;
} else {
loops = loopCount;
loopCount = 0;
}
if (benchMode == kPictureRecord_BenchMode) {
recordFrom->draw(canvas);
} else {
bench->draw(loops, canvas);
}
if (kDeferredSilent_BenchMode == benchMode) {
static_cast<SkDeferredCanvas*>(canvas.get())->silentFlush();
} else if (NULL != canvas) {
canvas->flush();
}
#if SK_SUPPORT_GPU
// swap drawing buffers on each frame to prevent the GPU
// from queuing up too much work
if (NULL != glContext) {
glContext->swapBuffers();
}
#endif
}
// Stop truncated timers before GL calls complete, and stop the full timers after.
timer.truncatedEnd();
#if SK_SUPPORT_GPU
if (NULL != glContext) {
context->flush();
SK_GL(*glContext, Finish());
}
#endif
timer.end();
// setup the frame interval for subsequent iterations
if (!frameIntervalComputed) {
frameIntervalTime += timer.fWall;
frameIntervalTotalLoops += loopsPerIter;
if (frameIntervalTime >= FLAGS_minMs) {
frameIntervalComputed = true;
loopsPerFrame =
(int)(((double)frameIntervalTotalLoops / frameIntervalTime) * FLAGS_minMs);
if (loopsPerFrame < 1) {
示例13: flush
void flush() {
context->flush();
}