138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck/*
238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck * Copyright (C) 2016 The Android Open Source Project
338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck *
438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck * Licensed under the Apache License, Version 2.0 (the "License");
538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck * you may not use this file except in compliance with the License.
638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck * You may obtain a copy of the License at
738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck *
838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck *      http://www.apache.org/licenses/LICENSE-2.0
938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck *
1038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck * Unless required by applicable law or agreed to in writing, software
1138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck * distributed under the License is distributed on an "AS IS" BASIS,
1238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck * See the License for the specific language governing permissions and
1438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck * limitations under the License.
1538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck */
1638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck#pragma once
1738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
1838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck#include <pthread.h>
1938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck#include <ostream>
2038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
2152eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <log/log.h>
2252eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn
2338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Recknamespace android {
2438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Recknamespace uirenderer {
2538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
2638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckextern pthread_t gGpuThread;
2738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
2838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck#define ASSERT_GPU_THREAD() LOG_ALWAYS_FATAL_IF( \
2938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        !pthread_equal(gGpuThread, pthread_self()), \
3038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        "Error, %p of type %d (size=%d) used on wrong thread! cur thread %lu " \
3138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        "!= gpu thread %lu", this, static_cast<int>(mType), mSize, \
3238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        pthread_self(), gGpuThread)
3338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
3438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckenum class GpuObjectType {
3538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    Texture = 0,
3638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    OffscreenBuffer,
3738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    Layer,
3838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
3938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    TypeCount,
4038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck};
4138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
4238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckclass GpuMemoryTracker {
4338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckpublic:
4438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    GpuObjectType objectType() { return mType; }
4538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    int objectSize() { return mSize; }
4638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
4745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel    static void onGpuContextCreated();
4845ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel    static void onGpuContextDestroyed();
4938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    static void dump();
5038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    static void dump(std::ostream& stream);
5138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    static int getInstanceCount(GpuObjectType type);
5238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    static int getTotalSize(GpuObjectType type);
5338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    static void onFrameCompleted();
5438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
5538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckprotected:
56a619ec70cf765d9166f0862e74653711b87307b3Chih-Hung Hsieh    explicit GpuMemoryTracker(GpuObjectType type) : mType(type) {
5738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        ASSERT_GPU_THREAD();
5838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        startTrackingObject();
5938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    }
6038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
6138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    ~GpuMemoryTracker() {
6238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        notifySizeChanged(0);
6338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        stopTrackingObject();
6438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    }
6538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
6638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    void notifySizeChanged(int newSize);
6738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
6838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckprivate:
6938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    void startTrackingObject();
7038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    void stopTrackingObject();
7138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
7238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    int mSize = 0;
7338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    GpuObjectType mType;
7438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck};
7538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
7638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck} // namespace uirenderer
7738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck} // namespace android;
78