summaryrefslogtreecommitdiffstats
path: root/ui/surface/accelerated_surface_win.cc
diff options
context:
space:
mode:
authornick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-02 23:31:07 +0000
committernick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-02 23:31:07 +0000
commitd748d0ffa9996ae58ab39c2cfdd5abbfcb6dcec4 (patch)
treeaf8aab17d5d6a08ba69022f408792733471da483 /ui/surface/accelerated_surface_win.cc
parent89ae13ed038c80228a532f42c92cd5de5bbc8a35 (diff)
downloadchromium_src-d748d0ffa9996ae58ab39c2cfdd5abbfcb6dcec4.zip
chromium_src-d748d0ffa9996ae58ab39c2cfdd5abbfcb6dcec4.tar.gz
chromium_src-d748d0ffa9996ae58ab39c2cfdd5abbfcb6dcec4.tar.bz2
Change PlatformBitmap memory ownership story. Fix CopyFromBackingStore threading issues.
PlatformBitmap: restructure this class so that, on all platforms, it is safe to use an SkBitmap derived from the PlatformBitmap even after the PlatformBitmap is destroyed. In practice this means changes to Linux (use a different cairo creation routine that allows us to allocate the memory) and Windows (the HDC is owned by PlatformBitmap, the HBITMAP by the SkPixelRef). CopyFromBackingStore: instead of requiring the caller to provide a PlatformBitmap, modify the signature so that the completion callback accepts an SkBitmap. Sometimes, the backing store copiers will allocate a PlatformBitmap and pass its SkBitmap to the completion callback, but this becomes merely an implementation detail. Meanwhile, in the accelerated case, it is not at all necessary to allocate a PlatformBitmap, so don't. This fixes a bug on Linux where the cairo surface context was being freed on a thread other than the UI thread. PlatformBitmap is basically not thread safe on Linux, and this change fixes that. Also fixed is a Dr. Memory GDI usage warning -- we are sure to de-select the HBITMAP before deleting the memory DC. Lastly, moving CopyFromBackingStore's interface to use a callee-managed SkBitmap conditions the architecture for doing RGBA->YUV on the GPU, prior to readback. BUG=109963,159234,161537 Review URL: https://codereview.chromium.org/12087016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@180271 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/surface/accelerated_surface_win.cc')
-rw-r--r--ui/surface/accelerated_surface_win.cc46
1 files changed, 23 insertions, 23 deletions
diff --git a/ui/surface/accelerated_surface_win.cc b/ui/surface/accelerated_surface_win.cc
index cfd0d6c..8523493 100644
--- a/ui/surface/accelerated_surface_win.cc
+++ b/ui/surface/accelerated_surface_win.cc
@@ -23,6 +23,7 @@
#include "base/threading/thread_restrictions.h"
#include "base/time.h"
#include "base/win/wrapped_window_proc.h"
+#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/win/dpi.h"
#include "ui/base/win/hwnd_util.h"
#include "ui/base/win/shell.h"
@@ -306,15 +307,13 @@ void AcceleratedPresenter::Present(HDC dc) {
void AcceleratedPresenter::AsyncCopyTo(
const gfx::Rect& requested_src_subrect,
const gfx::Size& dst_size,
- void* buf,
- const base::Callback<void(bool)>& callback) {
+ const base::Callback<void(bool, const SkBitmap&)>& callback) {
present_thread_->message_loop()->PostTask(
FROM_HERE,
base::Bind(&AcceleratedPresenter::DoCopyToAndAcknowledge,
this,
requested_src_subrect,
dst_size,
- buf,
base::MessageLoopProxy::current(),
callback));
}
@@ -322,19 +321,21 @@ void AcceleratedPresenter::AsyncCopyTo(
void AcceleratedPresenter::DoCopyToAndAcknowledge(
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
- void* buf,
scoped_refptr<base::SingleThreadTaskRunner> callback_runner,
- const base::Callback<void(bool)>& callback) {
+ const base::Callback<void(bool, const SkBitmap&)>& callback) {
- bool result = DoCopyTo(src_subrect, dst_size, buf);
+ SkBitmap target;
+ bool result = DoCopyTo(src_subrect, dst_size, &target);
+ if (!result)
+ target.reset();
callback_runner->PostTask(
FROM_HERE,
- base::Bind(callback, result));
+ base::Bind(callback, result, target));
}
bool AcceleratedPresenter::DoCopyTo(const gfx::Rect& requested_src_subrect,
const gfx::Size& dst_size,
- void* buf) {
+ SkBitmap* bitmap) {
TRACE_EVENT2(
"gpu", "CopyTo",
"width", dst_size.width(),
@@ -410,19 +411,19 @@ bool AcceleratedPresenter::DoCopyTo(const gfx::Rect& requested_src_subrect,
{
TRACE_EVENT0("gpu", "memcpy");
- size_t bytesPerDstRow = 4 * dst_size.width();
- size_t bytesPerSrcRow = locked_rect.Pitch;
- if (bytesPerDstRow == bytesPerSrcRow) {
- memcpy(reinterpret_cast<int8*>(buf),
- reinterpret_cast<int8*>(locked_rect.pBits),
- bytesPerDstRow * dst_size.height());
- } else {
- for (int i = 0; i < dst_size.height(); ++i) {
- memcpy(reinterpret_cast<int8*>(buf) + bytesPerDstRow * i,
- reinterpret_cast<int8*>(locked_rect.pBits) + bytesPerSrcRow * i,
- bytesPerDstRow);
- }
+
+ bitmap->setConfig(SkBitmap::kARGB_8888_Config,
+ dst_size.width(), dst_size.height(),
+ locked_rect.Pitch);
+ if (!bitmap->allocPixels()) {
+ final_surface->UnlockRect();
+ return false;
}
+ bitmap->setIsOpaque(true);
+
+ memcpy(reinterpret_cast<int8*>(bitmap->getPixels()),
+ reinterpret_cast<int8*>(locked_rect.pBits),
+ locked_rect.Pitch * dst_size.height());
}
final_surface->UnlockRect();
@@ -854,9 +855,8 @@ void AcceleratedSurface::Present(HDC dc) {
void AcceleratedSurface::AsyncCopyTo(
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
- void* buf,
- const base::Callback<void(bool)>& callback) {
- presenter_->AsyncCopyTo(src_subrect, dst_size, buf, callback);
+ const base::Callback<void(bool, const SkBitmap&)>& callback) {
+ presenter_->AsyncCopyTo(src_subrect, dst_size, callback);
}
void AcceleratedSurface::Suspend() {