| /* |
| * Copyright (C) 2015 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 "memory_manager.h" |
| #include "replay_request.h" |
| #include "resource_provider.h" |
| #include "server_connection.h" |
| |
| #include <gapic/log.h> |
| |
| #include <string.h> |
| |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| namespace gapir { |
| |
| std::unique_ptr<ReplayRequest> ReplayRequest::create(const ServerConnection& gazer, |
| ResourceProvider* resourceProvider, |
| MemoryManager* memoryManager) { |
| GAPID_INFO("Load replay request...\n"); |
| |
| memoryManager->setReplayDataSize(gazer.replayLength()); |
| |
| // Request the replay data from the gazer connection |
| if (!resourceProvider->getUncached(gazer.replayId(), gazer, memoryManager->getReplayAddress(), |
| gazer.replayLength())) { |
| GAPID_WARNING("Can't load replay request: %s\n", gazer.replayId().c_str()); |
| return nullptr; |
| } |
| |
| std::unique_ptr<ReplayRequest> req(new ReplayRequest()); |
| if (req->load(memoryManager->getReplayAddress(), gazer.replayLength())) { |
| return req; |
| } else { |
| return nullptr; |
| } |
| } |
| |
| uint32_t ReplayRequest::getStackSize() const { |
| return mStackSize; |
| } |
| |
| uint32_t ReplayRequest::getVolatileMemorySize() const { |
| return mVolatileMemorySize; |
| } |
| |
| const std::vector<std::pair<std::string, uint32_t>>& ReplayRequest::getResources() const { |
| return mResources; |
| } |
| |
| const std::pair<const void*, uint32_t>& ReplayRequest::getConstantMemory() const { |
| return mConstantMemory; |
| } |
| |
| const std::pair<std::string, uint32_t>& ReplayRequest::getResourceData(uint32_t resourceIdx) const { |
| return mResources[resourceIdx]; |
| } |
| |
| const std::pair<const uint32_t*, uint32_t>& ReplayRequest::getInstructionList() const { |
| return mInstructionList; |
| } |
| |
| bool ReplayRequest::load(void* data, uint32_t size) { |
| // Parse the data fetched from the gazer connection |
| const uint8_t* ptr = static_cast<uint8_t*>(data); |
| ptr = loadStackSize(ptr); |
| ptr = loadVolatileMemorySize(ptr); |
| ptr = loadConstantMemory(ptr); |
| ptr = loadResourceIds(ptr); |
| ptr = loadInstructionList(ptr); |
| |
| GAPID_INFO("Replay request loaded\n"); |
| |
| return ptr - size == data; |
| } |
| |
| const uint8_t* ReplayRequest::loadVolatileMemorySize(const uint8_t* ptr) { |
| mVolatileMemorySize = *reinterpret_cast<const uint32_t*>(ptr); |
| ptr += sizeof(uint32_t); |
| GAPID_INFO("Volatile memory size: %d\n", mVolatileMemorySize); |
| return ptr; |
| } |
| |
| const uint8_t* ReplayRequest::loadStackSize(const uint8_t* ptr) { |
| mStackSize = *reinterpret_cast<const uint32_t*>(ptr); |
| ptr += sizeof(uint32_t); |
| GAPID_INFO("Stack size: %d\n", mStackSize); |
| return ptr; |
| } |
| |
| const uint8_t* ReplayRequest::loadConstantMemory(const uint8_t* ptr) { |
| uint32_t constantMemorySize = *reinterpret_cast<const uint32_t*>(ptr); |
| ptr += sizeof(uint32_t); |
| |
| mConstantMemory = {ptr, constantMemorySize}; |
| GAPID_INFO("Constant memory size: %d\n", constantMemorySize); |
| ptr += constantMemorySize; |
| |
| return ptr; |
| } |
| |
| const uint8_t* ReplayRequest::loadResourceIds(const uint8_t* ptr) { |
| uint32_t resourceCount = *reinterpret_cast<const uint32_t*>(ptr); |
| ptr += sizeof(uint32_t); |
| |
| mResources.reserve(resourceCount); |
| for (uint32_t i = 0; i < resourceCount; ++i) { |
| const std::string resourceName(reinterpret_cast<const char*>(ptr)); |
| ptr += resourceName.length() + 1; |
| |
| uint32_t resourceSize = *reinterpret_cast<const uint32_t*>(ptr); |
| ptr += sizeof(uint32_t); |
| |
| mResources.emplace_back(std::move(resourceName), resourceSize); |
| } |
| GAPID_INFO("Resources: %d\n", resourceCount); |
| |
| return ptr; |
| } |
| |
| const uint8_t* ReplayRequest::loadInstructionList(const uint8_t* ptr) { |
| uint32_t instructionListSize = *reinterpret_cast<const uint32_t*>(ptr); |
| ptr += sizeof(uint32_t); |
| |
| const uint32_t instructionCount = instructionListSize / sizeof(uint32_t); |
| mInstructionList = {reinterpret_cast<const uint32_t*>(ptr), instructionCount}; |
| GAPID_INFO("Instruction count: %d\n", instructionCount); |
| ptr += instructionListSize; |
| |
| return ptr; |
| } |
| |
| } // namespace gapir |