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

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: Fix a bad return in DoCommand(). 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
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 DVLOG(1) << "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 DVLOG(1) << "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 // TODO(gman): If you want to log errors this is the best place to catch them.
70 // It seems like we need an official way to turn on a debug mode and
71 // get these errors.
72 if (error::IsError(result)) {
73 ReportError(header.command, result);
74 }
75
76 // If get was not set somewhere else advance it.
77 if (get == get_ && result != error::kDeferCommandUntilLater)
78 get_ = (get + header.size) % entry_count_;
79 57
80 return result; 58 return result;
81 } 59 }
82 60
83 void CommandParser::ReportError(unsigned int command_id, 61 void CommandParser::ReportError(unsigned int command_id,
84 error::Error result) { 62 error::Error result) {
85 DVLOG(1) << "Error: " << result << " for Command " 63 DVLOG(1) << "Error: " << result << " for Command "
86 << handler_->GetCommandName(command_id); 64 << handler_->GetCommandName(command_id);
87 } 65 }
88 66
89 // Processes all the commands, while the buffer is not empty. Stop if an error 67 // Processes all the commands, while the buffer is not empty. Stop if an error
90 // is encountered. 68 // is encountered.
91 error::Error CommandParser::ProcessAllCommands() { 69 error::Error CommandParser::ProcessAllCommands() {
92 while (!IsEmpty()) { 70 while (!IsEmpty()) {
93 error::Error error = ProcessCommand(); 71 error::Error error = ProcessCommands(kParseCommandsSlice);
94 if (error) 72 if (error)
95 return error; 73 return error;
96 } 74 }
97 return error::kNoError; 75 return error::kNoError;
98 } 76 }
99 77
78 // Decode multiple commands, and call the corresponding GL functions.
79 // NOTE: buffer is a pointer to the command buffer. As such, it could be
80 // changed by a (malicious) client at any time, so if validation has to happen,
81 // it should operate on a copy of them.
82 error::Error AsyncAPIInterface::DoCommands(unsigned int num_commands,
83 const void* buffer,
84 int num_entries,
85 int* entries_processed) {
86 int commands_to_process = num_commands;
87 error::Error result = error::kNoError;
88 const CommandBufferEntry* cmd_data =
89 static_cast<const CommandBufferEntry*>(buffer);
90 int process_pos = 0;
91
92 while (process_pos < num_entries && result == error::kNoError &&
93 commands_to_process--) {
94 CommandHeader header = cmd_data->value_header;
95 if (header.size == 0) {
96 DVLOG(1) << "Error: zero sized command in command buffer";
97 return error::kInvalidSize;
98 }
99
100 if (static_cast<int>(header.size) + process_pos > num_entries) {
101 DVLOG(1) << "Error: get offset out of bounds";
102 return error::kOutOfBounds;
103 }
104
105 const unsigned int command = header.command;
106 const unsigned int arg_count = header.size - 1;
107
108 result = DoCommand(command, arg_count, cmd_data);
109
110 if (result != error::kDeferCommandUntilLater) {
111 process_pos += header.size;
112 cmd_data += header.size;
113 }
114 }
115
116 if (entries_processed)
117 *entries_processed = process_pos;
118
119 return result;
120 }
121
100 } // namespace gpu 122 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698