Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright 2011, 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 #ifndef TransferQueue_h
     27 #define TransferQueue_h
     28 
     29 #if USE(ACCELERATED_COMPOSITING)
     30 
     31 #include "BaseTile.h"
     32 #include "BaseTileTexture.h"
     33 #include "ShaderProgram.h"
     34 #include "TiledPage.h"
     35 
     36 namespace WebCore {
     37 
     38 struct GLState {
     39     GLint viewport[4];
     40     GLboolean scissor[1];
     41     GLboolean depth[1];
     42     GLfloat clearColor[4];
     43 };
     44 
     45 
     46 // While in the queue, the BaseTile can be re-used, the updated bitmap
     47 // can be discarded. In order to track this obsolete base tiles, we save
     48 // the Tile's Info to make the comparison.
     49 // At the time of base tile's dtor or webview destroy, we want to discard
     50 // all the data in the queue. However, we have to do the Surface Texture
     51 // update in the same GL context as the UI thread. So we mark the status
     52 // as pendingDiscard, and delay the Surface Texture operation to the next
     53 // draw call.
     54 
     55 enum TransferItemStatus {
     56     emptyItem = 0, // S.T. buffer ready for new content
     57     pendingBlit = 1, // Ready for bliting into tile's GL Tex.
     58     pendingDiscard = 2 // Waiting for the next draw call to discard
     59 };
     60 
     61 enum TextureUploadType {
     62     CpuUpload = 0,
     63     GpuUpload = 1
     64 };
     65 
     66 #define DEFAULT_UPLOAD_TYPE GpuUpload
     67 
     68 class TileTransferData {
     69 public:
     70     TileTransferData()
     71     : status(emptyItem)
     72     , savedBaseTilePtr(0)
     73     , savedBaseTileTexturePtr(0)
     74     , uploadType(DEFAULT_UPLOAD_TYPE)
     75     , bitmap(0)
     76     , m_syncKHR(EGL_NO_SYNC_KHR)
     77     {
     78     }
     79 
     80     ~TileTransferData()
     81     {
     82         // Bitmap will be created lazily, need to delete them at dtor.
     83         delete bitmap;
     84     }
     85 
     86     TransferItemStatus status;
     87     BaseTile* savedBaseTilePtr;
     88     BaseTileTexture* savedBaseTileTexturePtr;
     89     TextureTileInfo tileInfo;
     90     TextureUploadType uploadType;
     91     // This is only useful in Cpu upload code path, so it will be dynamically
     92     // lazily allocated.
     93     SkBitmap* bitmap;
     94 
     95     // Sync object for GPU fence, this is the only the info passed from UI
     96     // thread to Tex Gen thread. The reason of having this is due to the
     97     // missing sync mechanism on Surface Texture on some vendor. b/5122031.
     98     // Bascially the idea is that when UI thread utilize one buffer from
     99     // the surface texture, we'll need to kick off the GPU commands, and only
    100     // when those particular commands finish, we could write into this buffer
    101     // again in Tex Gen thread.
    102     EGLSyncKHR m_syncKHR;
    103 };
    104 
    105 class TransferQueue {
    106 public:
    107     TransferQueue();
    108     ~TransferQueue();
    109 
    110     // This will be called by the browser through nativeSetProperty
    111     void setTextureUploadType(TextureUploadType type);
    112 
    113     void updateDirtyBaseTiles();
    114 
    115     void initSharedSurfaceTextures(int width, int height);
    116 
    117     // insert the bitmap into the queue, mark the tile dirty if failing
    118     void updateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y,
    119                                const SkBitmap& bitmap);
    120 
    121     void discardQueue();
    122 
    123     void addItemInTransferQueue(const TileRenderInfo* info,
    124                                 TextureUploadType type,
    125                                 const SkBitmap* bitmap);
    126     // Check if the item @ index is ready for update.
    127     // The lock will be done when returning true.
    128     bool readyForUpdate();
    129 
    130     void interruptTransferQueue(bool);
    131 
    132     void lockQueue() { m_transferQueueItemLocks.lock(); }
    133     void unlockQueue() { m_transferQueueItemLocks.unlock(); }
    134 
    135     // This queue can be accessed from UI and TexGen thread, therefore, we need
    136     // a lock to protect its access
    137     TileTransferData* m_transferQueue;
    138 
    139     sp<ANativeWindow> m_ANW;
    140 
    141     // EGL wrapper around m_ANW for use by the GaneshRenderer
    142     EGLSurface m_eglSurface;
    143 
    144 private:
    145     // return true if successfully inserted into queue
    146     bool tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y,
    147                                   const SkBitmap& bitmap);
    148     bool getHasGLContext();
    149     void setHasGLContext(bool hasContext);
    150 
    151     int getNextTransferQueueIndex();
    152 
    153     // Save and restore the GL State while switching from/to FBO.
    154     void saveGLState();
    155     void setGLStateForCopy(int width, int height);
    156     void restoreGLState();
    157 
    158     // Check the current transfer queue item is obsolete or not.
    159     bool checkObsolete(int index);
    160 
    161     // Before each draw call and the blit operation, clean up all the
    162     // pendingDiscard items.
    163     void cleanupTransportQueue();
    164 
    165     void blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex,
    166                            GLuint srcTexId, GLenum srcTexTarget,
    167                            int index);
    168 
    169     // Note that the m_transferQueueIndex only changed in the TexGen thread
    170     // where we are going to move on to update the next item in the queue.
    171     int m_transferQueueIndex;
    172 
    173     GLuint m_fboID; // The FBO used for copy the SurfTex to each tile
    174 
    175     GLuint m_sharedSurfaceTextureId;
    176 
    177     // GLContext can be lost when WebView destroyed.
    178     bool m_hasGLContext;
    179 
    180     GLState m_GLStateBeforeBlit;
    181     sp<android::SurfaceTexture> m_sharedSurfaceTexture;
    182 
    183     int m_emptyItemCount;
    184 
    185     bool m_interruptedByRemovingOp;
    186 
    187     // We are using wait/signal to handle our own queue sync.
    188     // First of all, if we don't have our own lock, then while WebView is
    189     // destroyed, the UI thread will wait for the Tex Gen to get out from
    190     // dequeue operation, which will not succeed. B/c at this moment, we
    191     // already lost the GL Context.
    192     // Now we maintain a counter, which is m_emptyItemCount. When this reach
    193     // 0, then we need the Tex Gen thread to wait. UI thread can signal this
    194     // wait after calling updateTexImage at the draw call , or after WebView
    195     // is destroyed.
    196     android::Mutex m_transferQueueItemLocks;
    197     android::Condition m_transferQueueItemCond;
    198 
    199     EGLDisplay m_currentDisplay;
    200 
    201     // This should be GpuUpload for production, but for debug purpose or working
    202     // around driver/HW issue, we can set it to CpuUpload.
    203     TextureUploadType m_currentUploadType;
    204 };
    205 
    206 } // namespace WebCore
    207 
    208 #endif // USE(ACCELERATED_COMPOSITING)
    209 #endif // TransferQueue_h
    210