| OLD | NEW |
| 1 // Copyright 2010 The Chromium Authors. All rights reserved. | 1 // Copyright 2010 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 #include "cc/output/gl_renderer.h" | 5 #include "cc/output/gl_renderer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <limits> | 11 #include <limits> |
| 12 #include <memory> | 12 #include <memory> |
| 13 #include <numeric> | 13 #include <numeric> |
| 14 #include <set> | 14 #include <set> |
| 15 #include <string> | 15 #include <string> |
| 16 #include <vector> | 16 #include <vector> |
| 17 | 17 |
| 18 #include "base/callback_helpers.h" |
| 18 #include "base/feature_list.h" | 19 #include "base/feature_list.h" |
| 19 #include "base/logging.h" | 20 #include "base/logging.h" |
| 20 #include "base/macros.h" | 21 #include "base/macros.h" |
| 21 #include "base/memory/ptr_util.h" | 22 #include "base/memory/ptr_util.h" |
| 22 #include "base/strings/string_split.h" | 23 #include "base/strings/string_split.h" |
| 23 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
| 24 #include "base/strings/stringprintf.h" | 25 #include "base/strings/stringprintf.h" |
| 25 #include "base/threading/thread_task_runner_handle.h" | 26 #include "base/threading/thread_task_runner_handle.h" |
| 26 #include "base/trace_event/trace_event.h" | 27 #include "base/trace_event/trace_event.h" |
| 27 #include "build/build_config.h" | 28 #include "build/build_config.h" |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 } | 147 } |
| 147 } | 148 } |
| 148 | 149 |
| 149 // Smallest unit that impact anti-aliasing output. We use this to | 150 // Smallest unit that impact anti-aliasing output. We use this to |
| 150 // determine when anti-aliasing is unnecessary. | 151 // determine when anti-aliasing is unnecessary. |
| 151 const float kAntiAliasingEpsilon = 1.0f / 1024.0f; | 152 const float kAntiAliasingEpsilon = 1.0f / 1024.0f; |
| 152 | 153 |
| 153 // Block or crash if the number of pending sync queries reach this high as | 154 // Block or crash if the number of pending sync queries reach this high as |
| 154 // something is seriously wrong on the service side if this happens. | 155 // something is seriously wrong on the service side if this happens. |
| 155 const size_t kMaxPendingSyncQueries = 16; | 156 const size_t kMaxPendingSyncQueries = 16; |
| 157 |
| 158 void ReadbackSwappedOverlayTexturesDone( |
| 159 gpu::gles2::GLES2Interface* gl, |
| 160 std::vector<GLuint> buffers, |
| 161 GLuint query, |
| 162 std::vector<SkBitmap>* bitmaps, |
| 163 const base::Callback<void(bool)>& callback) { |
| 164 TRACE_EVENT0("cc", "ReadbackSwappedOverlayTexturesDone"); |
| 165 |
| 166 DCHECK_EQ(buffers.size(), bitmaps->size()); |
| 167 for (size_t i = 0; i < buffers.size(); ++i) { |
| 168 gl->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, buffers[i]); |
| 169 uint8_t* data = static_cast<uint8_t*>(gl->MapBufferCHROMIUM( |
| 170 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY)); |
| 171 if (data) |
| 172 memcpy(bitmaps->at(i).getPixels(), data, bitmaps->at(i).getSize()); |
| 173 gl->UnmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM); |
| 174 gl->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); |
| 175 } |
| 176 gl->DeleteBuffers(buffers.size(), &buffers[0]); |
| 177 gl->DeleteQueriesEXT(1, &query); |
| 178 callback.Run(true); |
| 179 } |
| 180 |
| 156 } // anonymous namespace | 181 } // anonymous namespace |
| 157 | 182 |
| 158 // Parameters needed to draw a RenderPassDrawQuad. | 183 // Parameters needed to draw a RenderPassDrawQuad. |
| 159 struct DrawRenderPassDrawQuadParams { | 184 struct DrawRenderPassDrawQuadParams { |
| 160 DrawRenderPassDrawQuadParams() {} | 185 DrawRenderPassDrawQuadParams() {} |
| 161 ~DrawRenderPassDrawQuadParams() {} | 186 ~DrawRenderPassDrawQuadParams() {} |
| 162 | 187 |
| 163 // Required Inputs. | 188 // Required Inputs. |
| 164 const RenderPassDrawQuad* quad = nullptr; | 189 const RenderPassDrawQuad* quad = nullptr; |
| 165 const Resource* contents_texture = nullptr; | 190 const Resource* contents_texture = nullptr; |
| (...skipping 2583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2749 } | 2774 } |
| 2750 | 2775 |
| 2751 swapping_overlay_resources_.push_back(std::move(pending_overlay_resources_)); | 2776 swapping_overlay_resources_.push_back(std::move(pending_overlay_resources_)); |
| 2752 pending_overlay_resources_.clear(); | 2777 pending_overlay_resources_.clear(); |
| 2753 | 2778 |
| 2754 output_surface_->SwapBuffers(std::move(output_frame)); | 2779 output_surface_->SwapBuffers(std::move(output_frame)); |
| 2755 | 2780 |
| 2756 swap_buffer_rect_ = gfx::Rect(); | 2781 swap_buffer_rect_ = gfx::Rect(); |
| 2757 } | 2782 } |
| 2758 | 2783 |
| 2784 void GLRenderer::ReadbackSwappedOverlayTextures( |
| 2785 std::vector<SkBitmap>* bitmaps, |
| 2786 const base::Callback<void(bool)>& callback) { |
| 2787 TRACE_EVENT0("cc", "GLRenderer::RequestSwappedOverlayTextureSnapshot"); |
| 2788 |
| 2789 if (swapped_and_acked_overlay_resources_.empty()) { |
| 2790 callback.Run(false); |
| 2791 return; |
| 2792 } |
| 2793 |
| 2794 std::vector<GLuint> buffers(swapped_and_acked_overlay_resources_.size()); |
| 2795 gl_->GenBuffers(buffers.size(), &buffers[0]); |
| 2796 |
| 2797 GLuint fbo = 0; |
| 2798 gl_->GenFramebuffers(1, &fbo); |
| 2799 gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo); |
| 2800 |
| 2801 GLuint query = 0; |
| 2802 gl_->GenQueriesEXT(1, &query); |
| 2803 gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, query); |
| 2804 |
| 2805 DCHECK_EQ(bitmaps->size(), 0u); |
| 2806 for (auto& entry : swapped_and_acked_overlay_resources_) { |
| 2807 const OverlayResourceLock& overlay_resource = entry.second; |
| 2808 gfx::Size size = overlay_resource->size(); |
| 2809 bitmaps->resize(bitmaps->size() + 1); |
| 2810 bitmaps->back().allocN32Pixels(size.width(), size.height()); |
| 2811 std::unique_ptr<ScopedResource> texture = |
| 2812 ScopedResource::Create(resource_provider_); |
| 2813 texture->Allocate(size, ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888, |
| 2814 gfx::ColorSpace()); |
| 2815 ResourceProvider::ScopedWriteLockGL write_lock(resource_provider_, |
| 2816 texture->id(), false); |
| 2817 gl_->CopyTextureCHROMIUM(overlay_resource->texture_id(), 0, GL_TEXTURE_2D, |
| 2818 write_lock.texture_id(), 0, GL_RGBA, |
| 2819 GL_UNSIGNED_BYTE, false, false, false); |
| 2820 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 2821 write_lock.target(), write_lock.texture_id(), 0); |
| 2822 DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) == |
| 2823 GL_FRAMEBUFFER_COMPLETE); |
| 2824 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| 2825 buffers[bitmaps->size() - 1]); |
| 2826 gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| 2827 bitmaps->back().getSize(), nullptr, GL_STREAM_READ); |
| 2828 gl_->ReadPixels(0, 0, size.width(), size.height(), GL_RGBA, |
| 2829 GL_UNSIGNED_BYTE, nullptr); |
| 2830 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); |
| 2831 } |
| 2832 |
| 2833 gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM); |
| 2834 gl_->DeleteFramebuffers(1, &fbo); |
| 2835 |
| 2836 context_support_->SignalQuery( |
| 2837 query, base::Bind(&ReadbackSwappedOverlayTexturesDone, gl_, |
| 2838 std::move(buffers), query, bitmaps, callback)); |
| 2839 } |
| 2840 |
| 2759 void GLRenderer::SwapBuffersComplete() { | 2841 void GLRenderer::SwapBuffersComplete() { |
| 2842 // If a query is not needed to release the overlay buffers, we can assume |
| 2843 // that once a swap buffer has completed we can release the previously |
| 2844 // swapped buffers. |
| 2845 if (!settings_->release_overlay_resources_after_gpu_query) |
| 2846 swapped_and_acked_overlay_resources_.clear(); |
| 2847 |
| 2848 if (!swapping_overlay_resources_.empty()) { |
| 2849 for (OverlayResourceLock& lock : swapping_overlay_resources_.front()) { |
| 2850 unsigned texture = lock->texture_id(); |
| 2851 if (swapped_and_acked_overlay_resources_.find(texture) == |
| 2852 swapped_and_acked_overlay_resources_.end()) { |
| 2853 swapped_and_acked_overlay_resources_[texture] = std::move(lock); |
| 2854 } |
| 2855 } |
| 2856 swapping_overlay_resources_.pop_front(); |
| 2857 } |
| 2858 |
| 2760 if (settings_->release_overlay_resources_after_gpu_query) { | 2859 if (settings_->release_overlay_resources_after_gpu_query) { |
| 2761 // Once a resource has been swap-ACKed, send a query to the GPU process to | 2860 // Once a resource has been swap-ACKed, send a query to the GPU process to |
| 2762 // ask if the resource is no longer being consumed by the system compositor. | 2861 // ask if the resource is no longer being consumed by the system compositor. |
| 2763 // The response will come with the next swap-ACK. | 2862 // The response will come with the next swap-ACK. |
| 2764 if (!swapping_overlay_resources_.empty()) { | |
| 2765 for (OverlayResourceLock& lock : swapping_overlay_resources_.front()) { | |
| 2766 unsigned texture = lock->texture_id(); | |
| 2767 if (swapped_and_acked_overlay_resources_.find(texture) == | |
| 2768 swapped_and_acked_overlay_resources_.end()) { | |
| 2769 swapped_and_acked_overlay_resources_[texture] = std::move(lock); | |
| 2770 } | |
| 2771 } | |
| 2772 swapping_overlay_resources_.pop_front(); | |
| 2773 } | |
| 2774 | |
| 2775 if (!swapped_and_acked_overlay_resources_.empty()) { | 2863 if (!swapped_and_acked_overlay_resources_.empty()) { |
| 2776 std::vector<unsigned> textures; | 2864 std::vector<unsigned> textures; |
| 2777 textures.reserve(swapped_and_acked_overlay_resources_.size()); | 2865 textures.reserve(swapped_and_acked_overlay_resources_.size()); |
| 2778 for (auto& pair : swapped_and_acked_overlay_resources_) { | 2866 for (auto& pair : swapped_and_acked_overlay_resources_) { |
| 2779 textures.push_back(pair.first); | 2867 textures.push_back(pair.first); |
| 2780 } | 2868 } |
| 2781 gl_->ScheduleCALayerInUseQueryCHROMIUM(textures.size(), textures.data()); | 2869 gl_->ScheduleCALayerInUseQueryCHROMIUM(textures.size(), textures.data()); |
| 2782 } | 2870 } |
| 2783 } else if (swapping_overlay_resources_.size() > 1) { | |
| 2784 // If a query is not needed to release the overlay buffers, we can assume | |
| 2785 // that once a swap buffer has completed we can remove the oldest buffers | |
| 2786 // from the queue. | |
| 2787 swapping_overlay_resources_.pop_front(); | |
| 2788 } | 2871 } |
| 2789 } | 2872 } |
| 2790 | 2873 |
| 2791 void GLRenderer::DidReceiveTextureInUseResponses( | 2874 void GLRenderer::DidReceiveTextureInUseResponses( |
| 2792 const gpu::TextureInUseResponses& responses) { | 2875 const gpu::TextureInUseResponses& responses) { |
| 2793 DCHECK(settings_->release_overlay_resources_after_gpu_query); | 2876 DCHECK(settings_->release_overlay_resources_after_gpu_query); |
| 2794 for (const gpu::TextureInUseResponse& response : responses) { | 2877 for (const gpu::TextureInUseResponse& response : responses) { |
| 2795 if (!response.in_use) { | 2878 if (!response.in_use) { |
| 2796 swapped_and_acked_overlay_resources_.erase(response.texture); | 2879 swapped_and_acked_overlay_resources_.erase(response.texture); |
| 2797 } | 2880 } |
| (...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3588 return; | 3671 return; |
| 3589 | 3672 |
| 3590 // Report GPU overdraw as a percentage of |max_result|. | 3673 // Report GPU overdraw as a percentage of |max_result|. |
| 3591 TRACE_COUNTER1( | 3674 TRACE_COUNTER1( |
| 3592 TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"), "GPU Overdraw", | 3675 TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"), "GPU Overdraw", |
| 3593 (std::accumulate(overdraw->begin(), overdraw->end(), 0) * 100) / | 3676 (std::accumulate(overdraw->begin(), overdraw->end(), 0) * 100) / |
| 3594 max_result); | 3677 max_result); |
| 3595 } | 3678 } |
| 3596 | 3679 |
| 3597 } // namespace cc | 3680 } // namespace cc |
| OLD | NEW |