blob: 3b9f99e91625681669bea96e322567b5b04b77b2 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "platform/graphics/gpu/SharedContextRateLimiter.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "platform/graphics/gpu/Extensions3DUtil.h"
#include "public/platform/Platform.h"
#include "public/platform/WebGraphicsContext3DProvider.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "wtf/PtrUtil.h"
#include <memory>
namespace blink {
std::unique_ptr<SharedContextRateLimiter> SharedContextRateLimiter::create(
unsigned maxPendingTicks) {
return wrapUnique(new SharedContextRateLimiter(maxPendingTicks));
}
SharedContextRateLimiter::SharedContextRateLimiter(unsigned maxPendingTicks)
: m_maxPendingTicks(maxPendingTicks), m_canUseSyncQueries(false) {
m_contextProvider = wrapUnique(
Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
if (!m_contextProvider)
return;
gpu::gles2::GLES2Interface* gl = m_contextProvider->contextGL();
if (gl && gl->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
std::unique_ptr<Extensions3DUtil> extensionsUtil =
Extensions3DUtil::create(gl);
// TODO(junov): when the GLES 3.0 command buffer is ready, we could use
// fenceSync instead.
m_canUseSyncQueries =
extensionsUtil->supportsExtension("GL_CHROMIUM_sync_query");
}
}
void SharedContextRateLimiter::tick() {
if (!m_contextProvider)
return;
gpu::gles2::GLES2Interface* gl = m_contextProvider->contextGL();
if (!gl || gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
return;
m_queries.append(0);
if (m_canUseSyncQueries)
gl->GenQueriesEXT(1, &m_queries.last());
if (m_canUseSyncQueries) {
gl->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, m_queries.last());
gl->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
}
if (m_queries.size() > m_maxPendingTicks) {
if (m_canUseSyncQueries) {
GLuint result;
gl->GetQueryObjectuivEXT(m_queries.first(), GL_QUERY_RESULT_EXT, &result);
gl->DeleteQueriesEXT(1, &m_queries.first());
m_queries.removeFirst();
} else {
gl->Finish();
reset();
}
}
}
void SharedContextRateLimiter::reset() {
if (!m_contextProvider)
return;
gpu::gles2::GLES2Interface* gl = m_contextProvider->contextGL();
if (gl && gl->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
while (m_queries.size() > 0) {
gl->DeleteQueriesEXT(1, &m_queries.first());
m_queries.removeFirst();
}
} else {
m_queries.clear();
}
}
} // namespace blink