• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2010, The Android Open Source Project
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *  * Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "BaseTileTexture.h"
28 
29 #include "BaseTile.h"
30 #include "ClassTracker.h"
31 #include "DeleteTextureOperation.h"
32 #include "GLUtils.h"
33 #include "TilesManager.h"
34 
35 #include <cutils/log.h>
36 #include <wtf/text/CString.h>
37 
38 #undef XLOGC
39 #define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTileTexture", __VA_ARGS__)
40 
41 #ifdef DEBUG
42 
43 #undef XLOG
44 #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTileTexture", __VA_ARGS__)
45 
46 #else
47 
48 #undef XLOG
49 #define XLOG(...)
50 
51 #endif // DEBUG
52 
53 namespace WebCore {
54 
BaseTileTexture(uint32_t w,uint32_t h)55 BaseTileTexture::BaseTileTexture(uint32_t w, uint32_t h)
56     : DoubleBufferedTexture(eglGetCurrentContext(),
57                             TilesManager::instance()->getSharedTextureMode())
58     , m_owner(0)
59     , m_busy(false)
60 {
61     m_size.set(w, h);
62     m_ownTextureId = 0;
63 
64     // Make sure they are created on the UI thread.
65     TilesManager::instance()->transferQueue()->initSharedSurfaceTextures(w, h);
66 
67 #ifdef DEBUG_COUNT
68     ClassTracker::instance()->increment("BaseTileTexture");
69 #endif
70 }
71 
~BaseTileTexture()72 BaseTileTexture::~BaseTileTexture()
73 {
74     if (m_sharedTextureMode == EglImageMode) {
75         SharedTexture* textures[3] = { m_textureA, m_textureB, 0 };
76         destroyTextures(textures);
77     }
78 #ifdef DEBUG_COUNT
79     ClassTracker::instance()->decrement("BaseTileTexture");
80 #endif
81 }
82 
requireGLTexture()83 void BaseTileTexture::requireGLTexture()
84 {
85     if (!m_ownTextureId)
86         m_ownTextureId = GLUtils::createBaseTileGLTexture(m_size.width(), m_size.height());
87 }
88 
discardGLTexture()89 void BaseTileTexture::discardGLTexture()
90 {
91     if (m_ownTextureId)
92         GLUtils::deleteTexture(&m_ownTextureId);
93 
94     if (m_owner) {
95         // clear both Tile->Texture and Texture->Tile links
96         m_owner->removeTexture(this);
97         release(m_owner);
98     }
99 }
100 
destroyTextures(SharedTexture ** textures)101 void BaseTileTexture::destroyTextures(SharedTexture** textures)
102 {
103     int x = 0;
104     while (textures[x]) {
105         // We need to delete the source texture and EGLImage in the texture
106         // generation thread. In theory we should be able to delete the EGLImage
107         // from either thread, but it currently throws an error if not deleted
108         // in the same EGLContext from which it was created.
109         textures[x]->lock();
110         DeleteTextureOperation* operation = new DeleteTextureOperation(
111             textures[x]->getSourceTextureId(), textures[x]->getEGLImage());
112         textures[x]->unlock();
113         TilesManager::instance()->scheduleOperation(operation);
114         x++;
115     }
116 }
117 
producerLock()118 TextureInfo* BaseTileTexture::producerLock()
119 {
120     m_busyLock.lock();
121     m_busy = true;
122     m_busyLock.unlock();
123     return DoubleBufferedTexture::producerLock();
124 }
125 
producerRelease()126 void BaseTileTexture::producerRelease()
127 {
128     DoubleBufferedTexture::producerRelease();
129     setNotBusy();
130 }
131 
producerReleaseAndSwap()132 void BaseTileTexture::producerReleaseAndSwap()
133 {
134     DoubleBufferedTexture::producerReleaseAndSwap();
135     setNotBusy();
136 }
137 
setNotBusy()138 void BaseTileTexture::setNotBusy()
139 {
140     android::Mutex::Autolock lock(m_busyLock);
141     m_busy = false;
142     m_busyCond.signal();
143 }
144 
busy()145 bool BaseTileTexture::busy()
146 {
147     android::Mutex::Autolock lock(m_busyLock);
148     return m_busy;
149 }
150 
producerUpdate(TextureInfo * textureInfo,const SkBitmap & bitmap)151 void BaseTileTexture::producerUpdate(TextureInfo* textureInfo, const SkBitmap& bitmap)
152 {
153     // no need to upload a texture since the bitmap is empty
154     if (!bitmap.width() && !bitmap.height()) {
155         producerRelease();
156         return;
157     }
158 
159     // After the tiled layer checked in, this is not called anyway.
160     // TODO: cleanup the old code path for layer painting
161     // GLUtils::paintTextureWithBitmap(info, m_size, bitmap, 0, 0);
162 
163     producerReleaseAndSwap();
164 }
165 
acquire(TextureOwner * owner,bool force)166 bool BaseTileTexture::acquire(TextureOwner* owner, bool force)
167 {
168     if (m_owner == owner)
169         return true;
170 
171     return setOwner(owner, force);
172 }
173 
setOwner(TextureOwner * owner,bool force)174 bool BaseTileTexture::setOwner(TextureOwner* owner, bool force)
175 {
176     // if the writable texture is busy (i.e. currently being written to) then we
177     // can't change the owner out from underneath that texture
178     m_busyLock.lock();
179     while (m_busy && force)
180         m_busyCond.wait(m_busyLock);
181     bool busy = m_busy;
182     m_busyLock.unlock();
183 
184     if (!busy) {
185         // if we are not busy we can try to remove the texture from the layer;
186         // LayerAndroid::removeTexture() is protected by the same lock as
187         // LayerAndroid::paintBitmapGL(), so either we execute removeTexture()
188         // first and paintBitmapGL() will bail out, or we execute it after,
189         // and paintBitmapGL() will mark the texture as busy before
190         // relinquishing the lock. LayerAndroid::removeTexture() will call
191         // BaseTileTexture::release(), which will then do nothing
192         // if the texture is busy and we then don't return true.
193         bool proceed = true;
194         if (m_owner && m_owner != owner)
195             proceed = m_owner->removeTexture(this);
196 
197         if (proceed) {
198             m_owner = owner;
199             return true;
200         }
201     }
202     return false;
203 }
204 
release(TextureOwner * owner)205 bool BaseTileTexture::release(TextureOwner* owner)
206 {
207     android::Mutex::Autolock lock(m_busyLock);
208     XLOG("texture %p releasing tile %p, m_owner %p, m_busy %d", this, owner, m_owner, m_busy);
209     if (m_owner != owner)
210         return false;
211 
212     m_owner = 0;
213     return true;
214 }
215 
setTile(TextureInfo * info,int x,int y,float scale,TilePainter * painter,unsigned int pictureCount)216 void BaseTileTexture::setTile(TextureInfo* info, int x, int y,
217                                           float scale, TilePainter* painter,
218                                           unsigned int pictureCount)
219 {
220     TextureTileInfo* textureInfo = m_texturesInfo.get(getWriteableTexture());
221     if (!textureInfo) {
222         textureInfo = new TextureTileInfo();
223     }
224     textureInfo->m_x = x;
225     textureInfo->m_y = y;
226     textureInfo->m_scale = scale;
227     textureInfo->m_painter = painter;
228     textureInfo->m_picture = pictureCount;
229     m_texturesInfo.set(getWriteableTexture(), textureInfo);
230 }
231 
scale()232 float BaseTileTexture::scale()
233 {
234     TextureTileInfo* textureInfo = &m_ownTextureTileInfo;
235     return textureInfo->m_scale;
236 }
237 
238 // This function + TilesManager::addItemInTransferQueue() is replacing the
239 // setTile().
setOwnTextureTileInfoFromQueue(const TextureTileInfo * info)240 void BaseTileTexture::setOwnTextureTileInfoFromQueue(const TextureTileInfo* info)
241 {
242     m_ownTextureTileInfo.m_x = info->m_x;
243     m_ownTextureTileInfo.m_y = info->m_y;
244     m_ownTextureTileInfo.m_scale = info->m_scale;
245     m_ownTextureTileInfo.m_painter = info->m_painter;
246     m_ownTextureTileInfo.m_picture = info->m_picture;
247     m_ownTextureTileInfo.m_inverted = TilesManager::instance()->invertedScreen();
248     if (m_owner) {
249         BaseTile* owner = static_cast<BaseTile*>(m_owner);
250         owner->backTextureTransfer();
251     }
252 
253 }
254 
readyFor(BaseTile * baseTile)255 bool BaseTileTexture::readyFor(BaseTile* baseTile)
256 {
257     const TextureTileInfo* info = &m_ownTextureTileInfo;
258     if (info &&
259         (info->m_x == baseTile->x()) &&
260         (info->m_y == baseTile->y()) &&
261         (info->m_scale == baseTile->scale()) &&
262         (info->m_painter == baseTile->painter()) &&
263         (info->m_inverted == TilesManager::instance()->invertedScreen()))
264         return true;
265 
266     XLOG("texture %p readyFor return false for tile x, y (%d %d) texId %d ,"
267          " BaseTileTexture %p, BaseTile is %p, SCALE %f, painter %p, inv %d",
268          this, baseTile->x(), baseTile->y(), m_ownTextureId, this, baseTile,
269          baseTile->scale(), baseTile->painter(), TilesManager::instance()->invertedScreen());
270     return false;
271 }
272 
273 } // namespace WebCore
274