summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-24 22:13:02 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-24 22:13:02 +0000
commitd7cf069b24322b95745d75ec6fa3244488900d20 (patch)
treef2552fe477e99d150614d339354db4f9ac4c5054 /gpu
parent15ec7dc683f017e4312f921f815f5b44a6476de6 (diff)
downloadchromium_src-d7cf069b24322b95745d75ec6fa3244488900d20.zip
chromium_src-d7cf069b24322b95745d75ec6fa3244488900d20.tar.gz
chromium_src-d7cf069b24322b95745d75ec6fa3244488900d20.tar.bz2
Add GLES2Implemention::FreeUnusedSharedMemory
This is to help get the compositor free memory when appropritate BUG=none TEST=unit tests R=vangelis@chromium.org Review URL: http://codereview.chromium.org/8369010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@106987 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/client/fenced_allocator.cc6
-rw-r--r--gpu/command_buffer/client/fenced_allocator.h10
-rw-r--r--gpu/command_buffer/client/fenced_allocator_test.cc6
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc4
-rw-r--r--gpu/command_buffer/client/gles2_implementation.h2
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest.cc29
-rw-r--r--gpu/command_buffer/client/mapped_memory.cc15
-rw-r--r--gpu/command_buffer/client/mapped_memory.h15
-rw-r--r--gpu/command_buffer/client/mapped_memory_unittest.cc20
9 files changed, 102 insertions, 5 deletions
diff --git a/gpu/command_buffer/client/fenced_allocator.cc b/gpu/command_buffer/client/fenced_allocator.cc
index f105f3a..d262115 100644
--- a/gpu/command_buffer/client/fenced_allocator.cc
+++ b/gpu/command_buffer/client/fenced_allocator.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -130,6 +130,10 @@ bool FencedAllocator::CheckConsistency() {
return true;
}
+bool FencedAllocator::InUse() {
+ return blocks_.size() != 1 || blocks_[0].state != FREE;
+}
+
// Collapse the block to the next one, then to the previous one. Provided the
// structure is consistent, those are the only blocks eligible for collapse.
FencedAllocator::BlockIndex FencedAllocator::CollapseFreeBlock(
diff --git a/gpu/command_buffer/client/fenced_allocator.h b/gpu/command_buffer/client/fenced_allocator.h
index 70d85f6..74cdf33 100644
--- a/gpu/command_buffer/client/fenced_allocator.h
+++ b/gpu/command_buffer/client/fenced_allocator.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -78,6 +78,9 @@ class FencedAllocator {
// testing.
bool CheckConsistency();
+ // True if any memory is allocated.
+ bool InUse();
+
private:
// Status of a block of memory, for book-keeping.
enum State {
@@ -231,6 +234,11 @@ class FencedAllocatorWrapper {
return allocator_.CheckConsistency();
}
+ // True if any memory is allocated.
+ bool InUse() {
+ return allocator_.InUse();
+ }
+
FencedAllocator &allocator() { return allocator_; }
private:
diff --git a/gpu/command_buffer/client/fenced_allocator_test.cc b/gpu/command_buffer/client/fenced_allocator_test.cc
index 8f2f609..aae3fd4 100644
--- a/gpu/command_buffer/client/fenced_allocator_test.cc
+++ b/gpu/command_buffer/client/fenced_allocator_test.cc
@@ -105,14 +105,17 @@ class FencedAllocatorTest : public BaseFencedAllocatorTest {
// Checks basic alloc and free.
TEST_F(FencedAllocatorTest, TestBasic) {
allocator_->CheckConsistency();
+ EXPECT_FALSE(allocator_->InUse());
const unsigned int kSize = 16;
FencedAllocator::Offset offset = allocator_->Alloc(kSize);
+ EXPECT_TRUE(allocator_->InUse());
EXPECT_NE(FencedAllocator::kInvalidOffset, offset);
EXPECT_GE(kBufferSize, offset+kSize);
EXPECT_TRUE(allocator_->CheckConsistency());
allocator_->Free(offset);
+ EXPECT_FALSE(allocator_->InUse());
EXPECT_TRUE(allocator_->CheckConsistency());
}
@@ -222,6 +225,7 @@ TEST_F(FencedAllocatorTest, FreeUnused) {
EXPECT_GE(kBufferSize, offsets[i]+kSize);
EXPECT_TRUE(allocator_->CheckConsistency());
}
+ EXPECT_TRUE(allocator_->InUse());
// No memory should be available.
EXPECT_EQ(0u, allocator_->GetLargestFreeSize());
@@ -258,12 +262,14 @@ TEST_F(FencedAllocatorTest, FreeUnused) {
// Check that the new largest free size takes into account the unused blocks.
EXPECT_EQ(kSize * 3, allocator_->GetLargestFreeSize());
+ EXPECT_TRUE(allocator_->InUse());
// Free up everything.
for (unsigned int i = 3; i < kAllocCount; ++i) {
allocator_->Free(offsets[i]);
EXPECT_TRUE(allocator_->CheckConsistency());
}
+ EXPECT_FALSE(allocator_->InUse());
}
// Tests GetLargestFreeSize
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 1ccccd9..9a9cd85 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -641,6 +641,10 @@ GLES2Implementation::~GLES2Implementation() {
#endif
}
+void GLES2Implementation::FreeUnusedSharedMemory() {
+ mapped_memory_->FreeUnused();
+}
+
void GLES2Implementation::WaitForCmd() {
TRACE_EVENT0("gpu", "GLES2::WaitForCmd");
helper_->CommandBufferHelper::Finish();
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 057b046e..43cb2ad 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -197,6 +197,8 @@ class GLES2Implementation {
texture_id_handler_->FreeIds(1, &id);
}
+ void FreeUnusedSharedMemory();
+
private:
// Wraps RingBufferWrapper to provide aligned allocations.
class AlignedRingBuffer : public RingBufferWrapper {
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index 9320cee..dc2f419 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -73,7 +73,7 @@ class GLES2MockCommandBufferHelper : public CommandBuffer {
return kTransferBufferId;
}
- virtual void DestroyTransferBuffer(int32) { // NOLINT
+ virtual void DestroyTransferBuffer(int32 /* id */) {
GPU_NOTREACHED();
}
@@ -121,6 +121,7 @@ class MockGLES2CommandBuffer : public GLES2MockCommandBufferHelper {
// This is so we can use all the gmock functions when Flush is called.
MOCK_METHOD1(OnFlush, void(void* result));
+ MOCK_METHOD1(DestroyTransferBuffer, void(int32 id));
};
// GCC requires these declarations, but MSVC requires they not be present
@@ -383,7 +384,6 @@ class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest {
const int32 GLES2ImplementationTest::kTransferBufferId;
#endif
-
TEST_F(GLES2ImplementationTest, ShaderSource) {
const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation
const GLuint kShaderId = 456;
@@ -931,6 +931,31 @@ TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) {
gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
}
+TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) {
+ struct Cmds {
+ BufferSubData buf;
+ cmd::SetToken set_token;
+ };
+ const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
+ const GLintptr kOffset = 15;
+ const GLsizeiptr kSize = 16;
+
+ uint32 offset = 0;
+ Cmds expected;
+ expected.buf.Init(
+ kTarget, kOffset, kSize, kTransferBufferId, offset);
+ expected.set_token.Init(GetNextToken());
+
+ void* mem = gl_->MapBufferSubDataCHROMIUM(
+ kTarget, kOffset, kSize, GL_WRITE_ONLY);
+ ASSERT_TRUE(mem != NULL);
+ gl_->UnmapBufferSubDataCHROMIUM(mem);
+ EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_))\
+ .Times(1)
+ .RetiresOnSaturation();
+ gl_->FreeUnusedSharedMemory();
+}
+
TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) {
struct Cmds {
BufferSubData buf;
diff --git a/gpu/command_buffer/client/mapped_memory.cc b/gpu/command_buffer/client/mapped_memory.cc
index 689b576b..461343e 100644
--- a/gpu/command_buffer/client/mapped_memory.cc
+++ b/gpu/command_buffer/client/mapped_memory.cc
@@ -88,6 +88,21 @@ void MappedMemoryManager::FreePendingToken(void* pointer, int32 token) {
GPU_NOTREACHED();
}
+void MappedMemoryManager::FreeUnused() {
+ CommandBuffer* cmd_buf = helper_->command_buffer();
+ MemoryChunkVector::iterator iter = chunks_.begin();
+ while (iter != chunks_.end()) {
+ MemoryChunk* chunk = *iter;
+ chunk->FreeUnused();
+ if (!chunk->InUse()) {
+ cmd_buf->DestroyTransferBuffer(chunk->shm_id());
+ iter = chunks_.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+}
+
} // namespace gpu
diff --git a/gpu/command_buffer/client/mapped_memory.h b/gpu/command_buffer/client/mapped_memory.h
index f5f3e37..ed66664 100644
--- a/gpu/command_buffer/client/mapped_memory.h
+++ b/gpu/command_buffer/client/mapped_memory.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -90,6 +90,11 @@ class MemoryChunk {
pointer < reinterpret_cast<const int8*>(shm_.ptr) + shm_.size;
}
+ // Returns true of any memory in this chuck is in use.
+ bool InUse() {
+ return allocator_.InUse();
+ }
+
private:
int32 shm_id_;
gpu::Buffer shm_;
@@ -129,6 +134,14 @@ class MappedMemoryManager {
// token: the token value to wait for before re-using the memory.
void FreePendingToken(void* pointer, int32 token);
+ // Free Any Shared memory that is not in use.
+ void FreeUnused();
+
+ // Used for testing
+ size_t num_chunks() {
+ return chunks_.size();
+ }
+
private:
typedef std::vector<MemoryChunk*> MemoryChunkVector;
diff --git a/gpu/command_buffer/client/mapped_memory_unittest.cc b/gpu/command_buffer/client/mapped_memory_unittest.cc
index ee9b025..0b60897 100644
--- a/gpu/command_buffer/client/mapped_memory_unittest.cc
+++ b/gpu/command_buffer/client/mapped_memory_unittest.cc
@@ -253,6 +253,26 @@ TEST_F(MappedMemoryManagerTest, DontFree) {
ASSERT_TRUE(mem1);
}
+TEST_F(MappedMemoryManagerTest, FreeUnused) {
+ int32 id = -1;
+ unsigned int offset = 0xFFFFFFFFU;
+ void* m1 = manager_->Alloc(kBufferSize, &id, &offset);
+ void* m2 = manager_->Alloc(kBufferSize, &id, &offset);
+ ASSERT_TRUE(m1 != NULL);
+ ASSERT_TRUE(m2 != NULL);
+ EXPECT_EQ(2u, manager_->num_chunks());
+ manager_->FreeUnused();
+ EXPECT_EQ(2u, manager_->num_chunks());
+ manager_->Free(m2);
+ EXPECT_EQ(2u, manager_->num_chunks());
+ manager_->FreeUnused();
+ EXPECT_EQ(1u, manager_->num_chunks());
+ manager_->Free(m1);
+ EXPECT_EQ(1u, manager_->num_chunks());
+ manager_->FreeUnused();
+ EXPECT_EQ(0u, manager_->num_chunks());
+}
+
} // namespace gpu