1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/compositor/browser_compositor_view_mac.h"
#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
#include "content/browser/compositor/image_transport_factory.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/renderer_host/render_widget_resize_helper.h"
#include "content/public/browser/context_factory.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
////////////////////////////////////////////////////////////////////////////////
// BrowserCompositorMac
namespace content {
namespace {
// Set when no browser compositors should remain alive.
bool g_has_shut_down = false;
// The number of placeholder objects allocated. If this reaches zero, then
// the BrowserCompositorMac being held on to for recycling,
// |g_recyclable_browser_compositor|, will be freed.
uint32 g_placeholder_count = 0;
// A spare BrowserCompositorMac kept around for recycling.
base::LazyInstance<scoped_ptr<BrowserCompositorMac>>
g_recyclable_browser_compositor;
bool WidgetNeedsGLFinishWorkaround() {
return GpuDataManagerImpl::GetInstance()->IsDriverBugWorkaroundActive(
gpu::FORCE_GL_FINISH_AFTER_COMPOSITING);
}
} // namespace
BrowserCompositorMac::BrowserCompositorMac()
: accelerated_widget_mac_(
new ui::AcceleratedWidgetMac(WidgetNeedsGLFinishWorkaround())),
compositor_(
accelerated_widget_mac_->accelerated_widget(),
content::GetContextFactory(),
RenderWidgetResizeHelper::Get()->task_runner()) {
}
BrowserCompositorMac::~BrowserCompositorMac() {}
// static
scoped_ptr<BrowserCompositorMac> BrowserCompositorMac::Create() {
if (g_recyclable_browser_compositor.Get())
return g_recyclable_browser_compositor.Get().Pass();
return scoped_ptr<BrowserCompositorMac>(new BrowserCompositorMac).Pass();
}
// static
void BrowserCompositorMac::Recycle(
scoped_ptr<BrowserCompositorMac> compositor) {
DCHECK(compositor);
content::ImageTransportFactory::GetInstance()->OnCompositorRecycled(
compositor->compositor());
// It is an error to have a browser compositor continue to exist after
// shutdown.
CHECK(!g_has_shut_down);
// Make this BrowserCompositorMac recyclable for future instances.
g_recyclable_browser_compositor.Get().swap(compositor);
// If there are no placeholders allocated, destroy the recyclable
// BrowserCompositorMac that we just populated.
if (!g_placeholder_count)
g_recyclable_browser_compositor.Get().reset();
}
// static
void BrowserCompositorMac::DisableRecyclingForShutdown() {
g_has_shut_down = true;
g_recyclable_browser_compositor.Get().reset();
}
////////////////////////////////////////////////////////////////////////////////
// BrowserCompositorMacPlaceholder
BrowserCompositorMacPlaceholder::BrowserCompositorMacPlaceholder() {
g_placeholder_count += 1;
}
BrowserCompositorMacPlaceholder::~BrowserCompositorMacPlaceholder() {
DCHECK_GT(g_placeholder_count, 0u);
g_placeholder_count -= 1;
// If there are no placeholders allocated, destroy the recyclable
// BrowserCompositorMac.
if (!g_placeholder_count)
g_recyclable_browser_compositor.Get().reset();
}
} // namespace content
|