1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker // Image_unittest.cpp : Unittets of the Image and ImageSibling classes.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "gmock/gmock.h"
10*8975f5c5SAndroid Build Coastguard Worker #include "gtest/gtest.h"
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Image.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Renderbuffer.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Texture.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/ImageImpl_mock.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/RenderbufferImpl_mock.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/TextureImpl_mock.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "tests/angle_unittests_utils.h"
19*8975f5c5SAndroid Build Coastguard Worker
20*8975f5c5SAndroid Build Coastguard Worker using ::testing::_;
21*8975f5c5SAndroid Build Coastguard Worker using ::testing::NiceMock;
22*8975f5c5SAndroid Build Coastguard Worker using ::testing::Return;
23*8975f5c5SAndroid Build Coastguard Worker
24*8975f5c5SAndroid Build Coastguard Worker namespace angle
25*8975f5c5SAndroid Build Coastguard Worker {
ACTION(CreateMockImageImpl)26*8975f5c5SAndroid Build Coastguard Worker ACTION(CreateMockImageImpl)
27*8975f5c5SAndroid Build Coastguard Worker {
28*8975f5c5SAndroid Build Coastguard Worker return new rx::MockImageImpl(arg0);
29*8975f5c5SAndroid Build Coastguard Worker }
30*8975f5c5SAndroid Build Coastguard Worker
31*8975f5c5SAndroid Build Coastguard Worker // Verify ref counts are maintained between images and their siblings when objects are deleted
TEST(ImageTest,RefCounting)32*8975f5c5SAndroid Build Coastguard Worker TEST(ImageTest, RefCounting)
33*8975f5c5SAndroid Build Coastguard Worker {
34*8975f5c5SAndroid Build Coastguard Worker NiceMock<rx::MockGLFactory> mockGLFactory;
35*8975f5c5SAndroid Build Coastguard Worker NiceMock<rx::MockEGLFactory> mockEGLFactory;
36*8975f5c5SAndroid Build Coastguard Worker
37*8975f5c5SAndroid Build Coastguard Worker // Create a texture and an EGL image that uses the texture as its source
38*8975f5c5SAndroid Build Coastguard Worker rx::MockTextureImpl *textureImpl = new rx::MockTextureImpl();
39*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(mockGLFactory, createTexture(_)).WillOnce(Return(textureImpl));
40*8975f5c5SAndroid Build Coastguard Worker gl::Texture *texture = new gl::Texture(&mockGLFactory, {1}, gl::TextureType::_2D);
41*8975f5c5SAndroid Build Coastguard Worker texture->addRef();
42*8975f5c5SAndroid Build Coastguard Worker
43*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(mockEGLFactory, createImage(_, _, _, _))
44*8975f5c5SAndroid Build Coastguard Worker .WillOnce(CreateMockImageImpl())
45*8975f5c5SAndroid Build Coastguard Worker .RetiresOnSaturation();
46*8975f5c5SAndroid Build Coastguard Worker
47*8975f5c5SAndroid Build Coastguard Worker egl::Image *image = new egl::Image(&mockEGLFactory, {1}, nullptr, EGL_GL_TEXTURE_2D, texture,
48*8975f5c5SAndroid Build Coastguard Worker egl::AttributeMap());
49*8975f5c5SAndroid Build Coastguard Worker rx::MockImageImpl *imageImpl = static_cast<rx::MockImageImpl *>(image->getImplementation());
50*8975f5c5SAndroid Build Coastguard Worker image->addRef();
51*8975f5c5SAndroid Build Coastguard Worker
52*8975f5c5SAndroid Build Coastguard Worker // Verify that the image does not add a ref to its source so that the source may still be
53*8975f5c5SAndroid Build Coastguard Worker // deleted
54*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(1u, texture->getRefCount());
55*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(1u, image->getRefCount());
56*8975f5c5SAndroid Build Coastguard Worker
57*8975f5c5SAndroid Build Coastguard Worker // Create a renderbuffer and set it as a target of the EGL image
58*8975f5c5SAndroid Build Coastguard Worker rx::MockRenderbufferImpl *renderbufferImpl = new rx::MockRenderbufferImpl();
59*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(mockGLFactory, createRenderbuffer(_)).WillOnce(Return(renderbufferImpl));
60*8975f5c5SAndroid Build Coastguard Worker gl::Renderbuffer *renderbuffer = new gl::Renderbuffer(&mockGLFactory, {1});
61*8975f5c5SAndroid Build Coastguard Worker renderbuffer->addRef();
62*8975f5c5SAndroid Build Coastguard Worker
63*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(*renderbufferImpl, setStorageEGLImageTarget(_, _))
64*8975f5c5SAndroid Build Coastguard Worker .WillOnce(Return(angle::Result::Continue))
65*8975f5c5SAndroid Build Coastguard Worker .RetiresOnSaturation();
66*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(angle::Result::Continue, renderbuffer->setStorageEGLImageTarget(nullptr, image));
67*8975f5c5SAndroid Build Coastguard Worker
68*8975f5c5SAndroid Build Coastguard Worker // Verify that the renderbuffer added a ref to the image and the image did not add a ref to
69*8975f5c5SAndroid Build Coastguard Worker // the renderbuffer
70*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(1u, texture->getRefCount());
71*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(2u, image->getRefCount());
72*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(1u, renderbuffer->getRefCount());
73*8975f5c5SAndroid Build Coastguard Worker
74*8975f5c5SAndroid Build Coastguard Worker // Simulate deletion of the texture and verify that it is deleted but the image still exists
75*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(*imageImpl, orphan(_, _))
76*8975f5c5SAndroid Build Coastguard Worker .WillOnce(Return(angle::Result::Continue))
77*8975f5c5SAndroid Build Coastguard Worker .RetiresOnSaturation();
78*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation();
79*8975f5c5SAndroid Build Coastguard Worker texture->release(nullptr);
80*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(2u, image->getRefCount());
81*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(1u, renderbuffer->getRefCount());
82*8975f5c5SAndroid Build Coastguard Worker
83*8975f5c5SAndroid Build Coastguard Worker // Simulate deletion of the image and verify that it still exists because the renderbuffer holds
84*8975f5c5SAndroid Build Coastguard Worker // a ref
85*8975f5c5SAndroid Build Coastguard Worker image->release(nullptr);
86*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(1u, image->getRefCount());
87*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(1u, renderbuffer->getRefCount());
88*8975f5c5SAndroid Build Coastguard Worker
89*8975f5c5SAndroid Build Coastguard Worker // Simulate deletion of the renderbuffer and verify that the deletion cascades to all objects
90*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(*imageImpl, destructor()).Times(1).RetiresOnSaturation();
91*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(*imageImpl, orphan(_, _))
92*8975f5c5SAndroid Build Coastguard Worker .WillOnce(Return(angle::Result::Continue))
93*8975f5c5SAndroid Build Coastguard Worker .RetiresOnSaturation();
94*8975f5c5SAndroid Build Coastguard Worker
95*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(*renderbufferImpl, destructor()).Times(1).RetiresOnSaturation();
96*8975f5c5SAndroid Build Coastguard Worker
97*8975f5c5SAndroid Build Coastguard Worker renderbuffer->release(nullptr);
98*8975f5c5SAndroid Build Coastguard Worker }
99*8975f5c5SAndroid Build Coastguard Worker
100*8975f5c5SAndroid Build Coastguard Worker // Verify that respecifying textures releases references to the Image.
TEST(ImageTest,RespecificationReleasesReferences)101*8975f5c5SAndroid Build Coastguard Worker TEST(ImageTest, RespecificationReleasesReferences)
102*8975f5c5SAndroid Build Coastguard Worker {
103*8975f5c5SAndroid Build Coastguard Worker NiceMock<rx::MockGLFactory> mockGLFactory;
104*8975f5c5SAndroid Build Coastguard Worker NiceMock<rx::MockEGLFactory> mockEGLFactory;
105*8975f5c5SAndroid Build Coastguard Worker
106*8975f5c5SAndroid Build Coastguard Worker // Create a texture and an EGL image that uses the texture as its source
107*8975f5c5SAndroid Build Coastguard Worker rx::MockTextureImpl *textureImpl = new rx::MockTextureImpl();
108*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(mockGLFactory, createTexture(_)).WillOnce(Return(textureImpl));
109*8975f5c5SAndroid Build Coastguard Worker gl::Texture *texture = new gl::Texture(&mockGLFactory, {1}, gl::TextureType::_2D);
110*8975f5c5SAndroid Build Coastguard Worker texture->addRef();
111*8975f5c5SAndroid Build Coastguard Worker
112*8975f5c5SAndroid Build Coastguard Worker gl::PixelUnpackState defaultUnpackState;
113*8975f5c5SAndroid Build Coastguard Worker
114*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(*textureImpl, setImage(_, _, _, _, _, _, _, _, _))
115*8975f5c5SAndroid Build Coastguard Worker .WillOnce(Return(angle::Result::Continue))
116*8975f5c5SAndroid Build Coastguard Worker .RetiresOnSaturation();
117*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(
118*8975f5c5SAndroid Build Coastguard Worker angle::Result::Continue,
119*8975f5c5SAndroid Build Coastguard Worker texture->setImage(nullptr, defaultUnpackState, nullptr, gl::TextureTarget::_2D, 0, GL_RGBA8,
120*8975f5c5SAndroid Build Coastguard Worker gl::Extents(1, 1, 1), GL_RGBA, GL_UNSIGNED_BYTE, nullptr));
121*8975f5c5SAndroid Build Coastguard Worker
122*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(mockEGLFactory, createImage(_, _, _, _))
123*8975f5c5SAndroid Build Coastguard Worker .WillOnce(CreateMockImageImpl())
124*8975f5c5SAndroid Build Coastguard Worker .RetiresOnSaturation();
125*8975f5c5SAndroid Build Coastguard Worker
126*8975f5c5SAndroid Build Coastguard Worker egl::Image *image = new egl::Image(&mockEGLFactory, {1}, nullptr, EGL_GL_TEXTURE_2D, texture,
127*8975f5c5SAndroid Build Coastguard Worker egl::AttributeMap());
128*8975f5c5SAndroid Build Coastguard Worker image->addRef();
129*8975f5c5SAndroid Build Coastguard Worker
130*8975f5c5SAndroid Build Coastguard Worker // Verify that the image did not add a ref to it's source.
131*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(1u, texture->getRefCount());
132*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(1u, image->getRefCount());
133*8975f5c5SAndroid Build Coastguard Worker
134*8975f5c5SAndroid Build Coastguard Worker // Respecify the texture and verify that the image is orphaned
135*8975f5c5SAndroid Build Coastguard Worker rx::MockImageImpl *imageImpl = static_cast<rx::MockImageImpl *>(image->getImplementation());
136*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(*imageImpl, orphan(_, _))
137*8975f5c5SAndroid Build Coastguard Worker .WillOnce(Return(angle::Result::Continue))
138*8975f5c5SAndroid Build Coastguard Worker .RetiresOnSaturation();
139*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(*textureImpl, setImage(_, _, _, _, _, _, _, _, _))
140*8975f5c5SAndroid Build Coastguard Worker .WillOnce(Return(angle::Result::Continue))
141*8975f5c5SAndroid Build Coastguard Worker .RetiresOnSaturation();
142*8975f5c5SAndroid Build Coastguard Worker
143*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(
144*8975f5c5SAndroid Build Coastguard Worker angle::Result::Continue,
145*8975f5c5SAndroid Build Coastguard Worker texture->setImage(nullptr, defaultUnpackState, nullptr, gl::TextureTarget::_2D, 0, GL_RGBA8,
146*8975f5c5SAndroid Build Coastguard Worker gl::Extents(1, 1, 1), GL_RGBA, GL_UNSIGNED_BYTE, nullptr));
147*8975f5c5SAndroid Build Coastguard Worker
148*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(1u, texture->getRefCount());
149*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(1u, image->getRefCount());
150*8975f5c5SAndroid Build Coastguard Worker
151*8975f5c5SAndroid Build Coastguard Worker // Delete the texture and verify that the image still exists
152*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation();
153*8975f5c5SAndroid Build Coastguard Worker texture->release(nullptr);
154*8975f5c5SAndroid Build Coastguard Worker
155*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(1u, image->getRefCount());
156*8975f5c5SAndroid Build Coastguard Worker
157*8975f5c5SAndroid Build Coastguard Worker // Delete the image
158*8975f5c5SAndroid Build Coastguard Worker EXPECT_CALL(*imageImpl, destructor()).Times(1).RetiresOnSaturation();
159*8975f5c5SAndroid Build Coastguard Worker image->release(nullptr);
160*8975f5c5SAndroid Build Coastguard Worker }
161*8975f5c5SAndroid Build Coastguard Worker } // namespace angle
162