blob: 9c89be0e09e35d35aa4e37f6f08e0bc759f19ada [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
Jamie Madill73a84962016-02-12 09:27:23 -050090 gl::PixelUnpackState defaultUnpackState;
91
Geoff Langa8406172015-07-21 16:53:39 -040092 EXPECT_CALL(*textureImpl, setImage(_, _, _, _, _, _, _, _))
93 .WillOnce(Return(gl::Error(GL_NO_ERROR)))
94 .RetiresOnSaturation();
Jamie Madill73a84962016-02-12 09:27:23 -050095 texture->setImage(defaultUnpackState, GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1), GL_RGBA,
Jamie Madill1b94d432015-08-07 13:23:23 -040096 GL_UNSIGNED_BYTE, nullptr);
Geoff Langa8406172015-07-21 16:53:39 -040097
98 rx::MockImageImpl *imageImpl = new rx::MockImageImpl();
99 egl::Image *image = new egl::Image(imageImpl, EGL_GL_TEXTURE_2D, texture, egl::AttributeMap());
100 image->addRef();
101
102 // Verify that the image added a ref to the texture and the texture has not added a ref to the
103 // image
104 EXPECT_EQ(texture->getRefCount(), 2u);
105 EXPECT_EQ(image->getRefCount(), 1u);
106
107 // Respecify the texture and verify that the image releases its reference
108 EXPECT_CALL(*imageImpl, orphan(_))
109 .WillOnce(Return(gl::Error(GL_NO_ERROR)))
110 .RetiresOnSaturation();
111 EXPECT_CALL(*textureImpl, setImage(_, _, _, _, _, _, _, _))
112 .WillOnce(Return(gl::Error(GL_NO_ERROR)))
113 .RetiresOnSaturation();
114
Jamie Madill73a84962016-02-12 09:27:23 -0500115 texture->setImage(defaultUnpackState, GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1), GL_RGBA,
Jamie Madill1b94d432015-08-07 13:23:23 -0400116 GL_UNSIGNED_BYTE, nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400117
118 EXPECT_EQ(texture->getRefCount(), 1u);
119 EXPECT_EQ(image->getRefCount(), 1u);
120
121 // Delete the texture and verify that the image still exists
122 EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation();
123 texture->release();
124
125 EXPECT_EQ(image->getRefCount(), 1u);
126
127 // Delete the image
128 EXPECT_CALL(*imageImpl, destructor()).Times(1).RetiresOnSaturation();
129 image->release();
130}
131}