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

Unified Diff: ui/gfx/surface/accelerated_surface_win.cc

Issue 8867005: Win AcceleratedSurface no longer polls queries on separate thread. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 9 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
« no previous file with comments | « ui/gfx/surface/accelerated_surface_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/surface/accelerated_surface_win.cc
===================================================================
--- ui/gfx/surface/accelerated_surface_win.cc (revision 113398)
+++ ui/gfx/surface/accelerated_surface_win.cc (working copy)
@@ -12,6 +12,7 @@
#include "base/callback.h"
#include "base/command_line.h"
#include "base/debug/trace_event.h"
+#include "base/file_path.h"
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
@@ -23,50 +24,14 @@
#include "ui/base/win/hwnd_util.h"
#include "ui/gfx/gl/gl_switches.h"
-#pragma comment(lib, "d3d9.lib")
-
namespace {
typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT sdk_version,
IDirect3D9Ex **d3d);
-const int64 kPollQueryInterval = 1;
-
const wchar_t kD3D9ModuleName[] = L"d3d9.dll";
const char kCreate3D9DeviceExName[] = "Direct3DCreate9Ex";
-class QuerySyncThread
- : public base::Thread,
- public base::RefCounted<QuerySyncThread> {
- public:
- explicit QuerySyncThread(const char* name);
- virtual ~QuerySyncThread();
-
- // Invoke the completion task when the query completes.
- void AcknowledgeQuery(const base::win::ScopedComPtr<IDirect3DQuery9>& query,
- const base::Closure& completion_task);
-
- // Acknowledge all pending queries for the given device early then invoke
- // the given task.
- void AcknowledgeEarly(
- const base::win::ScopedComPtr<IDirect3DDevice9Ex>& device,
- const base::Closure& completion_task);
-
- private:
- void PollQueries();
-
- struct PendingQuery {
- base::win::ScopedComPtr<IDirect3DQuery9> query;
- base::Closure completion_task;
- };
-
- typedef std::list<PendingQuery> PendingQueries;
- PendingQueries pending_queries_;
- base::WeakPtrFactory<QuerySyncThread> poll_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(QuerySyncThread);
-};
-
class PresentThreadPool {
public:
static const int kNumPresentThreads = 4;
@@ -79,19 +44,9 @@
const tracked_objects::Location& from_here,
const base::Closure& task);
- void AcknowledgeQuery(const tracked_objects::Location& from_here,
- const base::win::ScopedComPtr<IDirect3DQuery9>& query,
- const base::Closure& completion_task);
-
- void AcknowledgeEarly(
- const tracked_objects::Location& from_here,
- const base::win::ScopedComPtr<IDirect3DDevice9Ex>& device,
- const base::Closure& completion_task);
-
private:
int next_thread_;
scoped_ptr<base::Thread> present_threads_[kNumPresentThreads];
- scoped_refptr<QuerySyncThread> query_sync_thread_;
DISALLOW_COPY_AND_ASSIGN(PresentThreadPool);
};
@@ -99,92 +54,12 @@
base::LazyInstance<PresentThreadPool>
g_present_thread_pool = LAZY_INSTANCE_INITIALIZER;
-QuerySyncThread::QuerySyncThread(const char* name)
- : base::Thread(name),
- poll_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
-}
-
-QuerySyncThread::~QuerySyncThread() {
-}
-
-void QuerySyncThread::AcknowledgeQuery(
- const base::win::ScopedComPtr<IDirect3DQuery9>& query,
- const base::Closure& completion_task) {
- PendingQuery pending_query;
- pending_query.query = query;
- pending_query.completion_task = completion_task;
- pending_queries_.push_back(pending_query);
-
- // Cancel any pending poll tasks. There should only ever be one pending at a
- // time.
- poll_factory_.InvalidateWeakPtrs();
-
- PollQueries();
-}
-
-void QuerySyncThread::AcknowledgeEarly(
- const base::win::ScopedComPtr<IDirect3DDevice9Ex>& device,
- const base::Closure& completion_task) {
- TRACE_EVENT0("surface", "AcknowledgeEarly");
-
- PendingQueries::iterator it = pending_queries_.begin();
- while (it != pending_queries_.end()) {
- const PendingQuery& pending_query = *it;
-
- base::win::ScopedComPtr<IDirect3DDevice9> query_device;
- pending_query.query->GetDevice(query_device.Receive());
-
- base::win::ScopedComPtr<IDirect3DDevice9Ex> query_device_ex;
- query_device_ex.QueryFrom(query_device.get());
-
- if (query_device_ex.get() != device.get()) {
- ++it;
- } else {
- pending_query.completion_task.Run();
- it = pending_queries_.erase(it);
- }
- }
-
- if (!completion_task.is_null())
- completion_task.Run();
-}
-
-
-void QuerySyncThread::PollQueries() {
- TRACE_EVENT0("surface", "PollQueries");
-
- PendingQueries::iterator it = pending_queries_.begin();
- while (it != pending_queries_.end()) {
- const PendingQuery& pending_query = *it;
-
- HRESULT hr = pending_query.query->GetData(NULL, 0, D3DGETDATA_FLUSH);
- if (hr == S_FALSE) {
- ++it;
- } else {
- pending_query.completion_task.Run();
- it = pending_queries_.erase(it);
- }
- }
-
- // Try again later if there are incomplete queries. Otherwise don't poll again
- // until AcknowledgeQuery is called with a new query.
- if (!pending_queries_.empty()) {
- message_loop()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&QuerySyncThread::PollQueries, poll_factory_.GetWeakPtr()),
- kPollQueryInterval);
- }
-}
-
PresentThreadPool::PresentThreadPool() : next_thread_(0) {
for (int i = 0; i < kNumPresentThreads; ++i) {
present_threads_[i].reset(new base::Thread(
base::StringPrintf("PresentThread #%d", i).c_str()));
present_threads_[i]->Start();
}
-
- query_sync_thread_ = new QuerySyncThread("QuerySyncThread");
- query_sync_thread_->Start();
}
int PresentThreadPool::NextThread() {
@@ -201,30 +76,6 @@
present_threads_[thread]->message_loop()->PostTask(from_here, task);
}
-void PresentThreadPool::AcknowledgeQuery(
- const tracked_objects::Location& from_here,
- const base::win::ScopedComPtr<IDirect3DQuery9>& query,
- const base::Closure& completion_task) {
- query_sync_thread_->message_loop()->PostTask(
- from_here,
- base::Bind(&QuerySyncThread::AcknowledgeQuery,
- query_sync_thread_,
- query,
- completion_task));
-}
-
-void PresentThreadPool::AcknowledgeEarly(
- const tracked_objects::Location& from_here,
- const base::win::ScopedComPtr<IDirect3DDevice9Ex>& device,
- const base::Closure& completion_task) {
- query_sync_thread_->message_loop()->PostTask(
- from_here,
- base::Bind(&QuerySyncThread::AcknowledgeEarly,
- query_sync_thread_,
- device,
- completion_task));
-}
-
UINT GetPresentationInterval() {
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync))
return D3DPRESENT_INTERVAL_IMMEDIATE;
@@ -253,10 +104,10 @@
}
void AcceleratedSurface::Destroy() {
- g_present_thread_pool.Pointer()->AcknowledgeEarly(
+ g_present_thread_pool.Pointer()->PostTask(
+ thread_affinity_,
FROM_HERE,
- device_,
- base::Bind(&AcceleratedSurface::QueriesDestroyed, this));
+ base::Bind(&AcceleratedSurface::DoDestroy, this));
}
void AcceleratedSurface::AsyncPresentAndAcknowledge(
@@ -336,12 +187,10 @@
HRESULT hr;
- HMODULE module = GetModuleHandle(kD3D9ModuleName);
- if (!module)
- return;
+ d3d_module_.Reset(base::LoadNativeLibrary(FilePath(kD3D9ModuleName), NULL));
Direct3DCreate9ExFunc create_func = reinterpret_cast<Direct3DCreate9ExFunc>(
- GetProcAddress(module, kCreate3D9DeviceExName));
+ d3d_module_.GetFunctionPointer(kCreate3D9DeviceExName));
if (!create_func)
return;
@@ -406,6 +255,11 @@
base::AtomicRefCountDec(&num_pending_resizes_);
+ base::AutoLock locked(lock_);
+
+ if (!device_)
+ return;
+
D3DPRESENT_PARAMETERS parameters = { 0 };
parameters.BackBufferWidth = size.width();
parameters.BackBufferHeight = size.height();
@@ -439,6 +293,9 @@
// Ensure the task is always run and while the lock is taken.
base::ScopedClosureRunner scoped_completion_runner(completion_task);
+ if (!device_)
+ return;
+
if (!window_)
return;
@@ -504,13 +361,22 @@
SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOSENDCHANGING |
SWP_ASYNCWINDOWPOS);
- scoped_completion_runner.Release();
- if (!completion_task.is_null()) {
- g_present_thread_pool.Pointer()->AcknowledgeQuery(FROM_HERE,
- query_,
- completion_task);
+ // Wait for the StretchRect to complete before notifying the GPU process
+ // that it is safe to write to its backing store again.
+ {
+ TRACE_EVENT0("surface", "spin");
+ do {
+ hr = query_->GetData(NULL, 0, D3DGETDATA_FLUSH);
+
+ if (hr == S_FALSE)
+ Sleep(0);
+ } while (hr == S_FALSE);
Ken Russell (switch to Gerrit) 2011/12/08 01:55:07 As an FYI a problem in a similarly structured loop
}
+ scoped_completion_runner.Release();
+ if (!completion_task.is_null())
+ completion_task.Run();
+
{
TRACE_EVENT0("surface", "Present");
hr = device_->Present(&rect, &rect, NULL, NULL);
« no previous file with comments | « ui/gfx/surface/accelerated_surface_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698