2 * Copyright 2010, The Android Open Source Project
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "BaseTileTexture.h"
30 #include "ClassTracker.h"
31 #include "DeleteTextureOperation.h"
33 #include "TilesManager.h"
36 #define LOG_TAG "BaseTileTexture.cpp"
37 #include <utils/Log.h>
41 BaseTileTexture::BaseTileTexture(uint32_t w, uint32_t h)
42 : DoubleBufferedTexture(eglGetCurrentContext(), SurfaceTextureMode)
45 , m_delayedReleaseOwner(0)
46 , m_delayedRelease(false)
52 ClassTracker::instance()->increment("BaseTileTexture");
56 BaseTileTexture::~BaseTileTexture()
58 if (m_sharedTextureMode == EglImageMode) {
59 SharedTexture* textures[3] = { m_textureA, m_textureB, 0 };
60 destroyTextures(textures);
63 ClassTracker::instance()->decrement("BaseTileTexture");
67 void BaseTileTexture::destroyTextures(SharedTexture** textures)
71 // We need to delete the source texture and EGLImage in the texture
72 // generation thread. In theory we should be able to delete the EGLImage
73 // from either thread, but it currently throws an error if not deleted
74 // in the same EGLContext from which it was created.
76 DeleteTextureOperation* operation = new DeleteTextureOperation(
77 textures[x]->getSourceTextureId(), textures[x]->getEGLImage());
78 textures[x]->unlock();
79 TilesManager::instance()->scheduleOperation(operation);
84 TextureInfo* BaseTileTexture::producerLock()
89 return DoubleBufferedTexture::producerLock();
92 void BaseTileTexture::producerRelease()
94 DoubleBufferedTexture::producerRelease();
98 void BaseTileTexture::producerReleaseAndSwap()
100 DoubleBufferedTexture::producerReleaseAndSwap();
104 void BaseTileTexture::setNotBusy()
106 android::Mutex::Autolock lock(m_busyLock);
108 if (m_delayedRelease) {
109 if (m_owner == m_delayedReleaseOwner)
112 m_delayedRelease = false;
113 m_delayedReleaseOwner = 0;
118 bool BaseTileTexture::busy()
120 android::Mutex::Autolock lock(m_busyLock);
124 void BaseTileTexture::producerUpdate(TextureInfo* textureInfo, const SkBitmap& bitmap)
126 // no need to upload a texture since the bitmap is empty
127 if (!bitmap.width() && !bitmap.height()) {
132 GLUtils::paintTextureWithBitmap(textureInfo, m_size, bitmap, 0, 0);
134 producerReleaseAndSwap();
137 bool BaseTileTexture::acquire(TextureOwner* owner, bool force)
139 if (m_owner == owner) {
140 if (m_delayedRelease) {
141 m_delayedRelease = false;
142 m_delayedReleaseOwner = 0;
147 return setOwner(owner, force);
150 bool BaseTileTexture::tryAcquire(TextureOwner* owner)
155 && m_owner->state() != owner->state()) {
157 return this->acquire(owner);
163 bool BaseTileTexture::setOwner(TextureOwner* owner, bool force)
165 // if the writable texture is busy (i.e. currently being written to) then we
166 // can't change the owner out from underneath that texture
168 while (m_busy && force)
169 m_busyCond.wait(m_busyLock);
174 // if we are not busy we can try to remove the texture from the layer;
175 // LayerAndroid::removeTexture() is protected by the same lock as
176 // LayerAndroid::paintBitmapGL(), so either we execute removeTexture()
177 // first and paintBitmapGL() will bail out, or we execute it after,
178 // and paintBitmapGL() will mark the texture as busy before
179 // relinquishing the lock. LayerAndroid::removeTexture() will call
180 // BaseTileTexture::release(), which will then do nothing
181 // if the texture is busy and we then don't return true.
183 if (m_owner && m_owner != owner)
184 proceed = m_owner->removeTexture(this);
194 bool BaseTileTexture::release(TextureOwner* owner)
196 android::Mutex::Autolock lock(m_busyLock);
197 if (m_owner != owner)
203 m_delayedRelease = true;
204 m_delayedReleaseOwner = owner;
209 void BaseTileTexture::setTile(TextureInfo* info, int x, int y,
210 float scale, unsigned int pictureCount)
212 TextureTileInfo* textureInfo = m_texturesInfo.get(getWriteableTexture());
214 textureInfo = new TextureTileInfo();
216 textureInfo->m_x = x;
217 textureInfo->m_y = y;
218 textureInfo->m_scale = scale;
219 textureInfo->m_picture = pictureCount;
220 m_texturesInfo.set(getWriteableTexture(), textureInfo);
223 bool BaseTileTexture::readyFor(BaseTile* baseTile)
225 TextureTileInfo* info = m_texturesInfo.get(getReadableTexture());
227 (info->m_x == baseTile->x()) &&
228 (info->m_y == baseTile->y()) &&
229 (info->m_scale == baseTile->scale()) &&
230 (info->m_picture == baseTile->lastPaintedPicture())) {
236 } // namespace WebCore