|
|
Chromium Code Reviews|
Created:
4 years, 5 months ago by xinghua.cao Modified:
4 years, 5 months ago Base URL:
https://chromium.googlesource.com/chromium/src.git@master Target Ref:
refs/pending/heads/master Project:
chromium Visibility:
Public. |
DescriptionOcclusion query feature is already in GL ES3.0 spec, not an extension.
BUG=623871
CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_optional_gpu_tests_rel;tryserver.chromium.mac:mac_optional_gpu_tests_rel;tryserver.chromium.win:win_optional_gpu_tests_rel
Committed: https://crrev.com/2794a38ac40872a43fba5590297ef85ced1297b4
Cr-Commit-Position: refs/heads/master@{#404357}
Patch Set 1 #Patch Set 2 : logical error #
Total comments: 5
Patch Set 3 : Address ken's comments #
Total comments: 4
Patch Set 4 : Address ken's commments, and add a unit test #
Total comments: 3
Patch Set 5 : Address zhenyao's comments #Patch Set 6 : unit test cases fail #
Total comments: 1
Messages
Total messages: 53 (17 generated)
Description was changed from ========== Occlusion query feature is already in GL ES3.0 spec, not an extension. BUG= ========== to ========== Occlusion query feature is already in GL ES3.0 spec, not an extension. BUG= CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_optional_gpu_tests_rel;tryserver.chromium.mac:mac_optional_gpu_tests_rel;tryserver.chromium.win:win_optional_gpu_tests_rel ==========
Description was changed from ========== Occlusion query feature is already in GL ES3.0 spec, not an extension. BUG= CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_optional_gpu_tests_rel;tryserver.chromium.mac:mac_optional_gpu_tests_rel;tryserver.chromium.win:win_optional_gpu_tests_rel ========== to ========== Occlusion query feature is already in GL ES3.0 spec, not an extension. BUG=623871 CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_optional_gpu_tests_rel;tryserver.chromium.mac:mac_optional_gpu_tests_rel;tryserver.chromium.win:win_optional_gpu_tests_rel ==========
xinghua.cao@intel.com changed reviewers: + qiankun.miao@intel.com, yunchao.he@intel.com
xinghua.cao@intel.com changed reviewers: + kbr@chromium.org, zmo@chromium.org
https://codereview.chromium.org/2103773002/diff/20001/gpu/command_buffer/serv... File gpu/command_buffer/service/feature_info.cc (right): https://codereview.chromium.org/2103773002/diff/20001/gpu/command_buffer/serv... gpu/command_buffer/service/feature_info.cc:1056: On mesa+i965 platform, supports OpenGL ES 3.1, it has not any extension of GL_EXT_occlusion_query_boolean, GL_ARB_occlusion_query2, GL_ARB_occlusion_query. So the query feature cannot work correctly in command buffer, but I think it is standard feature for ES3.0. If driver version is above ES3.0 (or high OpenGL version), occlusion_query_boolean should be true.
https://codereview.chromium.org/2103773002/diff/20001/gpu/command_buffer/serv... File gpu/command_buffer/service/feature_info.cc (right): https://codereview.chromium.org/2103773002/diff/20001/gpu/command_buffer/serv... gpu/command_buffer/service/feature_info.cc:1059: } I think you need to be more careful in these settings here. If it's ES3Capable, you should set occlusion_qerry_boolean and use_arb_occlusion_query_for_occlusion_query_boolean to true, and use_arb_occlusion_query2_for_occlusion_query_boolean remains false. else, then you need to set the above three bools and do the if block below.
https://codereview.chromium.org/2103773002/diff/20001/gpu/command_buffer/serv... File gpu/command_buffer/service/feature_info.cc (right): https://codereview.chromium.org/2103773002/diff/20001/gpu/command_buffer/serv... gpu/command_buffer/service/feature_info.cc:1059: } On 2016/06/28 17:59:05, Zhenyao Mo wrote: > I think you need to be more careful in these settings here. > > If it's ES3Capable, you should set occlusion_qerry_boolean and > use_arb_occlusion_query_for_occlusion_query_boolean to true, and > use_arb_occlusion_query2_for_occlusion_query_boolean remains false. else, then > you need to set the above three bools and do the if block below. Not sure about that. Is Intel's driver OpenGL ES rather than OpenGL? There should probably be a new bool "have_es3_occlusion_query" and it should be integrated into the block below. It should be predicated not on IsES3Capable(), but rather on something like gl_version_info().IsAtLeastGLES(3, 0).
https://codereview.chromium.org/2103773002/diff/20001/gpu/command_buffer/serv... File gpu/command_buffer/service/feature_info.cc (right): https://codereview.chromium.org/2103773002/diff/20001/gpu/command_buffer/serv... gpu/command_buffer/service/feature_info.cc:1059: } On 2016/06/28 23:58:59, Ken Russell wrote: > On 2016/06/28 17:59:05, Zhenyao Mo wrote: > > I think you need to be more careful in these settings here. > > > > If it's ES3Capable, you should set occlusion_qerry_boolean and > > use_arb_occlusion_query_for_occlusion_query_boolean to true, and > > use_arb_occlusion_query2_for_occlusion_query_boolean remains false. else, then > > you need to set the above three bools and do the if block below. > > Not sure about that. Is Intel's driver OpenGL ES rather than OpenGL? > > There should probably be a new bool "have_es3_occlusion_query" and it should be > integrated into the block below. It should be predicated not on IsES3Capable(), > but rather on something like gl_version_info().IsAtLeastGLES(3, 0). My original suggestion was to always map to the ES3 semantics whenever possible. Ken's idea should work too. Probably safer than mine.
https://codereview.chromium.org/2103773002/diff/20001/gpu/command_buffer/serv... File gpu/command_buffer/service/feature_info.cc (right): https://codereview.chromium.org/2103773002/diff/20001/gpu/command_buffer/serv... gpu/command_buffer/service/feature_info.cc:1059: } On 2016/06/29 00:39:44, Zhenyao Mo wrote: > On 2016/06/28 23:58:59, Ken Russell wrote: > > On 2016/06/28 17:59:05, Zhenyao Mo wrote: > > > I think you need to be more careful in these settings here. > > > > > > If it's ES3Capable, you should set occlusion_qerry_boolean and > > > use_arb_occlusion_query_for_occlusion_query_boolean to true, and > > > use_arb_occlusion_query2_for_occlusion_query_boolean remains false. else, > then > > > you need to set the above three bools and do the if block below. > > > > Not sure about that. Is Intel's driver OpenGL ES rather than OpenGL? > > > > There should probably be a new bool "have_es3_occlusion_query" and it should > be > > integrated into the block below. It should be predicated not on > IsES3Capable(), > > but rather on something like gl_version_info().IsAtLeastGLES(3, 0). > > My original suggestion was to always map to the ES3 semantics whenever possible. > Ken's idea should work too. Probably safer than mine. It is Intel's driver OpenGL ES. I had changed it, please help to reivew it again, thank you.
lgtm
Sorry, one more comment. Also, could you please add a unit test for this change? https://codereview.chromium.org/2103773002/diff/40001/gpu/command_buffer/serv... File gpu/command_buffer/service/feature_info.cc (right): https://codereview.chromium.org/2103773002/diff/40001/gpu/command_buffer/serv... gpu/command_buffer/service/feature_info.cc:1063: AddExtensionString("GL_EXT_occlusion_query_boolean"); Do we want to add this extension string if we are advertising an ES 3.0 context? I would think it should only be advetised for ES 2.0 contexts.
https://codereview.chromium.org/2103773002/diff/40001/gpu/command_buffer/serv... File gpu/command_buffer/service/feature_info.cc (right): https://codereview.chromium.org/2103773002/diff/40001/gpu/command_buffer/serv... gpu/command_buffer/service/feature_info.cc:1057: gl_version_info_->IsAtLeastGLES(3, 0); This CL is used to fix crbug 623871, I think you can add the condition "feature_info_->IsES3Enabled()" to HandleBeginQueryEXT against the target GL_ANY_SAMPLES_PASSED. Just like what the code do for target GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN. The code revision here is not necessary. The code here introduce query as an extension for ES2 context. but query is already a core feature in ES3, we don't need to introduce query as en extension to ES3 context. WDYT?
https://codereview.chromium.org/2103773002/diff/40001/gpu/command_buffer/serv... File gpu/command_buffer/service/feature_info.cc (right): https://codereview.chromium.org/2103773002/diff/40001/gpu/command_buffer/serv... gpu/command_buffer/service/feature_info.cc:1057: gl_version_info_->IsAtLeastGLES(3, 0); On 2016/07/04 02:22:39, yunchao wrote: > This CL is used to fix crbug 623871, I think you can add the condition > "feature_info_->IsES3Enabled()" to HandleBeginQueryEXT against the target > GL_ANY_SAMPLES_PASSED. Just like what the code do for target > GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN. > The code revision here is not necessary. The code here introduce query as an > extension for ES2 context. but query is already a core feature in ES3, we don't > need to introduce query as en extension to ES3 context. WDYT? Yunchao, thanks for your comment. I still think that we should export "occlusion_query_boolean = true" when context is ES3. It can also be used when client call GetCapabilities function. Ken & zhenyao, what do you think? https://codereview.chromium.org/2103773002/diff/40001/gpu/command_buffer/serv... gpu/command_buffer/service/feature_info.cc:1063: AddExtensionString("GL_EXT_occlusion_query_boolean"); On 2016/06/29 22:29:56, Ken Russell wrote: > Do we want to add this extension string if we are advertising an ES 3.0 context? > I would think it should only be advetised for ES 2.0 contexts. Done.
https://codereview.chromium.org/2103773002/diff/60001/gpu/command_buffer/serv... File gpu/command_buffer/service/feature_info.cc (right): https://codereview.chromium.org/2103773002/diff/60001/gpu/command_buffer/serv... gpu/command_buffer/service/feature_info.cc:1060: if (have_ext_occlusion_query_boolean || You should use context_type_ is ES3 or WEBGL2 here. Even if we are on top of ES3, extension names may still be included in the EXTENSIONS string.
https://codereview.chromium.org/2103773002/diff/60001/gpu/command_buffer/serv... File gpu/command_buffer/service/feature_info.cc (right): https://codereview.chromium.org/2103773002/diff/60001/gpu/command_buffer/serv... gpu/command_buffer/service/feature_info.cc:1060: if (have_ext_occlusion_query_boolean || On 2016/07/04 16:06:05, Zhenyao Mo wrote: > You should use context_type_ is ES3 or WEBGL2 here. > > Even if we are on top of ES3, extension names may still be included in the > EXTENSIONS string. Zhenyao, sorry, I don't understand you clearly. I think I did not change the code original logical flow. What I do is setting "occlusion_query_boolean" to true only when context is ES3 and has not extension names. And if we are on top of ES3 and extension names are included in the EXTENSIONS string, AddExtensionString function will be called. Do you mean that if context_type_ is ES3 or WebGL2, AddExtensionString cannot be called? Could you give me more details, thank you.
https://codereview.chromium.org/2103773002/diff/60001/gpu/command_buffer/serv... File gpu/command_buffer/service/feature_info.cc (right): https://codereview.chromium.org/2103773002/diff/60001/gpu/command_buffer/serv... gpu/command_buffer/service/feature_info.cc:1060: if (have_ext_occlusion_query_boolean || On 2016/07/05 14:21:23, xinghua.cao wrote: > On 2016/07/04 16:06:05, Zhenyao Mo wrote: > > You should use context_type_ is ES3 or WEBGL2 here. > > > > Even if we are on top of ES3, extension names may still be included in the > > EXTENSIONS string. > > Zhenyao, sorry, I don't understand you clearly. > I think I did not change the code original logical flow. What I do is setting > "occlusion_query_boolean" to true only when context is ES3 and has not extension > names. And if we are on top of ES3 and extension names are included in the > EXTENSIONS string, AddExtensionString function will be called. > Do you mean that if context_type_ is ES3 or WebGL2, AddExtensionString cannot be > called? Could you give me more details, thank you. The outside if conditions make sure we actually have the functionality in the underlying driver, and the inside if conditions decide if we need to report the extension string. We only need to report the extension string in ES2 context. I don't even think we need to report it if it's WebGL1 context. (Sorry my original comment said the opposite thing)
LGTM again. This seems fine as written.
lgtm as well. thanks.
The CQ bit was checked by xinghua.cao@intel.com to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: cast_shell_linux on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/cast_shell_linu...)
The CQ bit was checked by xinghua.cao@intel.com to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
On 2016/07/06 19:46:57, Zhenyao Mo wrote: > lgtm as well. thanks. Hi, ken & zhenyao, Sorry, I had forgoten to run the gpu_unittest yesterday. The issue could not pass the CQ dry run. And I found that there was an error in the unit case. I should limit that "GL_EXT_occlusion_query_boolean" is expected when context_type_ is CONTEXT_TYPE_OPENGLES2. I had modified the unit test, please review it again. Thank you very much.
lgtm again
The CQ bit was checked by zmo@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
lgtm again too
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
The CQ bit was checked by xinghua.cao@intel.com
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Try jobs failed on following builders: linux_android_rel_ng on master.tryserver.chromium.android (JOB_FAILED, https://build.chromium.org/p/tryserver.chromium.android/builders/linux_androi...)
The CQ bit was checked by xinghua.cao@intel.com to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
The CQ bit was checked by xinghua.cao@intel.com
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
Message was sent while issue was closed.
Description was changed from ========== Occlusion query feature is already in GL ES3.0 spec, not an extension. BUG=623871 CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_optional_gpu_tests_rel;tryserver.chromium.mac:mac_optional_gpu_tests_rel;tryserver.chromium.win:win_optional_gpu_tests_rel ========== to ========== Occlusion query feature is already in GL ES3.0 spec, not an extension. BUG=623871 CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_optional_gpu_tests_rel;tryserver.chromium.mac:mac_optional_gpu_tests_rel;tryserver.chromium.win:win_optional_gpu_tests_rel ==========
Message was sent while issue was closed.
Committed patchset #6 (id:100001)
Message was sent while issue was closed.
Description was changed from ========== Occlusion query feature is already in GL ES3.0 spec, not an extension. BUG=623871 CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_optional_gpu_tests_rel;tryserver.chromium.mac:mac_optional_gpu_tests_rel;tryserver.chromium.win:win_optional_gpu_tests_rel ========== to ========== Occlusion query feature is already in GL ES3.0 spec, not an extension. BUG=623871 CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_optional_gpu_tests_rel;tryserver.chromium.mac:mac_optional_gpu_tests_rel;tryserver.chromium.win:win_optional_gpu_tests_rel Committed: https://crrev.com/2794a38ac40872a43fba5590297ef85ced1297b4 Cr-Commit-Position: refs/heads/master@{#404357} ==========
Message was sent while issue was closed.
Patchset 6 (id:??) landed as https://crrev.com/2794a38ac40872a43fba5590297ef85ced1297b4 Cr-Commit-Position: refs/heads/master@{#404357}
Message was sent while issue was closed.
On 2016/07/07 20:26:22, Ken Russell wrote: > lgtm again too Hi, Ken & zhenyao, Beacuse of the patch(https://codereview.chromium.org/2139673002), now, we could run webgl2.0 cases on mesa platform with opengl core profile 3.3. But all webgl2.0 occlusion query related htmls still fail. My patch here only resolves these failures on ES context. Do you think it is reasonable to extend this patch for OpenGL context. For example, use IsAtLeastGL(3, 3) to verify that occlusion query is standard feature.
Message was sent while issue was closed.
Yes, I think you should extend this into OGL context too. A suggestion is listed as below. https://codereview.chromium.org/2103773002/diff/100001/gpu/command_buffer/ser... File gpu/command_buffer/service/feature_info.cc (right): https://codereview.chromium.org/2103773002/diff/100001/gpu/command_buffer/ser... gpu/command_buffer/service/feature_info.cc:1048: gl_version_info_->IsAtLeastGLES(3, 0); We can use the code below: occlusion_query_in_core_feature = IsES3Capable(); Then use occlusion_query_in_core_feature, instead of have_es3_occlusion_query to cover both gles and OGL and other variants.
Message was sent while issue was closed.
On 2016/07/12 09:32:16, yunchao wrote: > Yes, I think you should extend this into OGL context too. A suggestion is listed > as below. > > https://codereview.chromium.org/2103773002/diff/100001/gpu/command_buffer/ser... > File gpu/command_buffer/service/feature_info.cc (right): > > https://codereview.chromium.org/2103773002/diff/100001/gpu/command_buffer/ser... > gpu/command_buffer/service/feature_info.cc:1048: > gl_version_info_->IsAtLeastGLES(3, 0); > We can use the code below: > occlusion_query_in_core_feature = IsES3Capable(); > > Then use occlusion_query_in_core_feature, instead of have_es3_occlusion_query to > cover both gles and OGL and other variants. I had check OpenGL 1.5 spec, and it already has this feature. Do I need to set least opengl version is 1.5 here? May someone give me some good idea?
Message was sent while issue was closed.
On 2016/07/12 10:17:23, xinghua.cao wrote: > On 2016/07/12 09:32:16, yunchao wrote: > > Yes, I think you should extend this into OGL context too. A suggestion is > listed > > as below. > > > > > https://codereview.chromium.org/2103773002/diff/100001/gpu/command_buffer/ser... > > File gpu/command_buffer/service/feature_info.cc (right): > > > > > https://codereview.chromium.org/2103773002/diff/100001/gpu/command_buffer/ser... > > gpu/command_buffer/service/feature_info.cc:1048: > > gl_version_info_->IsAtLeastGLES(3, 0); > > We can use the code below: > > occlusion_query_in_core_feature = IsES3Capable(); > > > > Then use occlusion_query_in_core_feature, instead of have_es3_occlusion_query > to > > cover both gles and OGL and other variants. > > I had check OpenGL 1.5 spec, and it already has this feature. Do I need to set > least opengl version is 1.5 here? May someone give me some good idea? It's not whether Query functions exist. The key is how to map |target| depending on the underlying functionality. See QueryManager::AdjustTargetForEmulation (I think that function probably should be updated that in ES3, ANY_SAMPLES_PASSED_CONSERVATIVE is actually supported by the underlying driver.
Message was sent while issue was closed.
On 2016/07/12 17:03:36, Zhenyao Mo wrote: > On 2016/07/12 10:17:23, xinghua.cao wrote: > > On 2016/07/12 09:32:16, yunchao wrote: > > > Yes, I think you should extend this into OGL context too. A suggestion is > > listed > > > as below. > > > > > > > > > https://codereview.chromium.org/2103773002/diff/100001/gpu/command_buffer/ser... > > > File gpu/command_buffer/service/feature_info.cc (right): > > > > > > > > > https://codereview.chromium.org/2103773002/diff/100001/gpu/command_buffer/ser... > > > gpu/command_buffer/service/feature_info.cc:1048: > > > gl_version_info_->IsAtLeastGLES(3, 0); > > > We can use the code below: > > > occlusion_query_in_core_feature = IsES3Capable(); > > > > > > Then use occlusion_query_in_core_feature, instead of > have_es3_occlusion_query > > to > > > cover both gles and OGL and other variants. > > > > I had check OpenGL 1.5 spec, and it already has this feature. Do I need to set > > least opengl version is 1.5 here? May someone give me some good idea? > > It's not whether Query functions exist. The key is how to map |target| depending > on the underlying functionality. > > See QueryManager::AdjustTargetForEmulation (I think that function probably > should be updated that in ES3, ANY_SAMPLES_PASSED_CONSERVATIVE is actually > supported by the underlying driver. Zhenyao, thank you for reply. I had checked the OpenGL spec, ANY_SAMPLES_PASSED is introduced by OpenGL 3.3, and ANY_SAMPLES_PASSED_CONSERVATIVE is introduced by OpenGL4.3. Does it mean cannot enable occlusion query feature on OpenGL3.3 context on mesa+i965 platform? Or is it possible to change the ANY_SAMPLES_PASSED_CONSERVATIVE to ANY_SAMPLES_PASSED in QueryManager::AdjustTargetForEmulation, which is like GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT?
Message was sent while issue was closed.
On 2016/07/13 09:51:57, xinghua.cao wrote: > On 2016/07/12 17:03:36, Zhenyao Mo wrote: > > On 2016/07/12 10:17:23, xinghua.cao wrote: > > > On 2016/07/12 09:32:16, yunchao wrote: > > > > Yes, I think you should extend this into OGL context too. A suggestion is > > > listed > > > > as below. > > > > > > > > > > > > > > https://codereview.chromium.org/2103773002/diff/100001/gpu/command_buffer/ser... > > > > File gpu/command_buffer/service/feature_info.cc (right): > > > > > > > > > > > > > > https://codereview.chromium.org/2103773002/diff/100001/gpu/command_buffer/ser... > > > > gpu/command_buffer/service/feature_info.cc:1048: > > > > gl_version_info_->IsAtLeastGLES(3, 0); > > > > We can use the code below: > > > > occlusion_query_in_core_feature = IsES3Capable(); > > > > > > > > Then use occlusion_query_in_core_feature, instead of > > have_es3_occlusion_query > > > to > > > > cover both gles and OGL and other variants. > > > > > > I had check OpenGL 1.5 spec, and it already has this feature. Do I need to > set > > > least opengl version is 1.5 here? May someone give me some good idea? > > > > It's not whether Query functions exist. The key is how to map |target| > depending > > on the underlying functionality. > > > > See QueryManager::AdjustTargetForEmulation (I think that function probably > > should be updated that in ES3, ANY_SAMPLES_PASSED_CONSERVATIVE is actually > > supported by the underlying driver. > > Zhenyao, thank you for reply. I had checked the OpenGL spec, ANY_SAMPLES_PASSED > is introduced by OpenGL 3.3, > and ANY_SAMPLES_PASSED_CONSERVATIVE is introduced by OpenGL4.3. Does it mean > cannot enable occlusion query > feature on OpenGL3.3 context on mesa+i965 platform? Or is it possible to change > the ANY_SAMPLES_PASSED_CONSERVATIVE > to ANY_SAMPLES_PASSED in QueryManager::AdjustTargetForEmulation, which is like > GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT? Xinghua, I think what Mo is saying is that yes, QueryManager::AdjustTargetForEmulation can be changed to use ANY_SAMPLES_PASSED for OpenGL versions >= 3.3 and < 4.3. Please submit a CL. Thanks. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
