Commit cdda8263 authored by jbauman@chromium.org's avatar jbauman@chromium.org

Limit renderer saved frames to avoid running out of fds.

Software delegated rendering uses one fd per tile, so with a bunch of tiles that means it can run out of fds. If it seems close to hitting the limit the browser should throw away old frames to avoid this from happening.

BUG=362603
TBR=piman@chromium.org

Review URL: https://codereview.chromium.org/258053008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266646 0039d316-1c4b-4281-b951-d872f2087c98
parent 6896d7f9
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/gpu/gpu_messages.h" #include "content/common/gpu/gpu_messages.h"
#include "content/common/host_shared_bitmap_manager.h"
#include "content/common/input_messages.h" #include "content/common/input_messages.h"
#include "content/common/view_messages.h" #include "content/common/view_messages.h"
#include "content/port/browser/render_widget_host_view_frame_subscriber.h" #include "content/port/browser/render_widget_host_view_frame_subscriber.h"
...@@ -1071,6 +1072,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) { ...@@ -1071,6 +1072,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
size_t renderer_count = max_renderer_frames + 1; size_t renderer_count = max_renderer_frames + 1;
gfx::Rect view_rect(100, 100); gfx::Rect view_rect(100, 100);
gfx::Size frame_size = view_rect.size(); gfx::Size frame_size = view_rect.size();
DCHECK_EQ(0u, HostSharedBitmapManager::current()->AllocatedBitmapCount());
scoped_ptr<RenderWidgetHostImpl * []> hosts( scoped_ptr<RenderWidgetHostImpl * []> hosts(
new RenderWidgetHostImpl* [renderer_count]); new RenderWidgetHostImpl* [renderer_count]);
...@@ -1157,6 +1159,35 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) { ...@@ -1157,6 +1159,35 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFrames) {
views[0]->WasHidden(); views[0]->WasHidden();
EXPECT_FALSE(views[0]->frame_provider_); EXPECT_FALSE(views[0]->frame_provider_);
for (size_t i = 0; i < renderer_count - 1; ++i)
views[i]->WasHidden();
// Allocate enough bitmaps so that two frames (proportionally) would be
// enough hit the handle limit.
int handles_per_frame = 5;
RendererFrameManager::GetInstance()->set_max_handles(handles_per_frame * 2);
for (size_t i = 0; i < (renderer_count - 1) * handles_per_frame; i++) {
HostSharedBitmapManager::current()->ChildAllocatedSharedBitmap(
1,
base::SharedMemory::NULLHandle(),
base::GetCurrentProcessHandle(),
cc::SharedBitmap::GenerateId());
}
// Hiding this last bitmap should evict all but two frames.
views[renderer_count - 1]->WasHidden();
for (size_t i = 0; i < renderer_count; ++i) {
if (i + 2 < renderer_count)
EXPECT_FALSE(views[i]->frame_provider_);
else
EXPECT_TRUE(views[i]->frame_provider_);
}
HostSharedBitmapManager::current()->ProcessRemoved(
base::GetCurrentProcessHandle());
RendererFrameManager::GetInstance()->set_max_handles(
base::SharedMemory::GetHandleLimit());
for (size_t i = 0; i < renderer_count; ++i) { for (size_t i = 0; i < renderer_count; ++i) {
views[i]->Destroy(); views[i]->Destroy();
delete hosts[i]; delete hosts[i];
...@@ -1170,6 +1201,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) { ...@@ -1170,6 +1201,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) {
size_t renderer_count = max_renderer_frames + 1; size_t renderer_count = max_renderer_frames + 1;
gfx::Rect view_rect(100, 100); gfx::Rect view_rect(100, 100);
gfx::Size frame_size = view_rect.size(); gfx::Size frame_size = view_rect.size();
DCHECK_EQ(0u, HostSharedBitmapManager::current()->AllocatedBitmapCount());
scoped_ptr<RenderWidgetHostImpl * []> hosts( scoped_ptr<RenderWidgetHostImpl * []> hosts(
new RenderWidgetHostImpl* [renderer_count]); new RenderWidgetHostImpl* [renderer_count]);
......
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
#include <algorithm> #include <algorithm>
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/shared_memory.h"
#include "base/sys_info.h" #include "base/sys_info.h"
#include "content/common/host_shared_bitmap_manager.h"
namespace content { namespace content {
...@@ -66,14 +68,26 @@ RendererFrameManager::RendererFrameManager() { ...@@ -66,14 +68,26 @@ RendererFrameManager::RendererFrameManager() {
#else #else
std::min(5, 2 + (base::SysInfo::AmountOfPhysicalMemoryMB() / 256)); std::min(5, 2 + (base::SysInfo::AmountOfPhysicalMemoryMB() / 256));
#endif #endif
max_handles_ = base::SharedMemory::GetHandleLimit() / 8.0f;
} }
RendererFrameManager::~RendererFrameManager() {} RendererFrameManager::~RendererFrameManager() {}
void RendererFrameManager::CullUnlockedFrames() { void RendererFrameManager::CullUnlockedFrames() {
uint32 saved_frame_limit = max_number_of_saved_frames();
if (unlocked_frames_.size() + locked_frames_.size() > 0) {
float handles_per_frame =
HostSharedBitmapManager::current()->AllocatedBitmapCount() * 1.0f /
(unlocked_frames_.size() + locked_frames_.size());
saved_frame_limit = std::max(
1,
static_cast<int>(std::min(static_cast<float>(saved_frame_limit),
max_handles_ / handles_per_frame)));
}
while (!unlocked_frames_.empty() && while (!unlocked_frames_.empty() &&
unlocked_frames_.size() + locked_frames_.size() > unlocked_frames_.size() + locked_frames_.size() > saved_frame_limit) {
max_number_of_saved_frames()) {
size_t old_size = unlocked_frames_.size(); size_t old_size = unlocked_frames_.size();
// Should remove self from list. // Should remove self from list.
unlocked_frames_.back()->EvictCurrentFrame(); unlocked_frames_.back()->EvictCurrentFrame();
......
...@@ -33,6 +33,9 @@ class CONTENT_EXPORT RendererFrameManager { ...@@ -33,6 +33,9 @@ class CONTENT_EXPORT RendererFrameManager {
return max_number_of_saved_frames_; return max_number_of_saved_frames_;
} }
// For testing only
void set_max_handles(float max_handles) { max_handles_ = max_handles; }
private: private:
RendererFrameManager(); RendererFrameManager();
~RendererFrameManager(); ~RendererFrameManager();
...@@ -43,6 +46,7 @@ class CONTENT_EXPORT RendererFrameManager { ...@@ -43,6 +46,7 @@ class CONTENT_EXPORT RendererFrameManager {
std::map<RendererFrameManagerClient*, size_t> locked_frames_; std::map<RendererFrameManagerClient*, size_t> locked_frames_;
std::list<RendererFrameManagerClient*> unlocked_frames_; std::list<RendererFrameManagerClient*> unlocked_frames_;
size_t max_number_of_saved_frames_; size_t max_number_of_saved_frames_;
float max_handles_;
DISALLOW_COPY_AND_ASSIGN(RendererFrameManager); DISALLOW_COPY_AND_ASSIGN(RendererFrameManager);
}; };
......
...@@ -65,6 +65,8 @@ class CONTENT_EXPORT HostSharedBitmapManager : public cc::SharedBitmapManager { ...@@ -65,6 +65,8 @@ class CONTENT_EXPORT HostSharedBitmapManager : public cc::SharedBitmapManager {
void ChildDeletedSharedBitmap(const cc::SharedBitmapId& id); void ChildDeletedSharedBitmap(const cc::SharedBitmapId& id);
void ProcessRemoved(base::ProcessHandle process_handle); void ProcessRemoved(base::ProcessHandle process_handle);
size_t AllocatedBitmapCount() const { return handle_map_.size(); }
private: private:
base::Lock lock_; base::Lock lock_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment