Skip to content

Commit

Permalink
[Android] Fix the render issue introduced by single process mode.
Browse files Browse the repository at this point in the history
* In Chromium, single process mode is only for Android WebView, ContentShell and
its derivatives only go to the multiple process mode.
* The context design is only for multiple process mode(ContentShell/XWalk), if we
force running it with single process mode, there are issues (black regions for
video/canvas/webgl layers, and black screen for stop/restart actions). The reason
is that Android port has browser-side compositor, and the shared context in
browser-side compositor has conflicts with renderer's contexts if running in single
process mode.
* To run ContentShell/XWalk in single process mode, we have to resolve the shared
context issue between renderer/browser.

BUG=crosswalk-project/crosswalk#516
  • Loading branch information
sqliu committed Oct 9, 2013
1 parent 0dcf0db commit d9f4725
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 19 deletions.
3 changes: 2 additions & 1 deletion content/browser/renderer_host/compositor_impl_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,8 @@ CreateGpuProcessViewContext(
new WebGraphicsContext3DCommandBufferImpl(surface_id,
url,
factory,
compositor_impl));
compositor_impl,
true));
static const size_t kBytesPerPixel = 4;
gfx::DeviceDisplayInfo display_info;
size_t full_screen_texture_size_in_bytes =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ CmdBufferImageTransportFactory::CmdBufferImageTransportFactory() {
context_.reset(new WebGraphicsContext3DCommandBufferImpl(0, // offscreen
url,
factory,
swap_client));
swap_client,
true));
static const size_t kBytesPerPixel = 4;
gfx::DeviceDisplayInfo display_info;
size_t full_screen_texture_size_in_bytes =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ static base::LazyInstance<base::Lock>::Leaky
static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> >
g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER;

static base::LazyInstance<base::Lock>::Leaky
g_all_shared_contexts_browser_lock = LAZY_INSTANCE_INITIALIZER;
static base::LazyInstance<std::set<WebGraphicsContext3DCommandBufferImpl*> >
g_all_shared_contexts_browser = LAZY_INSTANCE_INITIALIZER;

namespace {

void ClearSharedContextsIfInShareSet(
Expand All @@ -68,6 +73,26 @@ void ClearSharedContextsIfInShareSet(
}
}

void ClearSharedContextsIfInShareSetBrowser(
WebGraphicsContext3DCommandBufferImpl* context) {
// If the given context isn't in the share set, that means that it
// or another context it was previously sharing with already
// provoked a lost context. Other contexts might have since been
// successfully created and added to the share set, so do not clear
// out the share set unless we know that all the contexts in there
// are supposed to be lost simultaneously.
base::AutoLock lock(g_all_shared_contexts_browser_lock.Get());
std::set<WebGraphicsContext3DCommandBufferImpl*>* share_set =
g_all_shared_contexts_browser.Pointer();
for (std::set<WebGraphicsContext3DCommandBufferImpl*>::iterator iter =
share_set->begin(); iter != share_set->end(); ++iter) {
if (context == *iter) {
share_set->clear();
return;
}
}
}

size_t ClampUint64ToSizeT(uint64 value) {
value = std::min(value,
static_cast<uint64>(std::numeric_limits<size_t>::max()));
Expand Down Expand Up @@ -218,7 +243,8 @@ WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
int surface_id,
const GURL& active_url,
GpuChannelHostFactory* factory,
const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client)
const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client,
bool context_for_browser_compositor)
: initialize_failed_(false),
factory_(factory),
visible_(false),
Expand All @@ -245,6 +271,7 @@ WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
min_transfer_buffer_size_(0),
max_transfer_buffer_size_(0),
mapped_memory_limit_(gpu::gles2::GLES2Implementation::kNoLimit),
context_for_browser_compositor_(context_for_browser_compositor),
flush_id_(0) {
#if (defined(OS_MACOSX) || defined(OS_WIN)) && !defined(USE_AURA)
// Get ViewMsg_SwapBuffers_ACK from browser for single-threaded path.
Expand All @@ -260,7 +287,10 @@ WebGraphicsContext3DCommandBufferImpl::
real_gl_->SetErrorMessageCallback(NULL);
}

{
if (context_for_browser_compositor_) {
base::AutoLock lock(g_all_shared_contexts_browser_lock.Get());
g_all_shared_contexts_browser.Pointer()->erase(this);
} else {
base::AutoLock lock(g_all_shared_contexts_lock.Get());
g_all_shared_contexts.Pointer()->erase(this);
}
Expand Down Expand Up @@ -383,14 +413,23 @@ bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer(
// We need to lock g_all_shared_contexts to ensure that the context we picked
// for our share group isn't deleted.
// (There's also a lock in our destructor.)
base::AutoLock lock(g_all_shared_contexts_lock.Get());
CommandBufferProxyImpl* share_group = NULL;
if (attributes_.shareResources) {
WebGraphicsContext3DCommandBufferImpl* share_group_context =
g_all_shared_contexts.Pointer()->empty() ?
NULL : *g_all_shared_contexts.Pointer()->begin();
share_group = share_group_context ?
share_group_context->command_buffer_.get() : NULL;
if (context_for_browser_compositor_) {
base::AutoLock lock(g_all_shared_contexts_browser_lock.Get());
WebGraphicsContext3DCommandBufferImpl* share_group_context =
g_all_shared_contexts_browser.Pointer()->empty() ?
NULL : *g_all_shared_contexts_browser.Pointer()->begin();
share_group = share_group_context ?
share_group_context->command_buffer_.get() : NULL;
} else {
base::AutoLock lock(g_all_shared_contexts_lock.Get());
WebGraphicsContext3DCommandBufferImpl* share_group_context =
g_all_shared_contexts.Pointer()->empty() ?
NULL : *g_all_shared_contexts.Pointer()->begin();
share_group = share_group_context ?
share_group_context->command_buffer_.get() : NULL;
}
}

std::vector<int32> attribs;
Expand Down Expand Up @@ -457,11 +496,20 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext(
if (attributes_.shareResources) {
// Make sure two clients don't try to create a new ShareGroup
// simultaneously.
lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get()));
if (!g_all_shared_contexts.Pointer()->empty()) {
share_group = (*g_all_shared_contexts.Pointer()->begin())
->GetImplementation()->share_group();
DCHECK(share_group);
if (context_for_browser_compositor_) {
lock.reset(new base::AutoLock(g_all_shared_contexts_browser_lock.Get()));
if (!g_all_shared_contexts_browser.Pointer()->empty()) {
share_group = (*g_all_shared_contexts_browser.Pointer()->begin())
->GetImplementation()->share_group();
DCHECK(share_group);
}
} else {
lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get()));
if (!g_all_shared_contexts.Pointer()->empty()) {
share_group = (*g_all_shared_contexts.Pointer()->begin())
->GetImplementation()->share_group();
DCHECK(share_group);
}
}
}

Expand All @@ -476,7 +524,11 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext(

if (attributes_.shareResources) {
// Don't add ourselves to the list before others can get to our ShareGroup.
g_all_shared_contexts.Pointer()->insert(this);
if (context_for_browser_compositor_) {
g_all_shared_contexts_browser.Pointer()->insert(this);
} else {
g_all_shared_contexts.Pointer()->insert(this);
}
lock.reset();
}

Expand Down Expand Up @@ -1595,8 +1647,13 @@ void WebGraphicsContext3DCommandBufferImpl::OnContextLost() {
if (context_lost_callback_) {
context_lost_callback_->onContextLost();
}
if (attributes_.shareResources)
ClearSharedContextsIfInShareSet(this);
if (attributes_.shareResources) {
if (context_for_browser_compositor_) {
ClearSharedContextsIfInShareSetBrowser(this);
} else {
ClearSharedContextsIfInShareSet(this);
}
}
if (ShouldUseSwapClient())
swap_client_->OnViewContextSwapBuffersAborted();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ class WebGraphicsContext3DCommandBufferImpl
int surface_id,
const GURL& active_url,
GpuChannelHostFactory* factory,
const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client);
const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client,
bool context_for_browser_compositor = false);

virtual ~WebGraphicsContext3DCommandBufferImpl();

Expand Down Expand Up @@ -766,6 +767,8 @@ class WebGraphicsContext3DCommandBufferImpl
size_t max_transfer_buffer_size_;
size_t mapped_memory_limit_;

bool context_for_browser_compositor_;

uint32_t flush_id_;
};

Expand Down

0 comments on commit d9f4725

Please sign in to comment.