blob: 45614cd97863eb3152bb835ca42594749c693124 [file] [log] [blame]
Geoff Langa8406172015-07-21 16:53:39 -04001//
2// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Image_unittest.cpp : Unittets of the Image and ImageSibling classes.
8
9#include "gmock/gmock.h"
10#include "gtest/gtest.h"
11#include "libANGLE/Image.h"
12#include "libANGLE/Texture.h"
13#include "libANGLE/Renderbuffer.h"
14#include "libANGLE/renderer/ImageImpl_mock.h"
15#include "libANGLE/renderer/TextureImpl_mock.h"
16#include "libANGLE/renderer/RenderbufferImpl_mock.h"
17
18using ::testing::_;
19using ::testing::Return;
20
21namespace angle
22{
23// Verify ref counts are maintained between images and their siblings when objects are deleted
24TEST(ImageTest, RefCounting)
25{
26 // Create a texture and an EGL image that uses the texture as its source
27 rx::MockTextureImpl *textureImpl = new rx::MockTextureImpl();
28 gl::Texture *texture = new gl::Texture(textureImpl, 1, GL_TEXTURE_2D);
29 texture->addRef();
30
31 rx::MockImageImpl *imageImpl = new rx::MockImageImpl();
32 egl::Image *image = new egl::Image(imageImpl, EGL_GL_TEXTURE_2D, texture, egl::AttributeMap());
33 image->addRef();
34
35 // Verify that the image added a ref to the texture and the texture has not added a ref to the
36 // image
37 EXPECT_EQ(texture->getRefCount(), 2u);
38 EXPECT_EQ(image->getRefCount(), 1u);
39
40 // Create a renderbuffer and set it as a target of the EGL image
41 rx::MockRenderbufferImpl *renderbufferImpl = new rx::MockRenderbufferImpl();
42 gl::Renderbuffer *renderbuffer = new gl::Renderbuffer(renderbufferImpl, 1);
43 renderbuffer->addRef();
44
45 EXPECT_CALL(*renderbufferImpl, setStorageEGLImageTarget(_))
46 .WillOnce(Return(gl::Error(GL_NO_ERROR)))
47 .RetiresOnSaturation();
48 renderbuffer->setStorageEGLImageTarget(image);
49
50 // Verify that the renderbuffer added a ref to the image and the image did not add a ref to
51 // the renderbuffer
52 EXPECT_EQ(texture->getRefCount(), 2u);
53 EXPECT_EQ(image->getRefCount(), 2u);
54 EXPECT_EQ(renderbuffer->getRefCount(), 1u);
55
56 // Simulate deletion of the texture and verify that it still exists because the image holds a
57 // ref
58 texture->release();
59 EXPECT_EQ(texture->getRefCount(), 1u);
60 EXPECT_EQ(image->getRefCount(), 2u);
61 EXPECT_EQ(renderbuffer->getRefCount(), 1u);
62
63 // Simulate deletion of the image and verify that it still exists because the renderbuffer holds
64 // a ref
65 image->release();
66 EXPECT_EQ(texture->getRefCount(), 1u);
67 EXPECT_EQ(image->getRefCount(), 1u);
68 EXPECT_EQ(renderbuffer->getRefCount(), 1u);
69
70 // Simulate deletion of the renderbuffer and verify that the deletion cascades to all objects
71 EXPECT_CALL(*imageImpl, destructor()).Times(1).RetiresOnSaturation();
72 EXPECT_CALL(*imageImpl, orphan(_))
73 .WillOnce(Return(gl::Error(GL_NO_ERROR)))
74 .RetiresOnSaturation();
75
76 EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation();
77 EXPECT_CALL(*renderbufferImpl, destructor()).Times(1).RetiresOnSaturation();
78
79 renderbuffer->release();
80}
81
82// Verify that respecifiying textures releases references to the Image.
83TEST(ImageTest, RespecificationReleasesReferences)
84{
85 // Create a texture and an EGL image that uses the texture as its source
86 rx::MockTextureImpl *textureImpl = new rx::MockTextureImpl();
87 gl::Texture *texture = new gl::Texture(textureImpl, 1, GL_TEXTURE_2D);
88 texture->addRef();
89
90 EXPECT_CALL(*textureImpl, setImage(_, _, _, _, _, _, _, _))
91 .WillOnce(Return(gl::Error(GL_NO_ERROR)))
92 .RetiresOnSaturation();
93 texture->setImage(GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1), GL_RGBA, GL_UNSIGNED_BYTE,
94 gl::PixelUnpackState(), nullptr);
95
96 rx::MockImageImpl *imageImpl = new rx::MockImageImpl();
97 egl::Image *image = new egl::Image(imageImpl, EGL_GL_TEXTURE_2D, texture, egl::AttributeMap());
98 image->addRef();
99
100 // Verify that the image added a ref to the texture and the texture has not added a ref to the
101 // image
102 EXPECT_EQ(texture->getRefCount(), 2u);
103 EXPECT_EQ(image->getRefCount(), 1u);
104
105 // Respecify the texture and verify that the image releases its reference
106 EXPECT_CALL(*imageImpl, orphan(_))
107 .WillOnce(Return(gl::Error(GL_NO_ERROR)))
108 .RetiresOnSaturation();
109 EXPECT_CALL(*textureImpl, setImage(_, _, _, _, _, _, _, _))
110 .WillOnce(Return(gl::Error(GL_NO_ERROR)))
111 .RetiresOnSaturation();
112
113 texture->setImage(GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1), GL_RGBA, GL_UNSIGNED_BYTE,
114 gl::PixelUnpackState(), nullptr);
115
116 EXPECT_EQ(texture->getRefCount(), 1u);
117 EXPECT_EQ(image->getRefCount(), 1u);
118
119 // Delete the texture and verify that the image still exists
120 EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation();
121 texture->release();
122
123 EXPECT_EQ(image->getRefCount(), 1u);
124
125 // Delete the image
126 EXPECT_CALL(*imageImpl, destructor()).Times(1).RetiresOnSaturation();
127 image->release();
128}
129}