19fded232a9548a304e0145011df8849fba0dcda7Chris Craik/*
29fded232a9548a304e0145011df8849fba0dcda7Chris Craik * Copyright (C) 2015 The Android Open Source Project
39fded232a9548a304e0145011df8849fba0dcda7Chris Craik *
49fded232a9548a304e0145011df8849fba0dcda7Chris Craik * Licensed under the Apache License, Version 2.0 (the "License");
59fded232a9548a304e0145011df8849fba0dcda7Chris Craik * you may not use this file except in compliance with the License.
69fded232a9548a304e0145011df8849fba0dcda7Chris Craik * You may obtain a copy of the License at
79fded232a9548a304e0145011df8849fba0dcda7Chris Craik *
89fded232a9548a304e0145011df8849fba0dcda7Chris Craik *      http://www.apache.org/licenses/LICENSE-2.0
99fded232a9548a304e0145011df8849fba0dcda7Chris Craik *
109fded232a9548a304e0145011df8849fba0dcda7Chris Craik * Unless required by applicable law or agreed to in writing, software
119fded232a9548a304e0145011df8849fba0dcda7Chris Craik * distributed under the License is distributed on an "AS IS" BASIS,
129fded232a9548a304e0145011df8849fba0dcda7Chris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139fded232a9548a304e0145011df8849fba0dcda7Chris Craik * See the License for the specific language governing permissions and
149fded232a9548a304e0145011df8849fba0dcda7Chris Craik * limitations under the License.
159fded232a9548a304e0145011df8849fba0dcda7Chris Craik */
169fded232a9548a304e0145011df8849fba0dcda7Chris Craik
179fded232a9548a304e0145011df8849fba0dcda7Chris Craik#ifndef ANDROID_HWUI_OFFSCREEN_BUFFER_POOL_H
189fded232a9548a304e0145011df8849fba0dcda7Chris Craik#define ANDROID_HWUI_OFFSCREEN_BUFFER_POOL_H
199fded232a9548a304e0145011df8849fba0dcda7Chris Craik
2038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck#include <GpuMemoryTracker.h>
219fded232a9548a304e0145011df8849fba0dcda7Chris Craik#include "Caches.h"
229fded232a9548a304e0145011df8849fba0dcda7Chris Craik#include "Texture.h"
239fded232a9548a304e0145011df8849fba0dcda7Chris Craik#include "utils/Macros.h"
249fded232a9548a304e0145011df8849fba0dcda7Chris Craik#include <ui/Region.h>
259fded232a9548a304e0145011df8849fba0dcda7Chris Craik
269fded232a9548a304e0145011df8849fba0dcda7Chris Craik#include <set>
279fded232a9548a304e0145011df8849fba0dcda7Chris Craik
289fded232a9548a304e0145011df8849fba0dcda7Chris Craiknamespace android {
299fded232a9548a304e0145011df8849fba0dcda7Chris Craiknamespace uirenderer {
309fded232a9548a304e0145011df8849fba0dcda7Chris Craik
319fded232a9548a304e0145011df8849fba0dcda7Chris Craikclass RenderState;
329fded232a9548a304e0145011df8849fba0dcda7Chris Craik
339fded232a9548a304e0145011df8849fba0dcda7Chris Craik/**
349fded232a9548a304e0145011df8849fba0dcda7Chris Craik * Lightweight alternative to Layer. Owns the persistent state of an offscreen render target, and
359fded232a9548a304e0145011df8849fba0dcda7Chris Craik * encompasses enough information to draw it back on screen (minus paint properties, which are held
369fded232a9548a304e0145011df8849fba0dcda7Chris Craik * by LayerOp).
3798787e6c9b2c10b1ab7820bdac168686025b924aChris Craik *
3898787e6c9b2c10b1ab7820bdac168686025b924aChris Craik * Has two distinct sizes - viewportWidth/viewportHeight describe content area,
3998787e6c9b2c10b1ab7820bdac168686025b924aChris Craik * texture.width/.height are actual allocated texture size. Texture will tend to be larger than the
4098787e6c9b2c10b1ab7820bdac168686025b924aChris Craik * viewport bounds, since textures are always allocated with width / height as a multiple of 64, for
4198787e6c9b2c10b1ab7820bdac168686025b924aChris Craik * the purpose of improving reuse.
429fded232a9548a304e0145011df8849fba0dcda7Chris Craik */
4338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckclass OffscreenBuffer : GpuMemoryTracker {
449fded232a9548a304e0145011df8849fba0dcda7Chris Craikpublic:
459fded232a9548a304e0145011df8849fba0dcda7Chris Craik    OffscreenBuffer(RenderState& renderState, Caches& caches,
469fded232a9548a304e0145011df8849fba0dcda7Chris Craik            uint32_t viewportWidth, uint32_t viewportHeight);
479fded232a9548a304e0145011df8849fba0dcda7Chris Craik    ~OffscreenBuffer();
489fded232a9548a304e0145011df8849fba0dcda7Chris Craik
497435eb148e72382126e9073183e881357bb38a8bChris Craik    Rect getTextureCoordinates();
507435eb148e72382126e9073183e881357bb38a8bChris Craik
5164db2bf1118db88c937e2b8c61b299bb2a80e3cbChris Craik    void dirty(Rect dirtyArea);
5264db2bf1118db88c937e2b8c61b299bb2a80e3cbChris Craik
539fded232a9548a304e0145011df8849fba0dcda7Chris Craik    // must be called prior to rendering, to construct/update vertex buffer
549fded232a9548a304e0145011df8849fba0dcda7Chris Craik    void updateMeshFromRegion();
559fded232a9548a304e0145011df8849fba0dcda7Chris Craik
5698787e6c9b2c10b1ab7820bdac168686025b924aChris Craik    // Set by RenderNode for HW layers, TODO for clipped saveLayers
5798787e6c9b2c10b1ab7820bdac168686025b924aChris Craik    void setWindowTransform(const Matrix4& transform) {
5898787e6c9b2c10b1ab7820bdac168686025b924aChris Craik        inverseTransformInWindow.loadInverse(transform);
5998787e6c9b2c10b1ab7820bdac168686025b924aChris Craik    }
6098787e6c9b2c10b1ab7820bdac168686025b924aChris Craik
619fded232a9548a304e0145011df8849fba0dcda7Chris Craik    static uint32_t computeIdealDimension(uint32_t dimension);
629fded232a9548a304e0145011df8849fba0dcda7Chris Craik
6338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    uint32_t getSizeInBytes() { return texture.objectSize(); }
649fded232a9548a304e0145011df8849fba0dcda7Chris Craik
659fded232a9548a304e0145011df8849fba0dcda7Chris Craik    RenderState& renderState;
6698787e6c9b2c10b1ab7820bdac168686025b924aChris Craik
679fded232a9548a304e0145011df8849fba0dcda7Chris Craik    uint32_t viewportWidth;
689fded232a9548a304e0145011df8849fba0dcda7Chris Craik    uint32_t viewportHeight;
699fded232a9548a304e0145011df8849fba0dcda7Chris Craik    Texture texture;
709fded232a9548a304e0145011df8849fba0dcda7Chris Craik
719fded232a9548a304e0145011df8849fba0dcda7Chris Craik    // Portion of layer that has been drawn to. Used to minimize drawing area when
729fded232a9548a304e0145011df8849fba0dcda7Chris Craik    // drawing back to screen / parent FBO.
739fded232a9548a304e0145011df8849fba0dcda7Chris Craik    Region region;
7498787e6c9b2c10b1ab7820bdac168686025b924aChris Craik
7598787e6c9b2c10b1ab7820bdac168686025b924aChris Craik    Matrix4 inverseTransformInWindow;
7698787e6c9b2c10b1ab7820bdac168686025b924aChris Craik
7798787e6c9b2c10b1ab7820bdac168686025b924aChris Craik    // vbo / size of mesh
789fded232a9548a304e0145011df8849fba0dcda7Chris Craik    GLsizei elementCount = 0;
799fded232a9548a304e0145011df8849fba0dcda7Chris Craik    GLuint vbo = 0;
8037413289478a965336239c731ebfea37ac4dde28Chris Craik
8137413289478a965336239c731ebfea37ac4dde28Chris Craik    bool hasRenderedSinceRepaint;
829fded232a9548a304e0145011df8849fba0dcda7Chris Craik};
839fded232a9548a304e0145011df8849fba0dcda7Chris Craik
849fded232a9548a304e0145011df8849fba0dcda7Chris Craik/**
859fded232a9548a304e0145011df8849fba0dcda7Chris Craik * Pool of OffscreenBuffers allocated, but not currently in use.
869fded232a9548a304e0145011df8849fba0dcda7Chris Craik */
879fded232a9548a304e0145011df8849fba0dcda7Chris Craikclass OffscreenBufferPool {
889fded232a9548a304e0145011df8849fba0dcda7Chris Craikpublic:
899fded232a9548a304e0145011df8849fba0dcda7Chris Craik    OffscreenBufferPool();
909fded232a9548a304e0145011df8849fba0dcda7Chris Craik    ~OffscreenBufferPool();
919fded232a9548a304e0145011df8849fba0dcda7Chris Craik
929fded232a9548a304e0145011df8849fba0dcda7Chris Craik    WARN_UNUSED_RESULT OffscreenBuffer* get(RenderState& renderState,
939fded232a9548a304e0145011df8849fba0dcda7Chris Craik            const uint32_t width, const uint32_t height);
949fded232a9548a304e0145011df8849fba0dcda7Chris Craik
959fded232a9548a304e0145011df8849fba0dcda7Chris Craik    WARN_UNUSED_RESULT OffscreenBuffer* resize(OffscreenBuffer* layer,
969fded232a9548a304e0145011df8849fba0dcda7Chris Craik            const uint32_t width, const uint32_t height);
979fded232a9548a304e0145011df8849fba0dcda7Chris Craik
989fded232a9548a304e0145011df8849fba0dcda7Chris Craik    void putOrDelete(OffscreenBuffer* layer);
999fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1009fded232a9548a304e0145011df8849fba0dcda7Chris Craik    /**
1019fded232a9548a304e0145011df8849fba0dcda7Chris Craik     * Clears the pool. This causes all layers to be deleted.
1029fded232a9548a304e0145011df8849fba0dcda7Chris Craik     */
1039fded232a9548a304e0145011df8849fba0dcda7Chris Craik    void clear();
1049fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1059fded232a9548a304e0145011df8849fba0dcda7Chris Craik    /**
1069fded232a9548a304e0145011df8849fba0dcda7Chris Craik     * Returns the maximum size of the pool in bytes.
1079fded232a9548a304e0145011df8849fba0dcda7Chris Craik     */
1089fded232a9548a304e0145011df8849fba0dcda7Chris Craik    uint32_t getMaxSize() { return mMaxSize; }
1099fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1109fded232a9548a304e0145011df8849fba0dcda7Chris Craik    /**
1119fded232a9548a304e0145011df8849fba0dcda7Chris Craik     * Returns the current size of the pool in bytes.
1129fded232a9548a304e0145011df8849fba0dcda7Chris Craik     */
1139fded232a9548a304e0145011df8849fba0dcda7Chris Craik    uint32_t getSize() { return mSize; }
1149fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1159fded232a9548a304e0145011df8849fba0dcda7Chris Craik    size_t getCount() { return mPool.size(); }
1169fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1179fded232a9548a304e0145011df8849fba0dcda7Chris Craik    /**
1189fded232a9548a304e0145011df8849fba0dcda7Chris Craik     * Prints out the content of the pool.
1199fded232a9548a304e0145011df8849fba0dcda7Chris Craik     */
1209fded232a9548a304e0145011df8849fba0dcda7Chris Craik    void dump();
1219fded232a9548a304e0145011df8849fba0dcda7Chris Craikprivate:
1229fded232a9548a304e0145011df8849fba0dcda7Chris Craik    struct Entry {
1239fded232a9548a304e0145011df8849fba0dcda7Chris Craik        Entry() {}
1249fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1259fded232a9548a304e0145011df8849fba0dcda7Chris Craik        Entry(const uint32_t layerWidth, const uint32_t layerHeight)
1269fded232a9548a304e0145011df8849fba0dcda7Chris Craik                : width(OffscreenBuffer::computeIdealDimension(layerWidth))
1279fded232a9548a304e0145011df8849fba0dcda7Chris Craik                , height(OffscreenBuffer::computeIdealDimension(layerHeight)) {}
1289fded232a9548a304e0145011df8849fba0dcda7Chris Craik
129a619ec70cf765d9166f0862e74653711b87307b3Chih-Hung Hsieh        explicit Entry(OffscreenBuffer* layer)
1309fded232a9548a304e0145011df8849fba0dcda7Chris Craik                : layer(layer)
13138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck                , width(layer->texture.width())
13238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck                , height(layer->texture.height()) {
1339fded232a9548a304e0145011df8849fba0dcda7Chris Craik        }
1349fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1359fded232a9548a304e0145011df8849fba0dcda7Chris Craik        static int compare(const Entry& lhs, const Entry& rhs);
1369fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1379fded232a9548a304e0145011df8849fba0dcda7Chris Craik        bool operator==(const Entry& other) const {
1389fded232a9548a304e0145011df8849fba0dcda7Chris Craik            return compare(*this, other) == 0;
1399fded232a9548a304e0145011df8849fba0dcda7Chris Craik        }
1409fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1419fded232a9548a304e0145011df8849fba0dcda7Chris Craik        bool operator!=(const Entry& other) const {
1429fded232a9548a304e0145011df8849fba0dcda7Chris Craik            return compare(*this, other) != 0;
1439fded232a9548a304e0145011df8849fba0dcda7Chris Craik        }
1449fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1459fded232a9548a304e0145011df8849fba0dcda7Chris Craik        bool operator<(const Entry& other) const {
1469fded232a9548a304e0145011df8849fba0dcda7Chris Craik            return Entry::compare(*this, other) < 0;
1479fded232a9548a304e0145011df8849fba0dcda7Chris Craik        }
1489fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1499fded232a9548a304e0145011df8849fba0dcda7Chris Craik        OffscreenBuffer* layer = nullptr;
1509fded232a9548a304e0145011df8849fba0dcda7Chris Craik        uint32_t width = 0;
1519fded232a9548a304e0145011df8849fba0dcda7Chris Craik        uint32_t height = 0;
1529fded232a9548a304e0145011df8849fba0dcda7Chris Craik    }; // struct Entry
1539fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1549fded232a9548a304e0145011df8849fba0dcda7Chris Craik    std::multiset<Entry> mPool;
1559fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1569fded232a9548a304e0145011df8849fba0dcda7Chris Craik    uint32_t mSize = 0;
1579fded232a9548a304e0145011df8849fba0dcda7Chris Craik    uint32_t mMaxSize;
1589fded232a9548a304e0145011df8849fba0dcda7Chris Craik}; // class OffscreenBufferCache
1599fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1609fded232a9548a304e0145011df8849fba0dcda7Chris Craik}; // namespace uirenderer
1619fded232a9548a304e0145011df8849fba0dcda7Chris Craik}; // namespace android
1629fded232a9548a304e0145011df8849fba0dcda7Chris Craik
1639fded232a9548a304e0145011df8849fba0dcda7Chris Craik#endif // ANDROID_HWUI_OFFSCREEN_BUFFER_POOL_H
164