Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: gpu/command_buffer/service/cmd_parser.cc

Issue 558513003: command_buffer: Batch command processing to reduce handler overheads. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gpu/command_buffer/service/cmd_parser.h ('k') | gpu/command_buffer/service/cmd_parser_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file contains the implementation of the command parser. 5 // This file contains the implementation of the command parser.
6 6
7 #include "gpu/command_buffer/service/cmd_parser.h" 7 #include "gpu/command_buffer/service/cmd_parser.h"
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 26 matching lines...) Expand all
37 entry_count_ = size / 4; 37 entry_count_ = size / 4;
38 } 38 }
39 39
40 // Process one command, reading the header from the command buffer, and 40 // Process one command, reading the header from the command buffer, and
41 // forwarding the command index and the arguments to the handler. 41 // forwarding the command index and the arguments to the handler.
42 // Note that: 42 // Note that:
43 // - validation needs to happen on a copy of the data (to avoid race 43 // - validation needs to happen on a copy of the data (to avoid race
44 // conditions). This function only validates the header, leaving the arguments 44 // conditions). This function only validates the header, leaving the arguments
45 // validation to the handler, so it can pass a reference to them. 45 // validation to the handler, so it can pass a reference to them.
46 // - get_ is modified *after* the command has been executed. 46 // - get_ is modified *after* the command has been executed.
47 error::Error CommandParser::ProcessCommand() { 47 error::Error CommandParser::ProcessCommands(int num_commands) {
48 CommandBufferOffset get = get_; 48 int num_entries = put_ < get_ ? entry_count_ - get_ : put_ - get_;
49 if (get == put_) 49 int entries_processed = 0;
50 return error::kNoError;
51 50
52 CommandHeader header = buffer_[get].value_header; 51 error::Error result = handler_->DoCommands(
53 if (header.size == 0) { 52 num_commands, buffer_ + get_, num_entries, &entries_processed);
54 LOG(ERROR) << "Parse error: zero sized command in command buffer";
55 return error::kInvalidSize;
56 }
57 53
58 if (static_cast<int>(header.size) + get > entry_count_) { 54 get_ += entries_processed;
59 LOG(ERROR) << "Parse error: get offset out of bounds"; 55 if (get_ == entry_count_)
60 return error::kOutOfBounds; 56 get_ = 0;
61 }
62
63 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
64 handler_->GetCommandName(header.command));
65
66 error::Error result = handler_->DoCommand(
67 header.command, header.size - 1, buffer_ + get);
68
69 if (error::IsError(result)) {
70 ReportError(header.command, result);
71 }
72
73 // If get was not set somewhere else advance it.
74 if (get == get_ && result != error::kDeferCommandUntilLater)
75 get_ = (get + header.size) % entry_count_;
76 57
77 return result; 58 return result;
78 } 59 }
79 60
80 void CommandParser::ReportError(unsigned int command_id,
81 error::Error result) {
82 LOG(ERROR) << "Error: " << result << " for Command "
83 << handler_->GetCommandName(command_id);
84 }
85
86 // Processes all the commands, while the buffer is not empty. Stop if an error 61 // Processes all the commands, while the buffer is not empty. Stop if an error
87 // is encountered. 62 // is encountered.
88 error::Error CommandParser::ProcessAllCommands() { 63 error::Error CommandParser::ProcessAllCommands() {
89 while (!IsEmpty()) { 64 while (!IsEmpty()) {
90 error::Error error = ProcessCommand(); 65 error::Error error = ProcessCommands(kParseCommandsSlice);
91 if (error) 66 if (error)
92 return error; 67 return error;
93 } 68 }
94 return error::kNoError; 69 return error::kNoError;
95 } 70 }
96 71
72 // Decode multiple commands, and call the corresponding GL functions.
73 // NOTE: buffer is a pointer to the command buffer. As such, it could be
74 // changed by a (malicious) client at any time, so if validation has to happen,
75 // it should operate on a copy of them.
76 error::Error AsyncAPIInterface::DoCommands(unsigned int num_commands,
77 const void* buffer,
78 int num_entries,
79 int* entries_processed) {
80 int commands_to_process = num_commands;
81 error::Error result = error::kNoError;
82 const CommandBufferEntry* cmd_data =
83 static_cast<const CommandBufferEntry*>(buffer);
84 int process_pos = 0;
85
86 while (process_pos < num_entries && result == error::kNoError &&
87 commands_to_process--) {
88 CommandHeader header = cmd_data->value_header;
89 if (header.size == 0) {
90 DVLOG(1) << "Error: zero sized command in command buffer";
91 return error::kInvalidSize;
92 }
93
94 if (static_cast<int>(header.size) + process_pos > num_entries) {
95 DVLOG(1) << "Error: get offset out of bounds";
96 return error::kOutOfBounds;
97 }
98
99 const unsigned int command = header.command;
100 const unsigned int arg_count = header.size - 1;
101
102 result = DoCommand(command, arg_count, cmd_data);
103
104 if (result != error::kDeferCommandUntilLater) {
105 process_pos += header.size;
106 cmd_data += header.size;
107 }
108 }
109
110 if (entries_processed)
111 *entries_processed = process_pos;
112
113 return result;
114 }
115
97 } // namespace gpu 116 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/cmd_parser.h ('k') | gpu/command_buffer/service/cmd_parser_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698