Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(954)

Unified Diff: gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc

Issue 793693003: Tile Compression (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc
index 61db3b68413dde50d864b6d0ea5ce7218fed71b4..50758276f720bce1f463e1558d872de17b3d3813 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc
@@ -9,6 +9,7 @@
#include "base/debug/trace_event_synthetic_delay.h"
#include "base/lazy_instance.h"
#include "base/memory/weak_ptr.h"
+#include "base/synchronization/waitable_event.h"
#include "ui/gl/scoped_binders.h"
namespace gpu {
@@ -17,6 +18,20 @@ namespace {
static uint64 g_next_pixel_transfer_state_id = 1;
+static const uint64 kNotificationTask = 0;
+static const uint64 kSuspendTask = 1;
+
+uint64 NextPixelTransferStateId() {
+ g_next_pixel_transfer_state_id++;
+ switch (g_next_pixel_transfer_state_id) {
+ case kNotificationTask:
+ case kSuspendTask:
+ return NextPixelTransferStateId();
+ default:
+ return g_next_pixel_transfer_state_id;
+ }
+}
+
void PerformNotifyCompletion(
AsyncMemoryParams mem_params,
scoped_refptr<AsyncPixelTransferCompletionObserver> observer) {
@@ -36,6 +51,10 @@ class AsyncPixelTransferDelegateIdle
AsyncPixelTransferManagerIdle::SharedState* state,
GLuint texture_id,
const AsyncTexImage2DParams& define_params);
+ AsyncPixelTransferDelegateIdle(
+ AsyncPixelTransferManagerIdle::SharedState* state,
+ GLuint texture_id,
+ const AsyncCompressedTexImage2DParams& define_params);
~AsyncPixelTransferDelegateIdle() override;
// Implement AsyncPixelTransferDelegate:
@@ -44,6 +63,13 @@ class AsyncPixelTransferDelegateIdle
const base::Closure& bind_callback) override;
void AsyncTexSubImage2D(const AsyncTexSubImage2DParams& tex_params,
const AsyncMemoryParams& mem_params) override;
+ void AsyncCompressedTexImage2D(
+ const AsyncCompressedTexImage2DParams& tex_params,
+ const AsyncMemoryParams& mem_params,
+ const base::Closure& bind_callback) override;
+ void AsyncCompressedTexSubImage2D(
+ const AsyncCompressedTexSubImage2DParams& tex_params,
+ const AsyncMemoryParams& mem_params) override;
bool TransferIsInProgress() override;
void WaitForTransferCompletion() override;
@@ -53,11 +79,21 @@ class AsyncPixelTransferDelegateIdle
const base::Closure& bind_callback);
void PerformAsyncTexSubImage2D(AsyncTexSubImage2DParams tex_params,
AsyncMemoryParams mem_params);
+ void PerformAsyncCompressedTexImage2D(
+ AsyncCompressedTexImage2DParams tex_params,
+ AsyncMemoryParams mem_params,
+ const base::Closure& bind_callback);
+ void PerformAsyncCompressedTexSubImage2D(
+ AsyncCompressedTexSubImage2DParams tex_params,
+ AsyncMemoryParams mem_params);
uint64 id_;
GLuint texture_id_;
bool transfer_in_progress_;
- AsyncTexImage2DParams define_params_;
+ union {
+ AsyncTexImage2DParams define_params_;
+ AsyncCompressedTexImage2DParams compressed_define_params_;
+ };
// Safe to hold a raw pointer because SharedState is owned by the Manager
// which owns the Delegate.
@@ -70,12 +106,23 @@ AsyncPixelTransferDelegateIdle::AsyncPixelTransferDelegateIdle(
AsyncPixelTransferManagerIdle::SharedState* shared_state,
GLuint texture_id,
const AsyncTexImage2DParams& define_params)
- : id_(g_next_pixel_transfer_state_id++),
+ : id_(NextPixelTransferStateId()),
texture_id_(texture_id),
transfer_in_progress_(false),
define_params_(define_params),
shared_state_(shared_state) {}
+AsyncPixelTransferDelegateIdle::AsyncPixelTransferDelegateIdle(
+ AsyncPixelTransferManagerIdle::SharedState* shared_state,
+ GLuint texture_id,
+ const AsyncCompressedTexImage2DParams& define_params)
+ : id_(NextPixelTransferStateId()),
+ texture_id_(texture_id),
+ transfer_in_progress_(false),
+ compressed_define_params_(define_params),
+ shared_state_(shared_state) {
+}
+
AsyncPixelTransferDelegateIdle::~AsyncPixelTransferDelegateIdle() {}
void AsyncPixelTransferDelegateIdle::AsyncTexImage2D(
@@ -114,6 +161,37 @@ void AsyncPixelTransferDelegateIdle::AsyncTexSubImage2D(
transfer_in_progress_ = true;
}
+void AsyncPixelTransferDelegateIdle::AsyncCompressedTexImage2D(
+ const AsyncCompressedTexImage2DParams& tex_params,
+ const AsyncMemoryParams& mem_params,
+ const base::Closure& bind_callback) {
+ TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("gpu.AsyncTexImage");
+ DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
+
+ shared_state_->tasks.push_back(AsyncPixelTransferManagerIdle::Task(
+ id_, this,
+ base::Bind(
+ &AsyncPixelTransferDelegateIdle::PerformAsyncCompressedTexImage2D,
+ AsWeakPtr(), tex_params, mem_params, bind_callback)));
+
+ transfer_in_progress_ = true;
+}
+
+void AsyncPixelTransferDelegateIdle::AsyncCompressedTexSubImage2D(
+ const AsyncCompressedTexSubImage2DParams& tex_params,
+ const AsyncMemoryParams& mem_params) {
+ TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("gpu.AsyncTexImage");
+ DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
+
+ shared_state_->tasks.push_back(AsyncPixelTransferManagerIdle::Task(
+ id_, this,
+ base::Bind(
+ &AsyncPixelTransferDelegateIdle::PerformAsyncCompressedTexSubImage2D,
+ AsWeakPtr(), tex_params, mem_params)));
+
+ transfer_in_progress_ = true;
+}
+
bool AsyncPixelTransferDelegateIdle::TransferIsInProgress() {
return transfer_in_progress_;
}
@@ -223,6 +301,74 @@ void AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D(
base::TimeTicks::HighResNow() - begin_time;
}
+void AsyncPixelTransferDelegateIdle::PerformAsyncCompressedTexImage2D(
+ AsyncCompressedTexImage2DParams tex_params,
+ AsyncMemoryParams mem_params,
+ const base::Closure& bind_callback) {
+ TRACE_EVENT2("gpu", "PerformAsyncCompressedTexImage2D", "width",
+ tex_params.width, "height", tex_params.height);
+
+ void* data = mem_params.GetDataAddress();
+
+ base::TimeTicks begin_time(base::TimeTicks::HighResNow());
+ gfx::ScopedTextureBinder texture_binder(tex_params.target, texture_id_);
+
+ {
+ TRACE_EVENT0("gpu", "glCompressedTexImage2D");
+ glCompressedTexImage2D(tex_params.target, tex_params.level,
+ tex_params.internal_format, tex_params.width,
+ tex_params.height, tex_params.border,
+ tex_params.image_size, data);
+ }
+
+ TRACE_EVENT_SYNTHETIC_DELAY_END("gpu.AsyncTexImage");
+ transfer_in_progress_ = false;
+ shared_state_->texture_upload_count++;
+ shared_state_->total_texture_upload_time +=
+ base::TimeTicks::HighResNow() - begin_time;
+
+ // The texture is already fully bound so just call it now.
+ bind_callback.Run();
+}
+
+void AsyncPixelTransferDelegateIdle::PerformAsyncCompressedTexSubImage2D(
+ AsyncCompressedTexSubImage2DParams tex_params,
+ AsyncMemoryParams mem_params) {
+ TRACE_EVENT2("gpu", "PerformAsyncCompressedTexSubImage2D", "width",
+ tex_params.width, "height", tex_params.height);
+
+ void* data = mem_params.GetDataAddress();
+
+ base::TimeTicks begin_time(base::TimeTicks::HighResNow());
+ gfx::ScopedTextureBinder texture_binder(tex_params.target, texture_id_);
+
+ // If it's a full texture update, use glCompressedTexImage2D as it's faster.
+ if (tex_params.xoffset == 0 && tex_params.yoffset == 0 &&
+ tex_params.target == compressed_define_params_.target &&
+ tex_params.level == compressed_define_params_.level &&
+ tex_params.width == compressed_define_params_.width &&
+ tex_params.height == compressed_define_params_.height) {
+ TRACE_EVENT0("gpu", "glCompressedTexImage2D");
+ glCompressedTexImage2D(
+ compressed_define_params_.target, compressed_define_params_.level,
+ compressed_define_params_.internal_format,
+ compressed_define_params_.width, compressed_define_params_.height,
+ compressed_define_params_.border, tex_params.image_size, data);
+ } else {
+ TRACE_EVENT0("gpu", "glCompressedTexSubImage2D");
+ glCompressedTexSubImage2D(tex_params.target, tex_params.level,
+ tex_params.xoffset, tex_params.yoffset,
+ tex_params.width, tex_params.height,
+ tex_params.format, tex_params.image_size, data);
+ }
+
+ TRACE_EVENT_SYNTHETIC_DELAY_END("gpu.AsyncTexImage");
+ transfer_in_progress_ = false;
+ shared_state_->texture_upload_count++;
+ shared_state_->total_texture_upload_time +=
+ base::TimeTicks::HighResNow() - begin_time;
+}
+
AsyncPixelTransferManagerIdle::Task::Task(
uint64 transfer_id,
AsyncPixelTransferDelegate* delegate,
@@ -242,7 +388,7 @@ AsyncPixelTransferManagerIdle::SharedState::~SharedState() {}
void AsyncPixelTransferManagerIdle::SharedState::ProcessNotificationTasks() {
while (!tasks.empty()) {
// Stop when we reach a pixel transfer task.
- if (tasks.front().transfer_id)
+ if (tasks.front().transfer_id > kSuspendTask)
return;
tasks.front().task.Run();
@@ -269,7 +415,7 @@ void AsyncPixelTransferManagerIdle::AsyncNotifyCompletion(
}
shared_state_.tasks.push_back(
- Task(0, // 0 transfer_id for notification tasks.
+ Task(kNotificationTask,
NULL,
base::Bind(
&PerformNotifyCompletion,
@@ -289,8 +435,16 @@ void AsyncPixelTransferManagerIdle::ProcessMorePendingTransfers() {
if (shared_state_.tasks.empty())
return;
- // First task should always be a pixel transfer task.
- DCHECK(shared_state_.tasks.front().transfer_id);
+ // Suspend uploads until waitables have been signalled.
+ while (!suspend_waitables_.empty()) {
+ if (!suspend_waitables_.front()->IsSignaled())
+ return;
+ else
+ suspend_waitables_.erase(suspend_waitables_.begin());
+ }
+
+ // First task should always be a pixel transfer task or a suspend task.
+ DCHECK_NE(shared_state_.tasks.front().transfer_id, kNotificationTask);
shared_state_.tasks.front().task.Run();
shared_state_.tasks.pop_front();
@@ -310,6 +464,32 @@ void AsyncPixelTransferManagerIdle::WaitAllAsyncTexImage2D() {
task.delegate->WaitForTransferCompletion();
}
+void AsyncPixelTransferManagerIdle::DoSuspendUploads(
+ scoped_ptr<base::WaitableEvent> waitable) {
+ suspend_waitables_.push_back(waitable.release());
+}
+
+void AsyncPixelTransferManagerIdle::SuspendUploads(
+ base::WaitableEvent* waitable) {
+ shared_state_.tasks.push_back(
+ Task(kSuspendTask,
+ NULL,
+ base::Bind(&AsyncPixelTransferManagerIdle::DoSuspendUploads,
+ base::Unretained(this),
+ base::Passed(
+ scoped_ptr<base::WaitableEvent>(waitable)))));
+}
+
+void AsyncPixelTransferManagerIdle::SignalWhenUploadsCompleted(
+ base::WaitableEvent* waitable) {
+ shared_state_.tasks.push_back(
+ Task(kNotificationTask,
+ NULL,
+ base::Bind(&base::WaitableEvent::Signal,
+ // WaitableEvent owned by waiter.
+ base::Unretained(waitable))));
+}
+
AsyncPixelTransferDelegate*
AsyncPixelTransferManagerIdle::CreatePixelTransferDelegateImpl(
gles2::TextureRef* ref,
@@ -319,4 +499,12 @@ AsyncPixelTransferManagerIdle::CreatePixelTransferDelegateImpl(
define_params);
}
+AsyncPixelTransferDelegate*
+AsyncPixelTransferManagerIdle::CreatePixelTransferDelegateImpl(
+ gles2::TextureRef* ref,
+ const AsyncCompressedTexImage2DParams& define_params) {
+ return new AsyncPixelTransferDelegateIdle(&shared_state_, ref->service_id(),
+ define_params);
+}
+
} // namespace gpu

Powered by Google App Engine
This is Rietveld 408576698