summaryrefslogtreecommitdiffstats
path: root/ui/gfx/surface
diff options
context:
space:
mode:
authorjbauman@chromium.org <jbauman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-06 02:26:55 +0000
committerjbauman@chromium.org <jbauman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-06 02:26:55 +0000
commit1f305b559be7437fbb6d6ca0ea31897a1013e466 (patch)
tree720abc7d5f2aa811a71c61aa59f8494094b2af47 /ui/gfx/surface
parent16d8ae4a78625bccd8ec30795dbf5639f8d88794 (diff)
downloadchromium_src-1f305b559be7437fbb6d6ca0ea31897a1013e466.zip
chromium_src-1f305b559be7437fbb6d6ca0ea31897a1013e466.tar.gz
chromium_src-1f305b559be7437fbb6d6ca0ea31897a1013e466.tar.bz2
Do all Presents on present thread.
If we queue up presents from the UI thread on the present thread, that will avoid the present thread starving the UI thread due to the AcceleratedPresenter lock. The UI thread will synchronously wait for the present to finish, so the WM_PAINT callback will end at the correct time. Also remove the spin after the present, as it's probably unnecessary. BUG=122087 TEST= Review URL: http://codereview.chromium.org/9949043 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@131071 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx/surface')
-rw-r--r--ui/gfx/surface/accelerated_surface_win.cc38
-rw-r--r--ui/gfx/surface/accelerated_surface_win.h6
2 files changed, 28 insertions, 16 deletions
diff --git a/ui/gfx/surface/accelerated_surface_win.cc b/ui/gfx/surface/accelerated_surface_win.cc
index c1f0c66..0210534 100644
--- a/ui/gfx/surface/accelerated_surface_win.cc
+++ b/ui/gfx/surface/accelerated_surface_win.cc
@@ -283,7 +283,8 @@ scoped_refptr<AcceleratedPresenter> AcceleratedPresenterMap::GetPresenter(
AcceleratedPresenter::AcceleratedPresenter(gfx::NativeWindow window)
: present_thread_(g_present_thread_pool.Pointer()->NextThread()),
- window_(window) {
+ window_(window),
+ event_(false, false) {
}
scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow(
@@ -312,6 +313,26 @@ void AcceleratedPresenter::AsyncPresentAndAcknowledge(
bool AcceleratedPresenter::Present() {
TRACE_EVENT0("surface", "Present");
+ bool result;
+
+ present_thread_->message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&AcceleratedPresenter::DoPresent,
+ this,
+ &result));
+ event_.Wait();
+ return result;
+}
+
+void AcceleratedPresenter::DoPresent(bool* result)
+{
+ *result = DoRealPresent();
+ event_.Signal();
+}
+
+bool AcceleratedPresenter::DoRealPresent()
+{
+ TRACE_EVENT0("surface", "DoRealPresent");
HRESULT hr;
base::AutoLock locked(lock_);
@@ -341,21 +362,6 @@ bool AcceleratedPresenter::Present() {
return false;
}
- // Wait for the Present to complete before returning.
- {
- TRACE_EVENT0("surface", "spin");
- hr = present_thread_->query()->Issue(D3DISSUE_END);
- if (FAILED(hr))
- return false;
-
- do {
- hr = present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH);
-
- if (hr == S_FALSE)
- Sleep(0);
- } while (hr == S_FALSE);
- }
-
return true;
}
diff --git a/ui/gfx/surface/accelerated_surface_win.h b/ui/gfx/surface/accelerated_surface_win.h
index e428c50..32f7acf 100644
--- a/ui/gfx/surface/accelerated_surface_win.h
+++ b/ui/gfx/surface/accelerated_surface_win.h
@@ -11,6 +11,7 @@
#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
+#include "base/synchronization/waitable_event.h"
#include "base/win/scoped_comptr.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
@@ -61,6 +62,8 @@ class SURFACE_EXPORT AcceleratedPresenter
int64 surface_handle,
const base::Callback<void(bool)>& completion_task);
void DoSuspend();
+ void DoPresent(bool* presented);
+ bool DoRealPresent();
// The thread with which this presenter has affinity.
PresentThread* const present_thread_;
@@ -73,6 +76,9 @@ class SURFACE_EXPORT AcceleratedPresenter
// present_thread_ member.
base::Lock lock_;
+ // UI thread can wait on this event to ensure a present is finished.
+ base::WaitableEvent event_;
+
// The current size of the swap chain. This is only accessed on the thread
// with which the surface has affinity.
gfx::Size size_;