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

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

Issue 16175005: GPU: Replace AsyncPixelTransferState with AsyncPixelTransferDelegate. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 6 months 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_egl.cc
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc
index 50d2a84ccc526b718f6234ba5ba35a75c154e215..d6c17ce982e01bfbe0122b71e9a542a09c367101 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc
@@ -389,36 +389,6 @@ class TransferStateInternal
bool use_image_preserved_;
};
-// EGL needs thread-safe ref-counting, so this just wraps
-// an internal thread-safe ref-counted state object.
-class AsyncTransferStateImpl : public AsyncPixelTransferState {
- public:
- AsyncTransferStateImpl(GLuint texture_id,
- const AsyncTexImage2DParams& define_params,
- bool wait_for_uploads,
- bool wait_for_creation,
- bool use_image_preserved)
- : internal_(new TransferStateInternal(texture_id,
- define_params,
- wait_for_uploads,
- wait_for_creation,
- use_image_preserved)) {
- }
-
- virtual bool TransferIsInProgress() OVERRIDE {
- return internal_->TransferIsInProgress();
- }
-
- void BindTransfer() {
- internal_->BindTransfer();
- }
-
- scoped_refptr<TransferStateInternal> internal_;
-
- private:
- virtual ~AsyncTransferStateImpl() {}
-};
-
} // namespace
// Class which handles async pixel transfers using EGLImageKHR and another
@@ -427,55 +397,48 @@ class AsyncPixelTransferDelegateEGL
: public AsyncPixelTransferDelegate,
public base::SupportsWeakPtr<AsyncPixelTransferDelegateEGL> {
public:
- explicit AsyncPixelTransferDelegateEGL(
- AsyncPixelTransferManagerEGL::SharedState* shared_state);
+ AsyncPixelTransferDelegateEGL(
+ AsyncPixelTransferManagerEGL::SharedState* shared_state,
+ GLuint texture_id,
+ const AsyncTexImage2DParams& define_params);
virtual ~AsyncPixelTransferDelegateEGL();
+ void BindTransfer() { state_->BindTransfer(); }
+
// Implement AsyncPixelTransferDelegate:
- virtual AsyncPixelTransferState* CreatePixelTransferState(
- GLuint texture_id,
- const AsyncTexImage2DParams& define_params) OVERRIDE;
virtual void AsyncTexImage2D(
- AsyncPixelTransferState* state,
const AsyncTexImage2DParams& tex_params,
const AsyncMemoryParams& mem_params,
const base::Closure& bind_callback) OVERRIDE;
virtual void AsyncTexSubImage2D(
- AsyncPixelTransferState* state,
const AsyncTexSubImage2DParams& tex_params,
const AsyncMemoryParams& mem_params) OVERRIDE;
- virtual void WaitForTransferCompletion(
- AsyncPixelTransferState* state) OVERRIDE;
+ virtual bool TransferIsInProgress() OVERRIDE;
+ virtual void WaitForTransferCompletion() OVERRIDE;
private:
// Returns true if a work-around was used.
bool WorkAroundAsyncTexImage2D(
- AsyncPixelTransferState* state,
const AsyncTexImage2DParams& tex_params,
const AsyncMemoryParams& mem_params,
const base::Closure& bind_callback);
bool WorkAroundAsyncTexSubImage2D(
- AsyncPixelTransferState* state,
const AsyncTexSubImage2DParams& tex_params,
const AsyncMemoryParams& mem_params);
// A raw pointer is safe because the SharedState is owned by the Manager,
// which owns this Delegate.
AsyncPixelTransferManagerEGL::SharedState* shared_state_;
+ scoped_refptr<TransferStateInternal> state_;
DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferDelegateEGL);
};
AsyncPixelTransferDelegateEGL::AsyncPixelTransferDelegateEGL(
- AsyncPixelTransferManagerEGL::SharedState* shared_state)
+ AsyncPixelTransferManagerEGL::SharedState* shared_state,
+ GLuint texture_id,
+ const AsyncTexImage2DParams& define_params)
: shared_state_(shared_state) {
-}
-
-AsyncPixelTransferDelegateEGL::~AsyncPixelTransferDelegateEGL() {}
-
-AsyncPixelTransferState* AsyncPixelTransferDelegateEGL::
- CreatePixelTransferState(GLuint texture_id,
- const AsyncTexImage2DParams& define_params) {
// We can't wait on uploads on imagination (it can take 200ms+).
// In practice, they are complete when the CPU glTexSubImage2D completes.
bool wait_for_uploads = !shared_state_->is_imagination;
@@ -493,27 +456,27 @@ AsyncPixelTransferState* AsyncPixelTransferDelegateEGL::
bool use_image_preserved =
shared_state_->is_qualcomm || shared_state_->is_imagination;
- return new AsyncTransferStateImpl(texture_id,
- define_params,
- wait_for_uploads,
- wait_for_creation,
- use_image_preserved);
+ state_ = new TransferStateInternal(texture_id,
+ define_params,
+ wait_for_uploads,
+ wait_for_creation,
+ use_image_preserved);
}
-void AsyncPixelTransferDelegateEGL::WaitForTransferCompletion(
- AsyncPixelTransferState* transfer_state) {
- scoped_refptr<TransferStateInternal> state =
- static_cast<AsyncTransferStateImpl*>(transfer_state)->internal_.get();
- DCHECK(state.get());
- DCHECK(state->texture_id_);
+AsyncPixelTransferDelegateEGL::~AsyncPixelTransferDelegateEGL() {}
+
+bool AsyncPixelTransferDelegateEGL::TransferIsInProgress() {
+ return state_->TransferIsInProgress();
+}
- if (state->TransferIsInProgress()) {
+void AsyncPixelTransferDelegateEGL::WaitForTransferCompletion() {
+ if (state_->TransferIsInProgress()) {
#if defined(OS_ANDROID) || defined(OS_LINUX)
g_transfer_thread.Pointer()->SetPriority(base::kThreadPriority_Display);
#endif
- state->WaitForTransferCompletion();
- DCHECK(!state->TransferIsInProgress());
+ state_->WaitForTransferCompletion();
+ DCHECK(!state_->TransferIsInProgress());
#if defined(OS_ANDROID) || defined(OS_LINUX)
g_transfer_thread.Pointer()->SetPriority(base::kThreadPriority_Background);
@@ -522,40 +485,34 @@ void AsyncPixelTransferDelegateEGL::WaitForTransferCompletion(
}
void AsyncPixelTransferDelegateEGL::AsyncTexImage2D(
- AsyncPixelTransferState* transfer_state,
const AsyncTexImage2DParams& tex_params,
const AsyncMemoryParams& mem_params,
const base::Closure& bind_callback) {
- if (WorkAroundAsyncTexImage2D(transfer_state, tex_params,
- mem_params, bind_callback))
+ if (WorkAroundAsyncTexImage2D(tex_params, mem_params, bind_callback))
return;
- scoped_refptr<TransferStateInternal> state =
- static_cast<AsyncTransferStateImpl*>(transfer_state)->internal_.get();
DCHECK(mem_params.shared_memory);
DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
mem_params.shm_size);
- DCHECK(state.get());
- DCHECK(state->texture_id_);
- DCHECK(!state->TransferIsInProgress());
- DCHECK_EQ(state->egl_image_, EGL_NO_IMAGE_KHR);
+ DCHECK(!state_->TransferIsInProgress());
+ DCHECK_EQ(state_->egl_image_, EGL_NO_IMAGE_KHR);
DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
DCHECK_EQ(tex_params.level, 0);
// Mark the transfer in progress and save the late bind
// callback, so we can notify the client when it is bound.
- shared_state_->pending_allocations.push_back(transfer_state->AsWeakPtr());
- state->bind_callback_ = bind_callback;
+ shared_state_->pending_allocations.push_back(AsWeakPtr());
+ state_->bind_callback_ = bind_callback;
// Mark the transfer in progress.
- state->MarkAsTransferIsInProgress();
+ state_->MarkAsTransferIsInProgress();
// Duplicate the shared memory so there is no way we can get
// a use-after-free of the raw pixels.
transfer_message_loop_proxy()->PostTask(FROM_HERE,
base::Bind(
&TransferStateInternal::PerformAsyncTexImage2D,
- state,
+ state_,
tex_params,
mem_params,
base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
@@ -567,19 +524,14 @@ void AsyncPixelTransferDelegateEGL::AsyncTexImage2D(
}
void AsyncPixelTransferDelegateEGL::AsyncTexSubImage2D(
- AsyncPixelTransferState* transfer_state,
const AsyncTexSubImage2DParams& tex_params,
const AsyncMemoryParams& mem_params) {
TRACE_EVENT2("gpu", "AsyncTexSubImage2D",
"width", tex_params.width,
"height", tex_params.height);
- if (WorkAroundAsyncTexSubImage2D(transfer_state, tex_params, mem_params))
+ if (WorkAroundAsyncTexSubImage2D(tex_params, mem_params))
return;
- scoped_refptr<TransferStateInternal> state =
- static_cast<AsyncTransferStateImpl*>(transfer_state)->internal_.get();
-
- DCHECK(state->texture_id_);
- DCHECK(!state->TransferIsInProgress());
+ DCHECK(!state_->TransferIsInProgress());
DCHECK(mem_params.shared_memory);
DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
mem_params.shm_size);
@@ -587,18 +539,18 @@ void AsyncPixelTransferDelegateEGL::AsyncTexSubImage2D(
DCHECK_EQ(tex_params.level, 0);
// Mark the transfer in progress.
- state->MarkAsTransferIsInProgress();
+ state_->MarkAsTransferIsInProgress();
// If this wasn't async allocated, we don't have an EGLImage yet.
// Create the EGLImage if it hasn't already been created.
- state->CreateEglImageOnMainThreadIfNeeded();
+ state_->CreateEglImageOnMainThreadIfNeeded();
// Duplicate the shared memory so there are no way we can get
// a use-after-free of the raw pixels.
transfer_message_loop_proxy()->PostTask(FROM_HERE,
base::Bind(
&TransferStateInternal::PerformAsyncTexSubImage2D,
- state,
+ state_,
tex_params,
mem_params,
base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
@@ -625,7 +577,7 @@ bool DimensionsSupportImgFastPath(int width, int height) {
!(IsPowerOfTwo(width) &&
IsPowerOfTwo(height));
}
-} // namespace
+} // namespace
// It is very difficult to stream uploads on Imagination GPUs:
// - glTexImage2D defers a swizzle/stall until draw-time
@@ -642,14 +594,11 @@ bool DimensionsSupportImgFastPath(int width, int height) {
// on purely synchronous allocation/upload on the main thread.
bool AsyncPixelTransferDelegateEGL::WorkAroundAsyncTexImage2D(
- AsyncPixelTransferState* transfer_state,
const AsyncTexImage2DParams& tex_params,
const AsyncMemoryParams& mem_params,
const base::Closure& bind_callback) {
if (!shared_state_->is_imagination)
return false;
- scoped_refptr<TransferStateInternal> state =
- static_cast<AsyncTransferStateImpl*>(transfer_state)->internal_.get();
// On imagination we allocate synchronously all the time, even
// if the dimensions support fast uploads. This is for part a.)
@@ -664,16 +613,16 @@ bool AsyncPixelTransferDelegateEGL::WorkAroundAsyncTexImage2D(
// The allocation has already occured, so mark it as finished
// and ready for binding.
- CHECK(!state->TransferIsInProgress());
+ CHECK(!state_->TransferIsInProgress());
// If the dimensions support fast async uploads, create the
// EGLImage for future uploads. The late bind should not
// be needed since the EGLImage was created from the main thread
// texture, but this is required to prevent an imagination driver crash.
if (DimensionsSupportImgFastPath(tex_params.width, tex_params.height)) {
- state->CreateEglImageOnMainThreadIfNeeded();
- shared_state_->pending_allocations.push_back(transfer_state->AsWeakPtr());
- state->bind_callback_ = bind_callback;
+ state_->CreateEglImageOnMainThreadIfNeeded();
+ shared_state_->pending_allocations.push_back(AsWeakPtr());
+ state_->bind_callback_ = bind_callback;
}
DCHECK(CHECK_GL());
@@ -681,7 +630,6 @@ bool AsyncPixelTransferDelegateEGL::WorkAroundAsyncTexImage2D(
}
bool AsyncPixelTransferDelegateEGL::WorkAroundAsyncTexSubImage2D(
- AsyncPixelTransferState* transfer_state,
const AsyncTexSubImage2DParams& tex_params,
const AsyncMemoryParams& mem_params) {
if (!shared_state_->is_imagination)
@@ -692,22 +640,19 @@ bool AsyncPixelTransferDelegateEGL::WorkAroundAsyncTexSubImage2D(
if (DimensionsSupportImgFastPath(tex_params.width, tex_params.height))
return false;
- scoped_refptr<TransferStateInternal> state =
- static_cast<AsyncTransferStateImpl*>(transfer_state)->internal_.get();
-
// Fall back on a synchronous stub as we don't have a known fast path.
// Also, older ICS drivers crash when we do any glTexSubImage2D on the
// same thread. To work around this we do glTexImage2D instead. Since
// we didn't create an EGLImage for this texture (see above), this is
// okay, but it limits this API to full updates for now.
- DCHECK(!state->egl_image_);
+ DCHECK(!state_->egl_image_);
DCHECK_EQ(tex_params.xoffset, 0);
DCHECK_EQ(tex_params.yoffset, 0);
- DCHECK_EQ(state->define_params_.width, tex_params.width);
- DCHECK_EQ(state->define_params_.height, tex_params.height);
- DCHECK_EQ(state->define_params_.level, tex_params.level);
- DCHECK_EQ(state->define_params_.format, tex_params.format);
- DCHECK_EQ(state->define_params_.type, tex_params.type);
+ DCHECK_EQ(state_->define_params_.width, tex_params.width);
+ DCHECK_EQ(state_->define_params_.height, tex_params.height);
+ DCHECK_EQ(state_->define_params_.level, tex_params.level);
+ DCHECK_EQ(state_->define_params_.format, tex_params.format);
+ DCHECK_EQ(state_->define_params_.type, tex_params.type);
void* data = GetAddress(mem_params);
base::TimeTicks begin_time;
@@ -717,7 +662,7 @@ bool AsyncPixelTransferDelegateEGL::WorkAroundAsyncTexSubImage2D(
TRACE_EVENT0("gpu", "glTexSubImage2D");
// Note we use define_params_ instead of tex_params.
// The DCHECKs above verify this is always the same.
- DoTexImage2D(state->define_params_, data);
+ DoTexImage2D(state_->define_params_, data);
}
if (shared_state_->texture_upload_stats.get()) {
shared_state_->texture_upload_stats
@@ -739,8 +684,7 @@ AsyncPixelTransferManagerEGL::SharedState::SharedState()
AsyncPixelTransferManagerEGL::SharedState::~SharedState() {}
-AsyncPixelTransferManagerEGL::AsyncPixelTransferManagerEGL()
- : delegate_(new AsyncPixelTransferDelegateEGL(&shared_state_)) {}
+AsyncPixelTransferManagerEGL::AsyncPixelTransferManagerEGL() {}
AsyncPixelTransferManagerEGL::~AsyncPixelTransferManagerEGL() {}
@@ -752,11 +696,10 @@ void AsyncPixelTransferManagerEGL::BindCompletedAsyncTransfers() {
shared_state_.pending_allocations.pop_front();
continue;
}
- scoped_refptr<TransferStateInternal> state =
- static_cast<AsyncTransferStateImpl*>
- (shared_state_.pending_allocations.front().get())->internal_.get();
+ AsyncPixelTransferDelegateEGL* delegate =
+ shared_state_.pending_allocations.front().get();
// Terminate early, as all transfers finish in order, currently.
- if (state->TransferIsInProgress())
+ if (delegate->TransferIsInProgress())
break;
if (!texture_binder)
@@ -764,7 +707,7 @@ void AsyncPixelTransferManagerEGL::BindCompletedAsyncTransfers() {
// If the transfer is finished, bind it to the texture
// and remove it from pending list.
- state->BindTransfer();
+ delegate->BindTransfer();
shared_state_.pending_allocations.pop_front();
}
}
@@ -806,8 +749,11 @@ bool AsyncPixelTransferManagerEGL::NeedsProcessMorePendingTransfers() {
}
AsyncPixelTransferDelegate*
-AsyncPixelTransferManagerEGL::GetAsyncPixelTransferDelegate() {
- return delegate_.get();
+AsyncPixelTransferManagerEGL::CreatePixelTransferDelegateImpl(
+ gles2::TextureRef* ref,
+ const AsyncTexImage2DParams& define_params) {
+ return new AsyncPixelTransferDelegateEGL(
+ &shared_state_, ref->service_id(), define_params);
}
} // namespace gpu

Powered by Google App Engine
This is Rietveld 408576698