blob: 8c45dff4f2442c62c1f3b36416f79b2e1512b4f7 [file] [log] [blame]
// Copyright (c) 2013 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.
#ifndef CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_H_
#define CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/process/kill.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "base/values.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/common/three_d_api_types.h"
#include "gpu/config/gpu_control_list.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_info.h"
class GURL;
namespace base {
class CommandLine;
}
namespace gpu {
struct GpuPreferences;
struct VideoMemoryUsageStats;
}
namespace content {
class GpuDataManagerImplPrivate;
struct WebPreferences;
class CONTENT_EXPORT GpuDataManagerImpl
: public NON_EXPORTED_BASE(GpuDataManager) {
public:
// Indicates the guilt level of a domain which caused a GPU reset.
// If a domain is 100% known to be guilty of resetting the GPU, then
// it will generally not cause other domains' use of 3D APIs to be
// blocked, unless system stability would be compromised.
enum DomainGuilt {
DOMAIN_GUILT_KNOWN,
DOMAIN_GUILT_UNKNOWN
};
// Indicates the reason that access to a given client API (like
// WebGL or Pepper 3D) was blocked or not. This state is distinct
// from blacklisting of an entire feature.
enum DomainBlockStatus {
DOMAIN_BLOCK_STATUS_BLOCKED,
DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
DOMAIN_BLOCK_STATUS_NOT_BLOCKED
};
// Getter for the singleton. This will return NULL on failure.
static GpuDataManagerImpl* GetInstance();
// GpuDataManager implementation.
void BlacklistWebGLForTesting() override;
bool IsFeatureBlacklisted(int feature) const override;
bool IsFeatureEnabled(int feature) const override;
bool IsWebGLEnabled() const override;
gpu::GPUInfo GetGPUInfo() const override;
bool GpuAccessAllowed(std::string* reason) const override;
void RequestCompleteGpuInfoIfNeeded() override;
bool IsEssentialGpuInfoAvailable() const override;
bool IsCompleteGpuInfoAvailable() const override;
void RequestVideoMemoryUsageStatsUpdate(
const base::Callback<void(const gpu::VideoMemoryUsageStats& stats)>&
callback) const override;
bool ShouldUseSwiftShader() const override;
// TODO(kbr): the threading model for the GpuDataManagerObservers is
// not well defined, and it's impossible for callers to correctly
// delete observers from anywhere except in one of the observer's
// notification methods. Observer addition and removal, and their
// callbacks, should probably be required to occur on the UI thread.
void AddObserver(GpuDataManagerObserver* observer) override;
void RemoveObserver(GpuDataManagerObserver* observer) override;
void UnblockDomainFrom3DAPIs(const GURL& url) override;
void SetGLStrings(const std::string& gl_vendor,
const std::string& gl_renderer,
const std::string& gl_version) override;
void GetGLStrings(std::string* gl_vendor,
std::string* gl_renderer,
std::string* gl_version) override;
void DisableHardwareAcceleration() override;
bool HardwareAccelerationEnabled() const override;
bool CanUseGpuBrowserCompositor() const override;
void GetDisabledExtensions(std::string* disabled_extensions) const override;
void SetGpuInfo(const gpu::GPUInfo& gpu_info) override;
// This collects preliminary GPU info, load GpuBlacklist, and compute the
// preliminary blacklisted features; it should only be called at browser
// startup time in UI thread before the IO restriction is turned on.
void Initialize();
void InitializeForTesting(const gpu::GpuControlListData& gpu_blacklist_data,
const gpu::GPUInfo& gpu_info);
// Only update if the current GPUInfo is not finalized. If blacklist is
// loaded, run through blacklist and update blacklisted features.
void UpdateGpuInfo(const gpu::GPUInfo& gpu_info);
// Update the GPU feature info. This updates the blacklist and enabled status
// of GPU rasterization. In the future this will be used for more features.
void UpdateGpuFeatureInfo(const gpu::GpuFeatureInfo& gpu_feature_info);
// Insert disable-feature switches corresponding to preliminary gpu feature
// flags into the renderer process command line.
void AppendRendererCommandLine(base::CommandLine* command_line) const;
// Insert switches into gpu process command line: kUseGL, etc.
// If the gpu_preferences isn't a nullptr, the gpu_preferences will be set
// for some GPU switches which have been replaced by GpuPreferences, and those
// switches will not be append to the command_line anymore.
void AppendGpuCommandLine(base::CommandLine* command_line,
gpu::GpuPreferences* gpu_preferences) const;
// Update WebPreferences for renderer based on blacklisting decisions.
void UpdateRendererWebPrefs(WebPreferences* prefs) const;
std::string GetBlacklistVersion() const;
std::string GetDriverBugListVersion() const;
// Returns the reasons for the latest run of blacklisting decisions.
// For the structure of returned value, see documentation for
// GpuBlacklist::GetBlacklistedReasons().
void GetBlacklistReasons(base::ListValue* reasons) const;
// Returns the workarounds that are applied to the current system as
// a vector of strings.
std::vector<std::string> GetDriverBugWorkarounds() const;
void AddLogMessage(int level,
const std::string& header,
const std::string& message);
void ProcessCrashed(base::TerminationStatus exit_code);
// Returns a new copy of the ListValue.
std::unique_ptr<base::ListValue> GetLogMessages() const;
// Called when switching gpu.
void HandleGpuSwitch();
// Maintenance of domains requiring explicit user permission before
// using client-facing 3D APIs (WebGL, Pepper 3D), either because
// the domain has caused the GPU to reset, or because too many GPU
// resets have been observed globally recently, and system stability
// might be compromised.
//
// The given URL may be a partial URL (including at least the host)
// or a full URL to a page.
//
// Note that the unblocking API must be part of the content API
// because it is called from Chrome side code.
void BlockDomainFrom3DAPIs(const GURL& url, DomainGuilt guilt);
bool Are3DAPIsBlocked(const GURL& top_origin_url,
int render_process_id,
int render_frame_id,
ThreeDAPIType requester);
// Disables domain blocking for 3D APIs. For use only in tests.
void DisableDomainBlockingFor3DAPIsForTesting();
void Notify3DAPIBlocked(const GURL& top_origin_url,
int render_process_id,
int render_frame_id,
ThreeDAPIType requester);
// Get number of features being blacklisted.
size_t GetBlacklistedFeatureCount() const;
// Set the active gpu.
// Return true if it's a different GPU from the previous active one.
bool UpdateActiveGpu(uint32_t vendor_id, uint32_t device_id);
// Called when GPU process initialization failed.
void OnGpuProcessInitFailure();
bool IsDriverBugWorkaroundActive(int feature) const;
private:
friend class GpuDataManagerImplPrivate;
friend class GpuDataManagerImplPrivateTest;
friend struct base::DefaultSingletonTraits<GpuDataManagerImpl>;
// It's similar to AutoUnlock, but we want to make it a no-op
// if the owner GpuDataManagerImpl is null.
// This should only be used by GpuDataManagerImplPrivate where
// callbacks are called, during which re-entering
// GpuDataManagerImpl is possible.
class UnlockedSession {
public:
explicit UnlockedSession(GpuDataManagerImpl* owner)
: owner_(owner) {
DCHECK(owner_);
owner_->lock_.AssertAcquired();
owner_->lock_.Release();
}
~UnlockedSession() {
DCHECK(owner_);
owner_->lock_.Acquire();
}
private:
GpuDataManagerImpl* owner_;
DISALLOW_COPY_AND_ASSIGN(UnlockedSession);
};
GpuDataManagerImpl();
~GpuDataManagerImpl() override;
mutable base::Lock lock_;
std::unique_ptr<GpuDataManagerImplPrivate> private_;
DISALLOW_COPY_AND_ASSIGN(GpuDataManagerImpl);
};
} // namespace content
#endif // CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_H_