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 <cutils/log.h>
1938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck#include <pthread.h>
2038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck#include <ostream>
2138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
2238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Recknamespace android {
2338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Recknamespace uirenderer {
2438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
2538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckextern pthread_t gGpuThread;
2638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
2738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck#define ASSERT_GPU_THREAD() LOG_ALWAYS_FATAL_IF( \
2838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        !pthread_equal(gGpuThread, pthread_self()), \
2938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        "Error, %p of type %d (size=%d) used on wrong thread! cur thread %lu " \
3038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        "!= gpu thread %lu", this, static_cast<int>(mType), mSize, \
3138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        pthread_self(), gGpuThread)
3238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
3338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckenum class GpuObjectType {
3438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    Texture = 0,
3538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    OffscreenBuffer,
3638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    Layer,
3738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
3838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    TypeCount,
3938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck};
4038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
4138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckclass GpuMemoryTracker {
4238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckpublic:
4338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    GpuObjectType objectType() { return mType; }
4438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    int objectSize() { return mSize; }
4538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
4638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    static void onGLContextCreated();
4738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    static void onGLContextDestroyed();
4838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    static void dump();
4938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    static void dump(std::ostream& stream);
5038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    static int getInstanceCount(GpuObjectType type);
5138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    static int getTotalSize(GpuObjectType type);
5238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    static void onFrameCompleted();
5338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
5438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckprotected:
5538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    GpuMemoryTracker(GpuObjectType type) : mType(type) {
5638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        ASSERT_GPU_THREAD();
5738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        startTrackingObject();
5838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    }
5938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
6038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    ~GpuMemoryTracker() {
6138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        notifySizeChanged(0);
6238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        stopTrackingObject();
6338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    }
6438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
6538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    void notifySizeChanged(int newSize);
6638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
6738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckprivate:
6838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    void startTrackingObject();
6938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    void stopTrackingObject();
7038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
7138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    int mSize = 0;
7238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    GpuObjectType mType;
7338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck};
7438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
7538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck} // namespace uirenderer
7638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck} // namespace android;
77