static void
android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
- android::uirenderer::renderthread::RenderProxy::outputLogBuffer(fd);
+ android::uirenderer::renderthread::RenderProxy::dumpGraphicsMemory(fd);
}
// ----------------------------------------------------------------------------
DisplayList.cpp \
DeferredDisplayList.cpp \
DeferredLayerUpdater.cpp \
- DisplayListLogBuffer.cpp \
DisplayListRenderer.cpp \
Dither.cpp \
DrawProfiler.cpp \
# Defaults for ATRACE_TAG and LOG_TAG for libhwui
LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\"
-LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter -Wunused -Wunreachable-code
+LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter -Wunreachable-code
DEFER_LOGD("%d replaying DrawBatch %p, with %d ops (batch id %x, merge id %p)",
index, this, mOps.size(), getBatchId(), getMergeId());
- DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
for (unsigned int i = 0; i < mOps.size(); i++) {
DrawOp* op = mOps[i].op;
const DeferredDisplayState* state = mOps[i].state;
#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
renderer.eventMark(op->name());
#endif
- logBuffer.writeCommand(0, op->name());
op->applyDraw(renderer, dirty);
#if DEBUG_MERGE_BEHAVIOR
renderer.setupMergedMultiDraw(mClipSideFlags ? &mClipRect : nullptr);
DrawOp* op = mOps[0].op;
- DisplayListLogBuffer& buffer = DisplayListLogBuffer::getInstance();
- buffer.writeCommand(0, "multiDraw");
- buffer.writeCommand(1, op->name());
-
#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
renderer.eventMark("multiDraw");
renderer.eventMark(op->name());
#include "Debug.h"
#include "DisplayList.h"
#include "DisplayListOp.h"
-#include "DisplayListLogBuffer.h"
namespace android {
namespace uirenderer {
+++ /dev/null
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "DisplayListLogBuffer.h"
-
-// BUFFER_SIZE size must be one more than a multiple of COMMAND_SIZE to ensure
-// that mStart always points at the next command, not just the next item
-#define NUM_COMMANDS 50
-#define BUFFER_SIZE ((NUM_COMMANDS) + 1)
-
-/**
- * DisplayListLogBuffer is a utility class which logs the most recent display
- * list operations in a circular buffer. The log is process-wide, because we
- * only care about the most recent operations, not the operations on a per-window
- * basis for a given activity. The purpose of the log is to provide more debugging
- * information in a bug report, by telling us not just where a process hung (which
- * generally is just reported as a stack trace at the Java level) or crashed, but
- * also what happened immediately before that hang or crash. This may help track down
- * problems in the native rendering code or driver interaction related to the display
- * list operations that led up to the hang or crash.
- *
- * The log is implemented as a circular buffer for both space and performance
- * reasons - we only care about the last several operations to give us context
- * leading up to the problem, and we don't want to constantly copy data around or do
- * additional mallocs to keep the most recent operations logged. Only numbers are
- * logged to make the operation fast. If and when the log is output, we process this
- * data into meaningful strings.
- *
- * There is an assumption about the format of the command (currently 2 ints: the
- * opcode and the nesting level). If the type of information logged changes (for example,
- * we may want to save a timestamp), then the size of the buffer and the way the
- * information is recorded in writeCommand() should change to suit.
- */
-
-namespace android {
-
-using namespace uirenderer;
-ANDROID_SINGLETON_STATIC_INSTANCE(DisplayListLogBuffer);
-
-namespace uirenderer {
-
-
-DisplayListLogBuffer::DisplayListLogBuffer() {
- mBufferFirst = (OpLog*) malloc(BUFFER_SIZE * sizeof(OpLog));
- mStart = mBufferFirst;
- mBufferLast = mBufferFirst + BUFFER_SIZE - 1;
- mEnd = mStart;
-}
-
-DisplayListLogBuffer::~DisplayListLogBuffer() {
- free(mBufferFirst);
-}
-
-/**
- * Called from DisplayListRenderer to output the current buffer into the
- * specified FILE. This only happens in a dumpsys/bugreport operation.
- */
-void DisplayListLogBuffer::outputCommands(FILE *file)
-{
- OpLog* tmpBufferPtr = mStart;
- while (true) {
- if (tmpBufferPtr == mEnd) {
- break;
- }
-
- fprintf(file, "%*s%s\n", 2 * tmpBufferPtr->level, "", tmpBufferPtr->label);
-
- tmpBufferPtr++;
- if (tmpBufferPtr > mBufferLast) {
- tmpBufferPtr = mBufferFirst;
- }
- }
-}
-
-/**
- * Store the given level and label in the buffer and increment/wrap the mEnd
- * and mStart values as appropriate. Label should point to static memory.
- */
-void DisplayListLogBuffer::writeCommand(int level, const char* label) {
- mEnd->level = level;
- mEnd->label = label;
-
- if (mEnd == mBufferLast) {
- mEnd = mBufferFirst;
- } else {
- mEnd++;
- }
- if (mEnd == mStart) {
- mStart++;
- if (mStart > mBufferLast) {
- mStart = mBufferFirst;
- }
- }
-}
-
-}; // namespace uirenderer
-}; // namespace android
+++ /dev/null
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_DISPLAY_LIST_LOG_BUFFER_H
-#define ANDROID_HWUI_DISPLAY_LIST_LOG_BUFFER_H
-
-#include <utils/Singleton.h>
-
-#include <stdio.h>
-
-namespace android {
-namespace uirenderer {
-
-class DisplayListLogBuffer: public Singleton<DisplayListLogBuffer> {
- DisplayListLogBuffer();
- ~DisplayListLogBuffer();
-
- friend class Singleton<DisplayListLogBuffer>;
-
-public:
- void writeCommand(int level, const char* label);
- void outputCommands(FILE *file);
-
- bool isEmpty() {
- return (mStart == mEnd);
- }
-
- struct OpLog {
- int level;
- const char* label;
- };
-
-private:
- OpLog* mBufferFirst; // where the memory starts
- OpLog* mStart; // where the current command stream starts
- OpLog* mEnd; // where the current commands end
- OpLog* mBufferLast; // where the buffer memory ends
-
-};
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_DISPLAY_LIST_LOG_BUFFER_H
#include "ResourceCache.h"
#include "DeferredDisplayList.h"
#include "DeferredLayerUpdater.h"
-#include "DisplayListLogBuffer.h"
#include "DisplayListOp.h"
#include "DisplayListRenderer.h"
#include "RenderNode.h"
#include "Canvas.h"
#include "CanvasState.h"
#include "DisplayList.h"
-#include "DisplayListLogBuffer.h"
#include "RenderNode.h"
#include "Renderer.h"
#include "ResourceCache.h"
#include "DamageAccumulator.h"
#include "Debug.h"
#include "DisplayListOp.h"
-#include "DisplayListLogBuffer.h"
#include "LayerRenderer.h"
#include "OpenGLRenderer.h"
#include "TreeInfo.h"
namespace android {
namespace uirenderer {
-void RenderNode::outputLogBuffer(int fd) {
- DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
- if (logBuffer.isEmpty()) {
- return;
- }
-
- FILE *file = fdopen(fd, "a");
-
- fprintf(file, "\nRecent DisplayList operations\n");
- logBuffer.outputCommands(file);
-
- if (Caches::hasInstance()) {
- String8 cachesLog;
- Caches::getInstance().dumpMemoryUsage(cachesLog);
- fprintf(file, "\nCaches:\n%s\n", cachesLog.string());
- } else {
- fprintf(file, "\nNo caches instance.\n");
- }
-
- fflush(file);
-}
-
void RenderNode::debugDumpLayers(const char* prefix) {
if (mLayer) {
ALOGD("%sNode %p (%s) has layer %p (fbo = %u, wasBuildLayered = %s)",
} else {
const int saveCountOffset = renderer.getSaveCount() - 1;
const int projectionReceiveIndex = mDisplayListData->projectionReceiveIndex;
- DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
for (size_t chunkIndex = 0; chunkIndex < mDisplayListData->getChunks().size(); chunkIndex++) {
const DisplayListData::Chunk& chunk = mDisplayListData->getChunks()[chunkIndex];
#if DEBUG_DISPLAY_LIST
op->output(level + 1);
#endif
- logBuffer.writeCommand(level, op->name());
handler(op, saveCountOffset, properties().getClipToBounds());
if (CC_UNLIKELY(!mProjectedNodes.isEmpty() && projectionReceiveIndex >= 0 &&
postAndWait(task);
}
-CREATE_BRIDGE1(outputLogBuffer, int fd) {
- RenderNode::outputLogBuffer(args->fd);
+CREATE_BRIDGE1(dumpGraphicsMemory, int fd) {
+ FILE *file = fdopen(args->fd, "a");
+ if (Caches::hasInstance()) {
+ String8 cachesLog;
+ Caches::getInstance().dumpMemoryUsage(cachesLog);
+ fprintf(file, "\nCaches:\n%s\n", cachesLog.string());
+ } else {
+ fprintf(file, "\nNo caches instance.\n");
+ }
+ fflush(file);
return nullptr;
}
-void RenderProxy::outputLogBuffer(int fd) {
- SETUP_TASK(outputLogBuffer);
+void RenderProxy::dumpGraphicsMemory(int fd) {
+ SETUP_TASK(dumpGraphicsMemory);
args->fd = fd;
staticPostAndWait(task);
}
ANDROID_API void notifyFramePending();
ANDROID_API void dumpProfileInfo(int fd);
- ANDROID_API static void outputLogBuffer(int fd);
+ ANDROID_API static void dumpGraphicsMemory(int fd);
ANDROID_API void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size);