summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorfeng@chromium.org <feng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-24 10:30:37 +0000
committerfeng@chromium.org <feng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-24 10:30:37 +0000
commit83a52d03adb00524bacf706ac32061b06b64a860 (patch)
treeef80b3bf545f42aef618943e45e10bb35a97fccd /gpu
parentcf11843b193beb4fc0ceccb0d6b6fb7cd5ff8e8e (diff)
downloadchromium_src-83a52d03adb00524bacf706ac32061b06b64a860.zip
chromium_src-83a52d03adb00524bacf706ac32061b06b64a860.tar.gz
chromium_src-83a52d03adb00524bacf706ac32061b06b64a860.tar.bz2
Fix a memory leak.
ProgramManager::UnuseProgram was never called in existing code because state_.current_program was cleared first. So the current program object leaks. The fix is to clear state_.current_program at the end of function. BUG=258772 Review URL: https://chromiumcodereview.appspot.com/19577012 Review URL: https://chromiumcodereview.appspot.com/19876004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213390 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc10
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc4
2 files changed, 12 insertions, 2 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 1075b34..71bf1e0 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -3156,7 +3156,6 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
state_.texture_units.clear();
state_.bound_array_buffer = NULL;
state_.current_query = NULL;
- state_.current_program = NULL;
state_.bound_read_framebuffer = NULL;
state_.bound_draw_framebuffer = NULL;
state_.bound_renderbuffer = NULL;
@@ -3177,7 +3176,6 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
if (state_.current_program.get()) {
program_manager()->UnuseProgram(shader_manager(),
state_.current_program.get());
- state_.current_program = NULL;
}
if (attrib_0_buffer_id_) {
@@ -3225,6 +3223,14 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
if (offscreen_resolved_color_texture_.get())
offscreen_resolved_color_texture_->Invalidate();
}
+
+ // Current program must be cleared after calling ProgramManager::UnuseProgram.
+ // Otherwise, we can leak objects. http://crbug.com/258772.
+ // state_.current_program must be reset before group_ is reset because
+ // the later deletes the ProgramManager object that referred by
+ // state_.current_program object.
+ state_.current_program = NULL;
+
copy_texture_CHROMIUM_.reset();
if (query_manager_.get()) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index b426286..b8b08c2 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -292,6 +292,8 @@ TEST_F(GLES2DecoderWithShaderTest, DrawArraysDeletedProgramSucceeds) {
EXPECT_CALL(*gl_, DrawArrays(_, _, _))
.Times(1)
.RetiresOnSaturation();
+ EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
+ .Times(1);
DrawArrays cmd;
cmd.Init(GL_TRIANGLES, 0, kNumVertices);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -685,6 +687,8 @@ TEST_F(GLES2DecoderWithShaderTest, DrawElementsDeletedProgramSucceeds) {
EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
.Times(1);
+ EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
+ .Times(1);
DrawElements cmd;
cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
kValidIndexRangeStart * 2);