Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GLES2 2d Batch rendering (across items) #37349

Merged
merged 7 commits into from
Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,27 @@
<member name="rendering/environment/default_environment" type="String" setter="" getter="" default="&quot;&quot;">
[Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, it is best to delete [code]default_env.tres[/code], or to specify a different default environment here.
</member>
<member name="rendering/gles2/batching/batch_buffer_size" type="int" setter="" getter="" default="16384">
Size of buffer reserved for batched vertices. Larger size enables larger batches, but there are diminishing returns for the memory used.
</member>
<member name="rendering/gles2/batching/colored_vertex_format_threshold" type="float" setter="" getter="" default="0.25">
Including color in the vertex format has a cost, however, not including color prevents batching across color changes. This threshold determines the ratio of [code]number of vertex color changes / total number of vertices[/code] above which vertices will be translated to colored format. A value of 0 will always use colored vertices, 1 will never use colored vertices.
</member>
<member name="rendering/gles2/batching/light_scissor_area_threshold" type="float" setter="" getter="" default="1.0">
Sets the proportion of the screen area that must be saved by a scissor operation in order to activate light scissoring. This can prevent parts of items being rendered outside the light area. Lower values scissor more aggressively. A value of 1 scissors none of the items, a value of 0 scissors every item. This can reduce fill rate requirements in scenes with a lot of lighting.
</member>
<member name="rendering/gles2/batching/max_join_item_commands" type="int" setter="" getter="" default="16">
Sets the number of commands to lookahead to determine whether to batch render items. A value of 1 can join items consisting of single commands, 0 turns off joining. Higher values are in theory more likely to join, however this has diminishing returns and has a runtime cost so a small value is recommended.
</member>
<member name="rendering/gles2/batching/use_batching" type="bool" setter="" getter="" default="true">
Turns batching on and off. Batching increases performance by reducing the amount of graphics API drawcalls.
</member>
<member name="rendering/gles2/debug/flash_batching" type="bool" setter="" getter="" default="false">
[b]Experimental[/b] For regression testing against the old renderer. If this is switched on, and [code]use_batching[/code] is set, the renderer will swap alternately between using the old renderer, and the batched renderer, on each frame. This makes it easy to identify visual differences. Performance will be degraded.
</member>
<member name="rendering/gles2/debug/use_batching_in_editor" type="bool" setter="" getter="" default="false">
[b]Experimental[/b] Switches on batching within the editor. Use with caution - note that if your editor does not render correctly you may need to edit your [code]project.godot[/code] and remove the use_batching_in_editor setting manually.
</member>
<member name="rendering/limits/buffers/blend_shape_max_buffer_size_kb" type="int" setter="" getter="" default="4096">
Max buffer size for blend shapes. Any blend shape bigger than this will not work.
</member>
Expand Down
190 changes: 190 additions & 0 deletions drivers/gles2/rasterizer_array_gles2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#pragma once

/*************************************************************************/
/* rasterizer_array_gles2.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/

/**
* Fast single-threaded growable array for POD types.
* For use in render drivers, not for general use.
* TO BE REPLACED by local_vector.
*/

#include "core/os/memory.h"
#include "core/vector.h"

#include <string.h>

template <class T>
class RasterizerArrayGLES2 {
public:
RasterizerArrayGLES2() {
_list = 0;
_size = 0;
_max_size = 0;
}
~RasterizerArrayGLES2() { free(); }

_FORCE_INLINE_ T &operator[](unsigned int ui) { return _list[ui]; }
_FORCE_INLINE_ const T &operator[](unsigned int ui) const { return _list[ui]; }

void free() {
if (_list) {
memdelete_arr(_list);
_list = 0;
}
_size = 0;
_max_size = 0;
}

void create(int p_size) {
free();
if (p_size) {
_list = memnew_arr(T, p_size);
}
_size = 0;
_max_size = p_size;
}

_FORCE_INLINE_ void reset() { _size = 0; }

_FORCE_INLINE_ T *request_with_grow() {
T *p = request();
if (!p) {
grow();
return request_with_grow();
}
return p;
}

// none of that inefficient pass by value stuff here, thanks
_FORCE_INLINE_ T *request() {
if (_size < _max_size) {
return &_list[_size++];
}
return 0;
}

// several items at a time
_FORCE_INLINE_ T *request(int p_num_items) {
int old_size = _size;
_size += p_num_items;

if (_size <= _max_size) {
return &_list[old_size];
}

// revert
_size = old_size;
return 0;
}

_FORCE_INLINE_ int size() const { return _size; }
_FORCE_INLINE_ int max_size() const { return _max_size; }
_FORCE_INLINE_ const T *get_data() const { return _list; }

bool copy_from(const RasterizerArrayGLES2<T> &o) {
// no resizing done here, it should be done manually
if (o.size() > _max_size)
return false;

// pod types only please!
memcpy(_list, o.get_data(), o.size() * sizeof(T));
_size = o.size();
return true;
}

// if you want this to be cheap, call reset before grow,
// to ensure there is no data to copy
void grow() {
unsigned int new_max_size = _max_size * 2;
if (!new_max_size)
new_max_size = 1;

T *new_list = memnew_arr(T, new_max_size);

// copy .. pod types only
if (_list) {
memcpy(new_list, _list, _size * sizeof(T));
}

unsigned int new_size = size();
free();
_list = new_list;
_size = new_size;
_max_size = new_max_size;
}

private:
T *_list;
int _size;
int _max_size;
};

template <class T>
class RasterizerArray_non_pod_GLES2 {
public:
RasterizerArray_non_pod_GLES2() {
_size = 0;
}

const T &operator[](unsigned int ui) const { return _list[ui]; }

void create(int p_size) {
_list.resize(p_size);
_size = 0;
}
void reset() { _size = 0; }

void push_back(const T &val) {
while (true) {
if (_size < max_size()) {
_list.set(_size, val);
_size++;
return;
}

grow();
}
}

int size() const { return _size; }
int max_size() const { return _list.size(); }

private:
void grow() {
unsigned int new_max_size = _list.size() * 2;
if (!new_max_size)
new_max_size = 1;
_list.resize(new_max_size);
}

Vector<T> _list;
int _size;
};
Loading